Skip to content

Commit 63f2f60

Browse files
FGA_2: listResources(), get/update/delete resource_by_external_id
1 parent 526eb7d commit 63f2f60

File tree

2 files changed

+502
-0
lines changed

2 files changed

+502
-0
lines changed

src/workos/authorization.py

Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
)
99
from workos.types.authorization.organization_role import OrganizationRole
1010
from workos.types.authorization.permission import Permission
11+
from workos.types.authorization.resource import Resource
1112
from workos.types.authorization.role import Role, RoleList
1213
from workos.types.list_resource import (
1314
ListArgs,
@@ -28,6 +29,15 @@
2829
)
2930

3031
AUTHORIZATION_PERMISSIONS_PATH = "authorization/permissions"
32+
AUTHORIZATION_ORGANIZATIONS_PATH = "authorization/organizations"
33+
34+
35+
class ResourceListFilters(ListArgs, total=False):
36+
organization_id: str
37+
resource_type_slug: Optional[str]
38+
39+
40+
ResourcesListResource = WorkOSListResource[Resource, ResourceListFilters, ListMetadata]
3141

3242
_role_adapter: TypeAdapter[Role] = TypeAdapter(Role)
3343

@@ -161,6 +171,45 @@ def add_environment_role_permission(
161171
permission_slug: str,
162172
) -> SyncOrAsync[EnvironmentRole]: ...
163173

174+
# Resources (External ID) + List
175+
176+
def get_resource_by_external_id(
177+
self,
178+
organization_id: str,
179+
resource_type: str,
180+
external_id: str,
181+
) -> SyncOrAsync[Resource]: ...
182+
183+
def update_resource_by_external_id(
184+
self,
185+
organization_id: str,
186+
resource_type: str,
187+
external_id: str,
188+
*,
189+
name: Optional[str] = None,
190+
description: Optional[str] = None,
191+
) -> SyncOrAsync[Resource]: ...
192+
193+
def delete_resource_by_external_id(
194+
self,
195+
organization_id: str,
196+
resource_type: str,
197+
external_id: str,
198+
*,
199+
cascade_delete: Optional[bool] = None,
200+
) -> SyncOrAsync[None]: ...
201+
202+
def list_resources(
203+
self,
204+
organization_id: str,
205+
*,
206+
resource_type_slug: Optional[str] = None,
207+
limit: int = DEFAULT_LIST_RESPONSE_LIMIT,
208+
before: Optional[str] = None,
209+
after: Optional[str] = None,
210+
order: PaginationOrder = "desc",
211+
) -> SyncOrAsync[ResourcesListResource]: ...
212+
164213

