OAuth

Todo

Docstrings (module, models, provider)

Models

class indico.core.oauth.models.applications.OAuthApplication(**kwargs)

Bases: authlib.oauth2.rfc6749.models.ClientMixin, sqlalchemy.orm.decl_api.Model

OAuth applications registered in Indico.

A simple constructor that allows initialization from kwargs.

Sets attributes on the constructed instance using the names and values in kwargs.

Only keys that are present as attributes of the instance’s class are allowed. These could be, for example, any mapped columns or relationships.

allow_pkce_flow

whether the application can use the PKCE flow without a client secret

allowed_scopes

the OAuth scopes the application may request access to

check_client_secret(client_secret)

Check client_secret matching with the client. For instance, in the client table, the column is called client_secret:

def check_client_secret(self, client_secret):
    return self.client_secret == client_secret
Parameters:client_secret – A string of client secret
Returns:bool
check_endpoint_auth_method(method, endpoint)

Check if client support the given method for the given endpoint. There is a token_endpoint_auth_method defined via RFC7591. Developers MAY re-implement this method with:

def check_endpoint_auth_method(self, method, endpoint):
    if endpoint == 'token':
        # if client table has ``token_endpoint_auth_method``
        return self.token_endpoint_auth_method == method
    return True

Method values defined by this specification are:

  • “none”: The client is a public client as defined in OAuth 2.0,
    and does not have a client secret.
  • “client_secret_post”: The client uses the HTTP POST parameters
    as defined in OAuth 2.0
  • “client_secret_basic”: The client uses HTTP Basic as defined in
    OAuth 2.0
check_grant_type(grant_type)

Validate if the client can handle the given grant_type. There are four grant types defined by RFC6749:

  • authorization_code
  • implicit
  • client_credentials
  • password

For instance, there is a allowed_grant_types column in your client:

def check_grant_type(self, grant_type):
    return grant_type in self.grant_types
Parameters:grant_type – the requested grant_type string.
Returns:bool
check_redirect_uri(redirect_uri)

Called by authlib to validate the redirect_uri.

Uses a logic similar to the one at GitHub, i.e. protocol and host/port must match exactly and if there is a path in the whitelisted URL, the path of the redirect_uri must start with that path.

check_response_type(response_type)

Validate if the client can handle the given response_type. There are two response types defined by RFC6749: code and token. For instance, there is a allowed_response_types column in your client:

def check_response_type(self, response_type):
    return response_type in self.response_types
Parameters:response_type – the requested response_type string.
Returns:bool
client_id

the OAuth client_id

client_secret

the OAuth client_secret

default_redirect_uri
description

human readable description

get_allowed_scope(scope)

A method to return a list of requested scopes which are supported by this client. For instance, there is a scope column:

def get_allowed_scope(self, scope):
    if not scope:
        return ''
    allowed = set(scope_to_list(self.scope))
    return list_to_scope([s for s in scope.split() if s in allowed])
Parameters:scope – the requested scope.
Returns:string of scope
get_client_id()

A method to return client_id of the client. For instance, the value in database is saved in a column called client_id:

def get_client_id(self):
    return self.client_id
Returns:string
get_default_redirect_uri()

A method to get client default redirect_uri. For instance, the database table for client has a column called default_redirect_uri:

def get_default_redirect_uri(self):
    return self.default_redirect_uri
Returns:A URL string
id

the unique id of the application

is_enabled

whether the application is enabled or disabled

is_trusted

whether the application can access user data without asking for permission

locator
name

human readable name

redirect_uris

the OAuth absolute URIs that a application may use to redirect to after authorization

reset_client_secret()
system_app_type

the type of system app (if any). system apps cannot be deleted

Bases: sqlalchemy.orm.decl_api.Model

The authorization link between an OAuth app and a user.

A simple constructor that allows initialization from kwargs.

Sets attributes on the constructed instance using the names and values in kwargs.

Only keys that are present as attributes of the instance’s class are allowed. These could be, for example, any mapped columns or relationships.

application
application_id
id
scopes
update_scopes(scopes: set)
user
user_id
class indico.core.oauth.models.applications.SystemAppType

Bases: int, indico.util.enum.IndicoEnum

An enumeration.

checkin = 1
default_data
enforced_data
none = 0
class indico.core.oauth.models.tokens.OAuth2AuthorizationCode(code: str, user_id: int, client_id: str, code_challenge: str, code_challenge_method: str, redirect_uri: str = '', scope: str = '', auth_time: datetime.datetime = <factory>)

Bases: authlib.oauth2.rfc6749.models.AuthorizationCodeMixin

get_auth_time()
get_nonce()
get_redirect_uri()

A method to get authorization code’s redirect_uri. For instance, the database table for authorization code has a column called redirect_uri:

def get_redirect_uri(self):
    return self.redirect_uri
Returns:A URL string
get_scope()

A method to get scope of the authorization code. For instance, the column is called scope:

def get_scope(self):
    return self.scope
Returns:scope string
is_expired()
redirect_uri = ''
scope = ''
class indico.core.oauth.models.tokens.OAuthToken(**kwargs)

Bases: indico.core.oauth.models.tokens.TokenModelBase

OAuth tokens.

A simple constructor that allows initialization from kwargs.

Sets attributes on the constructed instance using the names and values in kwargs.

Only keys that are present as attributes of the instance’s class are allowed. These could be, for example, any mapped columns or relationships.

access_token_hash
application
check_client(client)

A method to check if this token is issued to the given client. For instance, client_id is saved on token table:

def check_client(self, client):
    return self.client_id == client.client_id
Returns:bool
created_dt
get_scope()

A method to get scope of the authorization code. For instance, the column is called scope:

def get_scope(self):
    return self.scope
Returns:scope string
id
is_revoked()

A method to define if this token is revoked. For instance, there is a boolean column revoked in the table:

def is_revoked(self):
    return self.revoked
Returns:boolean
last_used_dt
last_used_ip
use_count
user
class indico.core.oauth.models.tokens.TokenModelBase(**kwargs)

Bases: authlib.oauth2.rfc6749.models.TokenMixin, sqlalchemy.orm.decl_api.Model

A simple constructor that allows initialization from kwargs.

Sets attributes on the constructed instance using the names and values in kwargs.

Only keys that are present as attributes of the instance’s class are allowed. These could be, for example, any mapped columns or relationships.

access_token

Similar to PasswordProperty but tailored towards API tokens.

Since tokens are used much more often than passwords, they use a fast hash algorithm instead of a secure one. This is not a problem for tokens as they are fully random and much longer than the typical password or even passphrase.

access_token_hash = Column(None, String(), table=None, nullable=False)
created_dt = Column(None, UTCDateTime(), table=None, nullable=False, default=ColumnDefault(<function now_utc>))
get_expires_in()

A method to get the expires_in value of the token. e.g. the column is called expires_in:

def get_expires_in(self):
    return self.expires_in
Returns:timestamp int
id = Column(None, Integer(), table=None, primary_key=True, nullable=False)
is_expired()

A method to define if this token is expired. For instance, there is a column expired_at in the table:

def is_expired(self):
    return self.expired_at < now
Returns:boolean
last_used_dt = Column(None, UTCDateTime(), table=None)
last_used_ip = Column(None, INET(), table=None)
locator
scopes

The set of scopes this token has access to.

use_count = Column(None, Integer(), table=None, nullable=False, default=ColumnDefault(0))