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)); } }
// 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)); } }