Skip to content

Models

Models are the core of the application. They are the classes that represent the data in the database. Every ORM can have its own way of defining models fields, but they all should follow based Protocol. FastAuth provide predefined User models for most popular ORMs, you can find them in fastauth.contrib.<ORM>.models module. Supported ORMs:

User model

The User model represents the user data in the database. It is the most important model in the application. Every User model should follow UserProtocol

UserProtocol

class UserProtocol(Protocol[ID]):
    id: ID
    email: str
    username: str | None
    hashed_password: str
    is_active: bool
    is_verified: bool

For example SQLAlchemy User model can be defined as:

User model

from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
from fastauth.contrib.sqlalchemy import models


class Model(DeclarativeBase):
    pass


class User(models.SQLAlchemyBaseUserUUID, Model):
    pass
See more...

Role and Permission models

Role and Permission models are used to define the user roles and permissions. They are used to define the user access rights. This models should follow RoleProtocol and PermissionProtocol respectively.

RoleProtocol and PermissionProtocol

class RoleProtocol(Protocol[PP]):
    id: int
    codename: str
    permissions: list[PP]

class PermissionProtocol(Protocol):
    id: int
    codename: str
    detail: dict[str, Any] | None

FastAuth also provide predefined Role and Permission models in fastauth.contrib.<ORM>.models module. For example SQLAlchemy Role and Permission models can be defined as:

Role and Permission models

from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship
from fastauth.contrib.sqlalchemy import models


class Model(DeclarativeBase):
    pass


class Role(models.SQLAlchemyBaseRole, Model):
    permissions: Mapped[list["Permission"]] = relationship(
        secondary="role_permission_rel", lazy="joined"
    )


class Permission(models.SQLAlchemyBasePermission, Model):
    pass


class RolePermissionRel(models.SQLAlchemyBaseRolePermissionRel, Model):
    pass
See more...

Setup RBAC mixins

To bind RBAC models with User model we need follow expanded protocol RBACUserProtocol

RBACUserProtocol

class RBACUserProtocol(UserProtocol[ID], Generic[ID, RP, PP]):
    role_id: int
    role: RP
    permissions: list[PP]

As we see, we inherit previous UserProtocol and add roles and permissions fields. So in real case we can create Mixin class for User model: For example in SQLAlchemy we use UserRBACMixin and defines fields and relations:

UserRBACMixin

from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship
from fastauth.contrib.sqlalchemy import models


class Model(DeclarativeBase):
    pass


class Role(models.SQLAlchemyBaseRole, Model):
    permissions: Mapped[list["Permission"]] = relationship(
        secondary="role_permission_rel", lazy="joined"
    )


class Permission(models.SQLAlchemyBasePermission, Model):
    pass


class RolePermissionRel(models.SQLAlchemyBaseRolePermissionRel, Model):
    pass


class User(models.SQLAlchemyBaseUserUUID, models.UserRBACMixin, Model):
    role: Mapped[Role] = relationship(lazy="joined")
    permissions: Mapped[list[Permission]] = relationship(
        secondary="user_permission_rel", lazy="joined"
    )


class UserPermissionRel(models.SQLAlchemyBaseUserPermissionRel, Model):
    pass
See more...

OAuthAccount model

OAuth model is used to store the OAuth tokens. It is used to authenticate the user with OAuth providers. Every OAuth model should follow OAuthAccountProtocol

OAuthAccountProtocol

class OAuthProtocol(Protocol[ID]):
    id: ID
    oauth_name: str
    access_token: str
    expires_at: int | None
    refresh_token: str | None
    account_id: str
    account_email: str

For example SQLAlchemy OAuth model can be defined as:

OAuth model

from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship
from fastauth.contrib.sqlalchemy import models


class Model(DeclarativeBase):
    pass


class OAuthAccount(models.SQLAlchemyBaseOAuthAccountUUID, Model):
    pass
See more...

Setup OAuth mixins

To bind OAuth model with User model we need follow expanded protocol OAuthUserProtocol

OAuthUserProtocol

class OAuthUserProtocol(UserProtocol[ID], Generic[ID, OAP]):
    oauth_accounts: list[OAP]

We can also create Mixin class for User model. For example in SQLAlchemy we use UserOAuthMixin and defines fields and relations:

UserOAuthMixin

from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship
from fastauth.contrib.sqlalchemy import models


class Model(DeclarativeBase):
    pass


class OAuthAccount(models.SQLAlchemyBaseOAuthAccountUUID, Model):
    pass


class User(models.SQLAlchemyBaseUserUUID, models.UserOAuthMixin, Model):
    oauth_accounts: Mapped[list[OAuthAccount]] = relationship(lazy="joined")
See more...