Skip to content

Commit 34aa42f

Browse files
Updated Docs
1 parent 76be0bd commit 34aa42f

File tree

10 files changed

+205
-18
lines changed

10 files changed

+205
-18
lines changed

README.md

Lines changed: 79 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,18 @@ class User(Model, SoftDeletesMixin, Authenticates, HasRoles):
7373
## Usage
7474

7575
**Role**
76+
7677
Methods that can be used in role model object:
7778

7879
```python
80+
""" Creating Role """
81+
role = Role.create({
82+
"name": "Admin",
83+
"slug": "admin" # must be unique
84+
})
85+
7986
""" collection can be synced """
8087
permission_collection = Permission.all()
81-
role = Role.find(1)
8288

8389
role.sync_permissions(permission_collection)
8490

@@ -101,12 +107,18 @@ role.detatch_permission(1) # passing permission id instead of object, ignores if
101107
```
102108

103109
**Permission**
110+
104111
Methods that can be used in permission model object:
105112

106113
```python
114+
""" Creating Permission """
115+
permission = Permission.create({
116+
"name": "Create Post",
117+
"slug": "create-post" # must be unique
118+
})
119+
107120
""" collection can be synced """
108121
roles_collection = Role.all()
109-
permission = Permission.find(1)
110122

111123
permission.sync_roles(role_collection)
112124

@@ -129,6 +141,7 @@ permission.detatch_role(1) # passing role id instead of object, ignores if role
129141
```
130142

131143
**User**
144+
132145
Methods that can be used in user model object:
133146

134147
```python
@@ -137,8 +150,8 @@ user = User.first()
137150
# Add/Remove single role
138151
role = Role.first()
139152

140-
user.attach_role(role) # or you can pass role id
141-
user.detatch_role(role) # or you can pass role id
153+
user.assign_role(role) # or you can pass role id
154+
user.remove_role(role) # or you can pass role id
142155

143156
# if you want to add multiple roles
144157
roles = Role.all()
@@ -149,14 +162,75 @@ user.sync_roles(roles) # or you can also pass list of ids...
149162
user.sync_roles([])
150163

151164
# check if user has role
152-
user.has_role("role-slug") # returns boolean
165+
user.has_role("role-1") # returns boolean
153166

154167
# check if user has any of the roles
155168
user.has_any_role(["role-1", "role-2"]) # returns boolean
156169

157170
# check if user has all of the roles
158171
user.has_all_roles(["role-1", "role-2"]) # returns boolean
159172

173+
# check if user has permission
174+
user.has_permission("permission-1") # returns boolean
175+
176+
# check if user has any of the permissions
177+
user.has_any_permission(["permission-1", "permission-2"]) # returns boolean
178+
179+
# check if user has all of the permissions
180+
user.has_all_permissions(["permission-1", "permission-2"]) # returns boolean
181+
182+
```
183+
184+
## Using in Template
185+
186+
**In case of Roles**
187+
Checking if user has role.
188+
189+
```jinja2
190+
{% if user.is_("admin") %}
191+
<p>You are an admin</p>
192+
{% endif %}
193+
```
194+
195+
Checking if user has any of the roles
196+
197+
```jinja2
198+
{% if user.is_("admin|editor|truck-driver") %}
199+
<p>You can be either admin, editor, truck driver or all of those</p>
200+
{% endif %}
201+
```
202+
203+
Checking if user has all of the roles
204+
205+
```jinja2
206+
{% if user.is_("admin,editor,truck-driver") %}
207+
<p>You are an admin, editor and also truck-driver</p>
208+
{% endif %}
209+
```
210+
211+
**In case of Permissions**
212+
Checking if user can do {permission}.
213+
214+
```jinja2
215+
{% if user.can_("edit-post") %}
216+
<p>You can edit post</p>
217+
{% endif %}
218+
```
219+
220+
Checking if user can do any one or more of the {permissions}
221+
222+
```jinja2
223+
{% if user.can_("edit-post|delete-post") %}
224+
<p>You can either edit-post, delete-post or both.</p>
225+
{% endif %}
226+
```
227+
228+
Checking if user can do all of the {permissions}
229+
230+
```jinja2
231+
{% if user.can_("edit-post,delete-post") %}
232+
<p>You can edit post and also delete post.</p>
233+
{% endif %}
160234
```
161235

