/// <summary> /// Checks if [User] is allowed to manage [TargetUser] /// </summary> public static bool CanManageUser(User user, User targetUser) { // Superadmins can edit everyone if (user.UserRole == UserRole.SuperAdministrator) { return(true); } // Can edit thyself... if (user.UserId.GetValueOrDefault(0) == targetUser.UserId.GetValueOrDefault(-1)) { return(true); } // User access permissions for brand administrators if (user.UserRole == UserRole.BrandAdministrator) { // Otherwise, can edit if in same brands and in a lower or equal role if (targetUser.UserRoleId <= user.UserRoleId && user.PrimaryBrandId.Equals(targetUser.PrimaryBrandId)) { return(true); } // BU Admins can edit users belonging to companies they created if (UserSecurityManager.GetCompanyByDomain(targetUser.Email).CreatedByUserId == user.UserId.GetValueOrDefault()) { return(true); } } // Can't edit anyone else // m_Logger.DebugFormat("No approval checks passed. {0} cannot access {1}", user.FullName, targetUser.FullName); return(false); }
/// <summary> /// Gets the user authorised to manage (approve) the specified user's account /// </summary> public static User GetAuthorisingUser(User user) { User owner; if (user.IsEmployee) { UserFinder finder = new UserFinder { UserRole = UserRole.BrandAdministrator, PrimaryBrandId = user.PrimaryBrandId, IsSuspended = false }; owner = User.FindOne(finder); } else { // Get the user that created the company this user belongs to return(UserSecurityManager.GetCompanyByDomain(user.Email).CreatedByUser); } // Ensure that they are still active and in an authorised role // If not, try and get a super admin instead if (!user.IsActive() || owner.UserRoleId < Convert.ToInt32(UserRole.BrandAdministrator)) { UserFinder finder = new UserFinder { UserRole = UserRole.SuperAdministrator, IsSuspended = false }; owner = User.FindOne(finder); if (owner.IsNull) { throw new SystemException("Authorising user could not be found. User's company creator is invalid and no super-administrators are available."); } } return(owner); }
/// <summary> /// Verify the user credentials and the account, and if if valid, returns the user /// </summary> /// <param name="email">Email Address</param> /// <param name="password">Password</param> /// <exception cref="LoginException">Thrown if email or password is missing, account is not found, or password is invalid</exception> /// <exception cref="LoginSecurityException">Thrown if the account is pending admin approval, inactive, suspended, or the IP address is unknown and home access is not enabled</exception> /// <exception cref="UserPendingEmailConfirmationException">Thrown if the account is pending email confirmation</exception> /// <exception cref="AccountExpiredException">Thrown if the account is expired</exception> /// <exception cref="PasswordExpiredException">Thrown if the password is expired</exception> public static User Login(string email, string password) { // Remove space around posted values email = email.Trim(); password = password.Trim(); // Ensure email and password exists if (email.Length == 0 || password.Length == 0) { throw new LoginException("Please enter email and password", User.Empty); } // Get user matching email User user = User.GetByEmail(email); // Ensure user was found if (user.IsNull) { throw new LoginException("User account not found", user); } // Get any info about bad logins BadLoginInfo badLoginInfo = user.GetBadLoginInfo(m_BadLoginLockoutMinutes); // Check that the account isn't locked based on the bad login info if (AccountIsLocked(badLoginInfo)) { throw new LoginException("User account is locked. Please try again in " + m_BadLoginLockoutMinutes + " minutes.", user); } // Get the IP address as we'll need it later string ipAddress = BusinessHelper.GetCurrentIpAddress(); // Ensure password is correct if (!user.CheckPassword(password)) { // Update log m_Logger.DebugFormat("Login failed for {0}, UserId: {1} Invalid password.", user.FullName, user.UserId); AuditLogManager.LogUserAction(user, AuditUserAction.UserLogin, "Login Failed. Invalid Password."); // Update bad login info badLoginInfo.BadLoginCount++; badLoginInfo.LastBadLoginDate = DateTime.Now; // Check to see if this failed login has locked the account if (AccountIsLocked(badLoginInfo)) { throw new LoginException("Too many bad login attempts. Please try again in " + m_BadLoginLockoutMinutes + " minutes.", user); } // Otherwise, bad login but account isn't locked throw new LoginException("Invalid Password", user); } // Ensure user is not pending admin approval if (user.UserStatus == UserStatus.PendingAdminApproval) { m_Logger.DebugFormat("Login failed for {0}, UserId: {1} Account is pending admin approval.", user.FullName, user.UserId); AuditLogManager.LogUserAction(user, AuditUserAction.UserLogin, "Login Failed. Account pending admin approval."); throw new LoginSecurityException(user, "This account is awaiting approval", ipAddress); } // Ensure user is not pending email confirmation if (user.UserStatus == UserStatus.PendingEmailConfirmation) { m_Logger.DebugFormat("Login failed for {0}, UserId: {1} Account is pending email confirmation.", user.FullName, user.UserId); AuditLogManager.LogUserAction(user, AuditUserAction.UserLogin, "Login Failed. Account pending email confirmation."); throw new UserPendingEmailConfirmationException("This account is pending email confirmation", user); } // Ensure user is not rejected if (user.UserStatus == UserStatus.Rejected) { m_Logger.DebugFormat("Login failed for {0}, UserId: {1} Account is rejected.", user.FullName, user.UserId); AuditLogManager.LogUserAction(user, AuditUserAction.UserLogin, "Login Failed. Account status is rejected."); throw new LoginSecurityException(user, "This account is inactive", ipAddress); } // Ensure user is not suspended if (user.IsSuspended) { m_Logger.DebugFormat("Login failed for {0}, UserId: {1} Account is suspended.", user.FullName, user.UserId); AuditLogManager.LogUserAction(user, AuditUserAction.UserLogin, "Login Failed. Account is suspended."); throw new LoginSecurityException(user, "This account has been suspended", ipAddress); } // Ensure user can login from unapproved ip address if they are logging in from an unapproved ip address if (Settings.IpAddressRestrictionEnabled && !UserSecurityManager.IsApprovedIpAddress(ipAddress) && !user.IsAllowedExternalAccess) { m_Logger.DebugFormat("Login failed for {0}, UserId: {1} The IP address '{2}' is unapproved and account does not have external access enabled.", user.FullName, user.UserId, ipAddress); AuditLogManager.LogUserAction(user, AuditUserAction.UserLogin, string.Format("Login Failed. The IP address '{0}' is unapproved and user account does not have home access rights.", ipAddress)); throw new LoginSecurityException(user, "Unable to log in. Unknown IP Address.", ipAddress); } // Ensure the user account has not expired if (user.GetAccountExpiryDate() < DateTime.Now) { m_Logger.DebugFormat("Login succeeded for {0}, UserId: {1} but account is expired", user.FullName, user.UserId); AuditLogManager.LogUserAction(user, AuditUserAction.UserLogin, "Login succeeded, but account has expired."); throw new AccountExpiredException("This account has expired.", user); } // Ensure the password has not expired if (user.GetPasswordExpiryDate() < DateTime.Now) { m_Logger.DebugFormat("Login succeeded for {0}, UserId: {1} but password is expired", user.FullName, user.UserId); AuditLogManager.LogUserAction(user, AuditUserAction.UserLogin, "Login succeeded, but password has expired"); throw new PasswordExpiredException("This account's password has expired", user); } //create new session api token if (!UserManager.APISessionIsValid(user)) { UserManager.RenewSessionAPIToken(user); } // Update login date, audit login, etc UpdateLastLoginAuditInfo(user); return(user); }
private static ErrorList ValidateUser(User user) { ErrorList errors = new ErrorList(); if (StringUtils.IsBlank(user.FirstName)) { errors.Add("First name is required"); } if (StringUtils.IsBlank(user.LastName)) { errors.Add("Last name is required"); } if (StringUtils.IsBlank(user.Email)) { errors.Add("Email address is required"); } else if (!StringUtils.IsEmail(user.Email)) { errors.Add("Invalid email address"); } else { Company company = UserSecurityManager.GetCompanyByDomain(user.Email); if (company.IsNull) { switch (RegistrationEmailFormat) { case RegistrationEmailFormatType.InternalUsers: { if (user.IsEmployee && company.IsNull) { errors.Add("Email address is not valid for external users"); } break; } case RegistrationEmailFormatType.AllUsers: { if (company.IsNull) { errors.Add("Email address must belong to approved domain"); } break; } } } else { User u = User.GetByEmail(user.Email); if (!u.IsNull && !u.UserId.Equals(user.UserId)) { errors.Add("Email address is already in use"); } } } if (StringUtils.IsBlank(user.CompanyName)) { errors.Add("Company name is required"); } if (StringUtils.IsBlank(user.Password)) { errors.Add("Password is required"); } if (user.PasswordChanged) { if (user.UnencryptedPassword.Length == 0) { errors.Add("Password confirmation is required"); } else if (user.UnencryptedPassword != user.UnencryptedConfirmPassword) { errors.Add("Password and confirm password do not match"); } else { ErrorList e = PasswordGenerator.ValidatePassword(user.UnencryptedPassword); if (e.Count > 0) { errors.AddRange(e); } else if (!user.IsNew && PasswordHistory.IsRecentPassword(user, user.Password)) { errors.Add("Password has been used recently and cannot be used again"); } } } if (user.Brands.Count == 0) { errors.Add("User must be assigned to at least one brand"); } else { if (user.PrimaryBrandId <= 0) { errors.Add("One brand must be select as the main brand"); } else if (user.Brands.FindIndex(b => b.BrandId == user.PrimaryBrandId) < 0) { errors.Add("The main brand must be selected"); } } if (StringUtils.IsBlank(user.CompanyName)) { errors.Add("Company name is required"); } if (user.UserRoleId == 0) { errors.Add("System Error : User role must be specified"); } if (user.UserRole == UserRole.BrandAdministrator) { // Only one brand admin per business-unit UserFinder finder = new UserFinder { UserRole = UserRole.BrandAdministrator, PrimaryBrandId = user.PrimaryBrandId }; User u = User.FindOne(finder); // Found a user, and user id is different from this user, so don't allow change if (!u.IsNull && !u.UserId.Equals(user.UserId)) { string message = string.Format("The user {0} is already assigned to the Brand Administrator role for the selected brand(s)", u.FullName); errors.Add(message); } } return(errors); }
/// <summary> /// Used for public registrations /// </summary> public static void Register(User user) { // Initialise the approved company to a null instance Company company = Company.Empty; // Get the IP Address string ipAddress = BusinessHelper.GetCurrentIpAddress(); // Only check for an approved company if email is not blank. if (!StringUtils.IsBlank(user.Email)) { company = UserSecurityManager.GetCompanyByDomain(user.Email); } //Process depends on the value defined in the AppSettings key "RegisterUserRequiresKnownEmailFormat". switch (RegistrationEmailFormat) { case RegistrationEmailFormatType.Empty: { if (user.IsEmployee && !company.IsNull) { user.UserStatus = UserStatus.PendingEmailConfirmation; } else { user.UserStatus = UserStatus.PendingAdminApproval; } break; } case RegistrationEmailFormatType.InternalUsers: { if (user.IsEmployee) { if (company.IsNull) { throw new RegistrationSecurityException(user, "Your email address is not recognised as being from a company authorised to use this website. Please contact the system administrator for further information.", ipAddress); } user.UserStatus = UserStatus.PendingEmailConfirmation; } else { user.UserStatus = UserStatus.PendingAdminApproval; } break; } case RegistrationEmailFormatType.AllUsers: { if (company.IsNull) { throw new RegistrationSecurityException(user, "Your email address is not recognised as being from a company authorised to use this website. Please contact the system administrator for further information.", ipAddress); } user.UserStatus = UserStatus.PendingEmailConfirmation; break; } } // Check if user is employee or belongs to an internal company // (If a user belongs to an internal company, then they are effectively an employee) bool isEmployeeOrInternal = (user.IsEmployee || company.IsInternal); // They are an employee or their email belongs to an internal company, but their ip address isn't approved so quit if (Settings.IpAddressRestrictionEnabled && isEmployeeOrInternal && !UserSecurityManager.IsApprovedIpAddress(ipAddress)) { throw new RegistrationSecurityException(user, "Your IP address is not recognised as being from a company authorised to use this website. Please contact the system administrator for further information.", ipAddress); } // Everything passed, update some standard user settings user.IsAccountNonExpiring = false; user.IsPasswordNonExpiring = false; user.UserRole = UserRole.Normal; user.RegisterDate = DateTime.Now; // Set up default user rules and expiry dates user.IsAllowedExternalAccess = !user.IsEmployee; user.EnableFilePathIngestion = false; user.AccountExpiryDate = DateTime.Now.AddDays(AccountExpiryDays); user.PasswordExpiryDate = DateTime.Now.AddDays(PasswordExpiryDays); // Validate standard business objecr requirements ErrorList errors = ValidateUser(user); // Throw an error if the user fields are not all valid if (errors.Count > 0) { throw new InvalidUserException(errors, user); } // Save the user User u = SaveUser(user); FireUserCreateEvent(user); AuditLogManager.LogUserAction(u, AuditUserAction.Register, string.Format("Registration successful. Registered from IP Address: {0}. Account status is: {1}", ipAddress, u.UserStatus)); }