public void TimeUtilityService_TimespanToSeconds_ConvertToSecondsSuccessfull(int hours, int minutes, int seconds)
        {
            // Arrange: Get the expected seconds for the timespan object
            long expectedSeconds = (long)(new TimeSpan(hours, minutes, seconds)).TotalSeconds;

            TimeSpan ts = new TimeSpan(hours, minutes, seconds);
            // Act: Get the seconds for timespan object using the function.
            long actualSeconds = TimeUtilityService.TimespanToSeconds(ts);

            // Assert:
            Assert.AreEqual(expectedSeconds, actualSeconds);
        }
        /// <summary>
        /// Increment the registration failures of the anonymous user defined by the <paramref name="ipAddress"/>.
        /// </summary>
        /// <param name="ipAddress">The ip address to increment the registration failures of (string)</param>
        /// <param name="maxTimeBeforeFailureReset">The time before their failures reset (TimeSpan)</param>
        /// <param name="maxNumberOfTries">The max number of registration tries before they get locked (int)</param>
        /// <returns>Task (bool) whether the funciton executed without exception</returns>
        public static bool IncrementRegistrationFailures(string ipAddress, TimeSpan maxTimeBeforeFailureReset, int maxNumberOfTries)
        {
            IPAddressObject ip = _ipDAO.ReadById(ipAddress) as IPAddressObject;
            IPAddressRecord record;

            // Need to check if the maxtime + lastTime is less than now.
            // If it is then reset the failure
            long lastRegFailTimestamp = ip.LastRegFailTimestamp;
            long maxSeconds           = TimeUtilityService.TimespanToSeconds(maxTimeBeforeFailureReset);
            long currentUnix          = TimeUtilityService.CurrentUnixTime();

            bool reset = false;

            // If the time has passed their max time before reset, reset their failures. Don't reset
            // if they have no last registration fail timestamp.
            if (lastRegFailTimestamp + maxSeconds < currentUnix && lastRegFailTimestamp != Constants.NoValueLong)
            {
                reset  = true;
                record = new IPAddressRecord(ipAddress, registrationFailures: 0);
                _ipDAO.Update(record);
            }

            // Increment the user's login Failure count.
            int updatedRegistrationFailures = reset ? 1 : ip.RegistrationFailures + 1;

            // Lock the ip if they have reached the max number of tries.
            // Update the last reg fail time.
            if (updatedRegistrationFailures >= maxNumberOfTries)
            {
                record = new IPAddressRecord(ipAddress, timestampLocked: currentUnix, registrationFailures: updatedRegistrationFailures, lastRegFailTimestamp: currentUnix);

                // Notify the system admin if an ip address was locked during registration.
                NotifySystemAdmin($"{ipAddress} was locked at {currentUnix}", Constants.SystemAdminEmailAddress);
            }
            else
            {
                record = new IPAddressRecord(ipAddress, registrationFailures: updatedRegistrationFailures, lastRegFailTimestamp: currentUnix);
            }

            _ipDAO.Update(record);

            return(true);
        }
        /// <summary>
        /// Increment the login failures of a user and disables that user if he has
        /// reached the <paramref name="maxNumberOfTries"/> parameter and his last login failure time
        /// hs not exceeded the <paramref name="maxTimeBeforeFailureReset"/> parameter.
        /// </summary>
        /// <param name="username">Username of the user to increment</param>
        /// <param name="maxTimeBeforeFailureReset">TimeSpan object to represent how long the before the login failure resets.</param>
        /// <param name="maxNumberOfTries">The max number of tries a user can login before he is disabled.</param>
        /// <returns>Returns true if the operation is successfull and false if it failed.</returns>
        public static bool IncrementLoginFailures(string username, TimeSpan maxTimeBeforeFailureReset, int maxNumberOfTries)
        {
            UserObject user = _userDAO.ReadById(username) as UserObject;
            UserRecord record;

            // Need to check if the maxtime + lastTime is less than now.
            // If it is then reset the failure
            long lastLoginFailTimestamp = user.LastLoginFailTimestamp;
            long maxSeconds             = TimeUtilityService.TimespanToSeconds(maxTimeBeforeFailureReset);
            long currentUnix            = TimeUtilityService.CurrentUnixTime();

            bool reset = false;

            // If the time has passed their max time before reset, reset their failures. Don't reset if
            // they have no last login fail timestamp.
            if (lastLoginFailTimestamp + maxSeconds < currentUnix && lastLoginFailTimestamp != Constants.NoValueLong)
            {
                reset  = true;
                record = new UserRecord(username, loginFailures: 0);
                _userDAO.Update(record);
            }

            // Increment the user's login failure count.
            int updatedLoginFailures = reset ? 1 : user.LogInFailures + 1;

            // Disable the user if they have reached the max number of tries.
            // Update the last login fail time.
            if (updatedLoginFailures >= maxNumberOfTries)
            {
                record = new UserRecord(username, loginFailures: updatedLoginFailures, disabled: Constants.DisabledStatus, lastLoginFailTimestamp: currentUnix);
            }
            else
            {
                record = new UserRecord(username, loginFailures: updatedLoginFailures, lastLoginFailTimestamp: currentUnix);
            }

            _userDAO.Update(record);

            return(true);
        }
        public async Task <Result <bool> > VerifyEmailCodeAsync(string username, string inputCode, string ipAddress,
                                                                int currentNumExceptions)
        {
            try
            {
                bool emailVerificationSuccess = false;

                UserObject user = await _userManagementService.GetUserInfoAsync(username).ConfigureAwait(false);

                if (user.EmailCodeFailures >= Constants.MaxEmailCodeAttempts)
                {
                    _ = _loggingManager.LogAsync(DateTime.UtcNow.ToString(Constants.LoggingFormatString),
                                                 Constants.VerifyEmailOperation, username, ipAddress,
                                                 Constants.MaxEmailTriesReachedLogMessage).ConfigureAwait(false);

                    return(SystemUtilityService.CreateResult(Constants.MaxEmailTriesReachedUserMessage, emailVerificationSuccess, false));
                }

                long maxValidTimeSeconds = TimeUtilityService.TimespanToSeconds(Constants.EmailCodeMaxValidTime);
                long currentUnix         = TimeUtilityService.CurrentUnixTime();

                if (user.EmailCodeTimestamp + maxValidTimeSeconds < currentUnix)
                {
                    _ = _loggingManager.LogAsync(DateTime.UtcNow.ToString(Constants.LoggingFormatString),
                                                 Constants.VerifyEmailOperation, username, ipAddress,
                                                 Constants.EmailCodeExpiredLogMessage).ConfigureAwait(false);

                    return(SystemUtilityService.CreateResult(Constants.EmailCodeExpiredUserMessage, emailVerificationSuccess, false));
                }

                if (user.EmailCode.Equals(inputCode))
                {
                    emailVerificationSuccess = true;
                    await _loggingManager.LogAsync(DateTime.UtcNow.ToString(Constants.LoggingFormatString),
                                                   Constants.VerifyEmailOperation, username, ipAddress).ConfigureAwait(false);

                    return(SystemUtilityService.CreateResult(Constants.VerifyEmailSuccessUserMessage, emailVerificationSuccess, false));
                }
                else
                {
                    _ = _loggingManager.LogAsync(DateTime.UtcNow.ToString(Constants.LoggingFormatString),
                                                 Constants.VerifyEmailOperation, username, ipAddress,
                                                 Constants.WrongEmailCodeMessage).ConfigureAwait(false);

                    await _userManagementService.IncrementEmailCodeFailuresAsync(username).ConfigureAwait(false);

                    return(SystemUtilityService.CreateResult(Constants.WrongEmailCodeMessage, emailVerificationSuccess, false));
                }
            }
            catch (Exception e)
            {
                _ = _loggingManager.LogAsync(DateTime.UtcNow.ToString(Constants.LoggingFormatString),
                                             Constants.VerifyEmailOperation, username, ipAddress, e.Message).ConfigureAwait(false);

                if (currentNumExceptions + 1 >= Constants.MaximumOperationRetries)
                {
                    await SystemUtilityService.NotifySystemAdminAsync($"{Constants.VerifyEmailOperation} failed a maximum number of times for {username}.", Constants.SystemAdminEmailAddress).ConfigureAwait(false);
                }

                return(SystemUtilityService.CreateResult(Constants.SystemErrorUserMessage, false, true));
            }
        }