162236
## Contributing

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
# Versions should comply with PEP440. For a discussion on single-sourcing
99
# the version across setup.py and the project code, see
1010
# https://packaging.python.org/en/latest/single_source_version.html
11-
version="0.1.2",
11+
version="0.1.3",
1212
packages=[
1313
"masonite_permission",
1414
"masonite_permission.config",
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from masonite.configuration import config
2+
3+
4+
class MasonitePermission:
5+
def __init__(self) -> None:
6+
self.conf = config("masonite-permission")

src/masonite_permission/models/has_roles.py

Lines changed: 85 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,14 @@ class HasRoles:
1010
def roles(self):
1111
"""User can have multiple roles"""
1212
from ..models.role import Role
13+
1314
return Role
14-
15+
1516
def permissions(self):
1617
"""User can have multiple permissions"""
1718
from ..models.permission import Permission
18-
19-
roles = self.roles.pluck('id')
19+
20+
roles = self.roles.pluck("id")
2021
return (
2122
Permission.join("permission_role as pr", "pr.permission_id", "=", "id")
2223
.where_in("pr.role_id", roles)
@@ -71,7 +72,7 @@ def sync_roles(self, roles):
7172
QueryBuilder().table("role_user").where("user_id", self.id).delete()
7273
self.save_many("roles", roles)
7374

74-
def attach_role(self, role):
75+
def assign_role(self, role):
7576
"""Assign a role to a user
7677
7778
Arguments:
@@ -93,7 +94,7 @@ def attach_role(self, role):
9394
if not exists:
9495
self.attach("roles", role)
9596

96-
def detatch_role(self, role):
97+
def remove_role(self, role):
9798
"""Detach a role from a user
9899
99100
Arguments:
@@ -113,4 +114,82 @@ def detatch_role(self, role):
113114
)
114115

115116
if exists:
116-
self.detach("roles", role)
117+
self.detach("roles", role)
118+
119+
def has_permission(self, permission):
120+
"""Check if user has a permission"""
121+
if type(permission) != str:
122+
raise PermissionException("permission must be a string!")
123+
124+
return self.permissions().pluck("slug").contains(permission)
125+
126+
def has_any_permission(self, permissions):
127+
"""Check if user has any of the permissions"""
128+
from ..models.permission import Permission
129+
130+
if type(permissions) != Collection and type(permissions) != list:
131+
raise PermissionException(
132+
"argument must be a collection of permissions or list of permission ids!"
133+
)
134+
135+
if len(permissions) != 0:
136+
permission = permissions[0]
137+
if isinstance(permission, str):
138+
permissions = Permission.where_in("slug", permissions).get().pluck("slug")
139+
140+
slugs = set(self.permissions().pluck("slug"))
141+
142+
return len(slugs.intersection(permissions)) > 0
143+
144+
def has_all_permissions(self, permissions):
145+
"""Check if user has all of the permissions"""
146+
147+
if permissions is None or len(permissions) == 0 or type(permissions) != list:
148+
raise PermissionException("permissions must be list of permission slugs!")
149+
150+
slugs = self.permissions().pluck("slug")
151+
return set(permissions).issubset(slugs) and len(set(permissions) - set(slugs)) == 0
152+
153+
def can_(self, permissions):
154+
"""Check if user has a permission"""
155+
if type(permissions) != str:
156+
raise PermissionException("permission must be a string!")
157+
158+
action = "all" # can be all or any
159+
160+
# check if permissions contains a comma
161+
if "," in permissions:
162+
permissions = permissions.split(",")
163+
elif "|" in permissions:
164+
action = "any"
165+
permissions = permissions.split("|")
166+
else:
167+
permissions = [permissions]
168+
169+
if action == "all":
170+
return self.has_all_permissions(permissions)
171+
172+
if action == "any":
173+
return self.has_any_permission(permissions)
174+
175+
def is_(self, roles):
176+
"""Check if user has a role"""
177+
if type(roles) != str:
178+
raise PermissionException("role must be a string!")
179+
180+
action = "all" # can be all or any
181+
182+
# check if permissions contains a comma
183+
if "," in roles:
184+
roles = roles.split(",")
185+
elif "|" in roles:
186+
action = "any"
187+
roles = roles.split("|")
188+
else:
189+
roles = [roles]
190+
191+
if action == "all":
192+
return self.has_all_roles(roles)
193+
194+
if action == "any":
195+
return self.has_any_role(roles)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from masonite.providers import Provider
2+
from masonite.facades import Gate
3+
4+
5+
class PermissionGateProvider(Provider):
6+
def __init__(self, application):
7+
self.application = application
8+
9+
def register(self):
10+
pass
11+
12+
def boot(self):
13+
pass

src/masonite_permission/providers/PermissionProvider.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
from masonite.packages import PackageProvider
44

5+
from ..masonite_permission import MasonitePermission
6+
57

68
class PermissionProvider(PackageProvider):
79
def configure(self):
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
# flake8: noqa: E501
22
from .PermissionProvider import PermissionProvider
3+
from .PermissionGateProvider import PermissionGateProvider

tests/integrations/app/controllers/WelcomeController.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ class WelcomeController(Controller):
1212
"""WelcomeController Controller Class."""
1313

1414
def show(self, view: View):
15-
return view.render("welcome")
15+
user = User.first()
16+
17+
return view.render("welcome", {"user": user})
1618

1719
def test(self):
1820
"""users = [{
@@ -84,13 +86,14 @@ def test(self):
8486
8587
Methods:
8688
user.sync_roles([role])
87-
user.attach_role(role)
88-
user.detatch_role(role)
89+
user.assign_role(role)
90+
user.remove_role(role)
8991
user.has_role(role)
9092
user.has_any_role(roles)
9193
user.has_all_roles(roles)
9294
"""
9395
# role.sync_permissions(Permission.all())
9496
# return role.permissions
9597
# user.attach_role(role)
96-
return user.permissions().pluck('name')
98+
return user.roles
99+
return {"result": user.roles}

tests/integrations/config/providers.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
from masonite.notification.providers import NotificationProvider
2424
from masonite.validation.providers import ValidationProvider
2525

26-
from src.masonite_permission.providers import PermissionProvider
26+
from src.masonite_permission.providers import PermissionProvider, PermissionGateProvider
2727

2828
PROVIDERS = [
2929
FrameworkProvider,
@@ -47,4 +47,5 @@
4747
AuthorizationProvider,
4848
ORMProvider,
4949
PermissionProvider,
50+
PermissionGateProvider,
5051
]

tests/integrations/templates/welcome.html

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,15 @@
55
<div class="h-screen flex flex-col items-center justify-center">
66
<img src="/logo.png" alt="Masonite Logo" class="h-16 w-16 mb-4">
77
<div class="text-gray-500 text-5xl mb-10 tracking-wide">
8-
Masonite 4
8+
Masonite 4 {{ user.can_('create-post,delete-post') }}
9+
{% if user.has_role("admin") %}
10+
<p>You are an admin</p>
11+
{% endif %}
12+
13+
{% if user.is_("admin") %}
14+
<p>You are an admin</p>
15+
{% endif %}
16+
917
</div>
1018

1119
<nav class="flex space-x-4 justify-center text-gray-500 uppercase text-sm">

0 commit comments

Comments
 (0)