sanic_beskar package#

Submodules#

sanic_beskar.base module#

class sanic_beskar.base.Beskar(app: Sanic | None = None, user_class: object | None = None, is_blacklisted: Callable | None = None, encode_token_hook: Callable | None = None, refresh_token_hook: Callable | None = None, rbac_populate_hook: Callable | None = None)[source]#

Bases: object

Comprises the implementation for the sanic-beskar sanic extension. Provides a tool that allows password authentication and token provision for applications and designated endpoints

audit() None[source]#

Perform some basic sanity check of settings to make sure the developer didn’t try to do some blatantly lame stuff

async authenticate(user: str, password: str, token: str | None = None, lookup: str | None = 'username') object[source]#

Verifies that a password matches the stored password for that username or email. If verification passes, the matching user instance is returned

Note

If BESKAR_TOTP_ENFORCE is set to True (default), and a user has a TOTP configuration, this call must include the token value, or it will raise a TOTPRequired exception and not return the user.

This means either you will need to call it again, providing the token value from the user, or separately call authenticate_totp(), which only performs validation of the token value, and not the users password.

Choose your own adventure.

Parameters:
  • user (str) – Username or email to authenticate

  • password (str) – Password to validate against

  • token (str, optional) – TOTP Token value to validate against. Defaults to None.

  • lookup (str, optional) – Type of lookup to perform, either username or email based. Defaults to ‘username’.

Returns:

Authenticated User object.

Return type:

User

Raises:
async authenticate_totp(user: str | object, token: str, lookup: str | None = 'username') Any[source]#

Verifies that a TOTP validates against the stored TOTP for that username.

If verification passes, the matching user instance is returned.

If automatically called by authenticate(), it accepts a User object instead of username and skips the lookup() call.

Parameters:
  • username (Union[str, object]) – Username, email, or User object to perform TOTP authentication against.

  • token (str) – TOTP token value to validate.

  • lookup (str, optional) – Type of lookup to perform, either username or email based. Defaults to ‘username’.

Returns:

Validated User object.

Return type:

User

Raises:

AuthenticationError – Failed TOTP authentication attempt.

async encode_eternal_token(user: object, **custom_claims: dict | None) str[source]#

This utility function encodes an application configuration defined type token that never expires

Note

This should be used sparingly since the token could become a security concern if it is ever lost. If you use this method, you should be sure that your application also implements a blacklist so that a given token can be blocked should it be lost or become a security concern

Parameters:
  • user (User) – User to generate a token for.

  • custom_claims (dict, optional) – Additional claims that should be packed in the payload. Defaults to None.

Returns:

Encoded, never expiring, token string of application configuration type TOKEN_PROVIDER.

Return type:

str

async encode_jwt_token(user: Any, override_access_lifespan: Duration | None = None, override_refresh_lifespan: Duration | None = None, bypass_user_check: bool | None = False, is_registration_token: bool | None = False, is_reset_token: bool | None = False, **custom_claims: dict | None) str[source]#

Encodes user data into a jwt token that can be used for authorization at protected endpoints

Parameters:
  • user (User) – User to generate a token for.

  • override_access_lifespan (pendulum.Duration, optional) – Override’s the instance’s access lifespan to set a custom duration after which the new token’s accessibility will expire. May not exceed the refresh_lifespan. Defaults to None.

  • override_refresh_lifespan (pendulum.Duration, optional) – Override’s the instance’s refresh lifespan to set a custom duration after which the new token’s refreshability will expire. Defaults to None.

  • bypass_user_check (bool, optional) – Override checking the user for being real/active. Used for registration token generation. Defaults to False.

  • is_registration_token (bool, optional) – Indicates that the token will be used only for email-based registration. Defaults to False.

  • is_reset_token (bool, optional) – Indicates that the token will be used only for lost password reset. Defaults to False.

  • custom_claims (dict, optional) – Additional claims that should be packed in the payload. Defaults to None.

Returns:

Encoded JWT token string.

Return type:

str

Raises:

ClaimCollisionError – Tried to supply a RESERVED_CLAIM in the custom_claims.

async encode_paseto_token(user: Any, override_access_lifespan: Duration | None = None, override_refresh_lifespan: Duration | None = None, bypass_user_check: bool | None = False, is_registration_token: bool | None = False, is_reset_token: bool | None = False, **custom_claims: dict | None) str[source]#

Encodes user data into a PASETO token that can be used for authorization at protected endpoints

Note

Note that any claims supplied as custom_claims here must be json compatible types.

Parameters:
  • user (User) – User to generate a token for.

  • override_access_lifespan (pendulum.Duration, optional) – Override’s the instance’s access lifespan to set a custom duration after which the new token’s accessibility will expire. May not exceed the refresh_lifespan. Defaults to None.

  • override_refresh_lifespan (pendulum.Duration, optional) – Override’s the instance’s refresh lifespan to set a custom duration after which the new token’s refreshability will expire. Defaults to None.

  • bypass_user_check (bool, optional) – Override checking the user for being real/active. Used for registration token generation. Defaults to False.

  • is_registration_token (bool, optional) – Indicates that the token will be used only for email-based registration. Defaults to False.

  • is_reset_token (bool, optional) – Indicates that the token will be used only for lost password reset. Defaults to False.

  • custom_claims (dict, optional) – Additional claims that should be packed in the payload. Defaults to None.

Returns:

Encoded PASETO token string.

Return type:

str

Raises:

ClaimCollisionError – Tried to supply a RESERVED_CLAIM in the custom_claims.

async encode_token(user: object, override_access_lifespan: Duration | None = None, override_refresh_lifespan: Duration | None = None, bypass_user_check: bool | None = False, is_registration_token: bool | None = False, is_reset_token: bool | None = False, **custom_claims: dict | None) str[source]#

Wrapper function to encode user data into a insert_type_here token that can be used for authorization at protected endpoints.

Calling this will allow your app configuration to automagically create the appropriate token type.

Parameters:
  • user (User) – User to generate a token for.

  • override_access_lifespan (pendulum.Duration, optional) – Override’s the instance’s access lifespan to set a custom duration after which the new token’s accessibility will expire. May not exceed the refresh_lifespan. Defaults to None.

  • override_refresh_lifespan (pendulum.Duration, optional) – Override’s the instance’s refresh lifespan to set a custom duration after which the new token’s refreshability will expire. Defaults to None.

  • bypass_user_check (bool, optional) – Override checking the user for being real/active. Used for registration token generation. Defaults to False.

  • is_registration_token (bool, optional) – Indicates that the token will be used only for email-based registration. Defaults to False.

  • is_reset_token (bool, optional) – Indicates that the token will be used only for lost password reset. Defaults to False.

  • custom_claims (dict, optional) – Additional claims that should be packed in the payload. Defaults to None.

Returns:

Encoded token string of application configuration type TOKEN_PROVIDER.

Return type:

str

Raises:

ClaimCollisionError – Tried to supply a RESERVED_CLAIM in the custom_claims.

