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
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
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
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
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")