diff --git a/docs/auth.md b/docs/auth.md index 1599b06d..fe82eb9b 100644 --- a/docs/auth.md +++ b/docs/auth.md @@ -58,6 +58,41 @@ You can obviously change the routing URL prefix (default set to *auth*) as any o auth_routes = auth.module(__name__, url_prefix='account') ``` +Adding Custom Fields to Auth Models +------------------ + +*changed in version 2.5.3* + +By extending the default auth models provided by your authentication framework, you can easily add custom fields all of the auth models. + +To add custom fields to the auth models, you can add this piece of code: +``` +from emmett import App +from emmett.orm import Database, Field +from emmett.tools.auth import Auth, AuthUser, AuthMembership, AuthGroup, AuthPermission +from emmett.sessions import SessionManager + +app = App(__name__) +app.config.db.uri = "sqlite://storage.sqlite" +app.config.auth.hmac_key = "mysupersecretkey" +app.config.auth.single_template = True + +class User(AuthUser): + pass + +class Membership(AuthMembership): + pass + +class Group(AuthGroup): + extra_field = field.string() + +class Permission(AuthPermission): + pass + +db = Database(app) +auth = Auth(app, db, user_model=User, membership_model=Membership, group_model=Group, permission_model=Permission) +``` + Auth module configuration ------------------------- diff --git a/emmett/tools/auth/__init__.py b/emmett/tools/auth/__init__.py index 71dee404..ad10fb02 100644 --- a/emmett/tools/auth/__init__.py +++ b/emmett/tools/auth/__init__.py @@ -1,2 +1,2 @@ from .apis import Auth -from .models import AuthUser +from .models import AuthUser, AuthMembership, AuthGroup, AuthPermission diff --git a/emmett/tools/auth/apis.py b/emmett/tools/auth/apis.py index 7f083f6c..0aeb435e 100644 --- a/emmett/tools/auth/apis.py +++ b/emmett/tools/auth/apis.py @@ -27,10 +27,10 @@ class Auth: - def __init__(self, app, db, user_model=None): + def __init__(self, app, db, user_model=None, group_model=None, membership_model=None, permission_model=None): self.ext = app.use_extension(AuthExtension) self.ext.bind_auth(self) - self.ext.use_database(db, user_model) + self.ext.use_database(db, user_model, membership_model, group_model, permission_model) self.ext.init_forms() self.pipe = AuthPipe(self) diff --git a/emmett/tools/auth/ext.py b/emmett/tools/auth/ext.py index 8162225f..d2ed9ae6 100644 --- a/emmett/tools/auth/ext.py +++ b/emmett/tools/auth/ext.py @@ -189,13 +189,25 @@ def _inject_pipe(self): if self.config.inject_pipe: self.app.pipeline.append(self.auth.pipe) - def use_database(self, db, user_model=None): + def _set_model_config(self, config_name, model): + if not model: + return + _model_bases = { + 'user': AuthModel, + 'group': AuthGroup, + 'membership': AuthMembership, + 'permission': AuthPermission + } + if not issubclass(model, _model_bases[config_name]): + raise RuntimeError(f'{model.__name__} is an invalid {config_name} auth model') + self.config.models[config_name] = model + + def use_database(self, db, user_model=None, membership_model=None, group_model=None, permission_model=None): self.db = db - if user_model: - if not issubclass(user_model, AuthModel): - raise RuntimeError( - '%s is an invalid user model' % user_model.__name__) - self.config.models['user'] = user_model + self._set_model_config("user", user_model) + self._set_model_config("membership", membership_model) + self._set_model_config("group", group_model) + self._set_model_config("permission", permission_model) self.define_models() def __set_models_labels(self):