async extract_jwt_token(token: str, access_type: AccessType = AccessType.access) dict[source]#

Extracts a data dictionary from a JWT token.

Parameters:
  • token (str) – Token to be processed

  • access_type (AccessType) – Type of token being processed

Returns:

Extracted token as a dict

Return type:

dict

async extract_paseto_token(token: bytes | str, access_type: AccessType = AccessType.access) dict[source]#

Extracts a data dictionary from a PASETO token.

Parameters:
  • token (str) – Token to be processed

  • access_type (AccessType) – Type of token being processed

Returns:

Extracted token as a dict

Return type:

dict

async extract_token(token: str, access_type: AccessType = AccessType.access) dict[source]#

Wrapper function to extract a data dictionary from a token. This function will automagically identify the token type based upon application configuration and process it accordingly.

Parameters:
  • token (str) – Token to be processed

  • access_type (AccessType) – Type of token being processed

Returns:

Extracted token as a dict

Return type:

dict

async generate_user_totp() object[source]#

Generates a passlib TOTP for a user. This must be manually saved/updated to the User object.

. ..note:: The application secret(s) should be stored in a secure location, and each

secret should contain a large amount of entropy (to prevent brute-force attacks if the encrypted keys are leaked). passlib.generate_secret() is provided as a convenience helper to generate a new application secret of suitable size. Best practice is to load these values from a file via secrets_path, pulled in value, or utilizing a passlib wallet, and then have your application give up permission to read this file once it’s running.

Returns:

New passlib TOTP secret object

async get_user_from_registration_token(token: str) Any[source]#

Gets a user based on the registration token that is supplied. Verifies that the token is a registration token and that the user can be properly retrieved

Parameters:

token (str) – Registration token to validate.

Returns:

User object of looked up user after token validation

Return type:

User

hash_password(raw_password: str) str[source]#

Hashes a plaintext password using the stored passlib password context

Parameters:

raw_password (str) – cleartext password for the user

Returns:

Properly hashed ciphertext of supplied raw_password

Return type:

str

Raises:

BeskarError – No password is provided

init_app(app: Sanic, user_class: object, is_blacklisted: Callable | None = None, encode_token_hook: Callable | None = None, refresh_token_hook: Callable | None = None, rbac_populate_hook: Callable | None = None) Sanic[source]#

Initializes the Beskar extension

Parameters:
  • app (Sanic) – The Sanic app to bind this extension. Defaults to None.

  • user_class (object) – Class used to interact with a User. Defaults to None.

  • is_blacklisted (Callable, optional) – A method that may optionally be used to check the token against a blacklist when access or refresh is requested should take the jti for the token to check as a single argument. Returns True if the jti is blacklisted, False otherwise. Defaults to False.

  • encode_token_hook (Callable, optional) – A method that may optionally be called right before an encoded jwt is generated. Should take payload_parts which contains the ingredients for the jwt. Defaults to None.

  • refresh_token_hook (Callable, optional) – A method that may optionally be called right before an encoded jwt is refreshed. Should take payload_parts which contains the ingredients for the jwt. Defaults to None.

  • rbac_populate_hook (Callable, optional) – A method that may optionally be called at Beskar init time, or periodcally, to populate a RBAC dictionary mapping user Roles to RBAC rights. Defaults to None.

Returns:

Initialized sanic-beskar object.

Return type:

Object

Raises:

ConfigurationError – Invalid/missing configuration value is detected.

async open_session(request: Request) None[source]#

required for Sanic

async pack_header_for_user(user: object | str, override_access_lifespan: Duration | None = None, override_refresh_lifespan: Duration | None = None, bypass_user_check: bool | None = False, is_registration_token: bool | None = False, is_reset_token: bool | None = False, **custom_claims: dict | None) dict[source]#

Encodes a jwt token and packages it into a header dict for a given user

Parameters:
  • user (User) – The user to package the header for

  • override_access_lifespan (pendulum) – Override’s the instance’s access lifespan to set a custom duration after which the new token’s accessibility will expire. May not exceed the refresh_lifespan

  • override_refresh_lifespan (pendulum) – Override’s the instance’s refresh lifespan to set a custom duration after which the new token’s refreshability will expire.

  • custom_claims (dict) – Additional claims that should be packed in the payload. Note that any claims supplied here must be json compatible types

Returns:

Updated header, including token

Return type:

dict

read_token(request: Request) str[source]#

Tries to unpack the token from the current sanic request in the locations configured by TOKEN_PLACES. Check-Order is defined by the value order in TOKEN_PLACES.

Parameters:

request (sanic.Request) – Sanic request object

Returns:

Token.

Return type:

str

Raises:

MissingToken – Token is not found in any TOKEN_PLACES

Unpacks a token from the current sanic request

Parameters:

request (Request) – Current Sanic Request.

Returns:

Unpacked token from cookie.

Return type:

str

read_token_from_header(request: Request) str | None[source]#

Unpacks a token from the current sanic request

Parameters:

request (Request) – Current Sanic Request.

Returns:

Unpacked token from header.

Return type:

str

async refresh_jwt_token(token: str, override_access_lifespan: Duration | None = None) str[source]#

Creates a new JWT token for a user if and only if the old token’s access permission is expired but its refresh permission is not yet expired. The new token’s refresh expiration moment is the same as the old token’s, but the new token’s access expiration is refreshed

Parameters:
  • token (str) – The existing token that needs to be replaced with a new, refreshed token.

  • override_access_lifespan (_type_, optional) – Override’s the instance’s access lifespan to set a custom duration after which the new token’s accessibility will expire. May not exceed the refresh_lifespan. Defaults to None.

Returns:

Encoded JWT token string.

Return type:

str

async refresh_paseto_token(token: str, override_access_lifespan: Duration | None = None) bytes[source]#

Creates a new PASETO token for a user if and only if the old token’s access permission is expired but its refresh permission is not yet expired. The new token’s refresh expiration moment is the same as the old token’s, but the new token’s access expiration is refreshed

Parameters:
  • token (str) – The existing token that needs to be replaced with a new, refreshed token.

  • override_access_lifespan (_type_, optional) – Override’s the instance’s access lifespan to set a custom duration after which the new token’s accessibility will expire. May not exceed the refresh_lifespan. Defaults to None.

Returns:

Encoded PASETO token string.

Return type:

bytes

async refresh_token(token: str, override_access_lifespan: Duration | None = None) str[source]#

Wrapper function to creates a new token for a user if and only if the old token’s access permission is expired but its refresh permission is not yet expired. The new token’s refresh expiration moment is the same as the old token’s, but the new token’s access expiration is refreshed.

Token type is determined by application configuration, when using this helper function.

Parameters:
  • token (str) – The existing token that needs to be replaced with a new, refreshed token.

  • override_access_lifespan (_type_, optional) – Override’s the instance’s access lifespan to set a custom duration after which the new token’s accessibility will expire. May not exceed the refresh_lifespan. Defaults to None.

Returns:

