Coverage for app / security / models.py: 88%
24 statements
« prev ^ index » next coverage.py v7.12.0, created at 2025-12-06 04:49 +0000
« prev ^ index » next coverage.py v7.12.0, created at 2025-12-06 04:49 +0000
1"""
2Defines database models and admin views for authentication and role management.
4This module includes models for users and roles, integrating with Flask-Security
5and Flask-Admin for authentication and role-based access control. It also provides
6a custom admin view enforcing restricted access to authorized administrators only.
8Classes:
9 Role: Represents a user role in the application with specific permissions.
10 User: Represents an application user with role associations and relationships.
11 SecureModelView: A custom admin view with access restricted to 'admin' users.
12"""
13from flask_admin.contrib.sqla import ModelView
14from flask_security import current_user
15from flask_security.models import fsqla_v3 as fsqla
16from sqlalchemy.orm import relationship, declared_attr
18from app import db
20# Define models
21fsqla.FsModels.set_db_info(db)
24class Role(db.Model, fsqla.FsRoleMixin):
25 """
26 Represents the roles a user can have in the application.
28 Each role defines a set of permissions or access levels
29 assigned to users for role-based authentication.
30 """
32 def __repr__(self) -> str:
33 return f"{self.name}"
36class User(db.Model, fsqla.FsUserMixin):
37 """
38 Represents a user in the application with authentication and role information.
40 A user can have multiple relationships such as reading statuses and feedbacks,
41 allowing association with various entities in the application.
42 """
44 @declared_attr
45 def reading_statuses(self):
46 """
47 Defines a property for accessing the reading statuses associated with the user.
49 The property is declared as a SQLAlchemy relationship, linking the current
50 user to their respective reading statuses. This property facilitates
51 bidirectional association and interaction between the user and the
52 ReadingStatus model.
54 :return: A SQLAlchemy relationship object linking the user with their
55 reading statuses.
56 :rtype: sqlalchemy.orm.relationship
57 """
58 return relationship("ReadingStatus", back_populates="user")
60 @declared_attr
61 def feedbacks(self):
62 """
63 Represents the relationship between the current model and the "Feedback" model.
65 This property defines a relationship, where the "Feedback" model is connected
66 to the current model and can be accessed through the `user` attribute of
67 "Feedback". It uses the SQLAlchemy `relationship` function to establish this
68 link with bidirectional behavior.
70 :return: A SQLAlchemy relationship configured with "Feedback" as the related model.
71 :rtype: sqlalchemy.orm.relationship
72 """
73 return relationship("Feedback", back_populates="user")
75 # Relationship to tags owned by the user
76 @declared_attr
77 def tags(self):
78 """
79 Provides a declared attribute for relationship with the 'List' model.
81 This attribute enables the establishment of a relationship between the current
82 model and the 'List' model, defining how they are interconnected in the database
83 or ORM (Object-Relational Mapping) structure.
85 :return: A SQLAlchemy relationship between this model and the 'List' model.
86 :rtype: sqlalchemy.orm.relationship
87 """
88 return relationship("Tag", back_populates="owner")
90 def __repr__(self) -> str:
91 """
92 Provides a string representation of the instance for debugging
93 and logging purposes. The returned string is a concise,
94 format that includes the email attribute.
96 :return: A string representing the instance, primarily including
97 the email attribute.
98 :rtype: str
99 """
100 return f"{self.email}"
103class SecureModelView(ModelView):
104 """
105 Custom model view that adds security measures by restricting access to administrators.
107 The view ensures only authenticated users with the 'admin' role can access
108 the underlying functionality.
109 """
111 def is_accessible(self):
112 """
113 Checks if the current user is authenticated and has the 'admin' role.
115 :return: True if the current user can access this view, otherwise False.
116 :rtype: bool
117 """
118 return current_user.is_authenticated and current_user.has_role('admin')