/// <summary> /// клиент выполнил логаут /// </summary> public void Logout(ProtectedOperationContext ctx) { // проверить контекст var userHash = CredentialsHash.MakeOperationParamsHash(ctx.clientLocalTime, ctx.sessionTag, ctx.terminalId); if (ctx.hash != userHash) { return; } // найти сессию try { sessionLocker.AcquireWriterLock(SessionLockTimeout); } catch (ApplicationException) { Logger.Error("Logout read timout"); return; } try { sessions.Remove(ctx.terminalId); } catch (Exception ex) { Logger.Error("Logout error", ex); return; } finally { sessionLocker.ReleaseLock(); } }
public ProtectedOperationContext MakeProtectedContext() { if (sessionTag == 0) { return(null); } var context = new ProtectedOperationContext { sessionTag = sessionTag, terminalId = terminalId, clientLocalTime = DateTime.Now.Ticks, userMachineName = shortMachineName }; context.hash = CredentialsHash.MakeOperationParamsHash(context.clientLocalTime, sessionTag, terminalId); return(context); }
/// <summary> /// сравнить переданные в запросе на торговую операцию параметры /// с переданным хэш-отпечатком, найти запись в хранилище сессий, /// обновить ее /// второй параметр опциональный /// </summary> public bool PermitUserOperation(ProtectedOperationContext ctx, ITradeSharpServerCallback callback, int?accountId, string login, bool isTradeOperation, bool checkAccountId) { // отправитель - сервер? if (ctx == null) { Logger.ErrorFormat("PermitUserOperation - login is \"{0}\" - no context", login); return(false); } if (ProtectedOperationContext.IsServerContext(ctx)) { return(true); } var userHash = CredentialsHash.MakeOperationParamsHash(ctx.clientLocalTime, ctx.sessionTag, ctx.terminalId); if (ctx.hash != userHash) { Logger.InfoFormat("[{0: {1}] - hash is incorrect ({2}, correct hash: {3})", login, accountId, ctx, userHash); return(false); } // найти сессию try { sessionLocker.AcquireReaderLock(SessionLockTimeout); } catch (ApplicationException) { Logger.Error("PermitUserOperation read timout"); return(false); } try { UserSession session; sessions.TryGetValue(ctx.terminalId, out session); if (session == null) { return(false); } if (!string.IsNullOrEmpty(login)) { if (login != session.login) { Logger.InfoFormat("Session #{0}: login ({1}) != session login ({2})", ctx.terminalId, login, session.login); return(false); } } // обновить сессию try { sessionLocker.UpgradeToWriterLock(SessionLockTimeout); } catch (ApplicationException) { Logger.Error("PermitUserOperation write timout"); return(false); } if (accountId.HasValue || checkAccountId) { var targetAccount = accountId ?? session.accountId; var accountRights = session.enabledAccounts.FirstOrNull(a => a.a == targetAccount); // дополнительно проверяется, есть ли права на торговую (или иную защищенную) операцию var hasRights = accountRights.HasValue && (accountRights.Value.b || !isTradeOperation); if (!hasRights) { Logger.InfoFormat("User {0} #{1} has insufficient rights (trade op: {2}, session: {3} / {4})", login, targetAccount, isTradeOperation, ctx.terminalId, string.Join(",", session.enabledAccounts.Select(a => string.Format("{0}:{1}", a.a, a.b ? "en" : "dis")))); //Logger.Error("PermitUserOperation: возврат false, session.enabledAccounts.Contains счет " + // session.accountId); return(false); } } // прописать счет для сессии if (accountId.HasValue) { session.accountId = accountId.Value; Logger.Info("PermitUserOperation: Успешная смена счета " + accountId.Value); } session.lastRequestClientTime = ctx.clientLocalTime; if (callback != null) { session.callback = callback; } // доступ разрешен return(true); } catch (Exception ex) { Logger.Error("PermitUserOperation error", ex); return(false); } finally { sessionLocker.ReleaseLock(); } }