Encoded token string of application configuration type TOKEN_PROVIDER.

Return type:

str

async send_registration_email(email: str, user: object, template: str | Template | None = None, confirmation_sender: str | None = None, confirmation_uri: str | None = None, subject: str | None = None, override_access_lifespan: Duration | None = None) dict[source]#

Sends a registration email to a new user, containing a time expiring token usable for validation. This requires your application is initialized with a mail extension, which supports sanic-mailing’s Message object and a send_message() method.

Parameters:
  • user (User) – The user object to tie claim to (username, id, email, etc)

  • template (Optional, filehandle) – HTML Template for confirmation email. If not provided, a stock entry is used.

  • confirmation_sender (Optional, str) – The sender that should be attached to the confirmation email. Overrides the BESKAR_CONFIRMATION_SENDER config setting.

  • confirmation_uri (Optional, str) – The uri that should be visited to complete email registration. Should usually be a uri to a frontend or external service that calls a ‘finalize’ method in the api to complete registration. Will override the BESKAR_CONFIRMATION_URI config setting.

  • subject (Optional, str) – The registration email subject. Will override the BESKAR_CONFIRMATION_SUBJECT config setting.

  • override_access_lifespan (Optional, pendulum) – Overrides the TOKEN_ACCESS_LIFESPAN to set an access lifespan for the registration token.

Returns:

Summary of information sent, along with the result from mail send. (Essentially the response of send_token_email()).

Return type:

dict

async send_reset_email(email: str, template: str | Template | None = None, reset_sender: str | None = None, reset_uri: str | None = None, subject: str | None = None, override_access_lifespan: Duration | None = None) dict[source]#

Sends a password reset email to a user, containing a time expiring token usable for validation. This requires your application is initialized with a mail extension, which supports sanic-mailing’s Message object and a send_message() method.

Parameters:
  • email (str) – The email address to attempt to send to.

  • template (Optional, filehandle) – HTML Template for reset email. If not provided, a stock entry is used.

  • reset_sender (Optional, str) – The sender that should be attached to the reset email. Defaults to BESKAR_RESET_SENDER config setting.

  • reset_uri (Optional, str) – The uri that should be visited to complete password reset. Should usually be a uri to a frontend or external service that calls the ‘validate_reset_token()’ method in the api to complete reset. Defaults to BESKAR_RESET_URI config setting.

  • subject (Optional, str) – The reset email subject. Defaults to BESKAR_RESET_SUBJECT config setting.

  • override_access_lifespan (Optional, pendulum) – Overrides the TOKEN_ACCESS_LIFESPAN to set an access lifespan for the registration token. Defaults to TOKEN_ACCESS_LIFESPAN config setting.

Returns:

Summary of information sent, along with the result from mail send. (Essentially the response of send_token_email()).

Return type:

dict

async send_token_email(email: str, user: object, template: str | Template | None = None, action_sender: str | None = '', action_uri: str | None = '', subject: str | None = '', override_access_lifespan: Duration | None = None, custom_token: str = '') dict[source]#

Sends an email to a user, containing a time expiring token usable for several actions. This requires your application is initialized with a mail extension, which supports sanic-mailing’s Message object and a send_message() method.

Parameters:
  • user (User) – The user object to tie claim to (username, id, email, etc)

  • email (str) – The email address to attempt to send to.

  • template (Optional, filehandle) – HTML Template for the email. If not provided, a stock entry is used.

  • action_sender (str) – The sender that should be attached to the email.

  • action_uri (str) – The uri that should be visited to complete this notification action.

  • subject (str) – The email subject.

  • override_access_lifespan (Optional, pendulum) – Overrides the TOKEN_ACCESS_LIFESPAN to set an access lifespan for the registration token. Defaults to TOKEN_ACCESS_LIFESPAN config setting.

  • custom_token (str) – The token to be carried as the email’s payload.

Returns:

Summary of information sent, along with the result from mail send. (Essentially the response of send_token_email()).

Return type:

dict

Raises:

BeskarError – Missing required parameters.

set_config() None[source]#

Simple helper to populate all the config settings, making init_app() easier to read

async validate_reset_token(token: str) Any[source]#

Validates a password reset request based on the reset token that is supplied. Verifies that the token is a reset token and that the user can be properly retrieved

Parameters:

token (str) – Reset token to validate.

Returns:

object of looked up user after token validation

Return type:

User

Raises:

BeskarError – Missing required parameters

async verify_and_update(user: Any, password: str = '') Any[source]#

Validate a password hash contained in the user object is hashed with the defined hash scheme (BESKAR_HASH_SCHEME).

If not, raise an Exception of LegacySchema, unless the password argument is provided, in which case an updated User will be returned, and must be saved by the calling app. The updated User will contain the users current password updated to the currently desired hash scheme (BESKAR_HASH_SCHEME).

Parameters:
  • user (User) – The user class to tie claim to (username, id, email, etc). MUST include the password field, defined as password.

  • password (str) – The user’s provide password from login. If present, this is used to validate and then attempt to update with the new BESKAR_HASH_SCHEME scheme.

Returns:

Authenticated User

Return type:

User

Raises:

AuthenticationError – Authentication failure

sanic_beskar.constants module#

class sanic_beskar.constants.AccessType(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)[source]#

Bases: Enum

enum for the various Access token types

access: str = 'ACCESS'#
refresh: str = 'REFRESH'#
register: str = 'REGISTER'#
reset: str = 'RESET'#

sanic_beskar.decorators module#

sanic_beskar.decorators.auth_accepted(method: Callable) Callable[[...], Any][source]#

This decorator is used to allow an authenticated user to be identified while being able to access a sanic route, and adds the current user to the current sanic context.

Parameters:

method (Callable) – Function or route to protect.

Returns:

Decorator

Return type:

None

sanic_beskar.decorators.auth_required(method: Callable) Callable[[...], Any][source]#

This decorator is used to ensure that a user is authenticated before being able to access a sanic route. It also adds the current user to the current sanic context.

Parameters:

method (Callable) – Function or route to protect.

Returns:

Decorator

Return type:

None

sanic_beskar.decorators.rights_required(*required_rights: list | set) Callable[[...], Any][source]#

This decorator ensures that any uses accessing the decorated route have all the needed rights to access it. If an auth_required() decorator is not supplied already, this decorator will implicitly check auth_required() first.

Parameters:

required_rights (Union[list, set]) – Right names required to be present, based upon the implied rights in the authenticated users roles attribute breakdown.

Returns:

Decorator

Return type:

None

sanic_beskar.decorators.roles_accepted(*accepted_rolenames: list | set) Callable[[...], Any][source]#

This decorator ensures that any uses accessing the decorated route have one of the needed roles to access it. If an auth_required() decorator is not supplied already, this decorator will implicitly check auth_required() first

Parameters:

accepted_rolenames (Union[list, set]) – Role names, at least one of which is required to be present, in the authenticated users roles attribute.

Returns:

Decorator

Return type:

None

sanic_beskar.decorators.roles_required(*required_rolenames: list | set) Callable[[...], Any][source]#

