Skip to content

Commit e30a2f7

Browse files
fga p4
1 parent a5d3ce2 commit e30a2f7

File tree

2 files changed

+370
-0
lines changed

2 files changed

+370
-0
lines changed

src/workos/authorization.py

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from functools import partial
12
from typing import Any, Dict, Optional, Protocol, Sequence, Union
23

34
from pydantic import TypeAdapter
@@ -11,6 +12,7 @@
1112
from workos.types.authorization.permission import Permission
1213
from workos.types.authorization.resource import Resource
1314
from workos.types.authorization.role import Role, RoleList
15+
from workos.types.authorization.role_assignment import RoleAssignment
1416
from workos.types.list_resource import (
1517
ListArgs,
1618
ListMetadata,
@@ -31,6 +33,10 @@
3133

3234
AUTHORIZATION_PERMISSIONS_PATH = "authorization/permissions"
3335
AUTHORIZATION_RESOURCES_PATH = "authorization/resources"
36+
AUTHORIZATION_ROLE_ASSIGNMENTS_PATH = (
37+
"authorization/organization_memberships"
38+
"/{organization_membership_id}/role_assignments"
39+
)
3440

3541

3642
class ParentResourceById(TypedDict):
@@ -56,6 +62,15 @@ class PermissionListFilters(ListArgs, total=False):
5662
]
5763

5864

65+
class RoleAssignmentListFilters(ListArgs, total=False):
66+
pass
67+
68+
69+
RoleAssignmentsListResource = WorkOSListResource[
70+
RoleAssignment, RoleAssignmentListFilters, ListMetadata
71+
]
72+
73+
5974
class AuthorizationModule(Protocol):
6075
"""Offers methods through the WorkOS Authorization service."""
6176

@@ -206,6 +221,38 @@ def delete_resource(
206221
cascade_delete: Optional[bool] = None,
207222
) -> SyncOrAsync[None]: ...
208223

224+
# Role Assignments
225+
226+
def list_role_assignments(
227+
self,
228+
organization_membership_id: str,
229+
*,
230+
limit: int = DEFAULT_LIST_RESPONSE_LIMIT,
231+
before: Optional[str] = None,
232+
after: Optional[str] = None,
233+
order: PaginationOrder = "desc",
234+
) -> SyncOrAsync[RoleAssignmentsListResource]: ...
235+
236+
def assign_role(
237+
self,
238+
organization_membership_id: str,
239+
*,
240+
role_slug: str,
241+
) -> SyncOrAsync[RoleAssignment]: ...
242+
243+
def remove_role(
244+
self,
245+
organization_membership_id: str,
246+
*,
247+
role_slug: str,
248+
) -> SyncOrAsync[None]: ...
249+
250+
def remove_role_assignment(
251+
self,
252+
organization_membership_id: str,
253+
role_assignment_id: str,
254+
) -> SyncOrAsync[None]: ...
255+
209256

210257
class Authorization(AuthorizationModule):
211258
_http_client: SyncHTTPClient
@@ -558,6 +605,79 @@ def delete_resource(
558605
method=REQUEST_METHOD_DELETE,
559606
)
560607

