55from dataclasses import dataclass , field
66from enum import StrEnum
77from functools import wraps
8- from typing import ClassVar , Concatenate , ParamSpec , Protocol , TypeVar
8+ from typing import ClassVar , Concatenate , ParamSpec , Protocol , TypeVar , cast
99
1010from authzed .api .v1 import AsyncClient
1111from authzed .api .v1 .core_pb2 import ObjectReference , Relationship , RelationshipUpdate , SubjectReference , ZedToken
@@ -163,12 +163,12 @@ def all_users() -> ObjectReference:
163163 return ObjectReference (object_type = ResourceType .user , object_id = "*" )
164164
165165 @staticmethod
166- def group (id : str ) -> ObjectReference :
167- return ObjectReference (object_type = ResourceType .group , object_id = id )
166+ def group (id : ULID ) -> ObjectReference :
167+ return ObjectReference (object_type = ResourceType .group , object_id = str ( id ) )
168168
169169 @staticmethod
170- def user_namespace (id : str ) -> ObjectReference :
171- return ObjectReference (object_type = ResourceType .user_namespace , object_id = id )
170+ def user_namespace (id : ULID ) -> ObjectReference :
171+ return ObjectReference (object_type = ResourceType .user_namespace , object_id = str ( id ) )
172172
173173 @staticmethod
174174 def to_object (resource_type : ResourceType , resource_id : str | ULID | int ) -> ObjectReference :
@@ -179,9 +179,9 @@ def to_object(resource_type: ResourceType, resource_id: str | ULID | int) -> Obj
179179 return _AuthzConverter .user (sid )
180180 case (ResourceType .anonymous_user , _):
181181 return _AuthzConverter .anonymous_users ()
182- case (ResourceType .user_namespace , rid ) if isinstance (rid , str ):
182+ case (ResourceType .user_namespace , rid ) if isinstance (rid , ULID ):
183183 return _AuthzConverter .user_namespace (rid )
184- case (ResourceType .group , rid ) if isinstance (rid , str ):
184+ case (ResourceType .group , rid ) if isinstance (rid , ULID ):
185185 return _AuthzConverter .group (rid )
186186 raise errors .ProgrammingError (
187187 message = f"Unexpected or unknown resource type when checking permissions { resource_type } "
@@ -580,7 +580,7 @@ def _add_project(self, project: Project) -> _AuthzChange:
580580 object = (
581581 _AuthzConverter .user_namespace (project .namespace .id )
582582 if project .namespace .kind == NamespaceKind .user
583- else _AuthzConverter .group (project .namespace .underlying_resource_id )
583+ else _AuthzConverter .group (cast ( ULID , project .namespace .underlying_resource_id ) )
584584 )
585585 )
586586 project_in_platform = Relationship (
@@ -759,10 +759,14 @@ async def _update_project_namespace(
759759 else SubjectReference (object = _AuthzConverter .user_namespace (project .namespace .id ))
760760 )
761761 old_namespace_sub = (
762- SubjectReference (object = _AuthzConverter .group (current_namespace .relationship .subject .object .object_id ))
762+ SubjectReference (
763+ object = _AuthzConverter .group (ULID .from_str (current_namespace .relationship .subject .object .object_id ))
764+ )
763765 if current_namespace .relationship .subject .object .object_type == ResourceType .group .value
764766 else SubjectReference (
765- object = _AuthzConverter .user_namespace (current_namespace .relationship .subject .object .object_id )
767+ object = _AuthzConverter .user_namespace (
768+ ULID .from_str (current_namespace .relationship .subject .object .object_id )
769+ )
766770 )
767771 )
768772 new_namespace = Relationship (
@@ -1093,7 +1097,7 @@ async def _remove_group(
10931097 message = "Cannot remove a group in the authorization database if the group has no ID"
10941098 )
10951099 consistency = Consistency (at_least_as_fresh = zed_token ) if zed_token else Consistency (fully_consistent = True )
1096- rel_filter = RelationshipFilter (resource_type = ResourceType .group .value , optional_resource_id = group .id )
1100+ rel_filter = RelationshipFilter (resource_type = ResourceType .group .value , optional_resource_id = str ( group .id ) )
10971101 responses = self .client .ReadRelationships (
10981102 ReadRelationshipsRequest (consistency = consistency , relationship_filter = rel_filter )
10991103 )
@@ -1113,7 +1117,7 @@ async def upsert_group_members(
11131117 self ,
11141118 user : base_models .APIUser ,
11151119 resource_type : ResourceType ,
1116- resource_id : str ,
1120+ resource_id : ULID ,
11171121 members : list [Member ],
11181122 * ,
11191123 zed_token : ZedToken | None = None ,
@@ -1124,8 +1128,9 @@ async def upsert_group_members(
11241128 add_members : list [RelationshipUpdate ] = []
11251129 undo : list [RelationshipUpdate ] = []
11261130 output : list [MembershipChange ] = []
1131+ resource_id_str = str (resource_id )
11271132 expected_user_roles = {_Relation .viewer .value , _Relation .owner .value , _Relation .editor .value }
1128- existing_owners_rels = await self ._get_resource_owners (resource_type , resource_id , consistency )
1133+ existing_owners_rels = await self ._get_resource_owners (resource_type , resource_id_str , consistency )
11291134 n_existing_owners = len (existing_owners_rels )
11301135 for member in members :
11311136 rel = Relationship (
@@ -1135,7 +1140,7 @@ async def upsert_group_members(
11351140 )
11361141 existing_rel_filter = RelationshipFilter (
11371142 resource_type = resource_type .value ,
1138- optional_resource_id = resource_id ,
1143+ optional_resource_id = resource_id_str ,
11391144 optional_subject_filter = SubjectFilter (
11401145 subject_type = ResourceType .user , optional_subject_id = member .user_id
11411146 ),
@@ -1231,7 +1236,7 @@ async def remove_group_members(
12311236 self ,
12321237 user : base_models .APIUser ,
12331238 resource_type : ResourceType ,
1234- resource_id : str ,
1239+ resource_id : ULID ,
12351240 user_ids : list [str ],
12361241 * ,
12371242 zed_token : ZedToken | None = None ,
@@ -1242,12 +1247,13 @@ async def remove_group_members(
12421247 remove_members : list [RelationshipUpdate ] = []
12431248 output : list [MembershipChange ] = []
12441249 existing_owners_rels : list [ReadRelationshipsResponse ] | None = None
1250+ resource_id_str = str (resource_id )
12451251 for user_id in user_ids :
12461252 if user_id == "*" :
12471253 raise errors .ValidationError (message = "Cannot remove a group member with ID '*'" )
12481254 existing_rel_filter = RelationshipFilter (
12491255 resource_type = resource_type .value ,
1250- optional_resource_id = resource_id ,
1256+ optional_resource_id = resource_id_str ,
12511257 optional_subject_filter = SubjectFilter (subject_type = ResourceType .user , optional_subject_id = user_id ),
12521258 )
12531259 existing_rels : AsyncIterable [ReadRelationshipsResponse ] = self .client .ReadRelationships (
@@ -1258,7 +1264,9 @@ async def remove_group_members(
12581264 async for existing_rel in existing_rels :
12591265 if existing_rel .relationship .relation == _Relation .owner .value :
12601266 if existing_owners_rels is None :
1261- existing_owners_rels = await self ._get_resource_owners (resource_type , resource_id , consistency )
1267+ existing_owners_rels = await self ._get_resource_owners (
1268+ resource_type , resource_id_str , consistency
1269+ )
12621270 if len (existing_owners_rels ) == 1 :
12631271 raise errors .ValidationError (
12641272 message = "You are trying to remove the single last owner of the group, "
0 commit comments