This decorator ensures that any uses accessing the decorated route have all the needed roles to access it. If an auth_required() decorator is not supplied already, this decorator will implicitly check auth_required() first

Parameters:

required_rolenames (Union[list, set]) – Role names required to be present in the authenticated users roles attribute.

Returns:

Decorator

Return type:

None

sanic_beskar.exceptions module#

exception sanic_beskar.exceptions.AuthenticationError(message: str, *args: tuple, **kwargs: dict)[source]#

Bases: BeskarError

The entered user’s password did not match the stored password

exception sanic_beskar.exceptions.BeskarError(message: str, *args: tuple, **kwargs: dict)[source]#

Bases: SanicException, Buzz

Provides a custom exception class for sanic-beskar based on py-buzz. py-buzz on gitub

status: int = 401#
exception sanic_beskar.exceptions.BlacklistedError(message: str, *args: tuple, **kwargs: dict)[source]#

Bases: BeskarError

The token has been blacklisted and may not be used any more

status: int = 403#
exception sanic_beskar.exceptions.ClaimCollisionError(message: str, *args: tuple, **kwargs: dict)[source]#

Bases: BeskarError

” Custom claims to pack into the payload collide with reserved claims

exception sanic_beskar.exceptions.ConfigurationError(message: str, *args: tuple, **kwargs: dict)[source]#

Bases: BeskarError

There was a problem with the configuration

exception sanic_beskar.exceptions.EarlyRefreshError(message: str, *args: tuple, **kwargs: dict)[source]#

Bases: BeskarError

The token has not yet expired for access and may not be refreshed

status: int = 425#
exception sanic_beskar.exceptions.ExpiredAccessError(message: str, *args: tuple, **kwargs: dict)[source]#

Bases: BeskarError

The token has expired for access and must be refreshed

exception sanic_beskar.exceptions.ExpiredRefreshError(message: str, *args: tuple, **kwargs: dict)[source]#

Bases: BeskarError

The token has expired for refresh. An entirely new token must be issued

exception sanic_beskar.exceptions.InvalidRegistrationToken(message: str, *args: tuple, **kwargs: dict)[source]#

Bases: BeskarError

The supplied registration token is invalid

exception sanic_beskar.exceptions.InvalidResetToken(message: str, *args: tuple, **kwargs: dict)[source]#

Bases: BeskarError

The supplied registration token is invalid

exception sanic_beskar.exceptions.InvalidTokenHeader(message: str, *args: tuple, **kwargs: dict)[source]#

Bases: BeskarError

The token contained in the header is invalid

exception sanic_beskar.exceptions.InvalidUserError(message: str, *args: tuple, **kwargs: dict)[source]#

Bases: BeskarError

The user is no longer valid and is now not authorized

status: int = 403#
exception sanic_beskar.exceptions.LegacyScheme(message: str, *args: tuple, **kwargs: dict)[source]#

Bases: BeskarError

The processed hash is using an outdated scheme

exception sanic_beskar.exceptions.MissingClaimError(message: str, *args: tuple, **kwargs: dict)[source]#

Bases: BeskarError

The token is missing a required claim

exception sanic_beskar.exceptions.MissingRightError(message: str, *args: tuple, **kwargs: dict)[source]#

Bases: BeskarError

The token is missing a required right based upon role breakdown

status: int = 403#
exception sanic_beskar.exceptions.MissingRoleError(message: str, *args: tuple, **kwargs: dict)[source]#

Bases: BeskarError

The token is missing a required role

status: int = 403#
exception sanic_beskar.exceptions.MissingToken(message: str, *args: tuple, **kwargs: dict)[source]#

Bases: BeskarError

The header is missing the required token

exception sanic_beskar.exceptions.MissingUserError(message: str, *args: tuple, **kwargs: dict)[source]#

Bases: BeskarError

The user could not be identified

exception sanic_beskar.exceptions.MisusedRegistrationToken(message: str, *args: tuple, **kwargs: dict)[source]#

Bases: BeskarError

Attempted to use a registration token for normal access

exception sanic_beskar.exceptions.MisusedResetToken(message: str, *args: tuple, **kwargs: dict)[source]#

Bases: BeskarError

Attempted to use a password reset token for normal access

exception sanic_beskar.exceptions.TOTPRequired(message: str, *args: tuple, **kwargs: dict)[source]#

Bases: AuthenticationError

The user requires TOTP authentication, per configuration BESKAR_TOTP_ENFORCE which was not performed by this call to authenticate(). A call to authenticate_totp() should be performed separately, or a call to authenticate() again, but providing the users token value should be done.

exception sanic_beskar.exceptions.VerifyError(message: str, *args: tuple, **kwargs: dict)[source]#

Bases: InvalidTokenHeader

The token contained in the header is invalid

sanic_beskar.utilities module#

class sanic_beskar.utilities.JSONEncoder(*, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)[source]#

Bases: JSONEncoder

JSON encoder class to facilitate serializing datetimes and ObjectId’s

default(o: Any) Any[source]#

hooks for the various types

sanic_beskar.utilities.add_token_data_to_app_context(token_data: dict) None[source]#

Adds a dictionary of token data (presumably unpacked from a token) to the top of the sanic app’s context

Parameters:

token_data (dict) – dict of token data to add

sanic_beskar.utilities.app_context_has_token_data(ctx: Sanic | None = None) bool[source]#

Checks if there is already token_data added to the app context

Parameters:

ctx (Optional[Sanic]) – Application Context

Returns:

True, False

Return type:

bool

sanic_beskar.utilities.current_custom_claims() dict[source]#

This method returns any custom claims in the current token

Returns:

Custom claims for currently logged in user

Return type:

dict

sanic_beskar.utilities.current_guard(ctx: Sanic | SimpleNamespace | None = None) BeskarType[source]#

Fetches the current instance of Beskar that is attached to the current sanic app

Parameters:

ctx (Optional[sanic.Sanic]) – Application Context

Returns:

Current Beskar Guard object for this app context

Return type:

Beskar

Raises:

BeskarError if no guard found

async sanic_beskar.utilities.current_rolenames() set[source]#

This method returns the names of all roles associated with the current user

Returns:

Set of roles for currently logged in users

Return type:

set

async sanic_beskar.utilities.current_user() Any[source]#

This method returns a user instance for token data attached to the current sanic app’s context

Returns:

Current logged in User object

Return type:

populated user_class attribute of the logged in Beskar instance

Raises:

BeskarError if no user identified

sanic_beskar.utilities.current_user_id() str | None[source]#

This method returns the user id retrieved from token data attached to the current sanic app’s context

Returns:

id of current User, if any

Return type:

str

Raises:

BeskarError if no user/token found

sanic_beskar.utilities.duration_from_string(text: str) Duration[source]#

Parses a duration from a string. String may look like these patterns: * 1 Hour * 7 days, 45 minutes * 1y11d20m

An exception will be raised if the text cannot be parsed

Parameters:

