diff --git a/scaleway-async/scaleway_async/iam/v1alpha1/__init__.py b/scaleway-async/scaleway_async/iam/v1alpha1/__init__.py index 7be116781..195628ca1 100644 --- a/scaleway-async/scaleway_async/iam/v1alpha1/__init__.py +++ b/scaleway-async/scaleway_async/iam/v1alpha1/__init__.py @@ -11,6 +11,7 @@ from .types import ListPoliciesRequestOrderBy from .types import ListQuotaRequestOrderBy from .types import ListSSHKeysRequestOrderBy +from .types import ListScimTokensRequestOrderBy from .types import ListUsersRequestOrderBy from .types import LocalityType from .types import LogAction @@ -26,6 +27,7 @@ from .types import QuotumLimit from .types import JWT from .types import RuleSpecs +from .types import ScimToken from .types import CreateUserRequestMember from .types import Connection from .types import APIKey @@ -51,6 +53,8 @@ from .types import CreateJWTRequest from .types import CreatePolicyRequest from .types import CreateSSHKeyRequest +from .types import CreateScimTokenRequest +from .types import CreateScimTokenResponse from .types import CreateUserMFAOTPRequest from .types import CreateUserRequest from .types import DeleteAPIKeyRequest @@ -61,9 +65,12 @@ from .types import DeleteSSHKeyRequest from .types import DeleteSamlCertificateRequest from .types import DeleteSamlRequest +from .types import DeleteScimRequest +from .types import DeleteScimTokenRequest from .types import DeleteUserMFAOTPRequest from .types import DeleteUserRequest from .types import EnableOrganizationSamlRequest +from .types import EnableOrganizationScimRequest from .types import EncodedJWT from .types import GetAPIKeyRequest from .types import GetApplicationRequest @@ -106,6 +113,8 @@ from .types import ListSSHKeysResponse from .types import ListSamlCertificatesRequest from .types import ListSamlCertificatesResponse +from .types import ListScimTokensRequest +from .types import ListScimTokensResponse from .types import ListUsersRequest from .types import ListUsersResponse from .types import LockUserRequest @@ -117,6 +126,7 @@ from .types import RemoveGroupMemberRequest from .types import RemoveUserConnectionRequest from .types import Saml +from .types import Scim from .types import SetGroupMembersRequest from .types import SetOrganizationAliasRequest from .types import SetRulesRequest @@ -149,6 +159,7 @@ "ListPoliciesRequestOrderBy", "ListQuotaRequestOrderBy", "ListSSHKeysRequestOrderBy", + "ListScimTokensRequestOrderBy", "ListUsersRequestOrderBy", "LocalityType", "LogAction", @@ -164,6 +175,7 @@ "QuotumLimit", "JWT", "RuleSpecs", + "ScimToken", "CreateUserRequestMember", "Connection", "APIKey", @@ -189,6 +201,8 @@ "CreateJWTRequest", "CreatePolicyRequest", "CreateSSHKeyRequest", + "CreateScimTokenRequest", + "CreateScimTokenResponse", "CreateUserMFAOTPRequest", "CreateUserRequest", "DeleteAPIKeyRequest", @@ -199,9 +213,12 @@ "DeleteSSHKeyRequest", "DeleteSamlCertificateRequest", "DeleteSamlRequest", + "DeleteScimRequest", + "DeleteScimTokenRequest", "DeleteUserMFAOTPRequest", "DeleteUserRequest", "EnableOrganizationSamlRequest", + "EnableOrganizationScimRequest", "EncodedJWT", "GetAPIKeyRequest", "GetApplicationRequest", @@ -244,6 +261,8 @@ "ListSSHKeysResponse", "ListSamlCertificatesRequest", "ListSamlCertificatesResponse", + "ListScimTokensRequest", + "ListScimTokensResponse", "ListUsersRequest", "ListUsersResponse", "LockUserRequest", @@ -255,6 +274,7 @@ "RemoveGroupMemberRequest", "RemoveUserConnectionRequest", "Saml", + "Scim", "SetGroupMembersRequest", "SetOrganizationAliasRequest", "SetRulesRequest", diff --git a/scaleway-async/scaleway_async/iam/v1alpha1/api.py b/scaleway-async/scaleway_async/iam/v1alpha1/api.py index b5c1dcc26..882d07509 100644 --- a/scaleway-async/scaleway_async/iam/v1alpha1/api.py +++ b/scaleway-async/scaleway_async/iam/v1alpha1/api.py @@ -26,6 +26,7 @@ ListPoliciesRequestOrderBy, ListQuotaRequestOrderBy, ListSSHKeysRequestOrderBy, + ListScimTokensRequestOrderBy, ListUsersRequestOrderBy, LogAction, LogResourceType, @@ -42,6 +43,7 @@ CreateJWTRequest, CreatePolicyRequest, CreateSSHKeyRequest, + CreateScimTokenResponse, CreateUserRequest, CreateUserRequestMember, EncodedJWT, @@ -62,6 +64,7 @@ ListRulesResponse, ListSSHKeysResponse, ListSamlCertificatesResponse, + ListScimTokensResponse, ListUsersResponse, Log, MFAOTP, @@ -79,6 +82,8 @@ SSHKey, Saml, SamlCertificate, + Scim, + ScimToken, SetGroupMembersRequest, SetOrganizationAliasRequest, SetRulesRequest, @@ -109,6 +114,7 @@ unmarshal_SSHKey, unmarshal_SamlCertificate, unmarshal_User, + unmarshal_CreateScimTokenResponse, unmarshal_EncodedJWT, unmarshal_GetUserConnectionsResponse, unmarshal_InitiateUserConnectionResponse, @@ -124,12 +130,14 @@ unmarshal_ListRulesResponse, unmarshal_ListSSHKeysResponse, unmarshal_ListSamlCertificatesResponse, + unmarshal_ListScimTokensResponse, unmarshal_ListUsersResponse, unmarshal_MFAOTP, unmarshal_Organization, unmarshal_OrganizationSecuritySettings, unmarshal_ParseSamlMetadataResponse, unmarshal_Saml, + unmarshal_Scim, unmarshal_SetRulesResponse, unmarshal_ValidateUserMFAOTPResponse, marshal_AddGroupMemberRequest, @@ -3328,3 +3336,181 @@ async def delete_saml_certificate( ) self._throw_on_error(res) + + async def enable_organization_scim( + self, + *, + organization_id: Optional[str] = None, + ) -> Scim: + """ + :param organization_id: ID of the Organization. + :return: :class:`Scim ` + + Usage: + :: + + result = await api.enable_organization_scim() + """ + + param_organization_id = validate_path_param( + "organization_id", organization_id or self.client.default_organization_id + ) + + res = self._request( + "POST", + f"/iam/v1alpha1/organizations/{param_organization_id}/scim", + body={}, + ) + + self._throw_on_error(res) + return unmarshal_Scim(res.json()) + + async def delete_scim( + self, + *, + scim_id: str, + ) -> None: + """ + :param scim_id: ID of the SCIM configuration. + + Usage: + :: + + result = await api.delete_scim( + scim_id="example", + ) + """ + + param_scim_id = validate_path_param("scim_id", scim_id) + + res = self._request( + "DELETE", + f"/iam/v1alpha1/scim/{param_scim_id}", + ) + + self._throw_on_error(res) + + async def list_scim_tokens( + self, + *, + scim_id: str, + order_by: Optional[ListScimTokensRequestOrderBy] = None, + page: Optional[int] = None, + page_size: Optional[int] = None, + ) -> ListScimTokensResponse: + """ + :param scim_id: ID of the SCIM configuration. + :param order_by: Sort order of SCIM tokens. + :param page: Requested page number. Value must be greater or equal to 1. + :param page_size: Number of items per page. Value must be between 1 and 100. + :return: :class:`ListScimTokensResponse ` + + Usage: + :: + + result = await api.list_scim_tokens( + scim_id="example", + ) + """ + + param_scim_id = validate_path_param("scim_id", scim_id) + + res = self._request( + "GET", + f"/iam/v1alpha1/scim/{param_scim_id}/tokens", + params={ + "order_by": order_by, + "page": page, + "page_size": page_size or self.client.default_page_size, + }, + ) + + self._throw_on_error(res) + return unmarshal_ListScimTokensResponse(res.json()) + + async def list_scim_tokens_all( + self, + *, + scim_id: str, + order_by: Optional[ListScimTokensRequestOrderBy] = None, + page: Optional[int] = None, + page_size: Optional[int] = None, + ) -> list[ScimToken]: + """ + :param scim_id: ID of the SCIM configuration. + :param order_by: Sort order of SCIM tokens. + :param page: Requested page number. Value must be greater or equal to 1. + :param page_size: Number of items per page. Value must be between 1 and 100. + :return: :class:`list[ScimToken] ` + + Usage: + :: + + result = await api.list_scim_tokens_all( + scim_id="example", + ) + """ + + return await fetch_all_pages_async( + type=ListScimTokensResponse, + key="scim_tokens", + fetcher=self.list_scim_tokens, + args={ + "scim_id": scim_id, + "order_by": order_by, + "page": page, + "page_size": page_size, + }, + ) + + async def create_scim_token( + self, + *, + scim_id: str, + ) -> CreateScimTokenResponse: + """ + :param scim_id: ID of the SCIM configuration. + :return: :class:`CreateScimTokenResponse ` + + Usage: + :: + + result = await api.create_scim_token( + scim_id="example", + ) + """ + + param_scim_id = validate_path_param("scim_id", scim_id) + + res = self._request( + "POST", + f"/iam/v1alpha1/scim/{param_scim_id}/tokens", + ) + + self._throw_on_error(res) + return unmarshal_CreateScimTokenResponse(res.json()) + + async def delete_scim_token( + self, + *, + token_id: str, + ) -> None: + """ + :param token_id: The SCIM token ID. + + Usage: + :: + + result = await api.delete_scim_token( + token_id="example", + ) + """ + + param_token_id = validate_path_param("token_id", token_id) + + res = self._request( + "DELETE", + f"/iam/v1alpha1/scim-tokens/{param_token_id}", + ) + + self._throw_on_error(res) diff --git a/scaleway-async/scaleway_async/iam/v1alpha1/marshalling.py b/scaleway-async/scaleway_async/iam/v1alpha1/marshalling.py index ef27c0b35..bbf46155b 100644 --- a/scaleway-async/scaleway_async/iam/v1alpha1/marshalling.py +++ b/scaleway-async/scaleway_async/iam/v1alpha1/marshalling.py @@ -34,6 +34,8 @@ SSHKey, SamlCertificate, User, + ScimToken, + CreateScimTokenResponse, EncodedJWT, ConnectionConnectedOrganization, ConnectionConnectedUser, @@ -55,6 +57,7 @@ ListRulesResponse, ListSSHKeysResponse, ListSamlCertificatesResponse, + ListScimTokensResponse, ListUsersResponse, MFAOTP, Organization, @@ -62,6 +65,7 @@ ParseSamlMetadataResponse, SamlServiceProvider, Saml, + Scim, SetRulesResponse, ValidateUserMFAOTPResponse, AddGroupMemberRequest, @@ -919,6 +923,64 @@ def unmarshal_User(data: Any) -> User: return User(**args) +def unmarshal_ScimToken(data: Any) -> ScimToken: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'ScimToken' failed as data isn't a dictionary." + ) + + args: dict[str, Any] = {} + + field = data.get("id", None) + if field is not None: + args["id"] = field + else: + args["id"] = None + + field = data.get("scim_id", None) + if field is not None: + args["scim_id"] = field + else: + args["scim_id"] = None + + field = data.get("created_at", None) + if field is not None: + args["created_at"] = parser.isoparse(field) if isinstance(field, str) else field + else: + args["created_at"] = None + + field = data.get("expires_at", None) + if field is not None: + args["expires_at"] = parser.isoparse(field) if isinstance(field, str) else field + else: + args["expires_at"] = None + + return ScimToken(**args) + + +def unmarshal_CreateScimTokenResponse(data: Any) -> CreateScimTokenResponse: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'CreateScimTokenResponse' failed as data isn't a dictionary." + ) + + args: dict[str, Any] = {} + + field = data.get("bearer_token", None) + if field is not None: + args["bearer_token"] = field + else: + args["bearer_token"] = None + + field = data.get("token", None) + if field is not None: + args["token"] = unmarshal_ScimToken(field) + else: + args["token"] = None + + return CreateScimTokenResponse(**args) + + def unmarshal_EncodedJWT(data: Any) -> EncodedJWT: if not isinstance(data, dict): raise TypeError( @@ -1476,6 +1538,31 @@ def unmarshal_ListSamlCertificatesResponse(data: Any) -> ListSamlCertificatesRes return ListSamlCertificatesResponse(**args) +def unmarshal_ListScimTokensResponse(data: Any) -> ListScimTokensResponse: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'ListScimTokensResponse' failed as data isn't a dictionary." + ) + + args: dict[str, Any] = {} + + field = data.get("scim_tokens", None) + if field is not None: + args["scim_tokens"] = ( + [unmarshal_ScimToken(v) for v in field] if field is not None else None + ) + else: + args["scim_tokens"] = [] + + field = data.get("total_count", None) + if field is not None: + args["total_count"] = field + else: + args["total_count"] = 0 + + return ListScimTokensResponse(**args) + + def unmarshal_ListUsersResponse(data: Any) -> ListUsersResponse: if not isinstance(data, dict): raise TypeError( @@ -1705,6 +1792,29 @@ def unmarshal_Saml(data: Any) -> Saml: return Saml(**args) +def unmarshal_Scim(data: Any) -> Scim: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'Scim' failed as data isn't a dictionary." + ) + + args: dict[str, Any] = {} + + field = data.get("id", None) + if field is not None: + args["id"] = field + else: + args["id"] = None + + field = data.get("created_at", None) + if field is not None: + args["created_at"] = parser.isoparse(field) if isinstance(field, str) else field + else: + args["created_at"] = None + + return Scim(**args) + + def unmarshal_SetRulesResponse(data: Any) -> SetRulesResponse: if not isinstance(data, dict): raise TypeError( diff --git a/scaleway-async/scaleway_async/iam/v1alpha1/types.py b/scaleway-async/scaleway_async/iam/v1alpha1/types.py index a1f9828cf..8c42611a2 100644 --- a/scaleway-async/scaleway_async/iam/v1alpha1/types.py +++ b/scaleway-async/scaleway_async/iam/v1alpha1/types.py @@ -131,6 +131,14 @@ def __str__(self) -> str: return str(self.value) +class ListScimTokensRequestOrderBy(str, Enum, metaclass=StrEnumMeta): + CREATED_AT_ASC = "created_at_asc" + CREATED_AT_DESC = "created_at_desc" + + def __str__(self) -> str: + return str(self.value) + + class ListUsersRequestOrderBy(str, Enum, metaclass=StrEnumMeta): CREATED_AT_ASC = "created_at_asc" CREATED_AT_DESC = "created_at_desc" @@ -322,6 +330,14 @@ class RuleSpecs: organization_id: Optional[str] = None +@dataclass +class ScimToken: + id: str + scim_id: str + created_at: Optional[datetime] = None + expires_at: Optional[datetime] = None + + @dataclass class CreateUserRequestMember: email: str @@ -1170,6 +1186,27 @@ class CreateSSHKeyRequest: """ +@dataclass +class CreateScimTokenRequest: + scim_id: str + """ + ID of the SCIM configuration. + """ + + +@dataclass +class CreateScimTokenResponse: + bearer_token: str + """ + The Bearer Token to use to authenticate to SCIM endpoints. + """ + + token: Optional[ScimToken] = None + """ + The SCIM token metadata. + """ + + @dataclass class CreateUserMFAOTPRequest: user_id: str @@ -1256,6 +1293,22 @@ class DeleteSamlRequest: """ +@dataclass +class DeleteScimRequest: + scim_id: str + """ + ID of the SCIM configuration. + """ + + +@dataclass +class DeleteScimTokenRequest: + token_id: str + """ + The SCIM token ID. + """ + + @dataclass class DeleteUserMFAOTPRequest: user_id: str @@ -1280,6 +1333,14 @@ class EnableOrganizationSamlRequest: """ +@dataclass +class EnableOrganizationScimRequest: + organization_id: Optional[str] = None + """ + ID of the Organization. + """ + + @dataclass class EncodedJWT: token: str @@ -2010,6 +2071,44 @@ class ListSamlCertificatesResponse: """ +@dataclass +class ListScimTokensRequest: + scim_id: str + """ + ID of the SCIM configuration. + """ + + order_by: Optional[ListScimTokensRequestOrderBy] = ( + ListScimTokensRequestOrderBy.CREATED_AT_ASC + ) + """ + Sort order of SCIM tokens. + """ + + page: Optional[int] = 0 + """ + Requested page number. Value must be greater or equal to 1. + """ + + page_size: Optional[int] = 0 + """ + Number of items per page. Value must be between 1 and 100. + """ + + +@dataclass +class ListScimTokensResponse: + scim_tokens: list[ScimToken] + """ + List of SCIM tokens. + """ + + total_count: int + """ + Total count of SCIM tokens. + """ + + @dataclass class ListUsersRequest: order_by: Optional[ListUsersRequestOrderBy] = ListUsersRequestOrderBy.CREATED_AT_ASC @@ -2210,6 +2309,19 @@ class Saml: """ +@dataclass +class Scim: + id: str + """ + ID of the SCIM configuration. + """ + + created_at: Optional[datetime] = None + """ + Date and time of SCIM configuration creation. + """ + + @dataclass class SetGroupMembersRequest: group_id: str diff --git a/scaleway/scaleway/iam/v1alpha1/__init__.py b/scaleway/scaleway/iam/v1alpha1/__init__.py index 7be116781..195628ca1 100644 --- a/scaleway/scaleway/iam/v1alpha1/__init__.py +++ b/scaleway/scaleway/iam/v1alpha1/__init__.py @@ -11,6 +11,7 @@ from .types import ListPoliciesRequestOrderBy from .types import ListQuotaRequestOrderBy from .types import ListSSHKeysRequestOrderBy +from .types import ListScimTokensRequestOrderBy from .types import ListUsersRequestOrderBy from .types import LocalityType from .types import LogAction @@ -26,6 +27,7 @@ from .types import QuotumLimit from .types import JWT from .types import RuleSpecs +from .types import ScimToken from .types import CreateUserRequestMember from .types import Connection from .types import APIKey @@ -51,6 +53,8 @@ from .types import CreateJWTRequest from .types import CreatePolicyRequest from .types import CreateSSHKeyRequest +from .types import CreateScimTokenRequest +from .types import CreateScimTokenResponse from .types import CreateUserMFAOTPRequest from .types import CreateUserRequest from .types import DeleteAPIKeyRequest @@ -61,9 +65,12 @@ from .types import DeleteSSHKeyRequest from .types import DeleteSamlCertificateRequest from .types import DeleteSamlRequest +from .types import DeleteScimRequest +from .types import DeleteScimTokenRequest from .types import DeleteUserMFAOTPRequest from .types import DeleteUserRequest from .types import EnableOrganizationSamlRequest +from .types import EnableOrganizationScimRequest from .types import EncodedJWT from .types import GetAPIKeyRequest from .types import GetApplicationRequest @@ -106,6 +113,8 @@ from .types import ListSSHKeysResponse from .types import ListSamlCertificatesRequest from .types import ListSamlCertificatesResponse +from .types import ListScimTokensRequest +from .types import ListScimTokensResponse from .types import ListUsersRequest from .types import ListUsersResponse from .types import LockUserRequest @@ -117,6 +126,7 @@ from .types import RemoveGroupMemberRequest from .types import RemoveUserConnectionRequest from .types import Saml +from .types import Scim from .types import SetGroupMembersRequest from .types import SetOrganizationAliasRequest from .types import SetRulesRequest @@ -149,6 +159,7 @@ "ListPoliciesRequestOrderBy", "ListQuotaRequestOrderBy", "ListSSHKeysRequestOrderBy", + "ListScimTokensRequestOrderBy", "ListUsersRequestOrderBy", "LocalityType", "LogAction", @@ -164,6 +175,7 @@ "QuotumLimit", "JWT", "RuleSpecs", + "ScimToken", "CreateUserRequestMember", "Connection", "APIKey", @@ -189,6 +201,8 @@ "CreateJWTRequest", "CreatePolicyRequest", "CreateSSHKeyRequest", + "CreateScimTokenRequest", + "CreateScimTokenResponse", "CreateUserMFAOTPRequest", "CreateUserRequest", "DeleteAPIKeyRequest", @@ -199,9 +213,12 @@ "DeleteSSHKeyRequest", "DeleteSamlCertificateRequest", "DeleteSamlRequest", + "DeleteScimRequest", + "DeleteScimTokenRequest", "DeleteUserMFAOTPRequest", "DeleteUserRequest", "EnableOrganizationSamlRequest", + "EnableOrganizationScimRequest", "EncodedJWT", "GetAPIKeyRequest", "GetApplicationRequest", @@ -244,6 +261,8 @@ "ListSSHKeysResponse", "ListSamlCertificatesRequest", "ListSamlCertificatesResponse", + "ListScimTokensRequest", + "ListScimTokensResponse", "ListUsersRequest", "ListUsersResponse", "LockUserRequest", @@ -255,6 +274,7 @@ "RemoveGroupMemberRequest", "RemoveUserConnectionRequest", "Saml", + "Scim", "SetGroupMembersRequest", "SetOrganizationAliasRequest", "SetRulesRequest", diff --git a/scaleway/scaleway/iam/v1alpha1/api.py b/scaleway/scaleway/iam/v1alpha1/api.py index edcdffcba..e16164951 100644 --- a/scaleway/scaleway/iam/v1alpha1/api.py +++ b/scaleway/scaleway/iam/v1alpha1/api.py @@ -26,6 +26,7 @@ ListPoliciesRequestOrderBy, ListQuotaRequestOrderBy, ListSSHKeysRequestOrderBy, + ListScimTokensRequestOrderBy, ListUsersRequestOrderBy, LogAction, LogResourceType, @@ -42,6 +43,7 @@ CreateJWTRequest, CreatePolicyRequest, CreateSSHKeyRequest, + CreateScimTokenResponse, CreateUserRequest, CreateUserRequestMember, EncodedJWT, @@ -62,6 +64,7 @@ ListRulesResponse, ListSSHKeysResponse, ListSamlCertificatesResponse, + ListScimTokensResponse, ListUsersResponse, Log, MFAOTP, @@ -79,6 +82,8 @@ SSHKey, Saml, SamlCertificate, + Scim, + ScimToken, SetGroupMembersRequest, SetOrganizationAliasRequest, SetRulesRequest, @@ -109,6 +114,7 @@ unmarshal_SSHKey, unmarshal_SamlCertificate, unmarshal_User, + unmarshal_CreateScimTokenResponse, unmarshal_EncodedJWT, unmarshal_GetUserConnectionsResponse, unmarshal_InitiateUserConnectionResponse, @@ -124,12 +130,14 @@ unmarshal_ListRulesResponse, unmarshal_ListSSHKeysResponse, unmarshal_ListSamlCertificatesResponse, + unmarshal_ListScimTokensResponse, unmarshal_ListUsersResponse, unmarshal_MFAOTP, unmarshal_Organization, unmarshal_OrganizationSecuritySettings, unmarshal_ParseSamlMetadataResponse, unmarshal_Saml, + unmarshal_Scim, unmarshal_SetRulesResponse, unmarshal_ValidateUserMFAOTPResponse, marshal_AddGroupMemberRequest, @@ -3328,3 +3336,181 @@ def delete_saml_certificate( ) self._throw_on_error(res) + + def enable_organization_scim( + self, + *, + organization_id: Optional[str] = None, + ) -> Scim: + """ + :param organization_id: ID of the Organization. + :return: :class:`Scim ` + + Usage: + :: + + result = api.enable_organization_scim() + """ + + param_organization_id = validate_path_param( + "organization_id", organization_id or self.client.default_organization_id + ) + + res = self._request( + "POST", + f"/iam/v1alpha1/organizations/{param_organization_id}/scim", + body={}, + ) + + self._throw_on_error(res) + return unmarshal_Scim(res.json()) + + def delete_scim( + self, + *, + scim_id: str, + ) -> None: + """ + :param scim_id: ID of the SCIM configuration. + + Usage: + :: + + result = api.delete_scim( + scim_id="example", + ) + """ + + param_scim_id = validate_path_param("scim_id", scim_id) + + res = self._request( + "DELETE", + f"/iam/v1alpha1/scim/{param_scim_id}", + ) + + self._throw_on_error(res) + + def list_scim_tokens( + self, + *, + scim_id: str, + order_by: Optional[ListScimTokensRequestOrderBy] = None, + page: Optional[int] = None, + page_size: Optional[int] = None, + ) -> ListScimTokensResponse: + """ + :param scim_id: ID of the SCIM configuration. + :param order_by: Sort order of SCIM tokens. + :param page: Requested page number. Value must be greater or equal to 1. + :param page_size: Number of items per page. Value must be between 1 and 100. + :return: :class:`ListScimTokensResponse ` + + Usage: + :: + + result = api.list_scim_tokens( + scim_id="example", + ) + """ + + param_scim_id = validate_path_param("scim_id", scim_id) + + res = self._request( + "GET", + f"/iam/v1alpha1/scim/{param_scim_id}/tokens", + params={ + "order_by": order_by, + "page": page, + "page_size": page_size or self.client.default_page_size, + }, + ) + + self._throw_on_error(res) + return unmarshal_ListScimTokensResponse(res.json()) + + def list_scim_tokens_all( + self, + *, + scim_id: str, + order_by: Optional[ListScimTokensRequestOrderBy] = None, + page: Optional[int] = None, + page_size: Optional[int] = None, + ) -> list[ScimToken]: + """ + :param scim_id: ID of the SCIM configuration. + :param order_by: Sort order of SCIM tokens. + :param page: Requested page number. Value must be greater or equal to 1. + :param page_size: Number of items per page. Value must be between 1 and 100. + :return: :class:`list[ScimToken] ` + + Usage: + :: + + result = api.list_scim_tokens_all( + scim_id="example", + ) + """ + + return fetch_all_pages( + type=ListScimTokensResponse, + key="scim_tokens", + fetcher=self.list_scim_tokens, + args={ + "scim_id": scim_id, + "order_by": order_by, + "page": page, + "page_size": page_size, + }, + ) + + def create_scim_token( + self, + *, + scim_id: str, + ) -> CreateScimTokenResponse: + """ + :param scim_id: ID of the SCIM configuration. + :return: :class:`CreateScimTokenResponse ` + + Usage: + :: + + result = api.create_scim_token( + scim_id="example", + ) + """ + + param_scim_id = validate_path_param("scim_id", scim_id) + + res = self._request( + "POST", + f"/iam/v1alpha1/scim/{param_scim_id}/tokens", + ) + + self._throw_on_error(res) + return unmarshal_CreateScimTokenResponse(res.json()) + + def delete_scim_token( + self, + *, + token_id: str, + ) -> None: + """ + :param token_id: The SCIM token ID. + + Usage: + :: + + result = api.delete_scim_token( + token_id="example", + ) + """ + + param_token_id = validate_path_param("token_id", token_id) + + res = self._request( + "DELETE", + f"/iam/v1alpha1/scim-tokens/{param_token_id}", + ) + + self._throw_on_error(res) diff --git a/scaleway/scaleway/iam/v1alpha1/marshalling.py b/scaleway/scaleway/iam/v1alpha1/marshalling.py index ef27c0b35..bbf46155b 100644 --- a/scaleway/scaleway/iam/v1alpha1/marshalling.py +++ b/scaleway/scaleway/iam/v1alpha1/marshalling.py @@ -34,6 +34,8 @@ SSHKey, SamlCertificate, User, + ScimToken, + CreateScimTokenResponse, EncodedJWT, ConnectionConnectedOrganization, ConnectionConnectedUser, @@ -55,6 +57,7 @@ ListRulesResponse, ListSSHKeysResponse, ListSamlCertificatesResponse, + ListScimTokensResponse, ListUsersResponse, MFAOTP, Organization, @@ -62,6 +65,7 @@ ParseSamlMetadataResponse, SamlServiceProvider, Saml, + Scim, SetRulesResponse, ValidateUserMFAOTPResponse, AddGroupMemberRequest, @@ -919,6 +923,64 @@ def unmarshal_User(data: Any) -> User: return User(**args) +def unmarshal_ScimToken(data: Any) -> ScimToken: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'ScimToken' failed as data isn't a dictionary." + ) + + args: dict[str, Any] = {} + + field = data.get("id", None) + if field is not None: + args["id"] = field + else: + args["id"] = None + + field = data.get("scim_id", None) + if field is not None: + args["scim_id"] = field + else: + args["scim_id"] = None + + field = data.get("created_at", None) + if field is not None: + args["created_at"] = parser.isoparse(field) if isinstance(field, str) else field + else: + args["created_at"] = None + + field = data.get("expires_at", None) + if field is not None: + args["expires_at"] = parser.isoparse(field) if isinstance(field, str) else field + else: + args["expires_at"] = None + + return ScimToken(**args) + + +def unmarshal_CreateScimTokenResponse(data: Any) -> CreateScimTokenResponse: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'CreateScimTokenResponse' failed as data isn't a dictionary." + ) + + args: dict[str, Any] = {} + + field = data.get("bearer_token", None) + if field is not None: + args["bearer_token"] = field + else: + args["bearer_token"] = None + + field = data.get("token", None) + if field is not None: + args["token"] = unmarshal_ScimToken(field) + else: + args["token"] = None + + return CreateScimTokenResponse(**args) + + def unmarshal_EncodedJWT(data: Any) -> EncodedJWT: if not isinstance(data, dict): raise TypeError( @@ -1476,6 +1538,31 @@ def unmarshal_ListSamlCertificatesResponse(data: Any) -> ListSamlCertificatesRes return ListSamlCertificatesResponse(**args) +def unmarshal_ListScimTokensResponse(data: Any) -> ListScimTokensResponse: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'ListScimTokensResponse' failed as data isn't a dictionary." + ) + + args: dict[str, Any] = {} + + field = data.get("scim_tokens", None) + if field is not None: + args["scim_tokens"] = ( + [unmarshal_ScimToken(v) for v in field] if field is not None else None + ) + else: + args["scim_tokens"] = [] + + field = data.get("total_count", None) + if field is not None: + args["total_count"] = field + else: + args["total_count"] = 0 + + return ListScimTokensResponse(**args) + + def unmarshal_ListUsersResponse(data: Any) -> ListUsersResponse: if not isinstance(data, dict): raise TypeError( @@ -1705,6 +1792,29 @@ def unmarshal_Saml(data: Any) -> Saml: return Saml(**args) +def unmarshal_Scim(data: Any) -> Scim: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'Scim' failed as data isn't a dictionary." + ) + + args: dict[str, Any] = {} + + field = data.get("id", None) + if field is not None: + args["id"] = field + else: + args["id"] = None + + field = data.get("created_at", None) + if field is not None: + args["created_at"] = parser.isoparse(field) if isinstance(field, str) else field + else: + args["created_at"] = None + + return Scim(**args) + + def unmarshal_SetRulesResponse(data: Any) -> SetRulesResponse: if not isinstance(data, dict): raise TypeError( diff --git a/scaleway/scaleway/iam/v1alpha1/types.py b/scaleway/scaleway/iam/v1alpha1/types.py index a1f9828cf..8c42611a2 100644 --- a/scaleway/scaleway/iam/v1alpha1/types.py +++ b/scaleway/scaleway/iam/v1alpha1/types.py @@ -131,6 +131,14 @@ def __str__(self) -> str: return str(self.value) +class ListScimTokensRequestOrderBy(str, Enum, metaclass=StrEnumMeta): + CREATED_AT_ASC = "created_at_asc" + CREATED_AT_DESC = "created_at_desc" + + def __str__(self) -> str: + return str(self.value) + + class ListUsersRequestOrderBy(str, Enum, metaclass=StrEnumMeta): CREATED_AT_ASC = "created_at_asc" CREATED_AT_DESC = "created_at_desc" @@ -322,6 +330,14 @@ class RuleSpecs: organization_id: Optional[str] = None +@dataclass +class ScimToken: + id: str + scim_id: str + created_at: Optional[datetime] = None + expires_at: Optional[datetime] = None + + @dataclass class CreateUserRequestMember: email: str @@ -1170,6 +1186,27 @@ class CreateSSHKeyRequest: """ +@dataclass +class CreateScimTokenRequest: + scim_id: str + """ + ID of the SCIM configuration. + """ + + +@dataclass +class CreateScimTokenResponse: + bearer_token: str + """ + The Bearer Token to use to authenticate to SCIM endpoints. + """ + + token: Optional[ScimToken] = None + """ + The SCIM token metadata. + """ + + @dataclass class CreateUserMFAOTPRequest: user_id: str @@ -1256,6 +1293,22 @@ class DeleteSamlRequest: """ +@dataclass +class DeleteScimRequest: + scim_id: str + """ + ID of the SCIM configuration. + """ + + +@dataclass +class DeleteScimTokenRequest: + token_id: str + """ + The SCIM token ID. + """ + + @dataclass class DeleteUserMFAOTPRequest: user_id: str @@ -1280,6 +1333,14 @@ class EnableOrganizationSamlRequest: """ +@dataclass +class EnableOrganizationScimRequest: + organization_id: Optional[str] = None + """ + ID of the Organization. + """ + + @dataclass class EncodedJWT: token: str @@ -2010,6 +2071,44 @@ class ListSamlCertificatesResponse: """ +@dataclass +class ListScimTokensRequest: + scim_id: str + """ + ID of the SCIM configuration. + """ + + order_by: Optional[ListScimTokensRequestOrderBy] = ( + ListScimTokensRequestOrderBy.CREATED_AT_ASC + ) + """ + Sort order of SCIM tokens. + """ + + page: Optional[int] = 0 + """ + Requested page number. Value must be greater or equal to 1. + """ + + page_size: Optional[int] = 0 + """ + Number of items per page. Value must be between 1 and 100. + """ + + +@dataclass +class ListScimTokensResponse: + scim_tokens: list[ScimToken] + """ + List of SCIM tokens. + """ + + total_count: int + """ + Total count of SCIM tokens. + """ + + @dataclass class ListUsersRequest: order_by: Optional[ListUsersRequestOrderBy] = ListUsersRequestOrderBy.CREATED_AT_ASC @@ -2210,6 +2309,19 @@ class Saml: """ +@dataclass +class Scim: + id: str + """ + ID of the SCIM configuration. + """ + + created_at: Optional[datetime] = None + """ + Date and time of SCIM configuration creation. + """ + + @dataclass class SetGroupMembersRequest: group_id: str