Skip to content

oauth2

This module is concerned with authentication and security related operations.

create_access_token

create_access_token(data: dict) -> str

Creates a JWT token that will later be used by users to authenticate their requests.

Parameters:

Name Type Description Default
data dict

The payload data to be encoded into the token.

required

Returns:

Type Description
str

The encoded JWT token.

Source code in api/core/oauth2.py
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
def create_access_token(data: dict) -> str:
    """
    Creates a JWT token that will later be used by users to authenticate their requests.

    Parameters
    ----------
    data : dict
        The payload data to be encoded into the token.

    Returns
    -------
    str
        The encoded JWT token.
    """
    to_encode = data.copy()

    expire = datetime.datetime.now(datetime.UTC) + timedelta(minutes=settings.access_token_expire_minute)
    to_encode.update({"exp": expire})

    return jwt.encode(to_encode, settings.secret_key, algorithm=settings.algorithm)

verify_access_token

verify_access_token(token: str, credentials_exception: HTTPException)

Verifies a JWT token has been encrypted using the application's secret key, has the expected data in the payload, and hasn't expired yet.

Parameters:

Name Type Description Default
token str

The JWT token to be verified.

required
credentials_exception HTTPException

The exception to be raised if credentials cannot be validated.

required

Raises:

Type Description
HTTPException

If the token cannot be decoded or does not contain the expected user ID, raises the provided credentials exception.

Returns:

Type Description
str

The user ID extracted from the token payload.

Source code in api/core/oauth2.py
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
def verify_access_token(token: str, credentials_exception: HTTPException):
    """
    Verifies a JWT token has been encrypted using the application's secret key,
    has the expected data in the payload, and hasn't expired yet.

    Parameters
    ----------
    token : str
        The JWT token to be verified.
    credentials_exception : HTTPException
        The exception to be raised if credentials cannot be validated.

    Raises
    ------
    HTTPException
        If the token cannot be decoded or does not contain the expected user ID,
        raises the provided credentials exception.

    Returns
    -------
    str
        The user ID extracted from the token payload.

    """
    try:
        payload = jwt.decode(token, settings.secret_key, algorithms=[settings.algorithm])
        _id = payload.get("user")
        if _id is None:
            raise credentials_exception
    except JWTError as e:
        raise credentials_exception from e
    return _id

get_current_user

get_current_user(token: Annotated[str, Depends(oauth2_scheme)], session: Annotated[Session, Depends(database.get_session)]) -> models.User | None

Gets the current user by verifying the JWT token passed and using its payload data to query the users database for a corresponding user.

Parameters:

Name Type Description Default
token str

The JWT token used for authentication (default is obtained from oauth2_scheme).

required
session Session

The session to interact with the database (default is obtained from database.get_session).

required

Raises:

Type Description
HTTPException

If credentials cannot be validated, returns status code 401 (UNAUTHORIZED) with a detail message. The response header contains the WWW-Authenticate field set to 'Bearer'.

Returns:

Type Description
User | None

The user corresponding to the provided token, if found; otherwise, returns None.

Source code in api/core/oauth2.py
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
def get_current_user(
    token: Annotated[str, Depends(oauth2_scheme)],
    session: Annotated[Session, Depends(database.get_session)],
) -> models.User | None:
    """
    Gets the current user by verifying the JWT token passed and using its payload data
    to query the users database for a corresponding user.

    Parameters
    ----------
    token : str
        The JWT token used for authentication (default is obtained from `oauth2_scheme`).
    session : Session
        The session to interact with the database (default is obtained from `database.get_session`).

    Raises
    ------
    HTTPException
        If credentials cannot be validated, returns status code 401 (UNAUTHORIZED) with a detail message.
        The response header contains the WWW-Authenticate field set to 'Bearer'.

    Returns
    -------
    models.User | None
        The user corresponding to the provided token, if found; otherwise, returns None.
    """
    credentials_exception = HTTPException(
        status_code=status.HTTP_401_UNAUTHORIZED,
        detail="Could not validate credentials",
        headers={"WWW-Authenticate": "Bearer"},
    )
    _id = verify_access_token(token, credentials_exception)

    return session.exec(select(models.User).where(models.User.id == _id)).first()

hash_password

hash_password(password: str) -> str

Hashes plain text password.

Parameters:

Name Type Description Default
password str

The plaintext password to be hashed.

required

Returns:

Type Description
str

The hashed password.

Source code in api/core/oauth2.py
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
def hash_password(password: str) -> str:
    """
    Hashes plain text password.

    Parameters
    ----------
    password : str
        The plaintext password to be hashed.

    Returns
    -------
    str
        The hashed password.
    """
    return pwd_context.hash(password)

verify_password

verify_password(plain_password: str, hashed_password: str) -> bool

Verify plaintext password against hashed password in the database.

Parameters:

Name Type Description Default
plain_password str

The plaintext password to be verified.

required
hashed_password str

The hashed password stored in the database.

required

Returns:

Type Description
bool

True if the plaintext password matches the hashed password; otherwise, False.

Source code in api/core/oauth2.py
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
def verify_password(plain_password: str, hashed_password: str) -> bool:
    """
    Verify plaintext password against hashed password in the database.

    Parameters
    ----------
    plain_password : str
        The plaintext password to be verified.
    hashed_password : str
        The hashed password stored in the database.

    Returns
    -------
    bool
        True if the plaintext password matches the hashed password; otherwise, False.
    """
    return pwd_context.verify(plain_password, hashed_password)