text (str) – String to parse for duration detail

Returns:

Time Object

Return type:

pendulum

Raises:

ConfigurationError on bad strings

async sanic_beskar.utilities.generate_totp_qr(user_totp: str) QRCode[source]#

This is a helper utility to generate a segno QR code renderer, based upon a supplied User TOTP value.

Parameters:

user_totp (json) – TOTP configuration of the user

Returns:

Segno object based upon user’s stored TOTP configuration

Return type:

Segno

sanic_beskar.utilities.get_request(request: Request) Request[source]#

Get current Sanic Request

sanic_beskar.utilities.get_token_data_from_app_context() dict[source]#

Fetches a dict of token data from the top of the sanic app’s context

Returns:

Token dict found in current app context

Return type:

dict

Raises:

BeskarError on missing token

async sanic_beskar.utilities.is_valid_json(data: str) Any[source]#

Simple helper to validate if a value is valid json data

Parameters:

data (str) – Data to validate for valid JSON

Returns:

True, False

Return type:

bool

sanic_beskar.utilities.normalize_rbac(rbac_dump: dict) dict[source]#

Normalize an RBAC dump into something usable.

Yes, I know this will produce duplicates in the role lists of a permission, but its much faster than dealing with a set, so we don’t care.

Example

{‘rolename’: [‘read’, ‘write’, ‘update’],}

Produces:

{‘read’: [‘rolename’], ‘write’: [‘rolename’], ‘update’: [‘rolename’]}

Parameters:

rbac_dump (dict) – RBAC dump from config/storage.

Returns:

Normalized (for our purposes) RBAC policy.

Return type:

dict

sanic_beskar.utilities.remove_token_data_from_app_context() None[source]#

Removes the dict of token data from the top of the sanic app’s context

sanic_beskar.orm.tortoise_user_mixins module#

class sanic_beskar.orm.tortoise_user_mixins.TortoiseUserMixin(**kwargs: Any)[source]#

Bases: Model

A short-cut providing required methods and attributes for a user class implemented with tortoise-orm. Makes many assumptions about how the class is defined.

ASSUMPTIONS:

  • The model has an id column that uniquely identifies each instance

  • The model has a roles column that contains the roles for the user instance as a comma separated list of roles

  • The model has a username column that is a unique string for each instance

  • The model has a password column that contains its hashed password

async classmethod identify(id: ObjectId) Model | None[source]#

Required Attribute or Property

sanic-beskar requires that the user class implements an identify() class method that takes a single id argument and returns user instance if there is one that matches or None if there is not.

Parameters:

self (User) – a User object

Returns:

Provided User id

Return type:

str, None

property identity: str | ObjectId#

Required Attribute or Property

sanic-beskar requires that the user class has an identity() instance attribute or property that provides the unique id of the user instance

Returns:

Provided User.id

Return type:

str

async classmethod lookup(username: str | None = None, email: str | None = None) Model | None[source]#

Required Method

sanic-beskar requires that the user class implements a lookup() class method that takes a single username or email argument and returns a user instance if there is one that matches or None if there is not.

Parameters:
  • username (Optional[str]) – username of the user to lookup

  • email (Optional[str]) – email of the user to lookup

Returns:

None or User of the found user

Return type:

User

property rolenames: list | None#

Required Attribute or Property

sanic-beskaruires that the user class has a rolenames instance attribute or property that provides a list of strings that describe the roles attached to the user instance.

This can be a separate table (probably sane), so long as this attribute or property properly returns the associated values for the user as a RBAC dict, as: {‘rolename’, [‘permissions’],}

Returns:

Provided User’s current roles

Return type:

list

sanic_beskar.orm.umongo_user_mixins module#

class sanic_beskar.orm.umongo_user_mixins.UmongoUserMixin(*args, **kwargs)[source]#

Bases: MixinDocumentTemplate

A short-cut providing required methods and attributes for a user class implemented with uMongo + Motor(async). Makes many assumptions about how the class is defined.

ASSUMPTIONS

  • The model has an id column that uniquely identifies each instance

  • The model has a rolenames column that contains the roles for the user instance as a comma separated list of roles

  • The model has a username column that is a unique string for each instance

  • The model has a password column that contains its hashed password

class Meta[source]#

Bases: object

abstract = True#
async classmethod identify(id: str) DocumentTemplate | None[source]#

Required Attribute or Property

sanic-beskar requires that the user class implements an identify() class method that takes a single id argument and returns user instance if there is one that matches or None if there is not.

Parameters:

self (User) – a User object

Returns:

Provided User id

Return type:

str, None

property identity: str#

Required Attribute or Property

sanic-beskar requires that the user class has an identity() instance attribute or property that provides the unique id of the user instance

Mongo’s id, by default, is an ObjectId(), which cannot be serialized by default – so return as as a string value instead!

Returns:

Provided User id

Return type:

str

async classmethod lookup(username: str | None = None, email: str | None = None) DocumentTemplate | None[source]#

Required Method

sanic-beskar requires that the user class implements a lookup() class method that takes a single username or email argument and returns a user instance if there is one that matches or None if there is not.

Parameters:
  • username (Optional[str]) – username of the user to lookup

  • email (Optional[str]) – email of the user to lookup

Returns:

None or User of the found user

Return type:

User, None

property rolenames: list | None#

Required Attribute or Property

sanic-beskar requires that the user class has a roles instance attribute or property that provides a list of strings that describe the roles attached to the user instance.

This can be a separate table (probably sane), so long as this attribute or property properly returns the associated values for the user as a RBAC dict, as: {‘rolename’, [‘permissions’],}

Returns:

Provided User’s current roles

Return type:

list

Module contents#

class sanic_beskar.Beskar(app: Sanic | None = None, user_class: object | None = None, is_blacklisted: Callable | None = None, encode_token_hook: Callable | None = None, refresh_token_hook: Callable | None = None, rbac_populate_hook: Callable | None = None)[source]#

Bases: object

Comprises the implementation for the sanic-beskar sanic extension. Provides a tool that allows password authentication and token provision for applications and designated endpoints

audit() None[source]#

Perform some basic sanity check of settings to make sure the developer didn’t try to do some blatantly lame stuff

async authenticate(user: str, password: str, token: str | None = None, lookup: str | None = 'username') object[source]#

Verifies that a password matches the stored password for that username or email. If verification passes, the matching user instance is returned

Note

If BESKAR_TOTP_ENFORCE is set to True (default), and a user has a TOTP configuration, this call must include the token value, or it will raise a TOTPRequired exception and not return the user.

This means either you will need to call it again, providing the token value from the user, or separately call authenticate_totp(), which only performs validation of the token value, and not the users password.

Choose your own adventure.

Parameters:
  • user (str) – Username or email to authenticate

  • password (str) – Password to validate against

  • token (str, optional) – TOTP Token value to validate against. Defaults to None.

  • lookup (str, optional) – Type of lookup to perform, either username or email based. Defaults to ‘username’.

Returns:

Authenticated User object.

