OAuth

Todo

Docstrings (module, models, provider)

Models

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

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:

import secrets

def check_client_secret(self, client_secret):
    return secrets.compare_digest(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

property 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

property locator
name

human readable name

query: IndicoBaseQuery

A SQLAlchemy query for a model. Equivalent to db.session.query(Model). Can be customized per-model by overriding query_class.

Warning

The query interface is considered legacy in SQLAlchemy. Prefer using session.execute(select()) instead.

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

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
query: IndicoBaseQuery

A SQLAlchemy query for a model. Equivalent to db.session.query(Model). Can be customized per-model by overriding query_class.

Warning

The query interface is considered legacy in SQLAlchemy. Prefer using session.execute(select()) instead.

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

An enumeration.

checkin = 1
property default_data
property 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>)
auth_time: datetime
client_id: str
code: str
code_challenge: str
code_challenge_method: str
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: str = ''
scope: str = ''
user_id: int
class indico.core.oauth.models.tokens.OAuthToken(**kwargs)

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
property 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
query: IndicoBaseQuery

A SQLAlchemy query for a model. Equivalent to db.session.query(Model). Can be customized per-model by overriding query_class.

Warning

The query interface is considered legacy in SQLAlchemy. Prefer using session.execute(select()) instead.

use_count
property user
class indico.core.oauth.models.tokens.TokenModelBase(**kwargs)

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)
property locator
property scopes

The set of scopes this token has access to.

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