Esempio n. 5
0
        // Time out after X seconds will be conducted in Controllers with Task.Wait

        // Re-trying after exceptions occur will be conducted in Controllers, who will check if an exception occurred and how
        // many exceptions have currently occured after a manager has returned.

        // Encrypted password, encrypted AES key, and AES IV are all in hex string format.
        public async Task <Result <bool> > RegisterAsync(string firstName, string lastName,
                                                         string email, string username, string phoneNumber,
                                                         string ipAddress, string hashedPassword, string salt,
                                                         string proxyPassword, int currentNumExceptions)
        {
            try
            {
                bool registrationSuccess = false;

                // If the ip address is not in our system. Insert into datastore
                if (!await _userManagementService.CheckIPExistenceAsync(ipAddress).ConfigureAwait(false))
                {
                    await _userManagementService.CreateIPAsync(ipAddress).ConfigureAwait(false);
                }

                // Grab the user ip object.
                IPAddressObject ip = await _userManagementService.GetIPAddressInfoAsync(ipAddress).ConfigureAwait(false);

                // Set fields for repeated fails to lock them out.
                long timeLocked  = ip.TimestampLocked;
                long maxSeconds  = TimeUtilityService.TimespanToSeconds(Constants.MaxIPLockTime);
                long currentUnix = TimeUtilityService.CurrentUnixTime();

                // If the time has passed their max time before unlock, unlock them
                if (timeLocked + maxSeconds < currentUnix && timeLocked != Constants.NoValueLong)
                {
                    await _userManagementService.UnlockIPAsync(ipAddress).ConfigureAwait(false);
                }

                if (await _userManagementService.CheckIfIPLockedAsync(ipAddress).ConfigureAwait(false))
                {
                    _ = _loggingManager.LogAsync(DateTime.UtcNow.ToString(Constants.LoggingFormatString),
                                                 Constants.RegistrationOperation, Constants.AnonymousUserIdentifier, ipAddress,
                                                 Constants.IPLockedLogMessage).ConfigureAwait(false);

                    return(SystemUtilityService.CreateResult(Constants.IPLockedUserMessage, registrationSuccess, false));
                }

                // Check the length of their first name.
                if (!StringUtilityService.CheckLength(firstName, Constants.MaximumFirstNameCharacters,
                                                      Constants.MinimumFirstNameCharacters))
                {
                    await _userManagementService.IncrementRegistrationFailuresAsync(ipAddress,
                                                                                    Constants.RegistrationTriesResetTime,
                                                                                    Constants.MaxRegistrationAttempts).ConfigureAwait(false);

                    _ = _loggingManager.LogAsync(DateTime.UtcNow.ToString(Constants.LoggingFormatString),
                                                 Constants.RegistrationOperation, Constants.AnonymousUserIdentifier, ipAddress,
                                                 Constants.InvalidFirstNameLengthLogMessage).ConfigureAwait(false);

                    return(SystemUtilityService.CreateResult(Constants.InvalidFirstNameLengthUserMessage, registrationSuccess, false));
                }

                // Check the character requirements of their first name.
                if (!StringUtilityService.CheckCharacters(firstName, Constants.CharSetsData[Constants.FirstNameCharacterType]))
                {
                    await _userManagementService.IncrementRegistrationFailuresAsync(ipAddress,
                                                                                    Constants.RegistrationTriesResetTime,
                                                                                    Constants.MaxRegistrationAttempts).ConfigureAwait(false);

                    _ = _loggingManager.LogAsync(DateTime.UtcNow.ToString(Constants.LoggingFormatString),
                                                 Constants.RegistrationOperation, Constants.AnonymousUserIdentifier, ipAddress,
                                                 Constants.InvalidFirstNameCharactersLogMessage).ConfigureAwait(false);

                    return(SystemUtilityService.CreateResult(Constants.InvalidFirstNameCharactersUserMessage, registrationSuccess, false));
                }

                // Check the length of their last name.
                if (!StringUtilityService.CheckLength(lastName, Constants.MaximumLastNameCharacters,
                                                      Constants.MinimumLastNameCharacters))
                {
                    await _userManagementService.IncrementRegistrationFailuresAsync(ipAddress,
                                                                                    Constants.RegistrationTriesResetTime,
                                                                                    Constants.MaxRegistrationAttempts).ConfigureAwait(false);

                    _ = _loggingManager.LogAsync(DateTime.UtcNow.ToString(Constants.LoggingFormatString),
                                                 Constants.RegistrationOperation, Constants.AnonymousUserIdentifier, ipAddress,
                                                 Constants.InvalidLastNameLengthLogMessage).ConfigureAwait(false);

                    return(SystemUtilityService.CreateResult(Constants.InvalidLastNameLengthUserMessage, registrationSuccess, false));
                }

                // Check the character requirements of their last name.
                if (!StringUtilityService.CheckCharacters(lastName, Constants.CharSetsData[Constants.LastNameCharacterType]))
                {
                    await _userManagementService.IncrementRegistrationFailuresAsync(ipAddress,
                                                                                    Constants.RegistrationTriesResetTime,
                                                                                    Constants.MaxRegistrationAttempts).ConfigureAwait(false);

                    _ = _loggingManager.LogAsync(DateTime.UtcNow.ToString(Constants.LoggingFormatString),
                                                 Constants.RegistrationOperation, Constants.AnonymousUserIdentifier, ipAddress,
                                                 Constants.InvalidLastNameCharactersLogMessage).ConfigureAwait(false);

                    return(SystemUtilityService.CreateResult(Constants.InvalidLastNameCharactersUserMessage, registrationSuccess, false));
                }

                // Check the length of their email.
                if (!StringUtilityService.CheckLength(email, Constants.MaximumEmailCharacters,
                                                      Constants.MinimumEmailCharacters))
                {
                    await _userManagementService.IncrementRegistrationFailuresAsync(ipAddress,
                                                                                    Constants.RegistrationTriesResetTime,
                                                                                    Constants.MaxRegistrationAttempts).ConfigureAwait(false);

                    _ = _loggingManager.LogAsync(DateTime.UtcNow.ToString(Constants.LoggingFormatString),
                                                 Constants.RegistrationOperation, Constants.AnonymousUserIdentifier, ipAddress,
                                                 Constants.InvalidEmailLengthLogMessage).ConfigureAwait(false);

                    return(SystemUtilityService.CreateResult(Constants.InvalidEmailLengthUserMessage, registrationSuccess, false));
                }

                // Check the character requirements of their email.
                if (!StringUtilityService.CheckCharacters(email, Constants.CharSetsData[Constants.EmailCharacterType]))
                {
                    await _userManagementService.IncrementRegistrationFailuresAsync(ipAddress,
                                                                                    Constants.RegistrationTriesResetTime,
                                                                                    Constants.MaxRegistrationAttempts).ConfigureAwait(false);

                    _ = _loggingManager.LogAsync(DateTime.UtcNow.ToString(Constants.LoggingFormatString),
                                                 Constants.RegistrationOperation, Constants.AnonymousUserIdentifier, ipAddress,
                                                 Constants.InvalidEmailCharactersLogMessage).ConfigureAwait(false);

                    return(SystemUtilityService.CreateResult(Constants.InvalidEmailCharactersUserMessage, registrationSuccess, false));
                }

                // Check the format of their email.
                if (!StringUtilityService.CheckEmailFormatValidity(email))
                {
                    await _userManagementService.IncrementRegistrationFailuresAsync(ipAddress,
                                                                                    Constants.RegistrationTriesResetTime,
                                                                                    Constants.MaxRegistrationAttempts).ConfigureAwait(false);

                    _ = _loggingManager.LogAsync(DateTime.UtcNow.ToString(Constants.LoggingFormatString),
                                                 Constants.RegistrationOperation, Constants.AnonymousUserIdentifier, ipAddress,
                                                 Constants.InvalidEmailFormatMessage).ConfigureAwait(false);

                    return(SystemUtilityService.CreateResult(Constants.InvalidEmailFormatMessage, registrationSuccess, false));
                }

                // Email must be unique after canonicalization.
                string canonicalizedEmail = StringUtilityService.CanonicalizeEmail(email);

                if (await _userManagementService.CheckEmailExistenceAsync(canonicalizedEmail).ConfigureAwait(false))
                {
                    await _userManagementService.IncrementRegistrationFailuresAsync(ipAddress,
                                                                                    Constants.RegistrationTriesResetTime,
                                                                                    Constants.MaxRegistrationAttempts).ConfigureAwait(false);

                    _ = _loggingManager.LogAsync(DateTime.UtcNow.ToString(Constants.LoggingFormatString),
                                                 Constants.RegistrationOperation, Constants.AnonymousUserIdentifier, ipAddress,
                                                 Constants.EmailExistsLogMessage).ConfigureAwait(false);

                    Console.WriteLine("Email");
                    return(SystemUtilityService.CreateResult(Constants.UniqueIdExistsRegistrationUserMessage, registrationSuccess, false));
                }

                // Check the length of their username.
                if (!StringUtilityService.CheckLength(username, Constants.MaximumUsernameCharacters,
                                                      Constants.MinimumUsernameCharacters))
                {
                    await _userManagementService.IncrementRegistrationFailuresAsync(ipAddress,
                                                                                    Constants.RegistrationTriesResetTime,
                                                                                    Constants.MaxRegistrationAttempts).ConfigureAwait(false);

                    _ = _loggingManager.LogAsync(DateTime.UtcNow.ToString(Constants.LoggingFormatString),
                                                 Constants.RegistrationOperation, Constants.AnonymousUserIdentifier, ipAddress,
                                                 Constants.InvalidUsernameLengthLogMessage).ConfigureAwait(false);

                    return(SystemUtilityService.CreateResult(Constants.InvalidUsernameLengthUserMessage, registrationSuccess, false));
                }

                // Check the character requirements of their username.
                if (!StringUtilityService.CheckCharacters(email, Constants.CharSetsData[Constants.UsernameCharacterType]))
                {
                    await _userManagementService.IncrementRegistrationFailuresAsync(ipAddress,
                                                                                    Constants.RegistrationTriesResetTime,
                                                                                    Constants.MaxRegistrationAttempts).ConfigureAwait(false);

                    _ = _loggingManager.LogAsync(DateTime.UtcNow.ToString(Constants.LoggingFormatString),
                                                 Constants.RegistrationOperation, Constants.AnonymousUserIdentifier, ipAddress,
                                                 Constants.InvalidUsernameCharactersLogMessage).ConfigureAwait(false);

                    return(SystemUtilityService.CreateResult(Constants.InvalidUsernameCharactersUserMessage, registrationSuccess, false));
                }

                // Check username uniqueness.
                if (await _userManagementService.CheckUserExistenceAsync(username).ConfigureAwait(false))
                {
                    await _userManagementService.IncrementRegistrationFailuresAsync(ipAddress,
                                                                                    Constants.RegistrationTriesResetTime,
                                                                                    Constants.MaxRegistrationAttempts).ConfigureAwait(false);

                    _ = _loggingManager.LogAsync(DateTime.UtcNow.ToString(Constants.LoggingFormatString),
                                                 Constants.RegistrationOperation, Constants.AnonymousUserIdentifier, ipAddress,
                                                 Constants.UsernameExistsLogMessage).ConfigureAwait(false);

                    Console.WriteLine("username");
                    return(SystemUtilityService.CreateResult(Constants.UniqueIdExistsRegistrationUserMessage, registrationSuccess, false));
                }

                // Check the length of their phone number.
                if (!StringUtilityService.CheckLength(phoneNumber, Constants.PhoneNumberCharacterLength))
                {
                    await _userManagementService.IncrementRegistrationFailuresAsync(ipAddress,
                                                                                    Constants.RegistrationTriesResetTime,
                                                                                    Constants.MaxRegistrationAttempts).ConfigureAwait(false);

                    _ = _loggingManager.LogAsync(DateTime.UtcNow.ToString(Constants.LoggingFormatString),
                                                 Constants.RegistrationOperation, Constants.AnonymousUserIdentifier, ipAddress,
                                                 Constants.InvalidPhoneNumberLengthLogMessage).ConfigureAwait(false);

                    return(SystemUtilityService.CreateResult(Constants.InvalidPhoneNumberLengthUserMessage, registrationSuccess, false));
                }

                // Check the character requirements of their phone number.
                if (!StringUtilityService.CheckCharacters(phoneNumber, Constants.CharSetsData[Constants.PhoneNumberCharacterType]))
                {
                    await _userManagementService.IncrementRegistrationFailuresAsync(ipAddress,
                                                                                    Constants.RegistrationTriesResetTime,
                                                                                    Constants.MaxRegistrationAttempts).ConfigureAwait(false);

                    _ = _loggingManager.LogAsync(DateTime.UtcNow.ToString(Constants.LoggingFormatString),
                                                 Constants.RegistrationOperation, Constants.AnonymousUserIdentifier, ipAddress,
                                                 Constants.InvalidPhoneNumberCharactersLogMessage).ConfigureAwait(false);

                    return(SystemUtilityService.CreateResult(Constants.InvalidPhoneNumberCharactersUserMessage, registrationSuccess, false));
                }

                // Check phone number uniqueness.
                if (await _userManagementService.CheckPhoneNumberExistenceAsync(phoneNumber).ConfigureAwait(false))
                {
                    await _userManagementService.IncrementRegistrationFailuresAsync(ipAddress,
                                                                                    Constants.RegistrationTriesResetTime,
                                                                                    Constants.MaxRegistrationAttempts).ConfigureAwait(false);

                    _ = _loggingManager.LogAsync(DateTime.UtcNow.ToString(Constants.LoggingFormatString),
                                                 Constants.RegistrationOperation, Constants.AnonymousUserIdentifier, ipAddress,
                                                 Constants.PhoneNumberExistsLogMessage).ConfigureAwait(false);

                    Console.WriteLine("phone");
                    return(SystemUtilityService.CreateResult(Constants.UniqueIdExistsRegistrationUserMessage, registrationSuccess, false));
                }

                // Check the length of their password.
                if (!StringUtilityService.CheckLength(proxyPassword, Constants.MaximumPasswordCharacters,
                                                      Constants.MinimumPasswordCharacters))
                {
                    await _userManagementService.IncrementRegistrationFailuresAsync(ipAddress,
                                                                                    Constants.RegistrationTriesResetTime,
                                                                                    Constants.MaxRegistrationAttempts).ConfigureAwait(false);

                    _ = _loggingManager.LogAsync(DateTime.UtcNow.ToString(Constants.LoggingFormatString),
                                                 Constants.RegistrationOperation, Constants.AnonymousUserIdentifier, ipAddress,
                                                 Constants.InvalidPasswordLengthLogMessage).ConfigureAwait(false);

                    return(SystemUtilityService.CreateResult(Constants.InvalidPasswordLengthUserMessage,
                                                             registrationSuccess, false));
                }

                // Successful registration!
                registrationSuccess = true;

                // Create user record object to represent a user.

                // Email code, email code timestamp, login failures, last login failure timestamp, email code failures, and phone code failures initialized to have no value.
                UserRecord user = new UserRecord(username, firstName + " " + lastName, canonicalizedEmail, phoneNumber, hashedPassword, Constants.EnabledStatus, Constants.CustomerUserType,
                                                 salt, Constants.NoValueLong, Constants.NoValueString, Constants.NoValueLong, Constants.NoValueInt, Constants.NoValueLong, Constants.NoValueInt, Constants.NoValueInt);

                // Create that user.
                await _userManagementService.CreateUserAsync(true, user).ConfigureAwait(false);

                _ = _loggingManager.LogAsync(DateTime.UtcNow.ToString(Constants.LoggingFormatString),
                                             Constants.RegistrationOperation, Constants.AnonymousUserIdentifier, ipAddress).ConfigureAwait(false);

                return(SystemUtilityService.CreateResult(Constants.RegistrationSuccessUserMessage, registrationSuccess, false));
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Console.WriteLine(e.StackTrace);
                _ = _loggingManager.LogAsync(DateTime.UtcNow.ToString(Constants.LoggingFormatString),
                                             Constants.RegistrationOperation, Constants.AnonymousUserIdentifier, ipAddress, e.Message).ConfigureAwait(false);

                if (currentNumExceptions + 1 >= Constants.MaximumOperationRetries)
                {
                    await SystemUtilityService.NotifySystemAdminAsync($"{Constants.RegistrationOperation} failed a maximum number of times for {ipAddress}.", Constants.SystemAdminEmailAddress).ConfigureAwait(false);
                }

                return(SystemUtilityService.CreateResult(Constants.SystemErrorUserMessage, false, true));
            }
        }