Return type:

User

Raises:
async authenticate_totp(user: str | object, token: str, lookup: str | None = 'username') Any[source]#

Verifies that a TOTP validates against the stored TOTP for that username.

If verification passes, the matching user instance is returned.

If automatically called by authenticate(), it accepts a User object instead of username and skips the lookup() call.

Parameters:
  • username (Union[str, object]) – Username, email, or User object to perform TOTP authentication against.

  • token (str) – TOTP token value to validate.

  • lookup (str, optional) – Type of lookup to perform, either username or email based. Defaults to ‘username’.

Returns:

Validated User object.

Return type:

User

Raises:

AuthenticationError – Failed TOTP authentication attempt.

async encode_eternal_token(user: object, **custom_claims: dict | None) str[source]#

This utility function encodes an application configuration defined type token that never expires

Note

This should be used sparingly since the token could become a security concern if it is ever lost. If you use this method, you should be sure that your application also implements a blacklist so that a given token can be blocked should it be lost or become a security concern

Parameters:
  • user (User) – User to generate a token for.

  • custom_claims (dict, optional) – Additional claims that should be packed in the payload. Defaults to None.

Returns:

Encoded, never expiring, token string of application configuration type TOKEN_PROVIDER.

Return type:

str

async encode_jwt_token(user: Any, override_access_lifespan: Duration | None = None, override_refresh_lifespan: Duration | None = None, bypass_user_check: bool | None = False, is_registration_token: bool | None = False, is_reset_token: bool | None = False, **custom_claims: dict | None) str[source]#

Encodes user data into a jwt token that can be used for authorization at protected endpoints

Parameters:
  • user (User) – User to generate a token for.

  • override_access_lifespan (pendulum.Duration, optional) – Override’s the instance’s access lifespan to set a custom duration after which the new token’s accessibility will expire. May not exceed the refresh_lifespan. Defaults to None.

  • override_refresh_lifespan (pendulum.Duration, optional) – Override’s the instance’s refresh lifespan to set a custom duration after which the new token’s refreshability will expire. Defaults to None.

  • bypass_user_check (bool, optional) – Override checking the user for being real/active. Used for registration token generation. Defaults to False.

  • is_registration_token (bool, optional) – Indicates that the token will be used only for email-based registration. Defaults to False.

  • is_reset_token (bool, optional) – Indicates that the token will be used only for lost password reset. Defaults to False.

  • custom_claims (dict, optional) – Additional claims that should be packed in the payload. Defaults to None.

Returns:

Encoded JWT token string.

Return type:

str

Raises:

ClaimCollisionError – Tried to supply a RESERVED_CLAIM in the custom_claims.

async encode_paseto_token(user: Any, override_access_lifespan: Duration | None = None, override_refresh_lifespan: Duration | None = None, bypass_user_check: bool | None = False, is_registration_token: bool | None = False, is_reset_token: bool | None = False, **custom_claims: dict | None) str[source]#

Encodes user data into a PASETO token that can be used for authorization at protected endpoints

Note

Note that any claims supplied as custom_claims here must be json compatible types.

Parameters:
  • user (User) – User to generate a token for.

  • override_access_lifespan (pendulum.Duration, optional) – Override’s the instance’s access lifespan to set a custom duration after which the new token’s accessibility will expire. May not exceed the refresh_lifespan. Defaults to None.

  • override_refresh_lifespan (pendulum.Duration, optional) – Override’s the instance’s refresh lifespan to set a custom duration after which the new token’s refreshability will expire. Defaults to None.

  • bypass_user_check (bool, optional) – Override checking the user for being real/active. Used for registration token generation. Defaults to False.

  • is_registration_token (bool, optional) – Indicates that the token will be used only for email-based registration. Defaults to False.

  • is_reset_token (bool, optional) – Indicates that the token will be used only for lost password reset. Defaults to False.

  • custom_claims (dict, optional) – Additional claims that should be packed in the payload. Defaults to None.

Returns:

Encoded PASETO token string.

Return type:

str

Raises:

ClaimCollisionError – Tried to supply a RESERVED_CLAIM in the custom_claims.

async encode_token(user: object, override_access_lifespan: Duration | None = None, override_refresh_lifespan: Duration | None = None, bypass_user_check: bool | None = False, is_registration_token: bool | None = False, is_reset_token: bool | None = False, **custom_claims: dict | None) str[source]#

Wrapper function to encode user data into a insert_type_here token that can be used for authorization at protected endpoints.

Calling this will allow your app configuration to automagically create the appropriate token type.

Parameters:
  • user (User) – User to generate a token for.

  • override_access_lifespan (pendulum.Duration, optional) – Override’s the instance’s access lifespan to set a custom duration after which the new token’s accessibility will expire. May not exceed the refresh_lifespan. Defaults to None.

  • override_refresh_lifespan (pendulum.Duration, optional) – Override’s the instance’s refresh lifespan to set a custom duration after which the new token’s refreshability will expire. Defaults to None.

  • bypass_user_check (bool, optional) – Override checking the user for being real/active. Used for registration token generation. Defaults to False.

  • is_registration_token (bool, optional) – Indicates that the token will be used only for email-based registration. Defaults to False.

  • is_reset_token (bool, optional) – Indicates that the token will be used only for lost password reset. Defaults to False.

  • custom_claims (dict, optional) – Additional claims that should be packed in the payload. Defaults to None.

Returns:

Encoded token string of application configuration type TOKEN_PROVIDER.

Return type:

str

Raises:

ClaimCollisionError – Tried to supply a RESERVED_CLAIM in the custom_claims.

async extract_jwt_token(token: str, access_type: AccessType = AccessType.access) dict[source]#

Extracts a data dictionary from a JWT token.

Parameters:
  • token (str) – Token to be processed

  • access_type (AccessType) – Type of token being processed

Returns:

Extracted token as a dict

Return type:

dict

async extract_paseto_token(token: bytes | str, access_type: AccessType = AccessType.access) dict[source]#

Extracts a data dictionary from a PASETO token.

Parameters:
  • token (str) – Token to be processed

  • access_type (AccessType) – Type of token being processed

Returns:

Extracted token as a dict

Return type:

dict

async extract_token(token: str, access_type: AccessType = AccessType.access) dict[source]#

Wrapper function to extract a data dictionary from a token. This function will automagically identify the token type based upon application configuration and process it accordingly.

Parameters:
  • token (str) – Token to be processed

  • access_type (AccessType) – Type of token being processed

Returns:

Extracted token as a dict

Return type:

dict

async generate_user_totp() object[source]#

Generates a passlib TOTP for a user. This must be manually saved/updated to the User object.

. ..note:: The application secret(s) should be stored in a secure location, and each

secret should contain a large amount of entropy (to prevent brute-force attacks if the encrypted keys are leaked). passlib.generate_secret() is provided as a convenience helper to generate a new application secret of suitable size. Best practice is to load these values from a file via secrets_path, pulled in value, or utilizing a passlib wallet, and then have your application give up permission to read this file once it’s running.

