|
| 1 | +from authzed.api.v1 import ( |
| 2 | + CheckPermissionRequest, |
| 3 | + CheckPermissionResponse, |
| 4 | + Client, |
| 5 | + ObjectReference, |
| 6 | + Relationship, |
| 7 | + RelationshipUpdate, |
| 8 | + SubjectReference, |
| 9 | + WriteRelationshipsRequest, |
| 10 | + WriteSchemaRequest, |
| 11 | +) |
| 12 | +from grpcutil import insecure_bearer_token_credentials |
| 13 | + |
| 14 | +_TOUCH = RelationshipUpdate.Operation.OPERATION_TOUCH |
| 15 | +_DELETE = RelationshipUpdate.Operation.OPERATION_DELETE |
| 16 | +_HAS = CheckPermissionResponse.PERMISSIONSHIP_HAS_PERMISSION |
| 17 | + |
| 18 | + |
| 19 | +def _object_ref(obj_type: str, obj_id: str) -> ObjectReference: |
| 20 | + return ObjectReference(object_type=obj_type, object_id=obj_id) |
| 21 | + |
| 22 | + |
| 23 | +def _subject_ref(user_id: str) -> SubjectReference: |
| 24 | + return SubjectReference(object=_object_ref("user", user_id)) |
| 25 | + |
| 26 | + |
| 27 | +def _relationship(res_type: str, res_id: str, relation: str, user_id: str) -> Relationship: |
| 28 | + return Relationship( |
| 29 | + resource=_object_ref(res_type, res_id), |
| 30 | + relation=relation, |
| 31 | + subject=_subject_ref(user_id), |
| 32 | + ) |
| 33 | + |
| 34 | + |
| 35 | +def _update(operation, res_type: str, res_id: str, relation: str, user_id: str) -> RelationshipUpdate: |
| 36 | + return RelationshipUpdate( |
| 37 | + operation=operation, |
| 38 | + relationship=_relationship(res_type, res_id, relation, user_id), |
| 39 | + ) |
| 40 | + |
| 41 | + |
| 42 | +class AuthzClient: |
| 43 | + def __init__(self, endpoint: str, token: str): |
| 44 | + self._client = Client( |
| 45 | + endpoint, |
| 46 | + insecure_bearer_token_credentials(token), |
| 47 | + ) |
| 48 | + |
| 49 | + def check(self, res_type: str, res_id: str, permission: str, user_id: str) -> bool: |
| 50 | + resp = self._client.CheckPermission( |
| 51 | + CheckPermissionRequest( |
| 52 | + resource=_object_ref(res_type, res_id), |
| 53 | + permission=permission, |
| 54 | + subject=_subject_ref(user_id), |
| 55 | + ) |
| 56 | + ) |
| 57 | + return resp.permissionship == _HAS |
| 58 | + |
| 59 | + def add_relation(self, res_type: str, res_id: str, relation: str, user_id: str) -> None: |
| 60 | + self._write(_TOUCH, res_type, res_id, relation, user_id) |
| 61 | + |
| 62 | + def remove_relation(self, res_type: str, res_id: str, relation: str, user_id: str) -> None: |
| 63 | + self._write(_DELETE, res_type, res_id, relation, user_id) |
| 64 | + |
| 65 | + def write_schema(self, schema: str) -> None: |
| 66 | + self._client.WriteSchema(WriteSchemaRequest(schema=schema)) |
| 67 | + |
| 68 | + def _write(self, operation: int, res_type: str, res_id: str, relation: str, user_id: str) -> None: |
| 69 | + self._client.WriteRelationships( |
| 70 | + WriteRelationshipsRequest(updates=[_update(operation, res_type, res_id, relation, user_id)]) |
| 71 | + ) |
0 commit comments