/// <summary> /// Manager performs login, attempting to gain a new session. /// </summary> /// <param name="loginInfo">Login information</param> /// <param name="ipAddress">IP Address of request</param> public async Task <ManagerLoginResponse> Login(ManagerLoginRequest loginInfo, string ipAddress) { // Pull manager information from database. var manager = await _database.GetManagerByUsername(loginInfo.Username); // Default to a failed login attempt. bool canLogIn = false; if (manager.IsPasswordReset && loginInfo.Password == manager.Password) { // If the manager should reset their password and they have provided the correct cleartext password, // allow them to login -- assuming that the next phase will require them to reset their password. canLogIn = true; } else if (_password.IsPasswordMatch(loginInfo.Password, manager.Salt, manager.Password)) { // If the manager password + salt combination matches the stored password allow them to login canLogIn = true; } // If the login failed, throw an exception. if (!canLogIn) { throw new BadLoginException(); } // Create a new session. var newSession = new SessionDocument { Id = ObjectId.GenerateNewId().ToString(), // Generate a new sessionID. SessionId = await _session.GenerateSessionId(), ManagerId = manager.Id, IPAddress = ipAddress, CreatedAt = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), // If the manager needs to reset their password, limit the access to "RESET" status. AccessLevel = manager.IsPasswordReset ? "RESET" : "FULL", IsActive = true }; // Save new session. Note: _session.GenerateSessionId() handles retrying sessionID collisions. await _database.SaveSession(newSession); // Return manager login response information. return(new ManagerLoginResponse { SessionId = newSession.SessionId, AccessLevel = newSession.AccessLevel }); }