Returns:

New passlib TOTP secret object

async get_user_from_registration_token(token: str) Any[source]#

Gets a user based on the registration token that is supplied. Verifies that the token is a registration token and that the user can be properly retrieved

Parameters:

token (str) – Registration token to validate.

Returns:

User object of looked up user after token validation

Return type:

User

hash_password(raw_password: str) str[source]#

Hashes a plaintext password using the stored passlib password context

Parameters:

raw_password (str) – cleartext password for the user

Returns:

Properly hashed ciphertext of supplied raw_password

Return type:

str

Raises:

BeskarError – No password is provided

init_app(app: Sanic, user_class: object, is_blacklisted: Callable | None = None, encode_token_hook: Callable | None = None, refresh_token_hook: Callable | None = None, rbac_populate_hook: Callable | None = None) Sanic[source]#

Initializes the Beskar extension

Parameters:
  • app (Sanic) – The Sanic app to bind this extension. Defaults to None.

  • user_class (object) – Class used to interact with a User. Defaults to None.

  • is_blacklisted (Callable, optional) – A method that may optionally be used to check the token against a blacklist when access or refresh is requested should take the jti for the token to check as a single argument. Returns True if the jti is blacklisted, False otherwise. Defaults to False.

  • encode_token_hook (Callable, optional) – A method that may optionally be called right before an encoded jwt is generated. Should take payload_parts which contains the ingredients for the jwt. Defaults to None.

  • refresh_token_hook (Callable, optional) – A method that may optionally be called right before an encoded jwt is refreshed. Should take payload_parts which contains the ingredients for the jwt. Defaults to None.

  • rbac_populate_hook (Callable, optional) – A method that may optionally be called at Beskar init time, or periodcally, to populate a RBAC dictionary mapping user Roles to RBAC rights. Defaults to None.

Returns:

Initialized sanic-beskar object.

Return type:

Object

Raises:

ConfigurationError – Invalid/missing configuration value is detected.

async open_session(request: Request) None[source]#

required for Sanic

async pack_header_for_user(user: object | str, override_access_lifespan: Duration | None = None, override_refresh_lifespan: Duration | None = None, bypass_user_check: bool | None = False, is_registration_token: bool | None = False, is_reset_token: bool | None = False, **custom_claims: dict | None) dict[source]#

Encodes a jwt token and packages it into a header dict for a given user

Parameters:
  • user (User) – The user to package the header for

  • override_access_lifespan (pendulum) – Override’s the instance’s access lifespan to set a custom duration after which the new token’s accessibility will expire. May not exceed the refresh_lifespan

  • override_refresh_lifespan (pendulum) – Override’s the instance’s refresh lifespan to set a custom duration after which the new token’s refreshability will expire.

  • custom_claims (dict) – Additional claims that should be packed in the payload. Note that any claims supplied here must be json compatible types

Returns:

Updated header, including token

Return type:

dict

read_token(request: Request) str[source]#

Tries to unpack the token from the current sanic request in the locations configured by TOKEN_PLACES. Check-Order is defined by the value order in TOKEN_PLACES.

Parameters:

request (sanic.Request) – Sanic request object

Returns:

Token.

Return type:

str

Raises:

MissingToken – Token is not found in any TOKEN_PLACES

Unpacks a token from the current sanic request

Parameters:

request (Request) – Current Sanic Request.

Returns:

Unpacked token from cookie.

Return type:

str

read_token_from_header(request: Request) str | None[source]#

Unpacks a token from the current sanic request

Parameters:

request (Request) – Current Sanic Request.

Returns:

Unpacked token from header.

Return type:

str

async refresh_jwt_token(token: str, override_access_lifespan: Duration | None = None) str[source]#

Creates a new JWT token for a user if and only if the old token’s access permission is expired but its refresh permission is not yet expired. The new token’s refresh expiration moment is the same as the old token’s, but the new token’s access expiration is refreshed

Parameters:
  • token (str) – The existing token that needs to be replaced with a new, refreshed token.

  • override_access_lifespan (_type_, optional) – Override’s the instance’s access lifespan to set a custom duration after which the new token’s accessibility will expire. May not exceed the refresh_lifespan. Defaults to None.

Returns:

Encoded JWT token string.

Return type:

str

async refresh_paseto_token(token: str, override_access_lifespan: Duration | None = None) bytes[source]#

Creates a new PASETO token for a user if and only if the old token’s access permission is expired but its refresh permission is not yet expired. The new token’s refresh expiration moment is the same as the old token’s, but the new token’s access expiration is refreshed

Parameters:
  • token (str) – The existing token that needs to be replaced with a new, refreshed token.

  • override_access_lifespan (_type_, optional) – Override’s the instance’s access lifespan to set a custom duration after which the new token’s accessibility will expire. May not exceed the refresh_lifespan. Defaults to None.

Returns:

Encoded PASETO token string.

Return type:

bytes

async refresh_token(token: str, override_access_lifespan: Duration | None = None) str[source]#

Wrapper function to creates a new token for a user if and only if the old token’s access permission is expired but its refresh permission is not yet expired. The new token’s refresh expiration moment is the same as the old token’s, but the new token’s access expiration is refreshed.

Token type is determined by application configuration, when using this helper function.

Parameters:
  • token (str) – The existing token that needs to be replaced with a new, refreshed token.

  • override_access_lifespan (_type_, optional) – Override’s the instance’s access lifespan to set a custom duration after which the new token’s accessibility will expire. May not exceed the refresh_lifespan. Defaults to None.

Returns:

Encoded token string of application configuration type TOKEN_PROVIDER.

Return type:

str

async send_registration_email(email: str, user: object, template: str | Template | None = None, confirmation_sender: str | None = None, confirmation_uri: str | None = None, subject: str | None = None, override_access_lifespan: Duration | None = None) dict[source]#

Sends a registration email to a new user, containing a time expiring token usable for validation. This requires your application is initialized with a mail extension, which supports sanic-mailing’s Message object and a send_message() method.

Parameters:
  • user (User) – The user object to tie claim to (username, id, email, etc)

  • template (Optional, filehandle) – HTML Template for confirmation email. If not provided, a stock entry is used.

  • confirmation_sender (Optional, str) – The sender that should be attached to the confirmation email. Overrides the BESKAR_CONFIRMATION_SENDER config setting.

  • confirmation_uri (Optional, str) – The uri that should be visited to complete email registration. Should usually be a uri to a frontend or external service that calls a ‘finalize’ method in the api to complete registration. Will override the BESKAR_CONFIRMATION_URI config setting.

  • subject (Optional, str) – The registration email subject. Will override the BESKAR_CONFIRMATION_SUBJECT config setting.

  • override_access_lifespan (Optional, pendulum) – Overrides the TOKEN_ACCESS_LIFESPAN to set an access lifespan for the registration token.

Returns:

Summary of information sent, along with the result from mail send. (Essentially the response of send_token_email()).

Return type:

dict