608+
# Role Assignments
609+
610+
def list_role_assignments(
611+
self,
612+
organization_membership_id: str,
613+
*,
614+
limit: int = DEFAULT_LIST_RESPONSE_LIMIT,
615+
before: Optional[str] = None,
616+
after: Optional[str] = None,
617+
order: PaginationOrder = "desc",
618+
) -> RoleAssignmentsListResource:
619+
list_params: RoleAssignmentListFilters = {
620+
"limit": limit,
621+
"before": before,
622+
"after": after,
623+
"order": order,
624+
}
625+
626+
response = self._http_client.request(
627+
AUTHORIZATION_ROLE_ASSIGNMENTS_PATH.format(
628+
organization_membership_id=organization_membership_id
629+
),
630+
method=REQUEST_METHOD_GET,
631+
params=list_params,
632+
)
633+
634+
return WorkOSListResource[
635+
RoleAssignment, RoleAssignmentListFilters, ListMetadata
636+
](
637+
list_method=partial(self.list_role_assignments, organization_membership_id),
638+
list_args=list_params,
639+
**ListPage[RoleAssignment](**response).model_dump(),
640+
)
641+
642+
def assign_role(
643+
self,
644+
organization_membership_id: str,
645+
*,
646+
role_slug: str,
647+
) -> RoleAssignment:
648+
response = self._http_client.request(
649+
AUTHORIZATION_ROLE_ASSIGNMENTS_PATH.format(
650+
organization_membership_id=organization_membership_id
651+
),
652+
method=REQUEST_METHOD_POST,
653+
json={"role_slug": role_slug},
654+
)
655+
656+
return RoleAssignment.model_validate(response)
657+
658+
def remove_role(
659+
self,
660+
organization_membership_id: str,
661+
*,
662+
role_slug: str,
663+
) -> None:
664+
self._http_client.delete_with_body(
665+
AUTHORIZATION_ROLE_ASSIGNMENTS_PATH.format(
666+
organization_membership_id=organization_membership_id
667+
),
668+
json={"role_slug": role_slug},
669+
)
670+
671+
def remove_role_assignment(
672+
self,
673+
organization_membership_id: str,
674+
role_assignment_id: str,
675+
) -> None:
676+
self._http_client.request(
677+
f"{AUTHORIZATION_ROLE_ASSIGNMENTS_PATH.format(organization_membership_id=organization_membership_id)}/{role_assignment_id}",
678+
method=REQUEST_METHOD_DELETE,
679+
)
680+
561681

562682
class AsyncAuthorization(AuthorizationModule):
563683
_http_client: AsyncHTTPClient
@@ -909,3 +1029,76 @@ async def delete_resource(
9091029
f"{AUTHORIZATION_RESOURCES_PATH}/{resource_id}",
9101030
method=REQUEST_METHOD_DELETE,
9111031
)
1032+
1033+
# Role Assignments
1034+
1035+
async def list_role_assignments(
1036+
self,
1037+
organization_membership_id: str,
1038+
*,
1039+
limit: int = DEFAULT_LIST_RESPONSE_LIMIT,
1040+
before: Optional[str] = None,
1041+
after: Optional[str] = None,
1042+
order: PaginationOrder = "desc",
1043+
) -> RoleAssignmentsListResource:
1044+
list_params: RoleAssignmentListFilters = {
1045+
"limit": limit,
1046+
"before": before,
1047+
"after": after,
1048+
"order": order,
1049+
}
1050+
1051+
response = await self._http_client.request(
1052+
AUTHORIZATION_ROLE_ASSIGNMENTS_PATH.format(
1053+
organization_membership_id=organization_membership_id
1054+
),
1055+
method=REQUEST_METHOD_GET,
1056+
params=list_params,
1057+
)
1058+
1059+
return WorkOSListResource[
1060+
RoleAssignment, RoleAssignmentListFilters, ListMetadata
1061+
](
1062+
list_method=partial(self.list_role_assignments, organization_membership_id),
1063+
list_args=list_params,
1064+
**ListPage[RoleAssignment](**response).model_dump(),
1065+
)
1066+
1067+
async def assign_role(
1068+
self,
1069+
organization_membership_id: str,
1070+
*,
1071+
role_slug: str,
1072+
) -> RoleAssignment:
1073+
response = await self._http_client.request(
1074+
AUTHORIZATION_ROLE_ASSIGNMENTS_PATH.format(
1075+
organization_membership_id=organization_membership_id
1076+
),
1077+
method=REQUEST_METHOD_POST,
1078+
json={"role_slug": role_slug},
1079+
)
1080+
1081+
return RoleAssignment.model_validate(response)
1082+
1083+
async def remove_role(
1084+
self,
1085+
organization_membership_id: str,
1086+
*,
1087+
role_slug: str,
1088+
) -> None:
1089+
await self._http_client.delete_with_body(
1090+
AUTHORIZATION_ROLE_ASSIGNMENTS_PATH.format(
1091+
organization_membership_id=organization_membership_id
1092+
),
1093+
json={"role_slug": role_slug},
1094+
)
1095+
1096+
async def remove_role_assignment(
1097+
self,
1098+
organization_membership_id: str,
1099+
role_assignment_id: str,
1100+
) -> None:
1101+
await self._http_client.request(
1102+
f"{AUTHORIZATION_ROLE_ASSIGNMENTS_PATH.format(organization_membership_id=organization_membership_id)}/{role_assignment_id}",
1103+
method=REQUEST_METHOD_DELETE,
1104+
)

0 commit comments

Comments
 (0)