Skip to content

Commit efc57c0

Browse files
tsmith023jfrancoa
authored andcommitted
Add .has_permission method and test of its usage wth server image
1 parent 79643ef commit efc57c0

File tree

5 files changed

+94
-2
lines changed

5 files changed

+94
-2
lines changed

.github/workflows/main.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ env:
1717
WEAVIATE_125: 1.25.24
1818
WEAVIATE_126: 1.26.8
1919
WEAVIATE_127: 1.27.1
20-
WEAVIATE_128: 1.28.0-rc.0-ebcc021
20+
WEAVIATE_128: 1.28.0-rc.0-d00c5ca
2121
jobs:
2222
lint-and-format:
2323
name: Run Linter and Formatter

integration/test_rbac.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,5 +301,12 @@ def test_multiple_permissions(client_factory: ClientFactory) -> None:
301301
assert len(role.data_permissions) == 2
302302
assert role.data_permissions[0].action == Actions.Data.CREATE
303303
assert role.data_permissions[1].action == Actions.Data.UPDATE
304+
305+
assert client.roles.has_permission(
306+
permission=role.collections_permissions[0], role=role_name
307+
)
308+
assert client.roles.has_permission(
309+
permission=required_permissions[1][0], role=role_name
310+
)
304311
finally:
305312
client.roles.delete(role_name)

weaviate/rbac/models.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,41 +221,91 @@ class CollectionsPermission:
221221
collection: str
222222
action: CollectionsAction
223223

224+
def _to_weaviate(self) -> WeaviatePermission:
225+
return {
226+
"action": self.action,
227+
"collections": {
228+
"collection": self.collection,
229+
"tenant": "*",
230+
},
231+
}
232+
224233

225234
@dataclass
226235
class DataPermission:
227236
collection: str
228237
action: DataAction
229238

239+
def _to_weaviate(self) -> WeaviatePermission:
240+
return {
241+
"action": self.action,
242+
"data": {
243+
"collection": self.collection,
244+
"object": "*",
245+
"tenant": "*",
246+
},
247+
}
248+
230249

231250
@dataclass
232251
class RolesPermission:
233252
role: str
234253
action: RolesAction
235254

255+
def _to_weaviate(self) -> WeaviatePermission:
256+
return {
257+
"action": self.action,
258+
"roles": {
259+
"role": self.role,
260+
},
261+
}
262+
236263

237264
@dataclass
238265
class UsersPermission:
239266
action: UsersAction
240267

268+
def _to_weaviate(self) -> WeaviatePermission:
269+
return {"action": self.action}
270+
241271

242272
@dataclass
243273
class ClusterPermission:
244274
action: ClusterAction
245275

276+
def _to_weaviate(self) -> WeaviatePermission:
277+
return {"action": self.action}
278+
246279

247280
@dataclass
248281
class BackupsPermission:
249282
collection: str
250283
action: BackupsAction
251284

285+
def _to_weaviate(self) -> WeaviatePermission:
286+
return {
287+
"action": self.action,
288+
"backups": {
289+
"collection": self.collection,
290+
},
291+
}
292+
252293

253294
@dataclass
254295
class NodesPermission:
255296
collection: Optional[str]
256297
verbosity: Verbosity
257298
action: NodesAction
258299

300+
def _to_weaviate(self) -> WeaviatePermission:
301+
return {
302+
"action": self.action,
303+
"nodes": {
304+
"collection": self.collection or "*",
305+
"verbosity": self.verbosity,
306+
},
307+
}
308+
259309

260310
PermissionsOutputType = Union[
261311
ClusterPermission,

weaviate/rbac/roles.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from weaviate.connect.v4 import _ExpectedStatusCodes
66
from weaviate.rbac.models import (
77
_Permission,
8+
PermissionsOutputType,
89
PermissionsInputType,
910
Role,
1011
User,
@@ -129,6 +130,17 @@ async def _remove_permissions(self, permissions: List[WeaviatePermission], role:
129130
status_codes=_ExpectedStatusCodes(ok_in=[200], error="Remove permissions"),
130131
)
131132

133+
async def _has_permission(self, permission: WeaviatePermission, role: str) -> bool:
134+
path = f"/authz/roles/{role}/has-permission"
135+
136+
res = await self._connection.post(
137+
path,
138+
weaviate_object=permission,
139+
error_msg="Could not check permission",
140+
status_codes=_ExpectedStatusCodes(ok_in=[200], error="Check permission"),
141+
)
142+
return cast(bool, res.json())
143+
132144

133145
class _RolesAsync(_RolesBase):
134146
def __user_from_weaviate_user(self, user: str) -> User:
@@ -287,6 +299,20 @@ async def remove_permissions(
287299
role_name,
288300
)
289301

302+
async def has_permission(
303+
self, *, permission: Union[_Permission, PermissionsOutputType], role: str
304+
) -> bool:
305+
"""Check if a role has a specific permission.
306+
307+
Args:
308+
permission: The permission to check.
309+
role: The role to check the permission for.
310+
311+
Returns:
312+
True if the role has the permission, False otherwise.
313+
"""
314+
return await self._has_permission(permission._to_weaviate(), role)
315+
290316

291317
def _flatten_permissions(permissions: PermissionsInputType) -> List[_Permission]:
292318
if isinstance(permissions, _Permission):

weaviate/rbac/sync.pyi

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
from typing import Dict, List, Optional, Union
22

3-
from weaviate.rbac.models import PermissionsInputType, Role, User
3+
from weaviate.rbac.models import (
4+
_Permission,
5+
PermissionsOutputType,
6+
PermissionsInputType,
7+
Role,
8+
User,
9+
)
410
from weaviate.rbac.roles import _RolesBase
511

612
class _Roles(_RolesBase):
@@ -16,3 +22,6 @@ class _Roles(_RolesBase):
1622
def revoke_from_user(self, *, role_names: Union[str, List[str]], user: str) -> None: ...
1723
def add_permissions(self, *, permissions: PermissionsInputType, role_name: str) -> None: ...
1824
def remove_permissions(self, *, permissions: PermissionsInputType, role_name: str) -> None: ...
25+
def has_permission(
26+
self, *, permission: Union[_Permission, PermissionsOutputType], role: str
27+
) -> bool: ...

0 commit comments

Comments
 (0)