async send_reset_email(email: str, template: str | Template | None = None, reset_sender: str | None = None, reset_uri: str | None = None, subject: str | None = None, override_access_lifespan: Duration | None = None) dict[source]#

Sends a password reset email to a user, containing a time expiring token usable for validation. This requires your application is initialized with a mail extension, which supports sanic-mailing’s Message object and a send_message() method.

Parameters:
  • email (str) – The email address to attempt to send to.

  • template (Optional, filehandle) – HTML Template for reset email. If not provided, a stock entry is used.

  • reset_sender (Optional, str) – The sender that should be attached to the reset email. Defaults to BESKAR_RESET_SENDER config setting.

  • reset_uri (Optional, str) – The uri that should be visited to complete password reset. Should usually be a uri to a frontend or external service that calls the ‘validate_reset_token()’ method in the api to complete reset. Defaults to BESKAR_RESET_URI config setting.

  • subject (Optional, str) – The reset email subject. Defaults to BESKAR_RESET_SUBJECT config setting.

  • override_access_lifespan (Optional, pendulum) – Overrides the TOKEN_ACCESS_LIFESPAN to set an access lifespan for the registration token. Defaults to TOKEN_ACCESS_LIFESPAN config setting.

Returns:

Summary of information sent, along with the result from mail send. (Essentially the response of send_token_email()).

Return type:

dict

async send_token_email(email: str, user: object, template: str | Template | None = None, action_sender: str | None = '', action_uri: str | None = '', subject: str | None = '', override_access_lifespan: Duration | None = None, custom_token: str = '') dict[source]#

Sends an email to a user, containing a time expiring token usable for several actions. This requires your application is initialized with a mail extension, which supports sanic-mailing’s Message object and a send_message() method.

Parameters:
  • user (User) – The user object to tie claim to (username, id, email, etc)

  • email (str) – The email address to attempt to send to.

  • template (Optional, filehandle) – HTML Template for the email. If not provided, a stock entry is used.

  • action_sender (str) – The sender that should be attached to the email.

  • action_uri (str) – The uri that should be visited to complete this notification action.

  • subject (str) – The email subject.

  • override_access_lifespan (Optional, pendulum) – Overrides the TOKEN_ACCESS_LIFESPAN to set an access lifespan for the registration token. Defaults to TOKEN_ACCESS_LIFESPAN config setting.

  • custom_token (str) – The token to be carried as the email’s payload.

Returns:

Summary of information sent, along with the result from mail send. (Essentially the response of send_token_email()).

Return type:

dict

Raises:

BeskarError – Missing required parameters.

set_config() None[source]#

Simple helper to populate all the config settings, making init_app() easier to read

async validate_reset_token(token: str) Any[source]#

Validates a password reset request based on the reset token that is supplied. Verifies that the token is a reset token and that the user can be properly retrieved

Parameters:

token (str) – Reset token to validate.

Returns:

object of looked up user after token validation

Return type:

User

Raises:

BeskarError – Missing required parameters

async verify_and_update(user: Any, password: str = '') Any[source]#

Validate a password hash contained in the user object is hashed with the defined hash scheme (BESKAR_HASH_SCHEME).

If not, raise an Exception of LegacySchema, unless the password argument is provided, in which case an updated User will be returned, and must be saved by the calling app. The updated User will contain the users current password updated to the currently desired hash scheme (BESKAR_HASH_SCHEME).

Parameters:
  • user (User) – The user class to tie claim to (username, id, email, etc). MUST include the password field, defined as password.

  • password (str) – The user’s provide password from login. If present, this is used to validate and then attempt to update with the new BESKAR_HASH_SCHEME scheme.

Returns:

Authenticated User

Return type:

User

Raises:

AuthenticationError – Authentication failure

exception sanic_beskar.BeskarError(message: str, *args: tuple, **kwargs: dict)[source]#

Bases: SanicException, Buzz

Provides a custom exception class for sanic-beskar based on py-buzz. py-buzz on gitub

extra_args: tuple#
extra_kwargs: dict#
json_response: JSONResponse#
status: int = 401#
sanic_beskar.auth_accepted(method: Callable) Callable[[...], Any][source]#

This decorator is used to allow an authenticated user to be identified while being able to access a sanic route, and adds the current user to the current sanic context.

Parameters:

method (Callable) – Function or route to protect.

Returns:

Decorator

Return type:

None

sanic_beskar.auth_required(method: Callable) Callable[[...], Any][source]#

This decorator is used to ensure that a user is authenticated before being able to access a sanic route. It also adds the current user to the current sanic context.

Parameters:

method (Callable) – Function or route to protect.

Returns:

Decorator

Return type:

None

sanic_beskar.current_custom_claims() dict[source]#

This method returns any custom claims in the current token

Returns:

Custom claims for currently logged in user

Return type:

dict

async sanic_beskar.current_rolenames() set[source]#

This method returns the names of all roles associated with the current user

Returns:

Set of roles for currently logged in users

Return type:

set

async sanic_beskar.current_user() Any[source]#

This method returns a user instance for token data attached to the current sanic app’s context

Returns:

Current logged in User object

Return type:

populated user_class attribute of the logged in Beskar instance

Raises:

BeskarError if no user identified

sanic_beskar.current_user_id() str | None[source]#

This method returns the user id retrieved from token data attached to the current sanic app’s context

Returns:

id of current User, if any

Return type:

str

Raises:

BeskarError if no user/token found

async sanic_beskar.generate_totp_qr(user_totp: str) QRCode[source]#

This is a helper utility to generate a segno QR code renderer, based upon a supplied User TOTP value.

Parameters:

user_totp (json) – TOTP configuration of the user

Returns:

Segno object based upon user’s stored TOTP configuration

Return type:

Segno

sanic_beskar.rights_required(*required_rights: list | set) Callable[[...], Any][source]#

This decorator ensures that any uses accessing the decorated route have all the needed rights to access it. If an auth_required() decorator is not supplied already, this decorator will implicitly check auth_required() first.

Parameters:

required_rights (Union[list, set]) – Right names required to be present, based upon the implied rights in the authenticated users roles attribute breakdown.

Returns:

Decorator

Return type:

None

sanic_beskar.roles_accepted(*accepted_rolenames: list | set) Callable[[...], Any][source]#

This decorator ensures that any uses accessing the decorated route have one of the needed roles to access it. If an auth_required() decorator is not supplied already, this decorator will implicitly check auth_required() first

Parameters:

accepted_rolenames (Union[list, set]) – Role names, at least one of which is required to be present, in the authenticated users roles attribute.

Returns:

Decorator

Return type:

None

sanic_beskar.roles_required(*required_rolenames: list | set) Callable[[...], Any][source]#

This decorator ensures that any uses accessing the decorated route have all the needed roles to access it. If an auth_required() decorator is not supplied already, this decorator will implicitly check auth_required() first

Parameters:

required_rolenames (Union[list, set]) – Role names required to be present in the authenticated users roles attribute.

Returns:

Decorator

Return type:

None