Beispiel #1
0
        /// <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);
        }
Beispiel #2
0
        /// <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());
        }
Beispiel #3
0
        /// <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);
            }
        }
Beispiel #4
0
        /// <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);
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        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);
        }
Beispiel #8
0
        /// <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);
        }