165214
class Authorization(AuthorizationModule):
166215
_http_client: SyncHTTPClient
@@ -437,6 +486,97 @@ def add_environment_role_permission(
437486

438487
return EnvironmentRole.model_validate(response)
439488

489+
# Resources (External ID) + List
490+
491+
def get_resource_by_external_id(
492+
self,
493+
organization_id: str,
494+
resource_type: str,
495+
external_id: str,
496+
) -> Resource:
497+
response = self._http_client.request(
498+
f"{AUTHORIZATION_ORGANIZATIONS_PATH}/{organization_id}/resources/{resource_type}/{external_id}",
499+
method=REQUEST_METHOD_GET,
500+
)
501+
502+
return Resource.model_validate(response)
503+
504+
def update_resource_by_external_id(
505+
self,
506+
organization_id: str,
507+
resource_type: str,
508+
external_id: str,
509+
*,
510+
name: Optional[str] = None,
511+
description: Optional[str] = None,
512+
) -> Resource:
513+
json: Dict[str, Any] = {}
514+
if name is not None:
515+
json["name"] = name
516+
if description is not None:
517+
json["description"] = description
518+
519+
response = self._http_client.request(
520+
f"{AUTHORIZATION_ORGANIZATIONS_PATH}/{organization_id}/resources/{resource_type}/{external_id}",
521+
method=REQUEST_METHOD_PATCH,
522+
json=json,
523+
)
524+
525+
return Resource.model_validate(response)
526+
527+
def delete_resource_by_external_id(
528+
self,
529+
organization_id: str,
530+
resource_type: str,
531+
external_id: str,
532+
*,
533+
cascade_delete: Optional[bool] = None,
534+
) -> None:
535+
path = f"{AUTHORIZATION_ORGANIZATIONS_PATH}/{organization_id}/resources/{resource_type}/{external_id}"
536+
params: Dict[str, bool] = {}
537+
if cascade_delete is not None:
538+
params["cascade_delete"] = cascade_delete
539+
540+
self._http_client.request(
541+
path,
542+
method=REQUEST_METHOD_DELETE,
543+
params=params if params else None,
544+
)
545+
546+
def list_resources(
547+
self,
548+
organization_id: str,
549+
*,
550+
resource_type_slug: Optional[str] = None,
551+
limit: int = DEFAULT_LIST_RESPONSE_LIMIT,
552+
before: Optional[str] = None,
553+
after: Optional[str] = None,
554+
order: PaginationOrder = "desc",
555+
) -> ResourcesListResource:
556+
list_params: ResourceListFilters = {
557+
"organization_id": organization_id,
558+
"limit": limit,
559+
"before": before,
560+
"after": after,
561+
"order": order,
562+
}
563+
if resource_type_slug is not None:
564+
list_params["resource_type_slug"] = resource_type_slug
565+
566+
query_params = {k: v for k, v in list_params.items() if k != "organization_id"}
567+
568+
response = self._http_client.request(
569+
f"{AUTHORIZATION_ORGANIZATIONS_PATH}/{organization_id}/resources",
570+
method=REQUEST_METHOD_GET,
571+
params=query_params,
572+
)
573+
574+
return WorkOSListResource[Resource, ResourceListFilters, ListMetadata](
575+
list_method=self.list_resources,
576+
list_args=list_params,
577+
**ListPage[Resource](**response).model_dump(),
578+
)
579+
440580

441581
class AsyncAuthorization(AuthorizationModule):
442582
_http_client: AsyncHTTPClient
@@ -712,3 +852,94 @@ async def add_environment_role_permission(
712852
)
713853

714854
return EnvironmentRole.model_validate(response)
855+
856+
# Resources (External ID) + List
857+
858+
async def get_resource_by_external_id(
859+
self,
860+
organization_id: str,
861+
resource_type: str,
862+
external_id: str,
863+
) -> Resource:
864+
response = await self._http_client.request(
865+
f"{AUTHORIZATION_ORGANIZATIONS_PATH}/{organization_id}/resources/{resource_type}/{external_id}",
866+
method=REQUEST_METHOD_GET,
867+
)
868+
869+
return Resource.model_validate(response)
870+
871+
async def update_resource_by_external_id(
872+
self,
873+
organization_id: str,
874+
resource_type: str,
875+
external_id: str,
876+
*,
877+
name: Optional[str] = None,
878+
description: Optional[str] = None,
879+
) -> Resource:
880+
json: Dict[str, Any] = {}
881+
if name is not None:
882+
json["name"] = name
883+
if description is not None:
884+
json["description"] = description
885+
886+
response = await self._http_client.request(
887+
f"{AUTHORIZATION_ORGANIZATIONS_PATH}/{organization_id}/resources/{resource_type}/{external_id}",
888+
method=REQUEST_METHOD_PATCH,
889+
json=json,
890+
)
891+
892+
return Resource.model_validate(response)
893+
894+
async def delete_resource_by_external_id(
895+
self,
896+
organization_id: str,
897+
resource_type: str,
898+
external_id: str,
899+
*,
900+
cascade_delete: Optional[bool] = None,
901+
) -> None:
902+
path = f"{AUTHORIZATION_ORGANIZATIONS_PATH}/{organization_id}/resources/{resource_type}/{external_id}"
903+
params: Dict[str, bool] = {}
904+
if cascade_delete is not None:
905+
params["cascade_delete"] = cascade_delete
906+
907+
await self._http_client.request(
908+
path,
909+
method=REQUEST_METHOD_DELETE,
910+
params=params if params else None,
911+
)
912+
913+
async def list_resources(
914+
self,
915+
organization_id: str,
916+
*,
917+
resource_type_slug: Optional[str] = None,
918+
limit: int = DEFAULT_LIST_RESPONSE_LIMIT,
919+
before: Optional[str] = None,
920+
after: Optional[str] = None,
921+
order: PaginationOrder = "desc",
922+
) -> ResourcesListResource:
923+
list_params: ResourceListFilters = {
924+
"organization_id": organization_id,
925+
"limit": limit,
926+
"before": before,
927+
"after": after,
928+
"order": order,
929+
}
930+
if resource_type_slug is not None:
931+
list_params["resource_type_slug"] = resource_type_slug
932+
933+
query_params = {k: v for k, v in list_params.items() if k != "organization_id"}
934+
935+
response = await self._http_client.request(
936+
f"{AUTHORIZATION_ORGANIZATIONS_PATH}/{organization_id}/resources",
937+
method=REQUEST_METHOD_GET,
938+
params=query_params,
939+
)
940+
941+
return WorkOSListResource[Resource, ResourceListFilters, ListMetadata](
942+
list_method=self.list_resources,
943+
list_args=list_params,
944+
**ListPage[Resource](**response).model_dump(),
945+
)

0 commit comments

Comments
 (0)