Similar Problems

Similar Problems not available

Design Authentication Manager - Leetcode Solution

Companies:

  • linkedin
  • oracle

LeetCode:  Design Authentication Manager Leetcode Solution

Difficulty: Medium

Topics: design hash-table  

Problem:

Design a system that manages authentication.

The system should have the following functionalities:

  1. Register a user with their email address and password.
  2. Authenticate a user with their email address and password.
  3. Reset a user's password.
  4. Expire a user's session.

Assume that the system has the following components:

  1. A database to store user information.
  2. An authentication server to authenticate users.
  3. An email server to send password reset emails.

Design an object-oriented system that implements the above functionalities.

Solution:

The System would have two main classes: User and AuthenticationManager.

The User class would represent a user and have four instance variables: email, password, sessionToken, and passwordResetToken.

The AuthenticationManager class would be responsible for managing user authentication and would have methods to register a user, authenticate a user, reset a user's password, and expire a user's session. AuthenticationManager would have a reference to the database, authentication server, and email server.

The implementation of both classes are given below:

public class User {
    private String email;
    private String password;
    private String sessionToken; // after login, the session token is set
    private String passwordResetToken; // when a password reset is requested, a unique token is generated for the user

    public User(String email, String password) {
        this.email = email;
        this.password = password;
    }

    public String getEmail() {
        return email;
    }

    public String getPassword() {
        return password;
    }

    public String getSessionToken() {
        return sessionToken;
    }

    public void setSessionToken(String sessionToken) {
        this.sessionToken = sessionToken;
    }

    public String getPasswordResetToken() {
        return passwordResetToken;
    }

    public void setPasswordResetToken(String passwordResetToken) {
        this.passwordResetToken = passwordResetToken;
    }
}

public class AuthenticationManager {
    private Database database;
    private AuthenticationServer authServer;
    private EmailServer emailServer;

    public AuthenticationManager(Database database, AuthenticationServer authServer, EmailServer emailServer) {
        this.database = database;
        this.authServer = authServer;
        this.emailServer = emailServer;
    }

    public boolean register(String email, String password) {
        if (database.getUserByEmail(email) != null) { // user already exists
            return false;
        }

        User user = new User(email, password);
        database.addUser(user);
        return true;
    }

    public String login(String email, String password) {
        User user = database.getUserByEmail(email);
        if (user == null || !user.getPassword().equals(password)) {
            return null; // invalid email or password
        }

        String sessionToken = authServer.generateSessionToken();
        user.setSessionToken(sessionToken);
        return sessionToken;
    }

    public boolean resetPassword(String email) {
        User user = database.getUserByEmail(email);
        if (user == null) {
            return false; // user not found
        }

        String passwordResetToken = authServer.generatePasswordResetToken();
        user.setPasswordResetToken(passwordResetToken);

        // send email to the user's email address with a link that contains the password reset token
        emailServer.sendEmail(email, "Password reset", "Click this link to reset your password: https://example.com/reset-password?token=" + passwordResetToken);

        return true;
    }

    public boolean changePassword(String email, String password, String passwordResetToken) {
        User user = database.getUserByEmail(email);
        if (user == null || !user.getPasswordResetToken().equals(passwordResetToken)) {
            return false; // invalid email or password reset token
        }

        user.setPassword(password);
        user.setPasswordResetToken(null); // reset the password reset token
        return true;
    }

    public void expireSession(String sessionToken) {
        User user = database.getUserBySessionToken(sessionToken);
        if (user != null) {
            user.setSessionToken(null);
        }
    }
}

The AuthenticationManager would interact with the database to fetch and update user information, with the authentication server to generate session tokens and password reset tokens, and with the email server to send password reset links.

In this implementation, the AuthenticationManager class uses three other classes: Database, AuthenticationServer, EmailServer. These classes are just placeholders for actual implementations of these services.

The implementation of the Database class would depend on the specific database being used, and would have methods to add a user, get a user by email, and get a user by session token.

The AuthenticationServer class would have methods to generate session tokens and password reset tokens.

The EmailServer class would have a method to send emails.

In summary, the solution has two main classes: User and AuthenticationManager. The User class represents a user and has instance variables for a user's email, password, session token, and password reset token. The AuthenticationManager class manages user authentication and interacts with other services to register a user, login a user, reset a user's password, and expire a user's session. The implementation of these two classes depend on three other classes: Database, AuthenticationServer, and EmailServer.

Design Authentication Manager Solution Code

1