Renamed the AbstractUserUtils class to UserUtilityInterface, and added the can_view and can_edit functions to the UserUtilityInterface interface. There is no need to separately supply two additional can_view and can_edit callbacks.
This commit is contained in:
parent
cd8a480cd0
commit
8061a23fdc
@ -23,7 +23,7 @@ from pathlib import Path
|
|||||||
from flask import Flask, Blueprint
|
from flask import Flask, Blueprint
|
||||||
from flask_sqlalchemy import SQLAlchemy
|
from flask_sqlalchemy import SQLAlchemy
|
||||||
|
|
||||||
from accounting.utils.user import AbstractUserUtils
|
from accounting.utils.user import UserUtilityInterface
|
||||||
|
|
||||||
db: SQLAlchemy = SQLAlchemy()
|
db: SQLAlchemy = SQLAlchemy()
|
||||||
"""The database instance."""
|
"""The database instance."""
|
||||||
@ -31,19 +31,13 @@ data_dir: Path = Path(__file__).parent / "data"
|
|||||||
"""The data directory."""
|
"""The data directory."""
|
||||||
|
|
||||||
|
|
||||||
def init_app(app: Flask, user_utils: AbstractUserUtils,
|
def init_app(app: Flask, user_utils: UserUtilityInterface,
|
||||||
url_prefix: str = "/accounting",
|
url_prefix: str = "/accounting") -> None:
|
||||||
can_view_func: t.Callable[[], bool] | None = None,
|
|
||||||
can_edit_func: t.Callable[[], bool] | None = None) -> None:
|
|
||||||
"""Initialize the application.
|
"""Initialize the application.
|
||||||
|
|
||||||
:param app: The Flask application.
|
:param app: The Flask application.
|
||||||
:param user_utils: The user utilities.
|
:param user_utils: The user utilities.
|
||||||
:param url_prefix: The URL prefix of the accounting application.
|
:param url_prefix: The URL prefix of the accounting application.
|
||||||
:param can_view_func: A callback that returns whether the current user can
|
|
||||||
view the accounting data.
|
|
||||||
:param can_edit_func: A callback that returns whether the current user can
|
|
||||||
edit the accounting data.
|
|
||||||
:return: None.
|
:return: None.
|
||||||
"""
|
"""
|
||||||
# The database instance must be set before loading everything
|
# The database instance must be set before loading everything
|
||||||
@ -73,7 +67,7 @@ def init_app(app: Flask, user_utils: AbstractUserUtils,
|
|||||||
locale.init_app(app, bp)
|
locale.init_app(app, bp)
|
||||||
|
|
||||||
from .utils import permission
|
from .utils import permission
|
||||||
permission.init_app(bp, can_view_func, can_edit_func)
|
permission.init_app(bp, user_utils)
|
||||||
|
|
||||||
from .utils import next_uri
|
from .utils import next_uri
|
||||||
next_uri.init_app(bp)
|
next_uri.init_app(bp)
|
||||||
|
@ -23,7 +23,7 @@ import typing as t
|
|||||||
|
|
||||||
from flask import abort, Blueprint
|
from flask import abort, Blueprint
|
||||||
|
|
||||||
from accounting.utils.user import get_current_user
|
from accounting.utils.user import get_current_user, UserUtilityInterface
|
||||||
|
|
||||||
|
|
||||||
def has_permission(rule: t.Callable[[], bool]) -> t.Callable:
|
def has_permission(rule: t.Callable[[], bool]) -> t.Callable:
|
||||||
@ -87,22 +87,15 @@ def can_edit() -> bool:
|
|||||||
return __can_edit_func()
|
return __can_edit_func()
|
||||||
|
|
||||||
|
|
||||||
def init_app(bp: Blueprint,
|
def init_app(bp: Blueprint, user_utils: UserUtilityInterface) -> None:
|
||||||
can_view_func: t.Callable[[], bool] | None = None,
|
|
||||||
can_edit_func: t.Callable[[], bool] | None = None) -> None:
|
|
||||||
"""Initializes the application.
|
"""Initializes the application.
|
||||||
|
|
||||||
:param bp: The blueprint of the accounting application.
|
:param bp: The blueprint of the accounting application.
|
||||||
:param can_view_func: A callback that returns whether the current user can
|
:param user_utils: The user utilities.
|
||||||
view the accounting data.
|
|
||||||
:param can_edit_func: A callback that returns whether the current user can
|
|
||||||
edit the accounting data.
|
|
||||||
:return: None.
|
:return: None.
|
||||||
"""
|
"""
|
||||||
global __can_view_func, __can_edit_func
|
global __can_view_func, __can_edit_func
|
||||||
if can_view_func is not None:
|
__can_view_func = user_utils.can_view
|
||||||
__can_view_func = can_view_func
|
__can_edit_func = user_utils.can_edit
|
||||||
if can_edit_func is not None:
|
bp.add_app_template_global(user_utils.can_view, "accounting_can_view")
|
||||||
__can_edit_func = can_edit_func
|
bp.add_app_template_global(user_utils.can_edit, "accounting_can_edit")
|
||||||
bp.add_app_template_global(can_view, "accounting_can_view")
|
|
||||||
bp.add_app_template_global(can_edit, "accounting_can_edit")
|
|
||||||
|
@ -29,8 +29,26 @@ from flask_sqlalchemy.model import Model
|
|||||||
T = t.TypeVar("T", bound=Model)
|
T = t.TypeVar("T", bound=Model)
|
||||||
|
|
||||||
|
|
||||||
class AbstractUserUtils(t.Generic[T], ABC):
|
class UserUtilityInterface(t.Generic[T], ABC):
|
||||||
"""The abstract user utilities."""
|
"""The interface for the user utilities."""
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def can_view(self) -> bool:
|
||||||
|
"""Returns whether the currently logged-in user can view the accounting
|
||||||
|
data.
|
||||||
|
|
||||||
|
:return: True if the currently logged-in user can view the accounting
|
||||||
|
data, or False otherwise.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def can_edit(self) -> bool:
|
||||||
|
"""Returns whether the currently logged-in user can edit the accounting
|
||||||
|
data.
|
||||||
|
|
||||||
|
:return: True if the currently logged-in user can edit the accounting
|
||||||
|
data, or False otherwise.
|
||||||
|
"""
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
@ -72,7 +90,7 @@ class AbstractUserUtils(t.Generic[T], ABC):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
__user_utils: AbstractUserUtils
|
__user_utils: UserUtilityInterface
|
||||||
"""The user utilities."""
|
"""The user utilities."""
|
||||||
user_cls: t.Type[Model] = Model
|
user_cls: t.Type[Model] = Model
|
||||||
"""The user class."""
|
"""The user class."""
|
||||||
@ -80,7 +98,7 @@ user_pk_column: sa.Column = sa.Column(sa.Integer)
|
|||||||
"""The primary key column of the user class."""
|
"""The primary key column of the user class."""
|
||||||
|
|
||||||
|
|
||||||
def init_user_utils(utils: AbstractUserUtils) -> None:
|
def init_user_utils(utils: UserUtilityInterface) -> None:
|
||||||
"""Initializes the user utilities.
|
"""Initializes the user utilities.
|
||||||
|
|
||||||
:param utils: The user utilities.
|
:param utils: The user utilities.
|
||||||
|
@ -29,8 +29,6 @@ from flask_sqlalchemy import SQLAlchemy
|
|||||||
from flask_wtf import CSRFProtect
|
from flask_wtf import CSRFProtect
|
||||||
from sqlalchemy import Column
|
from sqlalchemy import Column
|
||||||
|
|
||||||
import accounting.utils.user
|
|
||||||
|
|
||||||
bp: Blueprint = Blueprint("home", __name__)
|
bp: Blueprint = Blueprint("home", __name__)
|
||||||
babel_js: BabelJS = BabelJS()
|
babel_js: BabelJS = BabelJS()
|
||||||
csrf: CSRFProtect = CSRFProtect()
|
csrf: CSRFProtect = CSRFProtect()
|
||||||
@ -69,7 +67,16 @@ def create_app(is_testing: bool = False) -> Flask:
|
|||||||
from . import auth
|
from . import auth
|
||||||
auth.init_app(app)
|
auth.init_app(app)
|
||||||
|
|
||||||
class UserUtils(accounting.utils.user.AbstractUserUtils[auth.User]):
|
class UserUtilities(accounting.UserUtilityInterface[auth.User]):
|
||||||
|
|
||||||
|
def can_view(self) -> bool:
|
||||||
|
return auth.current_user() is not None \
|
||||||
|
and auth.current_user().username in ["viewer", "editor",
|
||||||
|
"editor2"]
|
||||||
|
|
||||||
|
def can_edit(self) -> bool:
|
||||||
|
return auth.current_user() is not None \
|
||||||
|
and auth.current_user().username in ["editor", "editor2"]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def cls(self) -> t.Type[auth.User]:
|
def cls(self) -> t.Type[auth.User]:
|
||||||
@ -90,12 +97,7 @@ def create_app(is_testing: bool = False) -> Flask:
|
|||||||
def get_pk(self, user: auth.User) -> int:
|
def get_pk(self, user: auth.User) -> int:
|
||||||
return user.id
|
return user.id
|
||||||
|
|
||||||
can_view: t.Callable[[], bool] = lambda: auth.current_user() is not None \
|
accounting.init_app(app, user_utils=UserUtilities())
|
||||||
and auth.current_user().username in ["viewer", "editor", "editor2"]
|
|
||||||
can_edit: t.Callable[[], bool] = lambda: auth.current_user() is not None \
|
|
||||||
and auth.current_user().username in ["editor", "editor2"]
|
|
||||||
accounting.init_app(app, user_utils=UserUtils(),
|
|
||||||
can_view_func=can_view, can_edit_func=can_edit)
|
|
||||||
|
|
||||||
return app
|
return app
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user