abs-auth-rbac-core 0.1.4__tar.gz → 0.1.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of abs-auth-rbac-core might be problematic. Click here for more details.
- {abs_auth_rbac_core-0.1.4 → abs_auth_rbac_core-0.1.6}/PKG-INFO +1 -1
- {abs_auth_rbac_core-0.1.4 → abs_auth_rbac_core-0.1.6}/abs_auth_rbac_core/auth/middleware.py +1 -1
- {abs_auth_rbac_core-0.1.4 → abs_auth_rbac_core-0.1.6}/abs_auth_rbac_core/models/__init__.py +2 -1
- {abs_auth_rbac_core-0.1.4 → abs_auth_rbac_core-0.1.6}/abs_auth_rbac_core/models/permissions.py +6 -0
- {abs_auth_rbac_core-0.1.4 → abs_auth_rbac_core-0.1.6}/abs_auth_rbac_core/models/user.py +7 -1
- abs_auth_rbac_core-0.1.6/abs_auth_rbac_core/models/user_permission.py +15 -0
- {abs_auth_rbac_core-0.1.4 → abs_auth_rbac_core-0.1.6}/abs_auth_rbac_core/rbac/decorator.py +3 -3
- {abs_auth_rbac_core-0.1.4 → abs_auth_rbac_core-0.1.6}/abs_auth_rbac_core/rbac/service.py +188 -22
- abs_auth_rbac_core-0.1.6/abs_auth_rbac_core/schema/__init__.py +1 -0
- abs_auth_rbac_core-0.1.6/abs_auth_rbac_core/schema/permission.py +9 -0
- {abs_auth_rbac_core-0.1.4 → abs_auth_rbac_core-0.1.6}/pyproject.toml +1 -1
- {abs_auth_rbac_core-0.1.4 → abs_auth_rbac_core-0.1.6}/README.md +0 -0
- {abs_auth_rbac_core-0.1.4 → abs_auth_rbac_core-0.1.6}/abs_auth_rbac_core/__init__.py +0 -0
- {abs_auth_rbac_core-0.1.4 → abs_auth_rbac_core-0.1.6}/abs_auth_rbac_core/auth/__init__.py +0 -0
- {abs_auth_rbac_core-0.1.4 → abs_auth_rbac_core-0.1.6}/abs_auth_rbac_core/auth/auth_functions.py +0 -0
- {abs_auth_rbac_core-0.1.4 → abs_auth_rbac_core-0.1.6}/abs_auth_rbac_core/auth/jwt_functions.py +0 -0
- {abs_auth_rbac_core-0.1.4 → abs_auth_rbac_core-0.1.6}/abs_auth_rbac_core/models/base_model.py +0 -0
- {abs_auth_rbac_core-0.1.4 → abs_auth_rbac_core-0.1.6}/abs_auth_rbac_core/models/gov_casbin_rule.py +0 -0
- {abs_auth_rbac_core-0.1.4 → abs_auth_rbac_core-0.1.6}/abs_auth_rbac_core/models/rbac_model.py +0 -0
- {abs_auth_rbac_core-0.1.4 → abs_auth_rbac_core-0.1.6}/abs_auth_rbac_core/models/role_permission.py +0 -0
- {abs_auth_rbac_core-0.1.4 → abs_auth_rbac_core-0.1.6}/abs_auth_rbac_core/models/roles.py +0 -0
- {abs_auth_rbac_core-0.1.4 → abs_auth_rbac_core-0.1.6}/abs_auth_rbac_core/models/seeder/permission_seeder.py +0 -0
- {abs_auth_rbac_core-0.1.4 → abs_auth_rbac_core-0.1.6}/abs_auth_rbac_core/models/user_role.py +0 -0
- {abs_auth_rbac_core-0.1.4 → abs_auth_rbac_core-0.1.6}/abs_auth_rbac_core/rbac/__init__.py +0 -0
- {abs_auth_rbac_core-0.1.4 → abs_auth_rbac_core-0.1.6}/abs_auth_rbac_core/rbac/policy.conf +0 -0
- {abs_auth_rbac_core-0.1.4 → abs_auth_rbac_core-0.1.6}/abs_auth_rbac_core/util/__init__.py +0 -0
- {abs_auth_rbac_core-0.1.4 → abs_auth_rbac_core-0.1.6}/abs_auth_rbac_core/util/permission_constants.py +0 -0
|
@@ -3,5 +3,6 @@ from .roles import Role
|
|
|
3
3
|
from .user_role import UserRole
|
|
4
4
|
from .user import Users
|
|
5
5
|
from .role_permission import RolePermission
|
|
6
|
+
from .user_permission import UserPermission
|
|
6
7
|
|
|
7
|
-
__all__ = ["Permission", "Role", "UserRole", "Users","RolePermission"]
|
|
8
|
+
__all__ = ["Permission", "Role", "UserRole", "Users","RolePermission","UserPermission"]
|
{abs_auth_rbac_core-0.1.4 → abs_auth_rbac_core-0.1.6}/abs_auth_rbac_core/models/permissions.py
RENAMED
|
@@ -24,3 +24,9 @@ class Permission(RBACBaseModel):
|
|
|
24
24
|
roles = relationship(
|
|
25
25
|
"Role", secondary="gov_role_permissions", back_populates="permissions"
|
|
26
26
|
)
|
|
27
|
+
|
|
28
|
+
user_permissions = relationship(
|
|
29
|
+
"UserPermission",
|
|
30
|
+
back_populates="permission",
|
|
31
|
+
cascade="all, delete-orphan"
|
|
32
|
+
)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from sqlalchemy import Column, ForeignKey, String
|
|
2
|
+
from sqlalchemy.orm import relationship
|
|
3
|
+
from abs_auth_rbac_core.models.base_model import BaseModel
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class UserPermission(BaseModel):
|
|
7
|
+
"""Association model between users and permissions"""
|
|
8
|
+
|
|
9
|
+
__tablename__ = "gov_user_permissions"
|
|
10
|
+
|
|
11
|
+
user_uuid = Column(String(36), ForeignKey("gov_users.uuid"), index=True)
|
|
12
|
+
permission_uuid = Column(String(36), ForeignKey("gov_permissions.uuid"), index=True)
|
|
13
|
+
|
|
14
|
+
user = relationship("Users", back_populates="user_permissions")
|
|
15
|
+
permission = relationship("Permission", back_populates="user_permissions")
|
|
@@ -23,8 +23,8 @@ def rbac_require_permission(permissions: Union[str, List[str]]):
|
|
|
23
23
|
request:Request,
|
|
24
24
|
*args,rbac_service:RBACService, **kwargs,
|
|
25
25
|
):
|
|
26
|
-
|
|
27
|
-
if not
|
|
26
|
+
current_user_uuid = request.state.user.uuid
|
|
27
|
+
if not current_user_uuid:
|
|
28
28
|
raise PermissionDeniedError(
|
|
29
29
|
detail="User not found (missing 'uuid')."
|
|
30
30
|
)
|
|
@@ -37,7 +37,7 @@ def rbac_require_permission(permissions: Union[str, List[str]]):
|
|
|
37
37
|
)
|
|
38
38
|
|
|
39
39
|
has_permission = rbac_service.check_permission(
|
|
40
|
-
user_uuid=
|
|
40
|
+
user_uuid=current_user_uuid, resource=resource, action=action,module=module
|
|
41
41
|
)
|
|
42
42
|
|
|
43
43
|
if not has_permission:
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
from typing import List, Optional, Callable,Any
|
|
1
|
+
from typing import List, Optional, Callable,Any,Tuple
|
|
2
2
|
import os
|
|
3
3
|
import casbin
|
|
4
4
|
from casbin_sqlalchemy_adapter import Adapter
|
|
5
5
|
from sqlalchemy import and_, select
|
|
6
6
|
from sqlalchemy.orm import Session, joinedload
|
|
7
|
-
|
|
7
|
+
from ..schema import CreatePermissionSchema
|
|
8
8
|
from ..models import (
|
|
9
9
|
Role,
|
|
10
10
|
RolePermission,
|
|
11
11
|
UserRole,
|
|
12
12
|
Users,
|
|
13
|
-
Permission
|
|
13
|
+
Permission,
|
|
14
|
+
UserPermission
|
|
14
15
|
)
|
|
15
16
|
|
|
16
17
|
from abs_exception_core.exceptions import (
|
|
@@ -52,8 +53,151 @@ class RBACService:
|
|
|
52
53
|
)
|
|
53
54
|
# Load policies
|
|
54
55
|
self.enforcer.load_policy()
|
|
56
|
+
|
|
57
|
+
def add_policy(self,role:str,resource:str,action:str,module:str):
|
|
58
|
+
"""
|
|
59
|
+
Add a policy to the casbin enforcer
|
|
60
|
+
"""
|
|
61
|
+
self.enforcer.add_policy(role,resource,action,module)
|
|
62
|
+
self.enforcer.save_policy()
|
|
63
|
+
|
|
64
|
+
def remove_policy(self,role:str,resource:str,action:str,module:str):
|
|
65
|
+
"""
|
|
66
|
+
Remove a policy from the casbin enforcer
|
|
67
|
+
"""
|
|
68
|
+
self.enforcer.remove_policy(role,resource,action,module)
|
|
69
|
+
self.enforcer.save_policy()
|
|
70
|
+
|
|
71
|
+
def add_policies(self,policies:List[Tuple[str,str,str,str]]):
|
|
72
|
+
"""
|
|
73
|
+
Add a list of policies to the casbin enforcer
|
|
74
|
+
"""
|
|
75
|
+
self.enforcer.add_policies(policies)
|
|
76
|
+
self.enforcer.save_policy()
|
|
77
|
+
|
|
78
|
+
def remove_policies(self,policies:List[List[str]]):
|
|
79
|
+
"""
|
|
80
|
+
Remove a list of policies from the casbin enforcer
|
|
81
|
+
"""
|
|
82
|
+
self.enforcer.remove_policies(policies)
|
|
83
|
+
self.enforcer.save_policy()
|
|
84
|
+
|
|
85
|
+
def enforce_policy(self,role:str,resource:str,action:str,module:str):
|
|
86
|
+
"""
|
|
87
|
+
Enforce a policy
|
|
88
|
+
"""
|
|
89
|
+
return self.enforcer.enforce(role,resource,action,module)
|
|
90
|
+
|
|
91
|
+
def remove_filter_policy(self,index:int,value:str):
|
|
92
|
+
"""
|
|
93
|
+
Remove a policy by filtering the policy
|
|
94
|
+
Args:
|
|
95
|
+
index: The index of the policy to remove
|
|
96
|
+
value: The value of the policy to remove
|
|
97
|
+
"""
|
|
98
|
+
self.enforcer.remove_filtered_policy(index,value)
|
|
99
|
+
self.enforcer.save_policy()
|
|
100
|
+
|
|
101
|
+
async def bulk_create_permissions(self,permissions:List[CreatePermissionSchema]):
|
|
102
|
+
"""
|
|
103
|
+
Bulk create permissions for user
|
|
104
|
+
"""
|
|
105
|
+
with self.db() as session:
|
|
106
|
+
try:
|
|
107
|
+
permission_objs = [Permission(**permission.model_dump()) for permission in permissions]
|
|
108
|
+
session.bulk_save_objects(permission_objs)
|
|
109
|
+
session.commit()
|
|
110
|
+
return permission_objs
|
|
111
|
+
except Exception as e:
|
|
112
|
+
raise e
|
|
55
113
|
|
|
114
|
+
async def get_permissions_by_condition(self, condition: dict, use_filter_by: bool = True):
|
|
115
|
+
"""
|
|
116
|
+
Get permission(s) based on a condition dict.
|
|
117
|
+
If use_filter_by is True, assumes all conditions are `==`.
|
|
118
|
+
"""
|
|
119
|
+
with self.db() as session:
|
|
120
|
+
try:
|
|
121
|
+
query = session.query(Permission)
|
|
122
|
+
if use_filter_by:
|
|
123
|
+
query = query.filter_by(**condition)
|
|
124
|
+
else:
|
|
125
|
+
filters = [getattr(Permission, k) == v for k, v in condition.items()]
|
|
126
|
+
query = query.filter(*filters)
|
|
127
|
+
return query.all()
|
|
128
|
+
except Exception as e:
|
|
129
|
+
raise e
|
|
130
|
+
|
|
131
|
+
async def delete_permission_by_uuids(self,permission_uuids:List[str]):
|
|
132
|
+
"""
|
|
133
|
+
Delete a permission by uuids
|
|
134
|
+
"""
|
|
135
|
+
with self.db() as session:
|
|
136
|
+
try:
|
|
137
|
+
permissions = session.query(Permission).filter(Permission.uuid.in_(permission_uuids))
|
|
138
|
+
for permission in permissions:
|
|
139
|
+
self.enforcer.remove_filtered_policy(1,permission.resource)
|
|
140
|
+
self.enforcer.save_policy()
|
|
141
|
+
|
|
142
|
+
permissions.delete(synchronize_session=False)
|
|
143
|
+
session.commit()
|
|
144
|
+
return True
|
|
145
|
+
except Exception as e:
|
|
146
|
+
raise e
|
|
147
|
+
|
|
148
|
+
def assign_permissions_to_user(self,user_uuid:str,permission_uuids:List[str]):
|
|
149
|
+
"""
|
|
150
|
+
Assign permissions to a user
|
|
151
|
+
"""
|
|
152
|
+
with self.db() as session:
|
|
153
|
+
current_permissions = session.query(UserPermission).filter(UserPermission.user_uuid==user_uuid).all()
|
|
154
|
+
current_permission_uuids = [permission.permission_uuid for permission in current_permissions]
|
|
155
|
+
remove_permissions = set(current_permission_uuids) - set(permission_uuids)
|
|
156
|
+
add_permissions = set(permission_uuids) - set(current_permission_uuids)
|
|
157
|
+
if remove_permissions:
|
|
158
|
+
self.revoke_user_permissions(user_uuid,list(remove_permissions))
|
|
159
|
+
if add_permissions:
|
|
160
|
+
self.attach_permissions_to_user(user_uuid,list(add_permissions))
|
|
161
|
+
return True
|
|
56
162
|
|
|
163
|
+
def attach_permissions_to_user(self, user_uuid: str, permission_uuids: List[str]):
|
|
164
|
+
with self.db() as session:
|
|
165
|
+
user_permissions = [
|
|
166
|
+
UserPermission(user_uuid=user_uuid, permission_uuid=permission_uuid)
|
|
167
|
+
for permission_uuid in permission_uuids
|
|
168
|
+
]
|
|
169
|
+
session.bulk_save_objects(user_permissions)
|
|
170
|
+
session.commit()
|
|
171
|
+
|
|
172
|
+
permissions = session.query(Permission).filter(Permission.uuid.in_(permission_uuids)).all()
|
|
173
|
+
policies = [
|
|
174
|
+
[f"user:{user_uuid}", permission.resource, permission.action, permission.module]
|
|
175
|
+
for permission in permissions
|
|
176
|
+
]
|
|
177
|
+
self.enforcer.add_policies(policies)
|
|
178
|
+
self.enforcer.save_policy()
|
|
179
|
+
return user_permissions
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def revoke_user_permissions(self, user_uuid: str, permission_uuids: List[str]):
|
|
183
|
+
with self.db() as session:
|
|
184
|
+
user_permissions = session.query(UserPermission).filter(
|
|
185
|
+
UserPermission.user_uuid == user_uuid,
|
|
186
|
+
UserPermission.permission_uuid.in_(permission_uuids)
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
permissions = session.query(Permission).filter(Permission.uuid.in_(permission_uuids)).all()
|
|
190
|
+
policies = [
|
|
191
|
+
[f"user:{user_uuid}", permission.resource, permission.action, permission.module]
|
|
192
|
+
for permission in permissions
|
|
193
|
+
]
|
|
194
|
+
self.enforcer.remove_policies(policies)
|
|
195
|
+
self.enforcer.save_policy()
|
|
196
|
+
|
|
197
|
+
user_permissions.delete(synchronize_session=False)
|
|
198
|
+
session.commit()
|
|
199
|
+
return True
|
|
200
|
+
|
|
57
201
|
def list_roles(self) -> Any:
|
|
58
202
|
"""
|
|
59
203
|
Get the list of all roles
|
|
@@ -136,7 +280,7 @@ class RBACService:
|
|
|
136
280
|
|
|
137
281
|
# Batch add Casbin policies
|
|
138
282
|
policies = [
|
|
139
|
-
|
|
283
|
+
[role.uuid, permission.resource, permission.action, permission.module]
|
|
140
284
|
for permission in existing_permissions
|
|
141
285
|
]
|
|
142
286
|
self.enforcer.add_policies(policies)
|
|
@@ -213,13 +357,11 @@ class RBACService:
|
|
|
213
357
|
existing_permissions = role.permissions
|
|
214
358
|
|
|
215
359
|
# Remove Casbin policies for existing permissions
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
existing_permission.module
|
|
222
|
-
)
|
|
360
|
+
remove_policies = [
|
|
361
|
+
[role_uuid, existing_permission.resource, existing_permission.action, existing_permission.module]
|
|
362
|
+
for existing_permission in existing_permissions
|
|
363
|
+
]
|
|
364
|
+
self.enforcer.remove_policies(remove_policies)
|
|
223
365
|
self.enforcer.save_policy()
|
|
224
366
|
|
|
225
367
|
# Delete existing role permissions
|
|
@@ -250,11 +392,11 @@ class RBACService:
|
|
|
250
392
|
session.bulk_insert_mappings(RolePermission, role_permissions)
|
|
251
393
|
|
|
252
394
|
# Add Casbin policies
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
395
|
+
policies = [
|
|
396
|
+
[role_uuid, permission.resource, permission.action, permission.module]
|
|
397
|
+
for permission in permissions_objs
|
|
398
|
+
]
|
|
399
|
+
self.enforcer.add_policies(policies)
|
|
258
400
|
self.enforcer.save_policy()
|
|
259
401
|
|
|
260
402
|
session.commit()
|
|
@@ -290,7 +432,7 @@ class RBACService:
|
|
|
290
432
|
|
|
291
433
|
# Collect all policies to remove from the eagerly loaded permissions
|
|
292
434
|
remove_policies = [
|
|
293
|
-
[role.
|
|
435
|
+
[role.uuid, permission.resource, permission.action, permission.module]
|
|
294
436
|
for permission in role.permissions
|
|
295
437
|
]
|
|
296
438
|
|
|
@@ -317,6 +459,30 @@ class RBACService:
|
|
|
317
459
|
with self.db() as session:
|
|
318
460
|
return session.query(Permission).filter(Permission.module == module).all()
|
|
319
461
|
|
|
462
|
+
def get_user_only_permissions(self, user_uuid: str) -> List[Any]:
|
|
463
|
+
"""Get all allowed permissions for a user"""
|
|
464
|
+
with self.db() as session:
|
|
465
|
+
user_permissions = (
|
|
466
|
+
session.query(UserPermission)
|
|
467
|
+
.filter(UserPermission.user_uuid == user_uuid)
|
|
468
|
+
.options(joinedload(UserPermission.permission))
|
|
469
|
+
.all()
|
|
470
|
+
)
|
|
471
|
+
result = []
|
|
472
|
+
for user_permission in user_permissions:
|
|
473
|
+
result.append(
|
|
474
|
+
{
|
|
475
|
+
"permission_id": user_permission.permission.id,
|
|
476
|
+
"created_at": user_permission.permission.created_at,
|
|
477
|
+
"updated_at": user_permission.permission.updated_at,
|
|
478
|
+
"name": user_permission.permission.name,
|
|
479
|
+
"resource": user_permission.permission.resource,
|
|
480
|
+
"action": user_permission.permission.action,
|
|
481
|
+
"module": user_permission.permission.module
|
|
482
|
+
}
|
|
483
|
+
)
|
|
484
|
+
return result
|
|
485
|
+
|
|
320
486
|
def get_user_permissions(self, user_uuid: str) -> List[Any]:
|
|
321
487
|
"""Get all allowed permissions for a user"""
|
|
322
488
|
with self.db() as session:
|
|
@@ -397,7 +563,7 @@ class RBACService:
|
|
|
397
563
|
|
|
398
564
|
# Remove Casbin policies
|
|
399
565
|
policies_to_remove = [
|
|
400
|
-
(role.
|
|
566
|
+
(role.uuid, permission.resource, permission.action, permission.module)
|
|
401
567
|
for permission in permissions_to_revoke
|
|
402
568
|
]
|
|
403
569
|
self.enforcer.remove_policies(policies_to_remove)
|
|
@@ -465,7 +631,7 @@ class RBACService:
|
|
|
465
631
|
|
|
466
632
|
# Add Casbin policies
|
|
467
633
|
policies_to_add = [
|
|
468
|
-
(role.
|
|
634
|
+
(role.uuid, permission.resource, permission.action, permission.module)
|
|
469
635
|
for permission in new_permissions
|
|
470
636
|
]
|
|
471
637
|
self.enforcer.add_policies(policies_to_add)
|
|
@@ -648,15 +814,15 @@ class RBACService:
|
|
|
648
814
|
)
|
|
649
815
|
for role in roles:
|
|
650
816
|
# Try with module first
|
|
651
|
-
if self.enforcer.enforce(role.
|
|
817
|
+
if self.enforcer.enforce(role.uuid, resource, action, module):
|
|
652
818
|
return True
|
|
653
819
|
return False
|
|
654
820
|
|
|
655
821
|
def check_permission_by_role(
|
|
656
|
-
self,
|
|
822
|
+
self, role_uuid: str, resource: str, action: str, module: str
|
|
657
823
|
) -> bool:
|
|
658
824
|
# Try with module first
|
|
659
|
-
if self.enforcer.enforce(
|
|
825
|
+
if self.enforcer.enforce(role_uuid, resource, action, module):
|
|
660
826
|
return True
|
|
661
827
|
return False
|
|
662
828
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .permission import CreatePermissionSchema
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{abs_auth_rbac_core-0.1.4 → abs_auth_rbac_core-0.1.6}/abs_auth_rbac_core/auth/auth_functions.py
RENAMED
|
File without changes
|
{abs_auth_rbac_core-0.1.4 → abs_auth_rbac_core-0.1.6}/abs_auth_rbac_core/auth/jwt_functions.py
RENAMED
|
File without changes
|
{abs_auth_rbac_core-0.1.4 → abs_auth_rbac_core-0.1.6}/abs_auth_rbac_core/models/base_model.py
RENAMED
|
File without changes
|
{abs_auth_rbac_core-0.1.4 → abs_auth_rbac_core-0.1.6}/abs_auth_rbac_core/models/gov_casbin_rule.py
RENAMED
|
File without changes
|
{abs_auth_rbac_core-0.1.4 → abs_auth_rbac_core-0.1.6}/abs_auth_rbac_core/models/rbac_model.py
RENAMED
|
File without changes
|
{abs_auth_rbac_core-0.1.4 → abs_auth_rbac_core-0.1.6}/abs_auth_rbac_core/models/role_permission.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{abs_auth_rbac_core-0.1.4 → abs_auth_rbac_core-0.1.6}/abs_auth_rbac_core/models/user_role.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|