void Update(string statusMessage) { // temp stop timer _heartbeatTimer.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite); DbTableDmlMgr dmlUpdateMgr = _daMgr.DbCatalogGetTableDmlMgr(DataAccess.Constants.SCHEMA_CORE , Constants.AppSessions); dmlUpdateMgr.SetWhereCondition((j) => j.Column(Constants.AppCode) == j.Parameter(dmlUpdateMgr.MainTable.SchemaName , dmlUpdateMgr.MainTable.TableName , Constants.AppCode , _daMgr.BuildParamName(Constants.AppCode)) && j.Column(Constants.MultipleSessionCode) == j.Parameter(dmlUpdateMgr.MainTable.SchemaName , dmlUpdateMgr.MainTable.TableName , Constants.MultipleSessionCode , _daMgr.BuildParamName(Constants.MultipleSessionCode))); dmlUpdateMgr.AddColumn(Constants.StatusMessage, _daMgr.BuildParamName(Constants.StatusMessage)); dmlUpdateMgr.AddColumn(Constants.StatusDateTime, Core.EnumDateTimeLocale.UTC); DbCommand dbCmdUpdate = _daMgr.BuildUpdateDbCommand(dmlUpdateMgr); dbCmdUpdate.Parameters[_daMgr.BuildParamName(Constants.AppCode)].Value = _appCode; dbCmdUpdate.Parameters[_daMgr.BuildParamName(Constants.MultipleSessionCode)].Value = _appSessionCode; dbCmdUpdate.Parameters[_daMgr.BuildParamName(Constants.StatusMessage)].Value = statusMessage; DbCommandMgr dbCmdMgr = new DbCommandMgr(_daMgr); dbCmdMgr.AddDbCommand(dbCmdUpdate); // refresh signon control List <string> tableNames = new List <string>(); DbTableDmlMgr dmlSelectMgr = _daMgr.DbCatalogGetTableDmlMgr(DataAccess.Constants.SCHEMA_CORE , Constants.SignonControl); DbCommand dbCmdSelect = _daMgr.BuildSelectDbCommand(dmlSelectMgr, null); dbCmdMgr.AddDbCommand(dbCmdSelect); tableNames.Add(Constants.SignonControl); // refresh app sessions dmlSelectMgr = _daMgr.DbCatalogGetTableDmlMgr(DataAccess.Constants.SCHEMA_CORE , Constants.AppSessions); dbCmdSelect = _daMgr.BuildSelectDbCommand(dmlSelectMgr, null); dbCmdMgr.AddDbCommand(dbCmdSelect); tableNames.Add(Constants.AppSessions); DataSet controldata = dbCmdMgr.ExecuteDataSet(tableNames); _signonControl.Refresh(controldata.Tables[Constants.SignonControl]); _appSessions = controldata.Tables[Constants.AppSessions]; // temp start timer _heartbeatTimer.Change(_signonControl.SignonControlData.StatusSeconds * 1000 , _signonControl.SignonControlData.StatusSeconds * 1000); }
/// <summary> /// Implements the user signon operation /// </summary> /// <param name="daMgr">DataAccessMgr object</param> /// <param name="signonControl">SignonControl data structure</param> /// <param name="userId">Unique user identifier</param> /// <param name="userPassword">User's password (NULL for first time initialization)</param> /// <param name="userEnv">Meta data about user's environment</param> /// <param name="allowMultipleSessions">Indicates whether to allow multiple session for an account that was not setup for multiple sessions</param> /// <returns>SignonResult data structure</returns> public static SignonResultsStructure Signon(DataAccessMgr daMgr , SignonControl signonControl , string userId , string userPassword , UserEnvironmentStructure userEnv , bool allowMultipleSessions = false) { SignonResultsStructure results = new SignonResultsStructure(); results.ResultEnum = SignonResultsEnum.Success; results.ResultMessage = null; DbTableDmlMgr dmlSelectMgr = daMgr.DbCatalogGetTableDmlMgr(DataAccess.Constants.SCHEMA_CORE , Constants.UserMaster , Constants.UserCode , Constants.UserPassword , Constants.PasswordSalt , Constants.SignonRestricted , Constants.LastSignonDateTime , Constants.FailedSignonAttempts , Constants.ForcePasswordChange , Constants.MultipleSignonAllowed , Constants.DefaultAccessGroupCode); dmlSelectMgr.SetWhereCondition((j) => j.Column(Constants.UserId) == j.Parameter(dmlSelectMgr.MainTable.SchemaName , dmlSelectMgr.MainTable.TableName , Constants.UserId , daMgr.BuildParamName(Constants.UserId))); DbCommand cmdSelectUserMaster = daMgr.BuildSelectDbCommand(dmlSelectMgr, null); cmdSelectUserMaster.Parameters[daMgr.BuildParamName(Constants.UserId)].Value = userId; DbCommandMgr dbCmdMgr = new DbCommandMgr(daMgr); dbCmdMgr.AddDbCommand(cmdSelectUserMaster); if (!allowMultipleSessions) { dmlSelectMgr = daMgr.DbCatalogGetTableDmlMgr(DataAccess.Constants.SCHEMA_CORE , Constants.UserSessions , Constants.SessionCode , Constants.SessionDateTime , Constants.ForceSignOff); dmlSelectMgr.SetWhereCondition((j) => j.Column(Constants.UserId) == j.Parameter(dmlSelectMgr.MainTable.SchemaName , dmlSelectMgr.MainTable.TableName , Constants.UserId , daMgr.BuildParamName(Constants.UserId))); DbCommand cmdSelectSessions = daMgr.BuildSelectDbCommand(dmlSelectMgr, null); cmdSelectSessions.Parameters[daMgr.BuildParamName(Constants.UserId)].Value = userId; dbCmdMgr.AddDbCommand(cmdSelectSessions); } List <string> tableNames = new List <string>(); tableNames.Add(Constants.UserMaster); if (!allowMultipleSessions) { tableNames.Add(Constants.UserSessions); } DataSet userSigonData = dbCmdMgr.ExecuteDataSet(tableNames); DataTable userMaster = userSigonData.Tables[Constants.UserMaster]; // see if the userId exists and that the password is correct if (userMaster.Rows.Count == 0) { // userId does not exists, return an invalid credentials message results.ResultEnum = SignonResultsEnum.InvaldCredentials; results.ResultMessage = "Incorrect UserId or Password, please try again."; return(results); } string storedUserPassword = userMaster.Rows[0][Constants.UserPassword].ToString(); string passwordSalt = userMaster.Rows[0][Constants.PasswordSalt].ToString(); userPassword = Cryptography.HashOperation.ComputeHash(HashAlgorithmTypeEnum.SHA512HashAlgorithm, userPassword, passwordSalt); if (storedUserPassword != userPassword) { // invalid credentials; do not indicate whether userId or password is incorrect results.ResultEnum = SignonResultsEnum.InvaldCredentials; results.ResultMessage = "Incorrect UserId or Password, please try again."; Int16 failedAttempts = IncreaseFailedAttemptCount(daMgr, userId); // check for failed limit and restrict account if (failedAttempts >= signonControl.SignonControlData.FailedAttemptLimit) { RestrictSignon(daMgr, userId); } return(results); } // Since the UserId and Password matched, we found the account, // now check for account level restrictions bool signonRestricted = Convert.ToBoolean(userMaster.Rows[0][Constants.SignonRestricted]); if (signonRestricted) { // invalid credentials; do not indicate whether userId or password is incorrect results.ResultEnum = SignonResultsEnum.SignonsRestricted; results.ResultMessage = "The account is restrcited from signing on."; return(results); } bool ForcePasswordChange = Convert.ToBoolean(userMaster.Rows[0][Constants.ForcePasswordChange]); if (ForcePasswordChange) { // invalid credentials; do not indicate whether userId or password is incorrect results.ResultEnum = SignonResultsEnum.PasswordChangeRequired; results.ResultMessage = "The account requires a password change before proceeding."; return(results); } if (!allowMultipleSessions) { bool MultipleSignonAllowed = Convert.ToBoolean(userMaster.Rows[0][Constants.MultipleSignonAllowed]); DataTable userSessions = userSigonData.Tables[Constants.UserSessions]; Int16 sessionCount = 0; foreach (DataRow userSession in userSessions.Rows) { DateTime sessionDateTime = Convert.ToDateTime(userSession[Constants.SessionDateTime]); TimeSpan sessionInterval = daMgr.DbSynchTime - sessionDateTime; if (sessionInterval.TotalSeconds < signonControl.SignonControlData.TimeOutSeconds) { if (!MultipleSignonAllowed) { // if the user cannot have multiple signons, then we must check // for existing (Active) session results.ResultEnum = SignonResultsEnum.MultipleSignonRestricted; results.ResultMessage = "The account can only have a single signon session. They must signOff the other session first."; return(results); } ++sessionCount; } } } // if the userId and password are correct, check signon control (general restrictions) if (signonControl.SignonControlData.RestrictSignon) { results.ResultEnum = SignonResultsEnum.SignonsRestricted; results.ResultMessage = signonControl.SignonControlData.RestrictSignonMsg; return(results); } if (signonControl.SignonControlData.ForceSignoff) { results.ResultEnum = SignonResultsEnum.ForcedSignoff; results.ResultMessage = signonControl.SignonControlData.SignoffWarningMsg; return(results); } // successful signon UserSignonSessionStructure uss = new UserSignonSessionStructure(); uss.UserCode = Convert.ToInt32(userMaster.Rows[0][Constants.UserCode]); uss.PasswordHash = userMaster.Rows[0][Constants.UserPassword].ToString(); uss.DefaultAccessGroupCode = Convert.ToInt32(userMaster.Rows[0][Constants.DefaultAccessGroupCode]); uss.UserId = userId; uss.SignonApp.AppCode = userEnv.AppCode; uss.SignonApp.AppId = userEnv.AppId; uss.SignonApp.AppVersion = userEnv.AppVersion; uss.SessionCode = AddSession(daMgr, userId, uss.UserCode, userEnv); UserSession sessionMgr = new UserSession(daMgr, uss); results.ResultMessage = "Welcome."; if (userMaster.Rows[0][Constants.LastSignonDateTime] != DBNull.Value) { DateTime signonDateTime = Convert.ToDateTime(userMaster.Rows[0][Constants.LastSignonDateTime]); results.ResultMessage += " Your last signon was: ." + signonDateTime.ToString(); } results.ResultEnum = SignonResultsEnum.Success; results.UserSessionMgr = sessionMgr; return(results); }