maeser.user_manager module#

User management module for authentication and authorization.

This module provides classes and utilities for managing users, including authentication methods, database operations, and request tracking.

© 2024 Carson Bush, Blaine Freestone

This file is part of Maeser.

Maeser is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

Maeser is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with Maeser. If not, see <https://www.gnu.org/licenses/>.

class maeser.user_manager.BaseAuthenticator(*args, **kwargs)[source]#

Bases: ABC

Base class for authenticators.

abstract authenticate(*args, **kwargs) tuple | None[source]#

Authenticate a user.

Parameters:
  • *args – Positional arguments for authentication.

  • **kwargs – Keyword arguments for authentication.

Returns:

A tuple containing the user’s username, real name, and user group if authentication is successful, otherwise None.

Return type:

tuple or None

abstract fetch_user(ident: str) User | None[source]#

Fetch a user from the authenticator.

Parameters:

ident (str) – The identifier of the user to fetch.

Returns:

The fetched user object or None if not found.

ENSURE THAT YOU SET max_requests TO THE CORRECT VALUE FOR THE USER!

Return type:

User or None

abstract property style: LoginStyle#

Get the login style for the authenticator.

Returns:

The login style object.

Return type:

LoginStyle

class maeser.user_manager.GithubAuthenticator(client_id: str, client_secret: str, auth_callback_uri: str, timeout: int = 10, max_requests: int = 10)[source]#

Bases: BaseAuthenticator

Handles authentication with GitHub OAuth.

authenticate(request_args: dict, oauth_state: str) tuple | None[source]#

Authenticate a user with GitHub OAuth.

Parameters:
  • request_args (dict) – The request arguments containing the authorization code and state.

  • oauth_state (str) – The state value used to prevent CSRF attacks.

Returns:

A tuple containing the user’s username, real name, and user group if authentication is successful, otherwise None.

Return type:

tuple or None

fetch_user(ident: str) User | None[source]#

Fetch a user from the GitHub API.

Parameters:

ident (str) – The username of the user to fetch.

Returns:

The fetched user object or None if the user is not found.

Return type:

User or None

get_auth_info() Tuple[str, str][source]#

Get the GitHub authorization information.

Returns:

A tuple containing the OAuth state and provider URL.

Return type:

tuple

property style: LoginStyle#

Get the login style for the authenticator.

Returns:

The login style object.

Return type:

LoginStyle

class maeser.user_manager.LoginStyle(icon: str, login_submit: str, direct_submit: bool = False)[source]#

Bases: object

property form_html: str#
class maeser.user_manager.User(ident: str, blacklisted=False, admin=False, realname='Student', usergroup="b'guest'", authmethod='invalid', requests_left=10, max_requests=10, aka=[])[source]#

Bases: object

Provides default implementations for the methods that Flask-Login expects user objects to have.

property full_id_name#

Return the user’s full identifier name including authentication method.

get_id()[source]#

Return the user’s full identifier name including authentication method.

property is_anonymous#

Return False, as anonymous users are not supported.

property is_authenticated#

Return True if the user is authenticated.

property json: dict[str, Any]#
property requests_remaining#

Return the number of requests remaining for the user.

class maeser.user_manager.UserManager(db_file_path: str, max_requests: int = 10, rate_limit_interval: int = 180)[source]#

Bases: object

Manages user operations including authentication, database interactions, and request tracking.

authenticate(auth_method: str, *args: Any, **kwargs: Any) User | None[source]#

Authenticate a user using the specified authentication method.

Parameters:
  • auth_method (str) – The authentication method to use.

  • *args – Positional arguments for the authentication method.

  • **kwargs – Keyword arguments for the authentication method.

Returns:

The authenticated user object, or None if authentication fails.

Return type:

User

Raises:

ValueError – If the provided auth_method is invalid.

clean_cache() int[source]#

Clean the cache by removing non-banned and non-admin users.

Returns:

The number of users removed from the cache.

Return type:

int

property db_connection: Connection#

Open a connection to the SQLite database.

Returns:

The database connection.

Return type:

sqlite3.Connection

Raises:

sqlite3.OperationalError – If the database cannot be opened.

decrease_requests(auth_method: str, user_id: str, dec_by: int = 1)[source]#

