/// <summary> /// the client can cancel the job /// </summary> /// <param name="AClientID"></param> static public bool CancelJob(string AClientID) { if (TSession.HasVariable(PROGRESSTRACKER + AClientID)) { TProgressState state = ((JObject)TSession.GetVariable(PROGRESSTRACKER + AClientID)).ToObject <TProgressState>(); TLogging.SetStatusBarProcedure(null); if (state.JobFinished == true) { if (TLogging.DebugLevel >= DEBUG_PROGRESS) { TLogging.Log("Cannot cancel the job for " + AClientID + " because the job has already finished"); } } else { state.CancelJob = true; if (TLogging.DebugLevel >= DEBUG_PROGRESS) { TLogging.Log("Cancelled the job for " + AClientID); } TSession.SetVariable(PROGRESSTRACKER + AClientID, state); return(true); } } return(false); }
/// <summary> /// get the current state, by clientID /// </summary> /// <param name="AClientID"></param> /// <returns></returns> static public TProgressState GetCurrentState(string AClientID) { TSession.RefreshFromDatabase(); if ((AClientID != null) && TSession.HasVariable(PROGRESSTRACKER + AClientID)) { TProgressState state = ((JObject)TSession.GetVariable(PROGRESSTRACKER + AClientID)).ToObject <TProgressState>(); if (state.PercentageDone > 100) { TLogging.Log("invalid percentage: " + state.PercentageDone.ToString()); state.PercentageDone = 99; } return(state); } return(new TProgressState()); }
/// <summary> /// set the current state /// </summary> /// <param name="AClientID"></param> /// <param name="AStatusMessage"></param> /// <param name="ACurrentAbsoluteAmount"></param> static public void SetCurrentState(string AClientID, string AStatusMessage, Decimal ACurrentAbsoluteAmount) { if (TSession.HasVariable(PROGRESSTRACKER + AClientID)) { TProgressState state = ((JObject)TSession.GetVariable(PROGRESSTRACKER + AClientID)).ToObject <TProgressState>(); if (AStatusMessage.Length > 0) { state.StatusMessage = AStatusMessage; } state.PercentageDone = Convert.ToInt32((ACurrentAbsoluteAmount / state.AbsoluteOverallAmount) * 100.0m); if (TLogging.DebugLevel >= DEBUG_PROGRESS) { // avoid recursive calls, especially during report calculation Console.WriteLine(state.PercentageDone.ToString() + "%: " + state.StatusMessage); } TSession.SetVariable(PROGRESSTRACKER + AClientID, state); } }
/// <summary> /// the server will set the job to finished /// </summary> static public bool FinishJob(string AClientID) { if (TSession.HasVariable(PROGRESSTRACKER + AClientID)) { TProgressState state = ((JObject)TSession.GetVariable(PROGRESSTRACKER + AClientID)).ToObject <TProgressState>(); state.JobFinished = true; if (TLogging.DebugLevel >= DEBUG_PROGRESS) { TLogging.Log("Finished the job for " + AClientID); } TSession.SetVariable(PROGRESSTRACKER + AClientID, state); TLogging.SetStatusBarProcedure(null); return(true); } return(false); }
public static TPetraPrincipal PerformUserAuthentication(String AUserID, String APassword, string AClientComputerName, string AClientIPAddress, out Boolean ASystemEnabled, TDBTransaction ATransaction) { SUserRow UserDR; DateTime LoginDateTime; TPetraPrincipal PetraPrincipal = null; string UserAuthenticationMethod = TAppSettingsManager.GetValue("UserAuthenticationMethod", "OpenPetraDBSUser", false); IUserAuthentication AuthenticationAssembly; string AuthAssemblyErrorMessage; Int32 AProcessID = -1; ASystemEnabled = true; string EmailAddress = AUserID; if (EmailAddress.Contains("@")) { // try to find unique User for this e-mail address string sql = "SELECT s_user_id_c FROM PUB_s_user WHERE UPPER(s_email_address_c) = ?"; OdbcParameter[] parameters = new OdbcParameter[1]; parameters[0] = new OdbcParameter("EmailAddress", OdbcType.VarChar); parameters[0].Value = EmailAddress.ToUpper(); DataTable result = ATransaction.DataBaseObj.SelectDT(sql, "user", ATransaction, parameters); if (result.Rows.Count == 1) { AUserID = result.Rows[0][0].ToString(); } else { TLogging.Log("Login with E-Mail address failed for " + EmailAddress + ". " + "We found " + result.Rows.Count.ToString() + " matching rows for this address."); } } try { UserDR = LoadUser(AUserID, out PetraPrincipal, ATransaction); } catch (EUserNotExistantException) { TPetraIdentity PetraIdentity = new TPetraIdentity( "SYSADMIN", "", "", "", "", DateTime.MinValue, DateTime.MinValue, DateTime.MinValue, 0, -1, -1, false, false, false); UserInfo.GUserInfo = new TPetraPrincipal(PetraIdentity, null); // Logging TLoginLog.AddLoginLogEntry(AUserID, TLoginLog.LOGIN_STATUS_TYPE_LOGIN_ATTEMPT_FOR_NONEXISTING_USER, String.Format(Catalog.GetString( "User with User ID '{0}' attempted to log in, but there is no user account for this user! "), AUserID) + String.Format(ResourceTexts.StrRequestCallerInfo, AClientComputerName, AClientIPAddress), out AProcessID, ATransaction); // Only now throw the Exception! throw; } UserInfo.GUserInfo = PetraPrincipal; if ((AUserID == "SYSADMIN") && TSession.HasVariable("ServerAdminToken")) { // Login via server admin console authenticated by file token APassword = String.Empty; } // // (1) Check user-supplied password // else if (UserAuthenticationMethod == "OpenPetraDBSUser") { if (!TPasswordHelper.EqualsAntiTimingAttack( Convert.FromBase64String( CreateHashOfPassword(APassword, UserDR.PasswordSalt, UserDR.PwdSchemeVersion)), Convert.FromBase64String(UserDR.PasswordHash))) { // The password that the user supplied is wrong!!! --> Save failed user login attempt! // If the number of permitted failed logins in a row gets exceeded then also lock the user account! SaveFailedLogin(AUserID, UserDR, AClientComputerName, AClientIPAddress, ATransaction); if (UserDR.AccountLocked && (Convert.ToBoolean(UserDR[SUserTable.GetAccountLockedDBName(), DataRowVersion.Original]) != UserDR.AccountLocked)) { // User Account just got locked! throw new EUserAccountGotLockedException(StrInvalidUserIDPassword); } else { throw new EPasswordWrongException(StrInvalidUserIDPassword); } } } else { AuthenticationAssembly = LoadAuthAssembly(UserAuthenticationMethod); if (!AuthenticationAssembly.AuthenticateUser(EmailAddress, APassword, out AuthAssemblyErrorMessage)) { // The password that the user supplied is wrong!!! --> Save failed user login attempt! // If the number of permitted failed logins in a row gets exceeded then also lock the user account! SaveFailedLogin(AUserID, UserDR, AClientComputerName, AClientIPAddress, ATransaction); if (UserDR.AccountLocked && (Convert.ToBoolean(UserDR[SUserTable.GetAccountLockedDBName(), DataRowVersion.Original]) != UserDR.AccountLocked)) { // User Account just got locked! throw new EUserAccountGotLockedException(StrInvalidUserIDPassword); } else { throw new EPasswordWrongException(AuthAssemblyErrorMessage); } } } // // (2) Check if the User Account is Locked or if the user is 'Retired'. If either is true then deny the login!!! // // IMPORTANT: We perform these checks only AFTER the check for the correctness of the password so that every // log-in attempt that gets rejected on grounds of a wrong password takes the same amount of time (to help prevent // an attack vector called 'timing attack') if (PetraPrincipal.PetraIdentity.AccountLocked || PetraPrincipal.PetraIdentity.Retired) { if (PetraPrincipal.PetraIdentity.AccountLocked) { // Logging TLoginLog.AddLoginLogEntry(AUserID, TLoginLog.LOGIN_STATUS_TYPE_LOGIN_ATTEMPT_FOR_LOCKED_USER, Catalog.GetString("User attempted to log in, but the user account was locked! ") + String.Format(ResourceTexts.StrRequestCallerInfo, AClientComputerName, AClientIPAddress), out AProcessID, ATransaction); // Only now throw the Exception! throw new EUserAccountLockedException(StrInvalidUserIDPassword); } else { // Logging TLoginLog.AddLoginLogEntry(AUserID, TLoginLog.LOGIN_STATUS_TYPE_LOGIN_ATTEMPT_FOR_RETIRED_USER, Catalog.GetString("User attempted to log in, but the user is retired! ") + String.Format(ResourceTexts.StrRequestCallerInfo, AClientComputerName, AClientIPAddress), out AProcessID, ATransaction); // Only now throw the Exception! throw new EUserRetiredException(StrInvalidUserIDPassword); } } // // (3) Check SystemLoginStatus (whether the general use of the OpenPetra application is enabled/disabled) in the // SystemStatus table (this table always holds only a single record) // SSystemStatusTable SystemStatusDT; SystemStatusDT = SSystemStatusAccess.LoadAll(ATransaction); if (SystemStatusDT[0].SystemLoginStatus) { ASystemEnabled = true; } else { ASystemEnabled = false; // TODO: Check for Security Group membership might need reviewal when security model of OpenPetra might get reviewed... if (PetraPrincipal.IsInGroup("SYSADMIN")) { PetraPrincipal.LoginMessage = String.Format(StrSystemDisabled1, SystemStatusDT[0].SystemDisabledReason) + Environment.NewLine + Environment.NewLine + StrSystemDisabled2Admin; } else { TLoginLog.AddLoginLogEntry(AUserID, TLoginLog.LOGIN_STATUS_TYPE_LOGIN_ATTEMPT_WHEN_SYSTEM_WAS_DISABLED, Catalog.GetString("User wanted to log in, but the System was disabled. ") + String.Format(ResourceTexts.StrRequestCallerInfo, AClientComputerName, AClientIPAddress), out AProcessID, ATransaction); TLoginLog.RecordUserLogout(AUserID, AProcessID, ATransaction); throw new ESystemDisabledException(String.Format(StrSystemDisabled1, SystemStatusDT[0].SystemDisabledReason) + Environment.NewLine + Environment.NewLine + String.Format(StrSystemDisabled2, StringHelper.DateToLocalizedString(SystemStatusDT[0].SystemAvailableDate.Value), SystemStatusDT[0].SystemAvailableDate.Value.AddSeconds(SystemStatusDT[0].SystemAvailableTime).ToShortTimeString())); } } // // (4) Save successful login! // LoginDateTime = DateTime.Now; UserDR.LastLoginDate = LoginDateTime; UserDR.LastLoginTime = Conversions.DateTimeToInt32Time(LoginDateTime); UserDR.FailedLogins = 0; // this needs resetting! // Upgrade the user's password hashing scheme if it is older than the current password hashing scheme if (APassword != String.Empty && UserDR.PwdSchemeVersion < TPasswordHelper.CurrentPasswordSchemeNumber) { TMaintenanceWebConnector.SetNewPasswordHashAndSaltForUser(UserDR, APassword, AClientComputerName, AClientIPAddress, ATransaction); } SaveUser(AUserID, (SUserTable)UserDR.Table, ATransaction); PetraPrincipal.PetraIdentity.CurrentLogin = LoginDateTime; //PetraPrincipal.PetraIdentity.FailedLogins = 0; // TODO: Check for Security Group membership might need reviewal when security model of OpenPetra might get reviewed... if (PetraPrincipal.IsInGroup("SYSADMIN")) { TLoginLog.AddLoginLogEntry(AUserID, TLoginLog.LOGIN_STATUS_TYPE_LOGIN_SUCCESSFUL_SYSADMIN, Catalog.GetString("User login - SYSADMIN privileges. ") + String.Format(ResourceTexts.StrRequestCallerInfo, AClientComputerName, AClientIPAddress), out AProcessID, ATransaction); } else { TLoginLog.AddLoginLogEntry(AUserID, TLoginLog.LOGIN_STATUS_TYPE_LOGIN_SUCCESSFUL, Catalog.GetString("User login. ") + String.Format(ResourceTexts.StrRequestCallerInfo, AClientComputerName, AClientIPAddress), out AProcessID, ATransaction); } PetraPrincipal.ProcessID = AProcessID; AProcessID = 0; // // (5) Check if a password change is requested for this user // if (UserDR.PasswordNeedsChange) { // The user needs to change their password before they can use OpenPetra PetraPrincipal.LoginMessage = SharedConstants.LOGINMUSTCHANGEPASSWORD; } return(PetraPrincipal); }
public static bool PerformUserAuthentication(String AUserID, String APassword, string AClientComputerName, string AClientIPAddress, out Boolean ASystemEnabled, TDBTransaction ATransaction) { SUserRow UserDR; DateTime LoginDateTime; TPetraPrincipal PetraPrincipal = null; string UserAuthenticationMethod = TAppSettingsManager.GetValue("UserAuthenticationMethod", "OpenPetraDBSUser", false); IUserAuthentication AuthenticationAssembly; string AuthAssemblyErrorMessage; Int32 AProcessID = -1; ASystemEnabled = true; CheckDatabaseVersion(ATransaction.DataBaseObj); string EmailAddress = AUserID; try { UserDR = LoadUser(AUserID, out PetraPrincipal, ATransaction); } catch (EUserNotExistantException) { // pass ATransaction UserInfo.SetUserInfo(new TPetraPrincipal("SYSADMIN")); // Logging TLoginLog.AddLoginLogEntry(AUserID, TLoginLog.LOGIN_STATUS_TYPE_LOGIN_ATTEMPT_FOR_NONEXISTING_USER, String.Format(Catalog.GetString( "User with User ID '{0}' attempted to log in, but there is no user account for this user! "), AUserID) + String.Format(ResourceTexts.StrRequestCallerInfo, AClientComputerName, AClientIPAddress), out AProcessID, ATransaction); // Only now throw the Exception! throw; } // pass ATransaction UserInfo.SetUserInfo(PetraPrincipal); if (AUserID == "SELFSERVICE") { APassword = String.Empty; } else if ((AUserID == "SYSADMIN") && TSession.HasVariable("ServerAdminToken")) { // Login via server admin console authenticated by file token APassword = String.Empty; } // // (1) Check user-supplied password // else if (UserAuthenticationMethod == "OpenPetraDBSUser") { if (!TPasswordHelper.EqualsAntiTimingAttack( Convert.FromBase64String( CreateHashOfPassword(APassword, UserDR.PasswordSalt, UserDR.PwdSchemeVersion)), Convert.FromBase64String(UserDR.PasswordHash))) { // The password that the user supplied is wrong!!! --> Save failed user login attempt! // If the number of permitted failed logins in a row gets exceeded then also lock the user account! SaveFailedLogin(AUserID, UserDR, AClientComputerName, AClientIPAddress, ATransaction); if (UserDR.AccountLocked && (Convert.ToBoolean(UserDR[SUserTable.GetAccountLockedDBName(), DataRowVersion.Original]) != UserDR.AccountLocked)) { // User Account just got locked! throw new EUserAccountGotLockedException(StrInvalidUserIDPassword); } else { throw new EPasswordWrongException(StrInvalidUserIDPassword); } } } else { AuthenticationAssembly = LoadAuthAssembly(UserAuthenticationMethod); if (!AuthenticationAssembly.AuthenticateUser(EmailAddress, APassword, out AuthAssemblyErrorMessage)) { // The password that the user supplied is wrong!!! --> Save failed user login attempt! // If the number of permitted failed logins in a row gets exceeded then also lock the user account! SaveFailedLogin(AUserID, UserDR, AClientComputerName, AClientIPAddress, ATransaction); if (UserDR.AccountLocked && (Convert.ToBoolean(UserDR[SUserTable.GetAccountLockedDBName(), DataRowVersion.Original]) != UserDR.AccountLocked)) { // User Account just got locked! throw new EUserAccountGotLockedException(StrInvalidUserIDPassword); } else { throw new EPasswordWrongException(AuthAssemblyErrorMessage); } } } // // (2) Check if the User Account is Locked or if the user is 'Retired'. If either is true then deny the login!!! // // IMPORTANT: We perform these checks only AFTER the check for the correctness of the password so that every // log-in attempt that gets rejected on grounds of a wrong password takes the same amount of time (to help prevent // an attack vector called 'timing attack') if (UserDR.AccountLocked || UserDR.Retired) { if ((AUserID == "SYSADMIN") && TSession.HasVariable("ServerAdminToken")) { // this is ok. we need to be able to activate the sysadmin account on SetInitialSysadminEmail } else if (UserDR.AccountLocked) { // Logging TLoginLog.AddLoginLogEntry(AUserID, TLoginLog.LOGIN_STATUS_TYPE_LOGIN_ATTEMPT_FOR_LOCKED_USER, Catalog.GetString("User attempted to log in, but the user account was locked! ") + String.Format(ResourceTexts.StrRequestCallerInfo, AClientComputerName, AClientIPAddress), out AProcessID, ATransaction); // Only now throw the Exception! throw new EUserAccountLockedException(StrInvalidUserIDPassword); } else { // Logging TLoginLog.AddLoginLogEntry(AUserID, TLoginLog.LOGIN_STATUS_TYPE_LOGIN_ATTEMPT_FOR_RETIRED_USER, Catalog.GetString("User attempted to log in, but the user is retired! ") + String.Format(ResourceTexts.StrRequestCallerInfo, AClientComputerName, AClientIPAddress), out AProcessID, ATransaction); // Only now throw the Exception! throw new EUserRetiredException(StrInvalidUserIDPassword); } } // // (3) Check SystemLoginStatus (whether the general use of the OpenPetra application is enabled/disabled) in the // SystemStatus table (this table always holds only a single record) // SSystemStatusTable SystemStatusDT; SystemStatusDT = SSystemStatusAccess.LoadAll(ATransaction); if (SystemStatusDT[0].SystemLoginStatus) { ASystemEnabled = true; } else { ASystemEnabled = false; // TODO: Check for Security Group membership might need reviewal when security model of OpenPetra might get reviewed... if (PetraPrincipal.IsInGroup("SYSADMIN")) { PetraPrincipal.LoginMessage = String.Format(StrSystemDisabled1, SystemStatusDT[0].SystemDisabledReason) + Environment.NewLine + Environment.NewLine + StrSystemDisabled2Admin; } else { TLoginLog.AddLoginLogEntry(AUserID, TLoginLog.LOGIN_STATUS_TYPE_LOGIN_ATTEMPT_WHEN_SYSTEM_WAS_DISABLED, Catalog.GetString("User wanted to log in, but the System was disabled. ") + String.Format(ResourceTexts.StrRequestCallerInfo, AClientComputerName, AClientIPAddress), out AProcessID, ATransaction); TLoginLog.RecordUserLogout(AUserID, AProcessID, ATransaction); throw new ESystemDisabledException(String.Format(StrSystemDisabled1, SystemStatusDT[0].SystemDisabledReason) + Environment.NewLine + Environment.NewLine + String.Format(StrSystemDisabled2, StringHelper.DateToLocalizedString(SystemStatusDT[0].SystemAvailableDate.Value), SystemStatusDT[0].SystemAvailableDate.Value.AddSeconds(SystemStatusDT[0].SystemAvailableTime).ToShortTimeString())); } } // // (3b) Check if the license is valid // string LicenseCheckUrl = TAppSettingsManager.GetValue("LicenseCheck.Url", String.Empty, false); string LicenseUser = TAppSettingsManager.GetValue("Server.DBName"); if ((AUserID == "SYSADMIN") && TSession.HasVariable("ServerAdminToken")) { // don't check for the license, since this is called when upgrading the server as well. LicenseCheckUrl = String.Empty; } if ((LicenseCheckUrl != String.Empty) && (LicenseUser != "openpetra")) { string url = LicenseCheckUrl + LicenseUser; string result = THTTPUtils.ReadWebsite(url); bool valid = result.Contains("\"valid\":true"); bool gratis = result.Contains("\"gratis\":true"); if (!valid && !gratis) { TLoginLog.AddLoginLogEntry(AUserID, TLoginLog.LOGIN_STATUS_TYPE_LOGIN_ATTEMPT_WHEN_SYSTEM_WAS_DISABLED, Catalog.GetString("User wanted to log in, but the license is expired. ") + String.Format(ResourceTexts.StrRequestCallerInfo, AClientComputerName, AClientIPAddress), out AProcessID, ATransaction); TLoginLog.RecordUserLogout(AUserID, AProcessID, ATransaction); throw new ELicenseExpiredException("LICENSE_EXPIRED"); } } // // (4) Save successful login! // LoginDateTime = DateTime.Now; UserDR.LastLoginDate = LoginDateTime; UserDR.LastLoginTime = Conversions.DateTimeToInt32Time(LoginDateTime); UserDR.FailedLogins = 0; // this needs resetting! // Upgrade the user's password hashing scheme if it is older than the current password hashing scheme if (APassword != String.Empty && UserDR.PwdSchemeVersion < TPasswordHelper.CurrentPasswordSchemeNumber) { TMaintenanceWebConnector.SetNewPasswordHashAndSaltForUser(UserDR, APassword, AClientComputerName, AClientIPAddress, ATransaction); } SaveUser(AUserID, (SUserTable)UserDR.Table, ATransaction); // TODO: Check for Security Group membership might need reviewal when security model of OpenPetra might get reviewed... if (PetraPrincipal.IsInGroup("SYSADMIN")) { TLoginLog.AddLoginLogEntry(AUserID, TLoginLog.LOGIN_STATUS_TYPE_LOGIN_SUCCESSFUL_SYSADMIN, Catalog.GetString("User login - SYSADMIN privileges. ") + String.Format(ResourceTexts.StrRequestCallerInfo, AClientComputerName, AClientIPAddress), out AProcessID, ATransaction); } else { TLoginLog.AddLoginLogEntry(AUserID, TLoginLog.LOGIN_STATUS_TYPE_LOGIN_SUCCESSFUL, Catalog.GetString("User login. ") + String.Format(ResourceTexts.StrRequestCallerInfo, AClientComputerName, AClientIPAddress), out AProcessID, ATransaction); } PetraPrincipal.ProcessID = AProcessID; AProcessID = 0; // // (5) Check if a password change is requested for this user // if (UserDR.PasswordNeedsChange) { // The user needs to change their password before they can use OpenPetra PetraPrincipal.LoginMessage = SharedConstants.LOGINMUSTCHANGEPASSWORD; } return(true); }
public static TPetraPrincipal PerformUserAuthentication(String AUserID, String APassword, out Boolean ASystemEnabled) { DateTime LoginDateTime; TPetraPrincipal PetraPrincipal = null; Int32 AProcessID = -1; ASystemEnabled = true; string EmailAddress = AUserID; if (AUserID.Contains("@")) { AUserID = AUserID.Substring(0, AUserID.IndexOf("@")). Replace(".", string.Empty). Replace("_", string.Empty).ToUpper(); } try { SUserRow UserDR = LoadUser(AUserID, out PetraPrincipal); // Already assign the global variable here, because it is needed for SUserAccess.SubmitChanges later in this function UserInfo.GUserInfo = PetraPrincipal; // Check if user is retired if (PetraPrincipal.PetraIdentity.Retired) { throw new EUserRetiredException(StrInvalidUserIDPassword); } int FailedLoginsUntilRetire = Convert.ToInt32( TSystemDefaults.GetSystemDefault(SharedConstants.SYSDEFAULT_FAILEDLOGINS_UNTIL_RETIRE, "10")); // Console.WriteLine('PetraPrincipal.PetraIdentity.FailedLogins: ' + PetraPrincipal.PetraIdentity.FailedLogins.ToString + // '; PetraPrincipal.PetraIdentity.Retired: ' + PetraPrincipal.PetraIdentity.Retired.ToString); // Check if user should be autoretired if ((PetraPrincipal.PetraIdentity.FailedLogins >= FailedLoginsUntilRetire) && ((!PetraPrincipal.PetraIdentity.Retired))) { UserDR.Retired = true; UserDR.FailedLogins = 0; SaveUser(AUserID, (SUserTable)UserDR.Table); throw new EAccessDeniedException(StrInvalidUserIDPassword); } // Check SystemLoginStatus (Petra enabled/disabled) in the SystemStatus table (always holds only one record) Boolean NewTransaction = false; SSystemStatusTable SystemStatusDT; TDBTransaction ReadTransaction = DBAccess.GDBAccessObj.GetNewOrExistingTransaction(IsolationLevel.ReadCommitted, TEnforceIsolationLevel.eilMinimum, out NewTransaction); try { SystemStatusDT = SSystemStatusAccess.LoadAll(ReadTransaction); } finally { if (NewTransaction) { DBAccess.GDBAccessObj.CommitTransaction(); TLogging.LogAtLevel(7, "TUserManager.PerformUserAuthentication: committed own transaction."); } } if (SystemStatusDT[0].SystemLoginStatus) { ASystemEnabled = true; } else { ASystemEnabled = false; if (PetraPrincipal.IsInGroup("SYSADMIN")) { PetraPrincipal.LoginMessage = String.Format(StrSystemDisabled1, SystemStatusDT[0].SystemDisabledReason) + Environment.NewLine + Environment.NewLine + StrSystemDisabled2Admin; } else { TLoginLog.AddLoginLogEntry(AUserID, "System disabled", true, out AProcessID); throw new ESystemDisabledException(String.Format(StrSystemDisabled1, SystemStatusDT[0].SystemDisabledReason) + Environment.NewLine + Environment.NewLine + String.Format(StrSystemDisabled2, StringHelper.DateToLocalizedString(SystemStatusDT[0].SystemAvailableDate.Value), SystemStatusDT[0].SystemAvailableDate.Value.AddSeconds(SystemStatusDT[0].SystemAvailableTime).ToShortTimeString())); } } if ((AUserID == "SYSADMIN") && TSession.HasVariable("ServerAdminToken")) { // Login via server admin console authenticated by file token } else { string UserAuthenticationMethod = TAppSettingsManager.GetValue("UserAuthenticationMethod", "OpenPetraDBSUser", false); if (UserAuthenticationMethod == "OpenPetraDBSUser") { // TODO 1 oChristianK cSecurity : Perform user authentication by verifying password hash in the DB // see also ICTPetraWiki: Todo_Petra.NET#Implement_Security_.7B2.7D_.5BChristian.5D if (CreateHashOfPassword(String.Concat(APassword, UserDR.PasswordSalt)) != UserDR.PasswordHash) { // increase failed logins UserDR.FailedLogins++; LoginDateTime = DateTime.Now; UserDR.FailedLoginDate = LoginDateTime; UserDR.FailedLoginTime = Conversions.DateTimeToInt32Time(LoginDateTime); SaveUser(AUserID, (SUserTable)UserDR.Table); throw new EPasswordWrongException(StrInvalidUserIDPassword); } } else { IUserAuthentication auth = LoadAuthAssembly(UserAuthenticationMethod); string ErrorMessage; if (!auth.AuthenticateUser(EmailAddress, APassword, out ErrorMessage)) { UserDR.FailedLogins++; LoginDateTime = DateTime.Now; UserDR.FailedLoginDate = LoginDateTime; UserDR.FailedLoginTime = Conversions.DateTimeToInt32Time(LoginDateTime); SaveUser(AUserID, (SUserTable)UserDR.Table); throw new EPasswordWrongException(ErrorMessage); } } } // Save successful login LoginDateTime = DateTime.Now; UserDR.LastLoginDate = LoginDateTime; UserDR.LastLoginTime = Conversions.DateTimeToInt32Time(LoginDateTime); UserDR.FailedLogins = 0; SaveUser(AUserID, (SUserTable)UserDR.Table); PetraPrincipal.PetraIdentity.CurrentLogin = LoginDateTime; // PetraPrincipal.PetraIdentity.FailedLogins := 0; if (PetraPrincipal.IsInGroup("SYSADMIN")) { TLoginLog.AddLoginLogEntry(AUserID, "Successful SYSADMIN", out AProcessID); } else { TLoginLog.AddLoginLogEntry(AUserID, "Successful", out AProcessID); } PetraPrincipal.ProcessID = AProcessID; AProcessID = 0; if (UserDR.PasswordNeedsChange) { // The user needs to change their password before they can use OpenPetra PetraPrincipal.LoginMessage = Catalog.GetString("You need to change your password immediately."); } } finally { DBAccess.GDBAccessObj.RollbackTransaction(); } return(PetraPrincipal); }
/// <summary> /// This method is called when clients access the Daily Exchange Rate data. /// The Daily Exchange Rate table is unusual in that it doesn't really need to hold any data because the DataSet that the client receives /// contains all the used rates from the GL/Gift tables whether or not those rates are in the DER table itself. Any rates in the DER table /// that are NOT used are also returned, but, of course, because they are not used anywhere they are not very inetresting! /// Additionally, because the GL/Gift tables do not necessarily hold a time or a time that matches the same rate in the DER table, it is possible /// for the DER table to have a rate that is used on the date but at a different time. As a result the client sometimes does not see all rows /// from the DER table - and so has no way of deleting them. /// /// That is the reason why we need to automatically clean the table. /// /// But there is some value in having some 'unused' rows that are work-in-progress. So we delete everything in the DER table that /// applies to dates older than 30 days. In the future this might become a configurable server option. /// </summary> private static void DoDailyExchangeRateClean() { DateTime PreviousDailyExchangeRateAccessTime = DateTime.UtcNow.AddHours(-24); if (TSession.HasVariable("PreviousDailyExchangeRateAccessTime")) { PreviousDailyExchangeRateAccessTime = (DateTime)TSession.GetVariable("PreviousDailyExchangeRateAccessTime"); } DateTime PreviousDailyExchangeRateCleanTime = DateTime.UtcNow.AddDays(-30); if (TSession.HasVariable("PreviousDailyExchangeRateCleanTime")) { PreviousDailyExchangeRateCleanTime = (DateTime)TSession.GetVariable("PreviousDailyExchangeRateCleanTime"); } if ((DateTime.UtcNow - PreviousDailyExchangeRateAccessTime).TotalHours > 8) { // Nobody has opened a DailyExchangeRate screen for 8 hours if ((DateTime.UtcNow - PreviousDailyExchangeRateCleanTime).TotalHours > 24) { // It is more than 24 hours since our last clean TDBTransaction t = new TDBTransaction(); TDataBase db = DBAccess.Connect("DoDailyExchangeRateClean"); bool bSubmissionOk = false; db.WriteTransaction(ref t, ref bSubmissionOk, delegate { string logMsg = String.Empty; int affectedRowCount = 0; // Standard is that we delete rows applicable to dates more than 60 days old string criticalDate = DateTime.Now.AddDays(-60).ToString("yyyy-MM-dd"); try { // Our deletion rule is to delete rows where // either the effective date is too old and we have no info about creation or modification // or the creation date is too old and we have no info about any modification // or the modification date is too old // These rules ensure that if rates are added to a DB that is past its last accounting period (like SA-DB) // we can still continue to use the DER screen to add unused rates because they will have create/modify times // that can be long past the final accounting period because we will keep // any row that has been modified recently, whatever the effective date or creation date // any row that was created recently but not subsequently modified, whatever the effective date // any row where we don't have info about create/modify but where the effective date is recent string sql = String.Format( "DELETE FROM PUB_{0} WHERE (({1}<'{2}') and {3} is NULL and {4} is NULL) or (({3}<'{2}') and {4} is NULL) or ({4}<'{2}')", ADailyExchangeRateTable.GetTableDBName(), ADailyExchangeRateTable.GetDateEffectiveFromDBName(), criticalDate, ADailyExchangeRateTable.GetDateCreatedDBName(), ADailyExchangeRateTable.GetDateModifiedDBName()); affectedRowCount = db.ExecuteNonQuery(sql, t); bSubmissionOk = true; TSession.SetVariable("PreviousDailyExchangeRateCleanTime", DateTime.UtcNow); } catch (Exception ex) { logMsg = "An error occurred while trying to purge the Daily Exchange Rate table of 'aged' rows."; logMsg += String.Format(" The exception message was: {0}", ex.Message); } if ((affectedRowCount > 0) && (logMsg == String.Empty)) { logMsg = String.Format("The Daily Exchange Rate table was purged of {0} entries applicable prior to ", affectedRowCount) + criticalDate; } if (logMsg != String.Empty) { TLogging.Log(logMsg); } }); } } TSession.SetVariable("PreviousDailyExchangeRateAccessTime", DateTime.UtcNow); }