Decrease the number of requests remaining for a user.

Parameters:
  • auth_method (str) – The authentication method used.

  • user_id (str) – The identifier of the user.

  • dec_by (int, optional) – The amount to decrease the requests by. Defaults to 1.

Raises:

ValueError – If the provided auth_method is invalid.

fetch_user(auth_method: str, ident: str) bool[source]#

Fetch a user from the authentication source and add them to the cache without modifying their admin or banned status.

Parameters:
  • auth_method (str) – The authentication method (‘caedm’ or ‘github’).

  • ident (str) – The user’s identifier.

Returns:

True if the user was successfully fetched and cached, False otherwise.

Return type:

bool

get_requests_remaining(auth_method: str, user_id: str) int | None[source]#

Get the number of requests remaining for a user.

Parameters:
  • auth_method (str) – The authentication method used.

  • user_id (str) – The identifier of the user.

Returns:

The number of requests remaining, or None if the user is not found.

Return type:

Union[int, None]

Raises:

ValueError – If the provided auth_method is invalid.

get_user(auth_method: str, ident: str) User | None[source]#

Retrieve a user from the database.

Parameters:
  • auth_method (str) – The authentication method used.

  • ident (str) – The unique identifier of the user.

Returns:

The user object, or None if not found.

Return type:

User

Raises:

ValueError – If the provided auth_method is invalid.

increase_requests(auth_method: str, user_id: str, inc_by: int = 1)[source]#

Increase the number of requests remaining for a user.

Parameters:
  • auth_method (str) – The authentication method used.

  • user_id (str) – The identifier of the user.

  • inc_by (int, optional) – The amount to increase the requests by. Defaults to 1.

Raises:

ValueError – If the provided auth_method is invalid.

list_cleanables()[source]#

List non-banned and non-admin users in the cache/database.

Returns:

A list of user identifiers in the format “auth_method:user_id”.

Return type:

list[str]

list_users(auth_filter: str | None = None, admin_filter: str | None = None, banned_filter: str | None = None) list[User][source]#

List all users in the database, optionally filtered by authentication method, admin status, and banned status.

Parameters:
  • auth_filter (str, optional) – The authentication method to list users for. If None or ‘all’, list users from all authentication methods.

  • admin_filter (str, optional) – Filter users by admin status. Can be ‘all’, ‘admin’, or ‘non-admin’.

  • banned_filter (str, optional) – Filter users by banned status. Can be ‘all’, ‘banned’, or ‘non-banned’.

Returns:

A list of user objects.

Return type:

list[User]

Raises:

ValueError – If the provided auth_method is invalid or if admin_filter or banned_filter have invalid values.

refresh_requests(inc_by: int = 1)[source]#

Refresh the number of requests for all users by the given amount.

Parameters:

inc_by (int, optional) – The amount to increase the requests by. Defaults to 1.

register_authenticator(name: str, authenticator: BaseAuthenticator)[source]#

Register a new authentication method.

Parameters:
  • name (str) – The shorthand name of the authentication method. Must only contain letters.

  • authenticator (BaseAuthenticator) – The authenticator object.

Raises:

ValueError – If the provided name is invalid or the authenticator is already registered.

remove_user_from_cache(auth_method: str, ident: str) bool[source]#

Remove a user from the cache.

Parameters:
  • auth_method (str) – The authentication method used.

  • ident (str) – The identifier of the user.

Returns:

True if the user was removed, False otherwise.

Return type:

bool

Raises:

ValueError – If the provided auth_method is invalid.

update_admin_status(auth_method: str, ident: str, is_admin: bool)[source]#

Update the admin status of a user.

Parameters:
  • auth_method (str) – The authentication method used.

  • ident (str) – The identifier of the user.

  • is_admin (bool) – Whether the user should be an admin or not.

Raises:

ValueError – If the provided auth_method is invalid.

update_banned_status(auth_method: str, ident: str, is_banned: bool)[source]#

Update the banned status of a user.

Parameters:
  • auth_method (str) – The authentication method used.

  • ident (str) – The identifier of the user.

  • is_banned (bool) – Whether the user should be banned or not.

Raises:

ValueError – If the provided auth_method is invalid.