From 3cee119eb37fdab26ce039164b9d96db4b5eaeba Mon Sep 17 00:00:00 2001 From: Chuma Umenze Date: Sun, 26 Jun 2022 19:17:45 +0100 Subject: [PATCH] Add typing model definitions --- src/keycloak/connection.py | 45 +- src/keycloak/exceptions.py | 25 +- src/keycloak/keycloak_models.py | 875 ++++++++++++++++++++++++++++++++ src/keycloak/keycloak_openid.py | 109 ++-- src/keycloak/uma_permissions.py | 37 +- src/keycloak/urls_patterns.py | 202 ++++---- 6 files changed, 1118 insertions(+), 175 deletions(-) create mode 100644 src/keycloak/keycloak_models.py diff --git a/src/keycloak/connection.py b/src/keycloak/connection.py index 0757377..4d542aa 100644 --- a/src/keycloak/connection.py +++ b/src/keycloak/connection.py @@ -21,10 +21,12 @@ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +from typing import TYPE_CHECKING, Any, TypeVar, Union, Dict, Optional, List, Iterable + try: from urllib.parse import urljoin except ImportError: - from urlparse import urljoin + from urlparse import urljoin # pytype: disable=import-error import requests from requests.adapters import HTTPAdapter @@ -32,6 +34,10 @@ from requests.adapters import HTTPAdapter from .exceptions import KeycloakConnectionError +if TYPE_CHECKING: + from requests.models import Response + + class ConnectionManager(object): """ Represents a simple server connection. @@ -43,7 +49,14 @@ class ConnectionManager(object): :param proxies: (dict) The proxies servers requests is sent by. """ - def __init__(self, base_url, headers={}, timeout=60, verify=True, proxies=None): + def __init__( + self, + base_url: str, + headers: Optional[Dict[str, str,]] = {}, + timeout: Optional[int] = 60, + verify: Optional[bool] = True, + proxies: Optional[Dict[str, str]] = None + ) -> None: self._base_url = base_url self._headers = headers self._timeout = timeout @@ -65,7 +78,7 @@ class ConnectionManager(object): if proxies: self._s.proxies.update(proxies) - def __del__(self): + def __del__(self) -> None: self._s.close() @property @@ -74,7 +87,7 @@ class ConnectionManager(object): return self._base_url @base_url.setter - def base_url(self, value): + def base_url(self, value: str): """ """ self._base_url = value @@ -84,7 +97,7 @@ class ConnectionManager(object): return self._timeout @timeout.setter - def timeout(self, value): + def timeout(self, value: int): """ """ self._timeout = value @@ -94,7 +107,7 @@ class ConnectionManager(object): return self._verify @verify.setter - def verify(self, value): + def verify(self, value: bool): """ """ self._verify = value @@ -104,11 +117,11 @@ class ConnectionManager(object): return self._headers @headers.setter - def headers(self, value): + def headers(self, value: Dict[str, str]): """ """ self._headers = value - def param_headers(self, key): + def param_headers(self, key: str) -> None: """ Return a specific header parameter. @@ -117,11 +130,11 @@ class ConnectionManager(object): """ return self.headers.get(key) - def clean_headers(self): + def clean_headers(self) -> None: """Clear header parameters.""" self.headers = {} - def exist_param_headers(self, key): + def exist_param_headers(self, key: str) -> bool: """Check if the parameter exists in the header. :param key: (str) Header parameters key. @@ -129,7 +142,7 @@ class ConnectionManager(object): """ return self.param_headers(key) is not None - def add_param_headers(self, key, value): + def add_param_headers(self, key: str, value: str) -> None: """Add a single parameter inside the header. :param key: (str) Header parameters key. @@ -137,14 +150,14 @@ class ConnectionManager(object): """ self.headers[key] = value - def del_param_headers(self, key): + def del_param_headers(self, key: str) -> None: """Remove a specific parameter. :param key: (str) Key of the header parameters. """ self.headers.pop(key, None) - def raw_get(self, path, **kwargs): + def raw_get(self, path: str, **kwargs) -> "Response": """Submit get request to the path. :param path: (str) Path for request. @@ -163,7 +176,7 @@ class ConnectionManager(object): except Exception as e: raise KeycloakConnectionError("Can't connect to server (%s)" % e) - def raw_post(self, path, data, **kwargs): + def raw_post(self, path: str, data: Dict, **kwargs) -> "Response": """Submit post request to the path. :param path: (str) Path for request. @@ -183,7 +196,7 @@ class ConnectionManager(object): except Exception as e: raise KeycloakConnectionError("Can't connect to server (%s)" % e) - def raw_put(self, path, data, **kwargs): + def raw_put(self, path: str, data: Dict, **kwargs) -> "Response": """Submit put request to the path. :param path: (str) Path for request. @@ -203,7 +216,7 @@ class ConnectionManager(object): except Exception as e: raise KeycloakConnectionError("Can't connect to server (%s)" % e) - def raw_delete(self, path, data={}, **kwargs): + def raw_delete(self, path: str, data: Optional[Dict]={}, **kwargs) -> "Response": """Submit delete request to the path. :param path: (str) Path for request. diff --git a/src/keycloak/exceptions.py b/src/keycloak/exceptions.py index 925c937..9cef1db 100644 --- a/src/keycloak/exceptions.py +++ b/src/keycloak/exceptions.py @@ -21,11 +21,26 @@ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +from typing import TYPE_CHECKING, Type, Union, Dict, Optional + import requests +if TYPE_CHECKING: + from requests import Response + from keycloak.keycloak_models import KeycloakModel + +KeycloakErrorType = Type["KeycloakError"] +KeycloakModelType = Type["KeycloakModel"] +RequestResponseType = Union[Dict, bytes] + class KeycloakError(Exception): - def __init__(self, error_message="", response_code=None, response_body=None): + def __init__( + self, + error_message: Optional[str] = "", + response_code: Optional[int] = None, + response_body: Optional[RequestResponseType] = None + ) -> None: Exception.__init__(self, error_message) @@ -33,7 +48,7 @@ class KeycloakError(Exception): self.response_body = response_body self.error_message = error_message - def __str__(self): + def __str__(self) -> str: if self.response_code is not None: return "{0}: {1}".format(self.response_code, self.error_message) else: @@ -96,7 +111,11 @@ class PermissionDefinitionError(Exception): pass -def raise_error_from_response(response, error, expected_codes=None, skip_exists=False): +def raise_error_from_response( + response: "Response", + error: Union[KeycloakErrorType, Exception, Dict], + expected_codes=None, + skip_exists=False) -> RequestResponseType: if expected_codes is None: expected_codes = [200, 201, 204] diff --git a/src/keycloak/keycloak_models.py b/src/keycloak/keycloak_models.py new file mode 100644 index 0000000..7f53658 --- /dev/null +++ b/src/keycloak/keycloak_models.py @@ -0,0 +1,875 @@ +from enum import Enum +from typing import Optional, List, Dict, Any + +from pydantic import BaseModel, Field, Extra + + +DecisionStrategy = Enum("DecisionStrategy", ["AFFIRMATIVE", "UNANIMOUS", "CONSENSUS"]) +NodeType = Enum("NodeType", ["ARRAY", "BINARY", "BOOLEAN", "MISSING", "NULL", "NUMBER", "OBJECT", "POJO", "STRING"]) +PolicyEnforcementMode = Enum("PolicyEnforcementMode", ["ENFORCING", "PERMISSIVE", "DISABLED"]) +Category = Enum("Category", ["INTERNAL", "ACCESS", "ID", "ADMIN", "USERINFO", "LOGOUT", "AUTHORIZATION_RESPONSE"]) +Logic = Enum("Logic", ["POSITIVE", "NEGATIVE"]) +Use = Enum("Use", ["SIG", "ENC"]) +Policy = Enum("Policy", ["SKIP", "OVERWRITE", "FAIL"]) + + +class KeycloakModel(BaseModel): + + def __getitem__(self, k): + return getattr(self, k) + + def __setitem__(self, k, v): + return setattr(self, k, v) + + def __delitem__(self, k): + return delattr(self, k) + + def __contains__(self, k): + return hasattr(self, k) + + def get(self, k, default=None): + return getattr(self, k, default) + + class Config: + validate_all = True + validate_assignment = True + allow_mutation = False + extra = Extra.allow + smart_union = True + + +class AccessToken(KeycloakModel): + acr: Optional[str] = Field(None, alias="acr") + address: Optional["AddressClaimSet"] = Field(None, alias="address") + allowed_origins: Optional[List[str]] = Field(None, alias="allowed-origins") + at_hash: Optional[str] = Field(None, alias="at_hash") + auth_time: Optional[int] = Field(None, alias="auth_time") + authorization: Optional["AccessTokenAuthorization"] = Field(None, alias="authorization") + azp: Optional[str] = Field(None, alias="azp") + birthdate: Optional[str] = Field(None, alias="birthdate") + c_hash: Optional[str] = Field(None, alias="c_hash") + category: Optional[Category] = Field(None, alias="category") + claims_locales: Optional[str] = Field(None, alias="claims_locales") + cnf: Optional["AccessTokenCertConf"] = Field(None, alias="cnf") + email: Optional[str] = Field(None, alias="email") + email_verified: Optional[bool] = Field(None, alias="email_verified") + exp: Optional[int] = Field(None, alias="exp") + family_name: Optional[str] = Field(None, alias="family_name") + gender: Optional[str] = Field(None, alias="gender") + given_name: Optional[str] = Field(None, alias="given_name") + iat: Optional[int] = Field(None, alias="iat") + iss: Optional[str] = Field(None, alias="iss") + jti: Optional[str] = Field(None, alias="jti") + locale: Optional[str] = Field(None, alias="locale") + middle_name: Optional[str] = Field(None, alias="middle_name") + name: Optional[str] = Field(None, alias="name") + nbf: Optional[int] = Field(None, alias="nbf") + nickname: Optional[str] = Field(None, alias="nickname") + nonce: Optional[str] = Field(None, alias="nonce") + otherClaims: Optional[Dict[Any, Any]] = Field(None, alias="otherClaims") + phone_number: Optional[str] = Field(None, alias="phone_number") + phone_number_verified: Optional[bool] = Field(None, alias="phone_number_verified") + picture: Optional[str] = Field(None, alias="picture") + preferred_username: Optional[str] = Field(None, alias="preferred_username") + profile: Optional[str] = Field(None, alias="profile") + realm_access: Optional["AccessTokenAccess"] = Field(None, alias="realm_access") + s_hash: Optional[str] = Field(None, alias="s_hash") + scope: Optional[str] = Field(None, alias="scope") + session_state: Optional[str] = Field(None, alias="session_state") + sid: Optional[str] = Field(None, alias="sid") + sub: Optional[str] = Field(None, alias="sub") + trusted_certs: Optional[List[str]] = Field(None, alias="trusted-certs") + typ: Optional[str] = Field(None, alias="typ") + updated_at: Optional[int] = Field(None, alias="updated_at") + website: Optional[str] = Field(None, alias="website") + zoneinfo: Optional[str] = Field(None, alias="zoneinfo") + + +class AccessTokenAccess(KeycloakModel): + roles: Optional[List[str]] = Field(None, alias="roles") + verify_caller: Optional[bool] = Field(None, alias="verify_caller") + + +class AccessTokenAuthorization(KeycloakModel): + permissions: Optional[List["Permission"]] = Field(None, alias="permissions") + + +class AccessTokenCertConf(KeycloakModel): + x5t_S256: Optional[str] = Field(None, alias="x5t#S256") + + +class AddressClaimSet(KeycloakModel): + country: Optional[str] = Field(None, alias="country") + formatted: Optional[str] = Field(None, alias="formatted") + locality: Optional[str] = Field(None, alias="locality") + postal_code: Optional[str] = Field(None, alias="postal_code") + region: Optional[str] = Field(None, alias="region") + street_address: Optional[str] = Field(None, alias="street_address") + + +class AuthenticationExecutionExportRepresentation(KeycloakModel): + authenticator: Optional[str] = Field(None, alias="authenticator") + authenticatorConfig: Optional[str] = Field(None, alias="authenticatorConfig") + authenticatorFlow: Optional[bool] = Field(None, alias="authenticatorFlow") + flowAlias: Optional[str] = Field(None, alias="flowAlias") + priority: Optional[int] = Field(None, alias="priority") + requirement: Optional[str] = Field(None, alias="requirement") + userSetupAllowed: Optional[bool] = Field(None, alias="userSetupAllowed") + + +class AuthenticationExecutionInfoRepresentation(KeycloakModel): + alias: Optional[str] = Field(None, alias="alias") + authenticationConfig: Optional[str] = Field(None, alias="authenticationConfig") + authenticationFlow: Optional[bool] = Field(None, alias="authenticationFlow") + configurable: Optional[bool] = Field(None, alias="configurable") + description: Optional[str] = Field(None, alias="description") + displayName: Optional[str] = Field(None, alias="displayName") + flowId: Optional[str] = Field(None, alias="flowId") + id: Optional[str] = Field(None, alias="id") + index: Optional[int] = Field(None, alias="index") + level: Optional[int] = Field(None, alias="level") + providerId: Optional[str] = Field(None, alias="providerId") + requirement: Optional[str] = Field(None, alias="requirement") + requirementChoices: Optional[List[str]] = Field(None, alias="requirementChoices") + + +class AuthenticationExecutionRepresentation(KeycloakModel): + authenticator: Optional[str] = Field(None, alias="authenticator") + authenticatorConfig: Optional[str] = Field(None, alias="authenticatorConfig") + authenticatorFlow: Optional[bool] = Field(None, alias="authenticatorFlow") + flowId: Optional[str] = Field(None, alias="flowId") + id: Optional[str] = Field(None, alias="id") + parentFlow: Optional[str] = Field(None, alias="parentFlow") + priority: Optional[int] = Field(None, alias="priority") + requirement: Optional[str] = Field(None, alias="requirement") + + +class AuthenticationFlowRepresentation(KeycloakModel): + alias: Optional[str] = Field(None, alias="alias") + authenticationExecutions: Optional[List["AuthenticationExecutionExportRepresentation"]] = Field(None, alias="authenticationExecutions") + builtIn: Optional[bool] = Field(None, alias="builtIn") + description: Optional[str] = Field(None, alias="description") + id: Optional[str] = Field(None, alias="id") + providerId: Optional[str] = Field(None, alias="providerId") + topLevel: Optional[bool] = Field(None, alias="topLevel") + + +class AuthenticatorConfigInfoRepresentation(KeycloakModel): + helpText: Optional[str] = Field(None, alias="helpText") + name: Optional[str] = Field(None, alias="name") + properties: Optional[List["ConfigPropertyRepresentation"]] = Field(None, alias="properties") + providerId: Optional[str] = Field(None, alias="providerId") + + +class AuthenticatorConfigRepresentation(KeycloakModel): + alias: Optional[str] = Field(None, alias="alias") + config: Optional[Dict[Any, Any]] = Field(None, alias="config") + id: Optional[str] = Field(None, alias="id") + + +class CertificateRepresentation(KeycloakModel): + certificate: Optional[str] = Field(None, alias="certificate") + kid: Optional[str] = Field(None, alias="kid") + privateKey: Optional[str] = Field(None, alias="privateKey") + publicKey: Optional[str] = Field(None, alias="publicKey") + + +class ClientInitialAccessCreatePresentation(KeycloakModel): + count: Optional[int] = Field(None, alias="count") + expiration: Optional[int] = Field(None, alias="expiration") + + +class ClientInitialAccessPresentation(KeycloakModel): + count: Optional[int] = Field(None, alias="count") + expiration: Optional[int] = Field(None, alias="expiration") + id: Optional[str] = Field(None, alias="id") + remainingCount: Optional[int] = Field(None, alias="remainingCount") + timestamp: Optional[int] = Field(None, alias="timestamp") + token: Optional[str] = Field(None, alias="token") + + +class ClientMappingsRepresentation(KeycloakModel): + client: Optional[str] = Field(None, alias="client") + id: Optional[str] = Field(None, alias="id") + mappings: Optional[List["RoleRepresentation"]] = Field(None, alias="mappings") + + +class ClientPoliciesRepresentation(KeycloakModel): + policies: Optional[List["ClientPolicyRepresentation"]] = Field(None, alias="policies") + + +class ClientPolicyConditionRepresentation(KeycloakModel): + condition: Optional[str] = Field(None, alias="condition") + configuration: Optional["JsonNode"] = Field(None, alias="configuration") + + +class ClientPolicyExecutorRepresentation(KeycloakModel): + configuration: Optional["JsonNode"] = Field(None, alias="configuration") + executor: Optional[str] = Field(None, alias="executor") + + +class ClientPolicyRepresentation(KeycloakModel): + conditions: Optional[List["ClientPolicyConditionRepresentation"]] = Field(None, alias="conditions") + description: Optional[str] = Field(None, alias="description") + enabled: Optional[bool] = Field(None, alias="enabled") + name: Optional[str] = Field(None, alias="name") + profiles: Optional[List[str]] = Field(None, alias="profiles") + + +class ClientProfileRepresentation(KeycloakModel): + description: Optional[str] = Field(None, alias="description") + executors: Optional[List["ClientPolicyExecutorRepresentation"]] = Field(None, alias="executors") + name: Optional[str] = Field(None, alias="name") + + +class ClientProfilesRepresentation(KeycloakModel): + globalProfiles: Optional[List["ClientProfileRepresentation"]] = Field(None, alias="globalProfiles") + profiles: Optional[List["ClientProfileRepresentation"]] = Field(None, alias="profiles") + + +class ClientRepresentation(KeycloakModel): + access: Optional[Dict[Any, Any]] = Field(None, alias="access") + adminUrl: Optional[str] = Field(None, alias="adminUrl") + alwaysDisplayInConsole: Optional[bool] = Field(None, alias="alwaysDisplayInConsole") + attributes: Optional[Dict[Any, Any]] = Field(None, alias="attributes") + authenticationFlowBindingOverrides: Optional[Dict[Any, Any]] = Field(None, alias="authenticationFlowBindingOverrides") + authorizationServicesEnabled: Optional[bool] = Field(None, alias="authorizationServicesEnabled") + authorizationSettings: Optional["ResourceServerRepresentation"] = Field(None, alias="authorizationSettings") + baseUrl: Optional[str] = Field(None, alias="baseUrl") + bearerOnly: Optional[bool] = Field(None, alias="bearerOnly") + clientAuthenticatorType: Optional[str] = Field(None, alias="clientAuthenticatorType") + clientId: Optional[str] = Field(None, alias="clientId") + consentRequired: Optional[bool] = Field(None, alias="consentRequired") + defaultClientScopes: Optional[List[str]] = Field(None, alias="defaultClientScopes") + description: Optional[str] = Field(None, alias="description") + directAccessGrantsEnabled: Optional[bool] = Field(None, alias="directAccessGrantsEnabled") + enabled: Optional[bool] = Field(None, alias="enabled") + frontchannelLogout: Optional[bool] = Field(None, alias="frontchannelLogout") + fullScopeAllowed: Optional[bool] = Field(None, alias="fullScopeAllowed") + id: Optional[str] = Field(None, alias="id") + implicitFlowEnabled: Optional[bool] = Field(None, alias="implicitFlowEnabled") + name: Optional[str] = Field(None, alias="name") + nodeReRegistrationTimeout: Optional[int] = Field(None, alias="nodeReRegistrationTimeout") + notBefore: Optional[int] = Field(None, alias="notBefore") + oauth2DeviceAuthorizationGrantEnabled: Optional[bool] = Field(None, alias="oauth2DeviceAuthorizationGrantEnabled") + optionalClientScopes: Optional[List[str]] = Field(None, alias="optionalClientScopes") + origin: Optional[str] = Field(None, alias="origin") + protocol: Optional[str] = Field(None, alias="protocol") + protocolMappers: Optional[List["ProtocolMapperRepresentation"]] = Field(None, alias="protocolMappers") + publicClient: Optional[bool] = Field(None, alias="publicClient") + redirectUris: Optional[List[str]] = Field(None, alias="redirectUris") + registeredNodes: Optional[Dict[Any, Any]] = Field(None, alias="registeredNodes") + registrationAccessToken: Optional[str] = Field(None, alias="registrationAccessToken") + rootUrl: Optional[str] = Field(None, alias="rootUrl") + secret: Optional[str] = Field(None, alias="secret") + serviceAccountsEnabled: Optional[bool] = Field(None, alias="serviceAccountsEnabled") + standardFlowEnabled: Optional[bool] = Field(None, alias="standardFlowEnabled") + surrogateAuthRequired: Optional[bool] = Field(None, alias="surrogateAuthRequired") + webOrigins: Optional[List[str]] = Field(None, alias="webOrigins") + + +class ClientScopeEvaluateResourceProtocolMapperEvaluationRepresentation(KeycloakModel): + containerId: Optional[str] = Field(None, alias="containerId") + containerName: Optional[str] = Field(None, alias="containerName") + containerType: Optional[str] = Field(None, alias="containerType") + mapperId: Optional[str] = Field(None, alias="mapperId") + mapperName: Optional[str] = Field(None, alias="mapperName") + protocolMapper: Optional[str] = Field(None, alias="protocolMapper") + + +class ClientScopeRepresentation(KeycloakModel): + attributes: Optional[Dict[Any, Any]] = Field(None, alias="attributes") + description: Optional[str] = Field(None, alias="description") + id: Optional[str] = Field(None, alias="id") + name: Optional[str] = Field(None, alias="name") + protocol: Optional[str] = Field(None, alias="protocol") + protocolMappers: Optional[List["ProtocolMapperRepresentation"]] = Field(None, alias="protocolMappers") + + +class ComponentExportRepresentation(KeycloakModel): + config: Optional["MultivaluedHashMap"] = Field(None, alias="config") + id: Optional[str] = Field(None, alias="id") + name: Optional[str] = Field(None, alias="name") + providerId: Optional[str] = Field(None, alias="providerId") + subComponents: Optional["MultivaluedHashMap"] = Field(None, alias="subComponents") + subType: Optional[str] = Field(None, alias="subType") + + +class ComponentRepresentation(KeycloakModel): + config: Optional["MultivaluedHashMap"] = Field(None, alias="config") + id: Optional[str] = Field(None, alias="id") + name: Optional[str] = Field(None, alias="name") + parentId: Optional[str] = Field(None, alias="parentId") + providerId: Optional[str] = Field(None, alias="providerId") + providerType: Optional[str] = Field(None, alias="providerType") + subType: Optional[str] = Field(None, alias="subType") + + +class ConfigPropertyRepresentation(KeycloakModel): + defaultValue: Optional[Dict[Any, Any]] = Field(None, alias="defaultValue") + helpText: Optional[str] = Field(None, alias="helpText") + label: Optional[str] = Field(None, alias="label") + name: Optional[str] = Field(None, alias="name") + options: Optional[List[str]] = Field(None, alias="options") + readOnly: Optional[bool] = Field(None, alias="readOnly") + secret: Optional[bool] = Field(None, alias="secret") + type: Optional[str] = Field(None, alias="type") + + +class CredentialRepresentation(KeycloakModel): + createdDate: Optional[int] = Field(None, alias="createdDate") + credentialData: Optional[str] = Field(None, alias="credentialData") + id: Optional[str] = Field(None, alias="id") + priority: Optional[int] = Field(None, alias="priority") + secretData: Optional[str] = Field(None, alias="secretData") + temporary: Optional[bool] = Field(None, alias="temporary") + type: Optional[str] = Field(None, alias="type") + userLabel: Optional[str] = Field(None, alias="userLabel") + value: Optional[str] = Field(None, alias="value") + + +class FederatedIdentityRepresentation(KeycloakModel): + identityProvider: Optional[str] = Field(None, alias="identityProvider") + userId: Optional[str] = Field(None, alias="userId") + userName: Optional[str] = Field(None, alias="userName") + + +class GlobalRequestResult(KeycloakModel): + failedRequests: Optional[List[str]] = Field(None, alias="failedRequests") + successRequests: Optional[List[str]] = Field(None, alias="successRequests") + + +class GroupRepresentation(KeycloakModel): + access: Optional[Dict[Any, Any]] = Field(None, alias="access") + attributes: Optional[Dict[Any, Any]] = Field(None, alias="attributes") + clientRoles: Optional[Dict[Any, Any]] = Field(None, alias="clientRoles") + id: Optional[str] = Field(None, alias="id") + name: Optional[str] = Field(None, alias="name") + path: Optional[str] = Field(None, alias="path") + realmRoles: Optional[List[str]] = Field(None, alias="realmRoles") + subGroups: Optional[List["GroupRepresentation"]] = Field(None, alias="subGroups") + + +class IDToken(KeycloakModel): + acr: Optional[str] = Field(None, alias="acr") + address: Optional["AddressClaimSet"] = Field(None, alias="address") + at_hash: Optional[str] = Field(None, alias="at_hash") + auth_time: Optional[int] = Field(None, alias="auth_time") + azp: Optional[str] = Field(None, alias="azp") + birthdate: Optional[str] = Field(None, alias="birthdate") + c_hash: Optional[str] = Field(None, alias="c_hash") + category: Optional[Category] = Field(None, alias="category") + claims_locales: Optional[str] = Field(None, alias="claims_locales") + email: Optional[str] = Field(None, alias="email") + email_verified: Optional[bool] = Field(None, alias="email_verified") + exp: Optional[int] = Field(None, alias="exp") + family_name: Optional[str] = Field(None, alias="family_name") + gender: Optional[str] = Field(None, alias="gender") + given_name: Optional[str] = Field(None, alias="given_name") + iat: Optional[int] = Field(None, alias="iat") + iss: Optional[str] = Field(None, alias="iss") + jti: Optional[str] = Field(None, alias="jti") + locale: Optional[str] = Field(None, alias="locale") + middle_name: Optional[str] = Field(None, alias="middle_name") + name: Optional[str] = Field(None, alias="name") + nbf: Optional[int] = Field(None, alias="nbf") + nickname: Optional[str] = Field(None, alias="nickname") + nonce: Optional[str] = Field(None, alias="nonce") + otherClaims: Optional[Dict[Any, Any]] = Field(None, alias="otherClaims") + phone_number: Optional[str] = Field(None, alias="phone_number") + phone_number_verified: Optional[bool] = Field(None, alias="phone_number_verified") + picture: Optional[str] = Field(None, alias="picture") + preferred_username: Optional[str] = Field(None, alias="preferred_username") + profile: Optional[str] = Field(None, alias="profile") + s_hash: Optional[str] = Field(None, alias="s_hash") + session_state: Optional[str] = Field(None, alias="session_state") + sid: Optional[str] = Field(None, alias="sid") + sub: Optional[str] = Field(None, alias="sub") + typ: Optional[str] = Field(None, alias="typ") + updated_at: Optional[int] = Field(None, alias="updated_at") + website: Optional[str] = Field(None, alias="website") + zoneinfo: Optional[str] = Field(None, alias="zoneinfo") + + +class IdentityProviderMapperRepresentation(KeycloakModel): + config: Optional[Dict[Any, Any]] = Field(None, alias="config") + id: Optional[str] = Field(None, alias="id") + identityProviderAlias: Optional[str] = Field(None, alias="identityProviderAlias") + identityProviderMapper: Optional[str] = Field(None, alias="identityProviderMapper") + name: Optional[str] = Field(None, alias="name") + + +class IdentityProviderRepresentation(KeycloakModel): + addReadTokenRoleOnCreate: Optional[bool] = Field(None, alias="addReadTokenRoleOnCreate") + alias: Optional[str] = Field(None, alias="alias") + config: Optional[Dict[Any, Any]] = Field(None, alias="config") + displayName: Optional[str] = Field(None, alias="displayName") + enabled: Optional[bool] = Field(None, alias="enabled") + firstBrokerLoginFlowAlias: Optional[str] = Field(None, alias="firstBrokerLoginFlowAlias") + internalId: Optional[str] = Field(None, alias="internalId") + linkOnly: Optional[bool] = Field(None, alias="linkOnly") + postBrokerLoginFlowAlias: Optional[str] = Field(None, alias="postBrokerLoginFlowAlias") + providerId: Optional[str] = Field(None, alias="providerId") + storeToken: Optional[bool] = Field(None, alias="storeToken") + trustEmail: Optional[bool] = Field(None, alias="trustEmail") + + +class JsonNode(KeycloakModel): + array: Optional[bool] = Field(None, alias="array") + bigDecimal: Optional[bool] = Field(None, alias="bigDecimal") + bigInteger: Optional[bool] = Field(None, alias="bigInteger") + binary: Optional[bool] = Field(None, alias="binary") + boolean: Optional[bool] = Field(None, alias="boolean") + containerNode: Optional[bool] = Field(None, alias="containerNode") + double: Optional[bool] = Field(None, alias="double") + empty: Optional[bool] = Field(None, alias="empty") + float: Optional[bool] = Field(None, alias="float") + floatingPointNumber: Optional[bool] = Field(None, alias="floatingPointNumber") + int: Optional[bool] = Field(None, alias="int") + integralNumber: Optional[bool] = Field(None, alias="integralNumber") + long: Optional[bool] = Field(None, alias="long") + missingNode: Optional[bool] = Field(None, alias="missingNode") + nodeType: Optional[NodeType] = Field(None, alias="nodeType") + null: Optional[bool] = Field(None, alias="null") + number: Optional[bool] = Field(None, alias="number") + object: Optional[bool] = Field(None, alias="object") + pojo: Optional[bool] = Field(None, alias="pojo") + short: Optional[bool] = Field(None, alias="short") + textual: Optional[bool] = Field(None, alias="textual") + valueNode: Optional[bool] = Field(None, alias="valueNode") + + +class KeyStoreConfig(KeycloakModel): + format: Optional[str] = Field(None, alias="format") + keyAlias: Optional[str] = Field(None, alias="keyAlias") + keyPassword: Optional[str] = Field(None, alias="keyPassword") + realmAlias: Optional[str] = Field(None, alias="realmAlias") + realmCertificate: Optional[bool] = Field(None, alias="realmCertificate") + storePassword: Optional[str] = Field(None, alias="storePassword") + + +class KeysMetadataRepresentation(KeycloakModel): + active: Optional[Dict[Any, Any]] = Field(None, alias="active") + keys: Optional[List["KeysMetadataRepresentationKeyMetadataRepresentation"]] = Field(None, alias="keys") + + +class KeysMetadataRepresentationKeyMetadataRepresentation(KeycloakModel): + algorithm: Optional[str] = Field(None, alias="algorithm") + certificate: Optional[str] = Field(None, alias="certificate") + kid: Optional[str] = Field(None, alias="kid") + providerId: Optional[str] = Field(None, alias="providerId") + providerPriority: Optional[int] = Field(None, alias="providerPriority") + publicKey: Optional[str] = Field(None, alias="publicKey") + status: Optional[str] = Field(None, alias="status") + type: Optional[str] = Field(None, alias="type") + use: Optional[Use] = Field(None, alias="use") + + +class ManagementPermissionReference(KeycloakModel): + enabled: Optional[bool] = Field(None, alias="enabled") + resource: Optional[str] = Field(None, alias="resource") + scopePermissions: Optional[Dict[Any, Any]] = Field(None, alias="scopePermissions") + + +class MappingsRepresentation(KeycloakModel): + clientMappings: Optional[Dict[Any, Any]] = Field(None, alias="clientMappings") + realmMappings: Optional[List["RoleRepresentation"]] = Field(None, alias="realmMappings") + + +class MemoryInfoRepresentation(KeycloakModel): + free: Optional[int] = Field(None, alias="free") + freeFormated: Optional[str] = Field(None, alias="freeFormated") + freePercentage: Optional[int] = Field(None, alias="freePercentage") + total: Optional[int] = Field(None, alias="total") + totalFormated: Optional[str] = Field(None, alias="totalFormated") + used: Optional[int] = Field(None, alias="used") + usedFormated: Optional[str] = Field(None, alias="usedFormated") + + +class MultivaluedHashMap(KeycloakModel): + empty: Optional[bool] = Field(None, alias="empty") + loadFactor: Optional[float] = Field(None, alias="loadFactor") + threshold: Optional[int] = Field(None, alias="threshold") + + +class PartialImportRepresentation(KeycloakModel): + clients: Optional[List["ClientRepresentation"]] = Field(None, alias="clients") + groups: Optional[List["GroupRepresentation"]] = Field(None, alias="groups") + identityProviders: Optional[List["IdentityProviderRepresentation"]] = Field(None, alias="identityProviders") + ifResourceExists: Optional[str] = Field(None, alias="ifResourceExists") + policy: Optional[Policy] = Field(None, alias="policy") + roles: Optional["RolesRepresentation"] = Field(None, alias="roles") + users: Optional[List["UserRepresentation"]] = Field(None, alias="users") + + +class PasswordPolicyTypeRepresentation(KeycloakModel): + configType: Optional[str] = Field(None, alias="configType") + defaultValue: Optional[str] = Field(None, alias="defaultValue") + displayName: Optional[str] = Field(None, alias="displayName") + id: Optional[str] = Field(None, alias="id") + multipleSupported: Optional[bool] = Field(None, alias="multipleSupported") + + +class Permission(KeycloakModel): + claims: Optional[Dict[Any, Any]] = Field(None, alias="claims") + rsid: Optional[str] = Field(None, alias="rsid") + rsname: Optional[str] = Field(None, alias="rsname") + scopes: Optional[List[str]] = Field(None, alias="scopes") + + +class PolicyRepresentation(KeycloakModel): + config: Optional[Dict[Any, Any]] = Field(None, alias="config") + decisionStrategy: Optional[DecisionStrategy] = Field(None, alias="decisionStrategy") + description: Optional[str] = Field(None, alias="description") + id: Optional[str] = Field(None, alias="id") + logic: Optional[Logic] = Field(None, alias="logic") + name: Optional[str] = Field(None, alias="name") + owner: Optional[str] = Field(None, alias="owner") + policies: Optional[List[str]] = Field(None, alias="policies") + resources: Optional[List[str]] = Field(None, alias="resources") + resourcesData: Optional[List["ResourceRepresentation"]] = Field(None, alias="resourcesData") + scopes: Optional[List[str]] = Field(None, alias="scopes") + scopesData: Optional[List["ScopeRepresentation"]] = Field(None, alias="scopesData") + type: Optional[str] = Field(None, alias="type") + + +class ProfileInfoRepresentation(KeycloakModel): + disabledFeatures: Optional[List[str]] = Field(None, alias="disabledFeatures") + experimentalFeatures: Optional[List[str]] = Field(None, alias="experimentalFeatures") + name: Optional[str] = Field(None, alias="name") + previewFeatures: Optional[List[str]] = Field(None, alias="previewFeatures") + + +class ProtocolMapperRepresentation(KeycloakModel): + config: Optional[Dict[Any, Any]] = Field(None, alias="config") + id: Optional[str] = Field(None, alias="id") + name: Optional[str] = Field(None, alias="name") + protocol: Optional[str] = Field(None, alias="protocol") + protocolMapper: Optional[str] = Field(None, alias="protocolMapper") + + +class ProviderRepresentation(KeycloakModel): + operationalInfo: Optional[Dict[Any, Any]] = Field(None, alias="operationalInfo") + order: Optional[int] = Field(None, alias="order") + + +class RealmEventsConfigRepresentation(KeycloakModel): + adminEventsDetailsEnabled: Optional[bool] = Field(None, alias="adminEventsDetailsEnabled") + adminEventsEnabled: Optional[bool] = Field(None, alias="adminEventsEnabled") + enabledEventTypes: Optional[List[str]] = Field(None, alias="enabledEventTypes") + eventsEnabled: Optional[bool] = Field(None, alias="eventsEnabled") + eventsExpiration: Optional[int] = Field(None, alias="eventsExpiration") + eventsListeners: Optional[List[str]] = Field(None, alias="eventsListeners") + + +class RealmRepresentation(KeycloakModel): + accessCodeLifespan: Optional[int] = Field(None, alias="accessCodeLifespan") + accessCodeLifespanLogin: Optional[int] = Field(None, alias="accessCodeLifespanLogin") + accessCodeLifespanUserAction: Optional[int] = Field(None, alias="accessCodeLifespanUserAction") + accessTokenLifespan: Optional[int] = Field(None, alias="accessTokenLifespan") + accessTokenLifespanForImplicitFlow: Optional[int] = Field(None, alias="accessTokenLifespanForImplicitFlow") + accountTheme: Optional[str] = Field(None, alias="accountTheme") + actionTokenGeneratedByAdminLifespan: Optional[int] = Field(None, alias="actionTokenGeneratedByAdminLifespan") + actionTokenGeneratedByUserLifespan: Optional[int] = Field(None, alias="actionTokenGeneratedByUserLifespan") + adminEventsDetailsEnabled: Optional[bool] = Field(None, alias="adminEventsDetailsEnabled") + adminEventsEnabled: Optional[bool] = Field(None, alias="adminEventsEnabled") + adminTheme: Optional[str] = Field(None, alias="adminTheme") + attributes: Optional[Dict[Any, Any]] = Field(None, alias="attributes") + authenticationFlows: Optional[List["AuthenticationFlowRepresentation"]] = Field(None, alias="authenticationFlows") + authenticatorConfig: Optional[List["AuthenticatorConfigRepresentation"]] = Field(None, alias="authenticatorConfig") + browserFlow: Optional[str] = Field(None, alias="browserFlow") + browserSecurityHeaders: Optional[Dict[Any, Any]] = Field(None, alias="browserSecurityHeaders") + bruteForceProtected: Optional[bool] = Field(None, alias="bruteForceProtected") + clientAuthenticationFlow: Optional[str] = Field(None, alias="clientAuthenticationFlow") + clientOfflineSessionIdleTimeout: Optional[int] = Field(None, alias="clientOfflineSessionIdleTimeout") + clientOfflineSessionMaxLifespan: Optional[int] = Field(None, alias="clientOfflineSessionMaxLifespan") + clientPolicies: Optional["JsonNode"] = Field(None, alias="clientPolicies") + clientProfiles: Optional["JsonNode"] = Field(None, alias="clientProfiles") + clientScopeMappings: Optional[Dict[Any, Any]] = Field(None, alias="clientScopeMappings") + clientScopes: Optional[List["ClientScopeRepresentation"]] = Field(None, alias="clientScopes") + clientSessionIdleTimeout: Optional[int] = Field(None, alias="clientSessionIdleTimeout") + clientSessionMaxLifespan: Optional[int] = Field(None, alias="clientSessionMaxLifespan") + clients: Optional[List["ClientRepresentation"]] = Field(None, alias="clients") + components: Optional["MultivaluedHashMap"] = Field(None, alias="components") + defaultDefaultClientScopes: Optional[List[str]] = Field(None, alias="defaultDefaultClientScopes") + defaultGroups: Optional[List[str]] = Field(None, alias="defaultGroups") + defaultLocale: Optional[str] = Field(None, alias="defaultLocale") + defaultOptionalClientScopes: Optional[List[str]] = Field(None, alias="defaultOptionalClientScopes") + defaultRole: Optional["RoleRepresentation"] = Field(None, alias="defaultRole") + defaultSignatureAlgorithm: Optional[str] = Field(None, alias="defaultSignatureAlgorithm") + directGrantFlow: Optional[str] = Field(None, alias="directGrantFlow") + displayName: Optional[str] = Field(None, alias="displayName") + displayNameHtml: Optional[str] = Field(None, alias="displayNameHtml") + dockerAuthenticationFlow: Optional[str] = Field(None, alias="dockerAuthenticationFlow") + duplicateEmailsAllowed: Optional[bool] = Field(None, alias="duplicateEmailsAllowed") + editUsernameAllowed: Optional[bool] = Field(None, alias="editUsernameAllowed") + emailTheme: Optional[str] = Field(None, alias="emailTheme") + enabled: Optional[bool] = Field(None, alias="enabled") + enabledEventTypes: Optional[List[str]] = Field(None, alias="enabledEventTypes") + eventsEnabled: Optional[bool] = Field(None, alias="eventsEnabled") + eventsExpiration: Optional[int] = Field(None, alias="eventsExpiration") + eventsListeners: Optional[List[str]] = Field(None, alias="eventsListeners") + failureFactor: Optional[int] = Field(None, alias="failureFactor") + federatedUsers: Optional[List["UserRepresentation"]] = Field(None, alias="federatedUsers") + groups: Optional[List["GroupRepresentation"]] = Field(None, alias="groups") + id: Optional[str] = Field(None, alias="id") + identityProviderMappers: Optional[List["IdentityProviderMapperRepresentation"]] = Field(None, alias="identityProviderMappers") + identityProviders: Optional[List["IdentityProviderRepresentation"]] = Field(None, alias="identityProviders") + internationalizationEnabled: Optional[bool] = Field(None, alias="internationalizationEnabled") + keycloakVersion: Optional[str] = Field(None, alias="keycloakVersion") + loginTheme: Optional[str] = Field(None, alias="loginTheme") + loginWithEmailAllowed: Optional[bool] = Field(None, alias="loginWithEmailAllowed") + maxDeltaTimeSeconds: Optional[int] = Field(None, alias="maxDeltaTimeSeconds") + maxFailureWaitSeconds: Optional[int] = Field(None, alias="maxFailureWaitSeconds") + minimumQuickLoginWaitSeconds: Optional[int] = Field(None, alias="minimumQuickLoginWaitSeconds") + notBefore: Optional[int] = Field(None, alias="notBefore") + oAuth2DeviceCodeLifespan: Optional[int] = Field(None, alias="oAuth2DeviceCodeLifespan") + oAuth2DevicePollingInterval: Optional[int] = Field(None, alias="oAuth2DevicePollingInterval") + oauth2DeviceCodeLifespan: Optional[int] = Field(None, alias="oauth2DeviceCodeLifespan") + oauth2DevicePollingInterval: Optional[int] = Field(None, alias="oauth2DevicePollingInterval") + offlineSessionIdleTimeout: Optional[int] = Field(None, alias="offlineSessionIdleTimeout") + offlineSessionMaxLifespan: Optional[int] = Field(None, alias="offlineSessionMaxLifespan") + offlineSessionMaxLifespanEnabled: Optional[bool] = Field(None, alias="offlineSessionMaxLifespanEnabled") + otpPolicyAlgorithm: Optional[str] = Field(None, alias="otpPolicyAlgorithm") + otpPolicyDigits: Optional[int] = Field(None, alias="otpPolicyDigits") + otpPolicyInitialCounter: Optional[int] = Field(None, alias="otpPolicyInitialCounter") + otpPolicyLookAheadWindow: Optional[int] = Field(None, alias="otpPolicyLookAheadWindow") + otpPolicyPeriod: Optional[int] = Field(None, alias="otpPolicyPeriod") + otpPolicyType: Optional[str] = Field(None, alias="otpPolicyType") + otpSupportedApplications: Optional[List[str]] = Field(None, alias="otpSupportedApplications") + passwordPolicy: Optional[str] = Field(None, alias="passwordPolicy") + permanentLockout: Optional[bool] = Field(None, alias="permanentLockout") + protocolMappers: Optional[List["ProtocolMapperRepresentation"]] = Field(None, alias="protocolMappers") + quickLoginCheckMilliSeconds: Optional[int] = Field(None, alias="quickLoginCheckMilliSeconds") + realm: Optional[str] = Field(None, alias="realm") + refreshTokenMaxReuse: Optional[int] = Field(None, alias="refreshTokenMaxReuse") + registrationAllowed: Optional[bool] = Field(None, alias="registrationAllowed") + registrationEmailAsUsername: Optional[bool] = Field(None, alias="registrationEmailAsUsername") + registrationFlow: Optional[str] = Field(None, alias="registrationFlow") + rememberMe: Optional[bool] = Field(None, alias="rememberMe") + requiredActions: Optional[List["RequiredActionProviderRepresentation"]] = Field(None, alias="requiredActions") + resetCredentialsFlow: Optional[str] = Field(None, alias="resetCredentialsFlow") + resetPasswordAllowed: Optional[bool] = Field(None, alias="resetPasswordAllowed") + revokeRefreshToken: Optional[bool] = Field(None, alias="revokeRefreshToken") + roles: Optional["RolesRepresentation"] = Field(None, alias="roles") + scopeMappings: Optional[List["ScopeMappingRepresentation"]] = Field(None, alias="scopeMappings") + smtpServer: Optional[Dict[Any, Any]] = Field(None, alias="smtpServer") + sslRequired: Optional[str] = Field(None, alias="sslRequired") + ssoSessionIdleTimeout: Optional[int] = Field(None, alias="ssoSessionIdleTimeout") + ssoSessionIdleTimeoutRememberMe: Optional[int] = Field(None, alias="ssoSessionIdleTimeoutRememberMe") + ssoSessionMaxLifespan: Optional[int] = Field(None, alias="ssoSessionMaxLifespan") + ssoSessionMaxLifespanRememberMe: Optional[int] = Field(None, alias="ssoSessionMaxLifespanRememberMe") + supportedLocales: Optional[List[str]] = Field(None, alias="supportedLocales") + userFederationMappers: Optional[List["UserFederationMapperRepresentation"]] = Field(None, alias="userFederationMappers") + userFederationProviders: Optional[List["UserFederationProviderRepresentation"]] = Field(None, alias="userFederationProviders") + userManagedAccessAllowed: Optional[bool] = Field(None, alias="userManagedAccessAllowed") + users: Optional[List["UserRepresentation"]] = Field(None, alias="users") + verifyEmail: Optional[bool] = Field(None, alias="verifyEmail") + waitIncrementSeconds: Optional[int] = Field(None, alias="waitIncrementSeconds") + webAuthnPolicyAcceptableAaguids: Optional[List[str]] = Field(None, alias="webAuthnPolicyAcceptableAaguids") + webAuthnPolicyAttestationConveyancePreference: Optional[str] = Field(None, alias="webAuthnPolicyAttestationConveyancePreference") + webAuthnPolicyAuthenticatorAttachment: Optional[str] = Field(None, alias="webAuthnPolicyAuthenticatorAttachment") + webAuthnPolicyAvoidSameAuthenticatorRegister: Optional[bool] = Field(None, alias="webAuthnPolicyAvoidSameAuthenticatorRegister") + webAuthnPolicyCreateTimeout: Optional[int] = Field(None, alias="webAuthnPolicyCreateTimeout") + webAuthnPolicyPasswordlessAcceptableAaguids: Optional[List[str]] = Field(None, alias="webAuthnPolicyPasswordlessAcceptableAaguids") + webAuthnPolicyPasswordlessAttestationConveyancePreference: Optional[str] = Field(None, alias="webAuthnPolicyPasswordlessAttestationConveyancePreference") + webAuthnPolicyPasswordlessAuthenticatorAttachment: Optional[str] = Field(None, alias="webAuthnPolicyPasswordlessAuthenticatorAttachment") + webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister: Optional[bool] = Field(None, alias="webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister") + webAuthnPolicyPasswordlessCreateTimeout: Optional[int] = Field(None, alias="webAuthnPolicyPasswordlessCreateTimeout") + webAuthnPolicyPasswordlessRequireResidentKey: Optional[str] = Field(None, alias="webAuthnPolicyPasswordlessRequireResidentKey") + webAuthnPolicyPasswordlessRpEntityName: Optional[str] = Field(None, alias="webAuthnPolicyPasswordlessRpEntityName") + webAuthnPolicyPasswordlessRpId: Optional[str] = Field(None, alias="webAuthnPolicyPasswordlessRpId") + webAuthnPolicyPasswordlessSignatureAlgorithms: Optional[List[str]] = Field(None, alias="webAuthnPolicyPasswordlessSignatureAlgorithms") + webAuthnPolicyPasswordlessUserVerificationRequirement: Optional[str] = Field(None, alias="webAuthnPolicyPasswordlessUserVerificationRequirement") + webAuthnPolicyRequireResidentKey: Optional[str] = Field(None, alias="webAuthnPolicyRequireResidentKey") + webAuthnPolicyRpEntityName: Optional[str] = Field(None, alias="webAuthnPolicyRpEntityName") + webAuthnPolicyRpId: Optional[str] = Field(None, alias="webAuthnPolicyRpId") + webAuthnPolicySignatureAlgorithms: Optional[List[str]] = Field(None, alias="webAuthnPolicySignatureAlgorithms") + webAuthnPolicyUserVerificationRequirement: Optional[str] = Field(None, alias="webAuthnPolicyUserVerificationRequirement") + + +class RequiredActionProviderRepresentation(KeycloakModel): + alias: Optional[str] = Field(None, alias="alias") + config: Optional[Dict[Any, Any]] = Field(None, alias="config") + defaultAction: Optional[bool] = Field(None, alias="defaultAction") + enabled: Optional[bool] = Field(None, alias="enabled") + name: Optional[str] = Field(None, alias="name") + priority: Optional[int] = Field(None, alias="priority") + providerId: Optional[str] = Field(None, alias="providerId") + + +class ResourceRepresentation(KeycloakModel): + id: str = Field(None, alias="id") + attributes: Optional[Dict[Any, Any]] = Field(None, alias="attributes") + displayName: Optional[str] = Field(None, alias="displayName") + icon_uri: Optional[str] = Field(None, alias="icon_uri") + name: Optional[str] = Field(None, alias="name") + ownerManagedAccess: Optional[bool] = Field(None, alias="ownerManagedAccess") + scopes: Optional[List["ScopeRepresentation"]] = Field(None, alias="scopes") + type: Optional[str] = Field(None, alias="type") + uris: Optional[List[str]] = Field(None, alias="uris") + + +class ResourceServerRepresentation(KeycloakModel): + allowRemoteResourceManagement: Optional[bool] = Field(None, alias="allowRemoteResourceManagement") + clientId: Optional[str] = Field(None, alias="clientId") + decisionStrategy: Optional[DecisionStrategy] = Field(None, alias="decisionStrategy") + id: Optional[str] = Field(None, alias="id") + name: Optional[str] = Field(None, alias="name") + policies: Optional[List["PolicyRepresentation"]] = Field(None, alias="policies") + policyEnforcementMode: Optional[PolicyEnforcementMode] = Field(None, alias="policyEnforcementMode") + resources: Optional[List["ResourceRepresentation"]] = Field(None, alias="resources") + scopes: Optional[List["ScopeRepresentation"]] = Field(None, alias="scopes") + + +class RoleRepresentation(KeycloakModel): + attributes: Optional[Dict[Any, Any]] = Field(None, alias="attributes") + clientRole: Optional[bool] = Field(None, alias="clientRole") + composite: Optional[bool] = Field(None, alias="composite") + composites: Optional["RoleRepresentationComposites"] = Field(None, alias="composites") + containerId: Optional[str] = Field(None, alias="containerId") + description: Optional[str] = Field(None, alias="description") + id: Optional[str] = Field(None, alias="id") + name: Optional[str] = Field(None, alias="name") + + +class RoleRepresentationComposites(KeycloakModel): + client: Optional[Dict[Any, Any]] = Field(None, alias="client") + realm: Optional[List[str]] = Field(None, alias="realm") + + +class RolesRepresentation(KeycloakModel): + client: Optional[Dict[Any, Any]] = Field(None, alias="client") + realm: Optional[List["RoleRepresentation"]] = Field(None, alias="realm") + + +class ScopeMappingRepresentation(KeycloakModel): + client: Optional[str] = Field(None, alias="client") + clientScope: Optional[str] = Field(None, alias="clientScope") + roles: Optional[List[str]] = Field(None, alias="roles") + self: Optional[str] = Field(None, alias="self") + + +class ScopeRepresentation(KeycloakModel): + displayName: Optional[str] = Field(None, alias="displayName") + iconUri: Optional[str] = Field(None, alias="iconUri") + id: Optional[str] = Field(None, alias="id") + name: Optional[str] = Field(None, alias="name") + policies: Optional[List["PolicyRepresentation"]] = Field(None, alias="policies") + resources: Optional[List["ResourceRepresentation"]] = Field(None, alias="resources") + + +class ServerInfoRepresentation(KeycloakModel): + builtinProtocolMappers: Optional[Dict[Any, Any]] = Field(None, alias="builtinProtocolMappers") + clientImporters: Optional[List[Dict[Any, Any]]] = Field(None, alias="clientImporters") + clientInstallations: Optional[Dict[Any, Any]] = Field(None, alias="clientInstallations") + componentTypes: Optional[Dict[Any, Any]] = Field(None, alias="componentTypes") + enums: Optional[Dict[Any, Any]] = Field(None, alias="enums") + identityProviders: Optional[List[Dict[Any, Any]]] = Field(None, alias="identityProviders") + memoryInfo: Optional["MemoryInfoRepresentation"] = Field(None, alias="memoryInfo") + passwordPolicies: Optional[List["PasswordPolicyTypeRepresentation"]] = Field(None, alias="passwordPolicies") + profileInfo: Optional["ProfileInfoRepresentation"] = Field(None, alias="profileInfo") + protocolMapperTypes: Optional[Dict[Any, Any]] = Field(None, alias="protocolMapperTypes") + providers: Optional[Dict[Any, Any]] = Field(None, alias="providers") + socialProviders: Optional[List[Dict[Any, Any]]] = Field(None, alias="socialProviders") + systemInfo: Optional["SystemInfoRepresentation"] = Field(None, alias="systemInfo") + themes: Optional[Dict[Any, Any]] = Field(None, alias="themes") + + +class SpiInfoRepresentation(KeycloakModel): + internal: Optional[bool] = Field(None, alias="internal") + providers: Optional[Dict[Any, Any]] = Field(None, alias="providers") + + +class SynchronizationResult(KeycloakModel): + added: Optional[int] = Field(None, alias="added") + failed: Optional[int] = Field(None, alias="failed") + ignored: Optional[bool] = Field(None, alias="ignored") + removed: Optional[int] = Field(None, alias="removed") + status: Optional[str] = Field(None, alias="status") + updated: Optional[int] = Field(None, alias="updated") + + +class SystemInfoRepresentation(KeycloakModel): + fileEncoding: Optional[str] = Field(None, alias="fileEncoding") + javaHome: Optional[str] = Field(None, alias="javaHome") + javaRuntime: Optional[str] = Field(None, alias="javaRuntime") + javaVendor: Optional[str] = Field(None, alias="javaVendor") + javaVersion: Optional[str] = Field(None, alias="javaVersion") + javaVm: Optional[str] = Field(None, alias="javaVm") + javaVmVersion: Optional[str] = Field(None, alias="javaVmVersion") + osArchitecture: Optional[str] = Field(None, alias="osArchitecture") + osName: Optional[str] = Field(None, alias="osName") + osVersion: Optional[str] = Field(None, alias="osVersion") + serverTime: Optional[str] = Field(None, alias="serverTime") + uptime: Optional[str] = Field(None, alias="uptime") + uptimeMillis: Optional[int] = Field(None, alias="uptimeMillis") + userDir: Optional[str] = Field(None, alias="userDir") + userLocale: Optional[str] = Field(None, alias="userLocale") + userName: Optional[str] = Field(None, alias="userName") + userTimezone: Optional[str] = Field(None, alias="userTimezone") + version: Optional[str] = Field(None, alias="version") + + +class TestLdapConnectionRepresentation(KeycloakModel): + action: Optional[str] = Field(None, alias="action") + authType: Optional[str] = Field(None, alias="authType") + bindCredential: Optional[str] = Field(None, alias="bindCredential") + bindDn: Optional[str] = Field(None, alias="bindDn") + componentId: Optional[str] = Field(None, alias="componentId") + connectionTimeout: Optional[str] = Field(None, alias="connectionTimeout") + connectionUrl: Optional[str] = Field(None, alias="connectionUrl") + startTls: Optional[str] = Field(None, alias="startTls") + useTruststoreSpi: Optional[str] = Field(None, alias="useTruststoreSpi") + + +class UserConsentRepresentation(KeycloakModel): + clientId: Optional[str] = Field(None, alias="clientId") + createdDate: Optional[int] = Field(None, alias="createdDate") + grantedClientScopes: Optional[List[str]] = Field(None, alias="grantedClientScopes") + lastUpdatedDate: Optional[int] = Field(None, alias="lastUpdatedDate") + + +class UserFederationMapperRepresentation(KeycloakModel): + config: Optional[Dict[Any, Any]] = Field(None, alias="config") + federationMapperType: Optional[str] = Field(None, alias="federationMapperType") + federationProviderDisplayName: Optional[str] = Field(None, alias="federationProviderDisplayName") + id: Optional[str] = Field(None, alias="id") + name: Optional[str] = Field(None, alias="name") + + +class UserFederationProviderRepresentation(KeycloakModel): + changedSyncPeriod: Optional[int] = Field(None, alias="changedSyncPeriod") + config: Optional[Dict[Any, Any]] = Field(None, alias="config") + displayName: Optional[str] = Field(None, alias="displayName") + fullSyncPeriod: Optional[int] = Field(None, alias="fullSyncPeriod") + id: Optional[str] = Field(None, alias="id") + lastSync: Optional[int] = Field(None, alias="lastSync") + priority: Optional[int] = Field(None, alias="priority") + providerName: Optional[str] = Field(None, alias="providerName") + + +class UserRepresentation(KeycloakModel): + access: Optional[Dict[Any, Any]] = Field(None, alias="access") + attributes: Optional[Dict[Any, Any]] = Field(None, alias="attributes") + clientConsents: Optional[List["UserConsentRepresentation"]] = Field(None, alias="clientConsents") + clientRoles: Optional[Dict[Any, Any]] = Field(None, alias="clientRoles") + createdTimestamp: Optional[int] = Field(None, alias="createdTimestamp") + credentials: Optional[List["CredentialRepresentation"]] = Field(None, alias="credentials") + disableableCredentialTypes: Optional[List[str]] = Field(None, alias="disableableCredentialTypes") + email: Optional[str] = Field(None, alias="email") + emailVerified: Optional[bool] = Field(None, alias="emailVerified") + enabled: Optional[bool] = Field(None, alias="enabled") + federatedIdentities: Optional[List["FederatedIdentityRepresentation"]] = Field(None, alias="federatedIdentities") + federationLink: Optional[str] = Field(None, alias="federationLink") + firstName: Optional[str] = Field(None, alias="firstName") + groups: Optional[List[str]] = Field(None, alias="groups") + id: Optional[str] = Field(None, alias="id") + lastName: Optional[str] = Field(None, alias="lastName") + notBefore: Optional[int] = Field(None, alias="notBefore") + origin: Optional[str] = Field(None, alias="origin") + realmRoles: Optional[List[str]] = Field(None, alias="realmRoles") + requiredActions: Optional[List[str]] = Field(None, alias="requiredActions") + self: Optional[str] = Field(None, alias="self") + serviceAccountClientId: Optional[str] = Field(None, alias="serviceAccountClientId") + username: Optional[str] = Field(None, alias="username") diff --git a/src/keycloak/keycloak_openid.py b/src/keycloak/keycloak_openid.py index 7216b5d..ae2a8a3 100644 --- a/src/keycloak/keycloak_openid.py +++ b/src/keycloak/keycloak_openid.py @@ -23,6 +23,8 @@ import json +from typing import TYPE_CHECKING, Any, TypeVar, Union, Dict, Optional, List, Iterable + from jose import jwt from .authorization import Authorization @@ -49,6 +51,15 @@ from .urls_patterns import ( URL_USERINFO, URL_WELL_KNOWN, ) +from keycloak.uma_permissions import AuthStatus + + +_T0 = TypeVar('_T0', bound=Dict) +R = Union[bytes, dict] + + +if TYPE_CHECKING: + from keycloak.uma_permissions import UMAPermission class KeycloakOpenID: @@ -66,14 +77,14 @@ class KeycloakOpenID: def __init__( self, - server_url, - realm_name, - client_id, - client_secret_key=None, - verify=True, - custom_headers=None, - proxies=None, - timeout=60, + server_url: str, + realm_name: str, + client_id: str, + client_secret_key: Optional[str] = None, + verify: Optional[bool] = True, + custom_headers: Optional[Dict[str, str]] = None, + proxies: Optional[Dict[str, str]] = None, + timeout: Optional[int] = 60, ): self.client_id = client_id self.client_secret_key = client_secret_key @@ -125,7 +136,7 @@ class KeycloakOpenID: def authorization(self, value): self._authorization = value - def _add_secret_key(self, payload): + def _add_secret_key(self, payload: _T0) -> _T0: """ Add secret key if exist. @@ -137,7 +148,7 @@ class KeycloakOpenID: return payload - def _build_name_role(self, role): + def _build_name_role(self, role: str) -> str: """ :param role: @@ -145,7 +156,7 @@ class KeycloakOpenID: """ return self.client_id + "/" + role - def _token_info(self, token, method_token_info, **kwargs): + def _token_info(self, token: str, method_token_info: str, **kwargs) -> Any: """ :param token: @@ -160,7 +171,7 @@ class KeycloakOpenID: return token_info - def well_known(self): + def well_known(self) -> Union[bytes, dict]: """The most important endpoint to understand is the well-known configuration endpoint. It lists endpoints and other configuration options relevant to the OpenID Connect implementation in Keycloak. @@ -173,7 +184,7 @@ class KeycloakOpenID: return raise_error_from_response(data_raw, KeycloakGetError) - def auth_url(self, redirect_uri): + def auth_url(self, redirect_uri) -> str: """ http://openid.net/specs/openid-connect-core-1_0.html#AuthorizationEndpoint @@ -189,14 +200,14 @@ class KeycloakOpenID: def token( self, - username="", - password="", - grant_type=["password"], - code="", - redirect_uri="", - totp=None, + username: Optional[str] = "", + password: Optional[str] = "", + grant_type: Optional[List[str]] = None, + code: Optional[str] = "", + redirect_uri: Optional[str] = "", + totp: Optional[str] = None, **extra - ): + ) -> Union[bytes, dict]: """ The token endpoint is used to obtain tokens. Tokens can either be obtained by exchanging an authorization code or by supplying credentials directly depending on @@ -213,6 +224,7 @@ class KeycloakOpenID: :param totp: :return: """ + grant_type = grant_type or ["password"] params_path = {"realm-name": self.realm_name} payload = { "username": username, @@ -232,7 +244,11 @@ class KeycloakOpenID: data_raw = self.connection.raw_post(URL_TOKEN.format(**params_path), data=payload) return raise_error_from_response(data_raw, KeycloakGetError) - def refresh_token(self, refresh_token, grant_type=["refresh_token"]): + def refresh_token( + self, + refresh_token: str, + grant_type: Optional[List[str]] = None + ) -> Union[bytes, dict]: """ The token endpoint is used to obtain tokens. Tokens can either be obtained by exchanging an authorization code or by supplying credentials directly depending on @@ -245,6 +261,7 @@ class KeycloakOpenID: :param grant_type: :return: """ + grant_type = grant_type or ["refresh_token"] params_path = {"realm-name": self.realm_name} payload = { "client_id": self.client_id, @@ -255,7 +272,7 @@ class KeycloakOpenID: data_raw = self.connection.raw_post(URL_TOKEN.format(**params_path), data=payload) return raise_error_from_response(data_raw, KeycloakGetError) - def exchange_token(self, token: str, client_id: str, audience: str, subject: str) -> dict: + def exchange_token(self, token: str, client_id: str, audience: str, subject: str) -> Union[bytes, dict]: """ Use a token to obtain an entirely different token. See https://www.keycloak.org/docs/latest/securing_apps/index.html#_token-exchange @@ -279,7 +296,7 @@ class KeycloakOpenID: data_raw = self.connection.raw_post(URL_TOKEN.format(**params_path), data=payload) return raise_error_from_response(data_raw, KeycloakGetError) - def userinfo(self, token): + def userinfo(self, token: str) -> Union[bytes, dict]: """ The userinfo endpoint returns standard claims about the authenticated user, and is protected by a bearer token. @@ -297,7 +314,7 @@ class KeycloakOpenID: return raise_error_from_response(data_raw, KeycloakGetError) - def logout(self, refresh_token): + def logout(self, refresh_token: str) -> Union[bytes, dict]: """ The logout endpoint logs out the authenticated user. :param refresh_token: @@ -311,7 +328,7 @@ class KeycloakOpenID: return raise_error_from_response(data_raw, KeycloakGetError, expected_codes=[204]) - def certs(self): + def certs(self) -> Union[bytes, dict]: """ The certificate endpoint returns the public keys enabled by the realm, encoded as a JSON Web Key (JWK). Depending on the realm settings there can be one or more keys enabled @@ -325,7 +342,7 @@ class KeycloakOpenID: data_raw = self.connection.raw_get(URL_CERTS.format(**params_path)) return raise_error_from_response(data_raw, KeycloakGetError) - def public_key(self): + def public_key(self) -> Union[bytes, dict]: """ The public key is exposed by the realm page directly. @@ -335,7 +352,7 @@ class KeycloakOpenID: data_raw = self.connection.raw_get(URL_REALM.format(**params_path)) return raise_error_from_response(data_raw, KeycloakGetError)["public_key"] - def entitlement(self, token, resource_server_id): + def entitlement(self, token: str, resource_server_id: str) -> Union[bytes, dict]: """ Client applications can use a specific endpoint to obtain a special security token called a requesting party token (RPT). This token consists of all the entitlements @@ -354,7 +371,7 @@ class KeycloakOpenID: return raise_error_from_response(data_raw, KeycloakGetError) - def introspect(self, token, rpt=None, token_type_hint=None): + def introspect(self, token: str, rpt: Optional[str] = None, token_type_hint: Optional[str] = None) -> Union[bytes, dict]: """ The introspection endpoint is used to retrieve the active state of a token. It is can only be invoked by confidential clients. @@ -384,7 +401,11 @@ class KeycloakOpenID: return raise_error_from_response(data_raw, KeycloakGetError) - def decode_token(self, token, key, algorithms=["RS256"], **kwargs): + def decode_token( + self, + token: str, + key: str, + algorithms: Optional[Union[str, list]] = None, **kwargs) -> dict: """ A JSON Web Key (JWK) is a JavaScript Object Notation (JSON) data structure that represents a cryptographic key. This specification @@ -400,10 +421,10 @@ class KeycloakOpenID: :param algorithms: :return: """ - + algorithms = algorithms or ["RS256"] return jwt.decode(token, key, algorithms=algorithms, audience=self.client_id, **kwargs) - def load_authorization_config(self, path): + def load_authorization_config(self, path: str) -> None: """ Load Keycloak settings (authorization) @@ -415,11 +436,12 @@ class KeycloakOpenID: self.authorization.load_config(authorization_json) authorization_file.close() - def get_policies(self, token, method_token_info="introspect", **kwargs): + def get_policies(self, token: str, method_token_info: Optional[str] = "introspect", **kwargs) -> Optional[list]: """ Get policies by user token :param token: user token + :param method_token_info: method token info :return: policies list """ @@ -447,7 +469,7 @@ class KeycloakOpenID: return list(set(policies)) - def get_permissions(self, token, method_token_info="introspect", **kwargs): + def get_permissions(self, token: str, method_token_info: Optional[str] = "introspect", **kwargs) -> Optional[list]: """ Get permission by user token @@ -481,7 +503,7 @@ class KeycloakOpenID: return list(set(permissions)) - def uma_permissions(self, token, permissions=""): + def uma_permissions(self, token: str, permissions: Optional[str] = "") -> Union[bytes, dict]: """ Get UMA permissions by user token with requested permissions @@ -510,7 +532,7 @@ class KeycloakOpenID: return raise_error_from_response(data_raw, KeycloakPostError) - def has_uma_access(self, token, permissions): + def has_uma_access(self, token: str, permissions: Union["UMAPermission", str, dict, Iterable[str]]) -> AuthStatus: """ Determine whether user has uma permissions with specified user token @@ -532,14 +554,15 @@ class KeycloakOpenID: ) raise - for resource_struct in granted: - resource = resource_struct["rsname"] - scopes = resource_struct.get("scopes", None) - if not scopes: - needed.discard(resource) - continue - for scope in scopes: - needed.discard("{}#{}".format(resource, scope)) + if isinstance(granted, dict): + for _, resource_struct in granted.items(): + resource = resource_struct["rsname"] + scopes = resource_struct.get("scopes", None) + if not scopes: + needed.discard(resource) + continue + for scope in scopes: + needed.discard("{}#{}".format(resource, scope)) return AuthStatus( is_logged_in=True, is_authorized=len(needed) == 0, missing_permissions=needed diff --git a/src/keycloak/uma_permissions.py b/src/keycloak/uma_permissions.py index 5653c76..64f3a68 100644 --- a/src/keycloak/uma_permissions.py +++ b/src/keycloak/uma_permissions.py @@ -20,6 +20,7 @@ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +from typing import Type, Union, Optional, Set, Tuple, Iterable from keycloak.exceptions import KeycloakPermissionFormatError, PermissionDefinitionError @@ -38,7 +39,12 @@ class UMAPermission: """ - def __init__(self, permission=None, resource="", scope=""): + def __init__( + self, + permission: Optional[Type["UMAPermission"]] = None, + resource: Optional[str] = "", + scope: Optional[str] = "" + ) -> None: self.resource = resource self.scope = scope @@ -52,7 +58,7 @@ class UMAPermission: if permission.scope: self.scope = str(permission.scope) - def __str__(self): + def __str__(self) -> str: scope = self.scope if scope: scope = "#" + scope @@ -67,7 +73,12 @@ class UMAPermission: def __hash__(self) -> int: return hash(str(self)) - def __call__(self, permission=None, resource="", scope="") -> object: + def __call__( + self, + permission: Union["UMAPermission", str, dict, Iterable[str]] = None, + resource: Optional[str] = "", + scope: Optional[str] = "" + ) -> object: result_resource = self.resource result_scope = self.scope @@ -94,7 +105,7 @@ class Resource(UMAPermission): The class itself is callable, and will return the assembled permission. """ - def __init__(self, resource): + def __init__(self, resource: str) -> None: super().__init__(resource=resource) @@ -103,7 +114,7 @@ class Scope(UMAPermission): The class itself is callable, and will return the assembled permission. """ - def __init__(self, scope): + def __init__(self, scope: str) -> None: super().__init__(scope=scope) @@ -112,15 +123,15 @@ class AuthStatus: This has to evaluate to True if and only if the user is properly authorized for the requested resource.""" - def __init__(self, is_logged_in, is_authorized, missing_permissions): + def __init__(self, is_logged_in: bool, is_authorized: bool, missing_permissions: Iterable) -> None: self.is_logged_in = is_logged_in self.is_authorized = is_authorized self.missing_permissions = missing_permissions - def __bool__(self): + def __bool__(self) -> bool: return self.is_authorized - def __repr__(self): + def __repr__(self) -> str: return ( f"AuthStatus(" f"is_authorized={self.is_authorized}, " @@ -129,7 +140,9 @@ class AuthStatus: ) -def build_permission_param(permissions): +def build_permission_param( + permissions: Union["UMAPermission", str, dict, Iterable[str]] +) -> Union[Set[str], Set[Tuple[str]]]: """ Transform permissions to a set, so they are usable for requests @@ -142,13 +155,13 @@ def build_permission_param(permissions): if permissions is None or permissions == "": return set() if isinstance(permissions, str): - return set((permissions,)) + return {permissions} if isinstance(permissions, UMAPermission): - return set((str(permissions),)) + return {str(permissions)} try: # treat as dictionary of permissions result = set() - for resource, scopes in permissions.items(): + for resource, scopes in permissions.items(): # pytype: disable=attribute-error print(f"resource={resource}scopes={scopes}") if scopes is None: result.add(resource) diff --git a/src/keycloak/urls_patterns.py b/src/keycloak/urls_patterns.py index 3ec134c..2b0b095 100644 --- a/src/keycloak/urls_patterns.py +++ b/src/keycloak/urls_patterns.py @@ -22,161 +22,161 @@ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # OPENID URLS -URL_REALM = "realms/{realm-name}" -URL_WELL_KNOWN = "realms/{realm-name}/.well-known/openid-configuration" -URL_TOKEN = "realms/{realm-name}/protocol/openid-connect/token" -URL_USERINFO = "realms/{realm-name}/protocol/openid-connect/userinfo" -URL_LOGOUT = "realms/{realm-name}/protocol/openid-connect/logout" -URL_CERTS = "realms/{realm-name}/protocol/openid-connect/certs" -URL_INTROSPECT = "realms/{realm-name}/protocol/openid-connect/token/introspect" -URL_ENTITLEMENT = "realms/{realm-name}/authz/entitlement/{resource-server-id}" -URL_AUTH = ( +URL_REALM: str = "realms/{realm-name}" +URL_WELL_KNOWN: str = "realms/{realm-name}/.well-known/openid-configuration" +URL_TOKEN: str = "realms/{realm-name}/protocol/openid-connect/token" +URL_USERINFO: str = "realms/{realm-name}/protocol/openid-connect/userinfo" +URL_LOGOUT: str = "realms/{realm-name}/protocol/openid-connect/logout" +URL_CERTS: str = "realms/{realm-name}/protocol/openid-connect/certs" +URL_INTROSPECT: str = "realms/{realm-name}/protocol/openid-connect/token/introspect" +URL_ENTITLEMENT: str = "realms/{realm-name}/authz/entitlement/{resource-server-id}" +URL_AUTH: str = ( "{authorization-endpoint}?client_id={client-id}&response_type=code&redirect_uri={redirect-uri}" ) # ADMIN URLS -URL_ADMIN_USERS = "admin/realms/{realm-name}/users" -URL_ADMIN_USERS_COUNT = "admin/realms/{realm-name}/users/count" -URL_ADMIN_USER = "admin/realms/{realm-name}/users/{id}" -URL_ADMIN_USER_CONSENTS = "admin/realms/{realm-name}/users/{id}/consents" -URL_ADMIN_SEND_UPDATE_ACCOUNT = "admin/realms/{realm-name}/users/{id}/execute-actions-email" -URL_ADMIN_SEND_VERIFY_EMAIL = "admin/realms/{realm-name}/users/{id}/send-verify-email" -URL_ADMIN_RESET_PASSWORD = "admin/realms/{realm-name}/users/{id}/reset-password" -URL_ADMIN_GET_SESSIONS = "admin/realms/{realm-name}/users/{id}/sessions" -URL_ADMIN_USER_CLIENT_ROLES = ( +URL_ADMIN_USERS: str = "admin/realms/{realm-name}/users" +URL_ADMIN_USERS_COUNT: str = "admin/realms/{realm-name}/users/count" +URL_ADMIN_USER: str = "admin/realms/{realm-name}/users/{id}" +URL_ADMIN_USER_CONSENTS: str = "admin/realms/{realm-name}/users/{id}/consents" +URL_ADMIN_SEND_UPDATE_ACCOUNT: str = "admin/realms/{realm-name}/users/{id}/execute-actions-email" +URL_ADMIN_SEND_VERIFY_EMAIL: str = "admin/realms/{realm-name}/users/{id}/send-verify-email" +URL_ADMIN_RESET_PASSWORD: str = "admin/realms/{realm-name}/users/{id}/reset-password" +URL_ADMIN_GET_SESSIONS: str = "admin/realms/{realm-name}/users/{id}/sessions" +URL_ADMIN_USER_CLIENT_ROLES: str = ( "admin/realms/{realm-name}/users/{id}/role-mappings/clients/{client-id}" ) -URL_ADMIN_USER_REALM_ROLES = "admin/realms/{realm-name}/users/{id}/role-mappings/realm" -URL_ADMIN_USER_REALM_ROLES_AVAILABLE = ( +URL_ADMIN_USER_REALM_ROLES: str = "admin/realms/{realm-name}/users/{id}/role-mappings/realm" +URL_ADMIN_USER_REALM_ROLES_AVAILABLE: str = ( "admin/realms/{realm-name}/users/{id}/role-mappings/realm/available" ) -URL_ADMIN_USER_REALM_ROLES_COMPOSITE = ( +URL_ADMIN_USER_REALM_ROLES_COMPOSITE: str = ( "admin/realms/{realm-name}/users/{id}/role-mappings/realm/composite" ) -URL_ADMIN_GROUPS_REALM_ROLES = "admin/realms/{realm-name}/groups/{id}/role-mappings/realm" -URL_ADMIN_GROUPS_CLIENT_ROLES = ( +URL_ADMIN_GROUPS_REALM_ROLES: str = "admin/realms/{realm-name}/groups/{id}/role-mappings/realm" +URL_ADMIN_GROUPS_CLIENT_ROLES: str = ( "admin/realms/{realm-name}/groups/{id}/role-mappings/clients/{client-id}" ) -URL_ADMIN_USER_CLIENT_ROLES_AVAILABLE = ( +URL_ADMIN_USER_CLIENT_ROLES_AVAILABLE: str = ( "admin/realms/{realm-name}/users/{id}/role-mappings/clients/{client-id}/available" ) -URL_ADMIN_USER_CLIENT_ROLES_COMPOSITE = ( +URL_ADMIN_USER_CLIENT_ROLES_COMPOSITE: str = ( "admin/realms/{realm-name}/users/{id}/role-mappings/clients/{client-id}/composite" ) -URL_ADMIN_USER_GROUP = "admin/realms/{realm-name}/users/{id}/groups/{group-id}" -URL_ADMIN_USER_GROUPS = "admin/realms/{realm-name}/users/{id}/groups" -URL_ADMIN_USER_CREDENTIALS = "admin/realms/{realm-name}/users/{id}/credentials" -URL_ADMIN_USER_CREDENTIAL = "admin/realms/{realm-name}/users/{id}/credentials/{credential_id}" -URL_ADMIN_USER_LOGOUT = "admin/realms/{realm-name}/users/{id}/logout" -URL_ADMIN_USER_STORAGE = "admin/realms/{realm-name}/user-storage/{id}/sync" +URL_ADMIN_USER_GROUP: str = "admin/realms/{realm-name}/users/{id}/groups/{group-id}" +URL_ADMIN_USER_GROUPS: str = "admin/realms/{realm-name}/users/{id}/groups" +URL_ADMIN_USER_CREDENTIALS: str = "admin/realms/{realm-name}/users/{id}/credentials" +URL_ADMIN_USER_CREDENTIAL: str = "admin/realms/{realm-name}/users/{id}/credentials/{credential_id}" +URL_ADMIN_USER_LOGOUT: str = "admin/realms/{realm-name}/users/{id}/logout" +URL_ADMIN_USER_STORAGE: str = "admin/realms/{realm-name}/user-storage/{id}/sync" -URL_ADMIN_SERVER_INFO = "admin/serverinfo" +URL_ADMIN_SERVER_INFO: str = "admin/serverinfo" -URL_ADMIN_GROUPS = "admin/realms/{realm-name}/groups" -URL_ADMIN_GROUP = "admin/realms/{realm-name}/groups/{id}" -URL_ADMIN_GROUP_CHILD = "admin/realms/{realm-name}/groups/{id}/children" -URL_ADMIN_GROUP_PERMISSIONS = "admin/realms/{realm-name}/groups/{id}/management/permissions" -URL_ADMIN_GROUP_MEMBERS = "admin/realms/{realm-name}/groups/{id}/members" +URL_ADMIN_GROUPS: str = "admin/realms/{realm-name}/groups" +URL_ADMIN_GROUP: str = "admin/realms/{realm-name}/groups/{id}" +URL_ADMIN_GROUP_CHILD: str = "admin/realms/{realm-name}/groups/{id}/children" +URL_ADMIN_GROUP_PERMISSIONS: str = "admin/realms/{realm-name}/groups/{id}/management/permissions" +URL_ADMIN_GROUP_MEMBERS: str = "admin/realms/{realm-name}/groups/{id}/members" -URL_ADMIN_CLIENTS = "admin/realms/{realm-name}/clients" -URL_ADMIN_CLIENT = URL_ADMIN_CLIENTS + "/{id}" -URL_ADMIN_CLIENT_ALL_SESSIONS = URL_ADMIN_CLIENT + "/user-sessions" -URL_ADMIN_CLIENT_SECRETS = URL_ADMIN_CLIENT + "/client-secret" -URL_ADMIN_CLIENT_ROLES = URL_ADMIN_CLIENT + "/roles" -URL_ADMIN_CLIENT_ROLE = URL_ADMIN_CLIENT + "/roles/{role-name}" -URL_ADMIN_CLIENT_ROLES_COMPOSITE_CLIENT_ROLE = URL_ADMIN_CLIENT_ROLE + "/composites" -URL_ADMIN_CLIENT_ROLE_MEMBERS = URL_ADMIN_CLIENT + "/roles/{role-name}/users" -URL_ADMIN_CLIENT_ROLE_GROUPS = URL_ADMIN_CLIENT + "/roles/{role-name}/groups" -URL_ADMIN_CLIENT_MANAGEMENT_PERMISSIONS = URL_ADMIN_CLIENT + "/management/permissions" +URL_ADMIN_CLIENTS: str = "admin/realms/{realm-name}/clients" +URL_ADMIN_CLIENT: str = URL_ADMIN_CLIENTS + "/{id}" +URL_ADMIN_CLIENT_ALL_SESSIONS: str = URL_ADMIN_CLIENT + "/user-sessions" +URL_ADMIN_CLIENT_SECRETS: str = URL_ADMIN_CLIENT + "/client-secret" +URL_ADMIN_CLIENT_ROLES: str = URL_ADMIN_CLIENT + "/roles" +URL_ADMIN_CLIENT_ROLE: str = URL_ADMIN_CLIENT + "/roles/{role-name}" +URL_ADMIN_CLIENT_ROLES_COMPOSITE_CLIENT_ROLE: str = URL_ADMIN_CLIENT_ROLE + "/composites" +URL_ADMIN_CLIENT_ROLE_MEMBERS: str = URL_ADMIN_CLIENT + "/roles/{role-name}/users" +URL_ADMIN_CLIENT_ROLE_GROUPS: str = URL_ADMIN_CLIENT + "/roles/{role-name}/groups" +URL_ADMIN_CLIENT_MANAGEMENT_PERMISSIONS: str = URL_ADMIN_CLIENT + "/management/permissions" -URL_ADMIN_CLIENT_AUTHZ_SETTINGS = URL_ADMIN_CLIENT + "/authz/resource-server/settings" -URL_ADMIN_CLIENT_AUTHZ_RESOURCES = URL_ADMIN_CLIENT + "/authz/resource-server/resource?max=-1" -URL_ADMIN_CLIENT_AUTHZ_SCOPES = URL_ADMIN_CLIENT + "/authz/resource-server/scope?max=-1" -URL_ADMIN_CLIENT_AUTHZ_PERMISSIONS = URL_ADMIN_CLIENT + "/authz/resource-server/permission?max=-1" -URL_ADMIN_CLIENT_AUTHZ_POLICIES = ( +URL_ADMIN_CLIENT_AUTHZ_SETTINGS: str = URL_ADMIN_CLIENT + "/authz/resource-server/settings" +URL_ADMIN_CLIENT_AUTHZ_RESOURCES: str = URL_ADMIN_CLIENT + "/authz/resource-server/resource?max=-1" +URL_ADMIN_CLIENT_AUTHZ_SCOPES: str = URL_ADMIN_CLIENT + "/authz/resource-server/scope?max=-1" +URL_ADMIN_CLIENT_AUTHZ_PERMISSIONS: str = URL_ADMIN_CLIENT + "/authz/resource-server/permission?max=-1" +URL_ADMIN_CLIENT_AUTHZ_POLICIES: str = ( URL_ADMIN_CLIENT + "/authz/resource-server/policy?max=-1&permission=false" ) -URL_ADMIN_CLIENT_AUTHZ_ROLE_BASED_POLICY = ( +URL_ADMIN_CLIENT_AUTHZ_ROLE_BASED_POLICY: str = ( URL_ADMIN_CLIENT + "/authz/resource-server/policy/role?max=-1" ) -URL_ADMIN_CLIENT_AUTHZ_RESOURCE_BASED_PERMISSION = ( +URL_ADMIN_CLIENT_AUTHZ_RESOURCE_BASED_PERMISSION: str = ( URL_ADMIN_CLIENT + "/authz/resource-server/permission/resource?max=-1" ) -URL_ADMIN_CLIENT_AUTHZ_POLICY_SCOPES = ( +URL_ADMIN_CLIENT_AUTHZ_POLICY_SCOPES: str = ( URL_ADMIN_CLIENT + "/authz/resource-server/policy/{policy-id}/scopes" ) -URL_ADMIN_CLIENT_AUTHZ_POLICY_RESOURCES = ( +URL_ADMIN_CLIENT_AUTHZ_POLICY_RESOURCES: str = ( URL_ADMIN_CLIENT + "/authz/resource-server/policy/{policy-id}/resources" ) -URL_ADMIN_CLIENT_AUTHZ_SCOPE_PERMISSION = ( +URL_ADMIN_CLIENT_AUTHZ_SCOPE_PERMISSION: str = ( URL_ADMIN_CLIENT + "/authz/resource-server/permission/scope/{scope-id}" ) -URL_ADMIN_CLIENT_AUTHZ_CLIENT_POLICY = URL_ADMIN_CLIENT + "/authz/resource-server/policy/client" +URL_ADMIN_CLIENT_AUTHZ_CLIENT_POLICY: str = URL_ADMIN_CLIENT + "/authz/resource-server/policy/client" -URL_ADMIN_CLIENT_SERVICE_ACCOUNT_USER = URL_ADMIN_CLIENT + "/service-account-user" -URL_ADMIN_CLIENT_CERTS = URL_ADMIN_CLIENT + "/certificates/{attr}" -URL_ADMIN_CLIENT_INSTALLATION_PROVIDER = URL_ADMIN_CLIENT + "/installation/providers/{provider-id}" -URL_ADMIN_CLIENT_PROTOCOL_MAPPERS = URL_ADMIN_CLIENT + "/protocol-mappers/models" -URL_ADMIN_CLIENT_PROTOCOL_MAPPER = URL_ADMIN_CLIENT_PROTOCOL_MAPPERS + "/{protocol-mapper-id}" +URL_ADMIN_CLIENT_SERVICE_ACCOUNT_USER: str = URL_ADMIN_CLIENT + "/service-account-user" +URL_ADMIN_CLIENT_CERTS: str = URL_ADMIN_CLIENT + "/certificates/{attr}" +URL_ADMIN_CLIENT_INSTALLATION_PROVIDER: str = URL_ADMIN_CLIENT + "/installation/providers/{provider-id}" +URL_ADMIN_CLIENT_PROTOCOL_MAPPERS: str = URL_ADMIN_CLIENT + "/protocol-mappers/models" +URL_ADMIN_CLIENT_PROTOCOL_MAPPER: str = URL_ADMIN_CLIENT_PROTOCOL_MAPPERS + "/{protocol-mapper-id}" -URL_ADMIN_CLIENT_SCOPES = "admin/realms/{realm-name}/client-scopes" -URL_ADMIN_CLIENT_SCOPE = URL_ADMIN_CLIENT_SCOPES + "/{scope-id}" -URL_ADMIN_CLIENT_SCOPES_ADD_MAPPER = URL_ADMIN_CLIENT_SCOPE + "/protocol-mappers/models" -URL_ADMIN_CLIENT_SCOPES_MAPPERS = URL_ADMIN_CLIENT_SCOPES_ADD_MAPPER + "/{protocol-mapper-id}" +URL_ADMIN_CLIENT_SCOPES: str = "admin/realms/{realm-name}/client-scopes" +URL_ADMIN_CLIENT_SCOPE: str = URL_ADMIN_CLIENT_SCOPES + "/{scope-id}" +URL_ADMIN_CLIENT_SCOPES_ADD_MAPPER: str = URL_ADMIN_CLIENT_SCOPE + "/protocol-mappers/models" +URL_ADMIN_CLIENT_SCOPES_MAPPERS: str = URL_ADMIN_CLIENT_SCOPES_ADD_MAPPER + "/{protocol-mapper-id}" -URL_ADMIN_REALM_ROLES = "admin/realms/{realm-name}/roles" -URL_ADMIN_REALM_ROLES_MEMBERS = URL_ADMIN_REALM_ROLES + "/{role-name}/users" -URL_ADMIN_REALMS = "admin/realms" -URL_ADMIN_REALM = "admin/realms/{realm-name}" -URL_ADMIN_IDPS = "admin/realms/{realm-name}/identity-provider/instances" -URL_ADMIN_IDP_MAPPERS = "admin/realms/{realm-name}/identity-provider/instances/{idp-alias}/mappers" -URL_ADMIN_IDP_MAPPER_UPDATE = URL_ADMIN_IDP_MAPPERS + "/{mapper-id}" -URL_ADMIN_IDP = "admin/realms//{realm-name}/identity-provider/instances/{alias}" -URL_ADMIN_REALM_ROLES_ROLE_BY_NAME = "admin/realms/{realm-name}/roles/{role-name}" -URL_ADMIN_REALM_ROLES_COMPOSITE_REALM_ROLE = ( +URL_ADMIN_REALM_ROLES: str = "admin/realms/{realm-name}/roles" +URL_ADMIN_REALM_ROLES_MEMBERS: str = URL_ADMIN_REALM_ROLES + "/{role-name}/users" +URL_ADMIN_REALMS: str = "admin/realms" +URL_ADMIN_REALM: str = "admin/realms/{realm-name}" +URL_ADMIN_IDPS: str = "admin/realms/{realm-name}/identity-provider/instances" +URL_ADMIN_IDP_MAPPERS: str = "admin/realms/{realm-name}/identity-provider/instances/{idp-alias}/mappers" +URL_ADMIN_IDP_MAPPER_UPDATE: str = URL_ADMIN_IDP_MAPPERS + "/{mapper-id}" +URL_ADMIN_IDP: str = "admin/realms//{realm-name}/identity-provider/instances/{alias}" +URL_ADMIN_REALM_ROLES_ROLE_BY_NAME: str = "admin/realms/{realm-name}/roles/{role-name}" +URL_ADMIN_REALM_ROLES_COMPOSITE_REALM_ROLE: str = ( "admin/realms/{realm-name}/roles/{role-name}/composites" ) -URL_ADMIN_REALM_EXPORT = ( +URL_ADMIN_REALM_EXPORT: str = ( "admin/realms/{realm-name}/partial-export?exportClients={export-clients}&" + "exportGroupsAndRoles={export-groups-and-roles}" ) -URL_ADMIN_DEFAULT_DEFAULT_CLIENT_SCOPES = URL_ADMIN_REALM + "/default-default-client-scopes" -URL_ADMIN_DEFAULT_DEFAULT_CLIENT_SCOPE = URL_ADMIN_DEFAULT_DEFAULT_CLIENT_SCOPES + "/{id}" -URL_ADMIN_DEFAULT_OPTIONAL_CLIENT_SCOPES = URL_ADMIN_REALM + "/default-optional-client-scopes" -URL_ADMIN_DEFAULT_OPTIONAL_CLIENT_SCOPE = URL_ADMIN_DEFAULT_OPTIONAL_CLIENT_SCOPES + "/{id}" +URL_ADMIN_DEFAULT_DEFAULT_CLIENT_SCOPES: str = URL_ADMIN_REALM + "/default-default-client-scopes" +URL_ADMIN_DEFAULT_DEFAULT_CLIENT_SCOPE: str = URL_ADMIN_DEFAULT_DEFAULT_CLIENT_SCOPES + "/{id}" +URL_ADMIN_DEFAULT_OPTIONAL_CLIENT_SCOPES: str = URL_ADMIN_REALM + "/default-optional-client-scopes" +URL_ADMIN_DEFAULT_OPTIONAL_CLIENT_SCOPE: str = URL_ADMIN_DEFAULT_OPTIONAL_CLIENT_SCOPES + "/{id}" -URL_ADMIN_FLOWS = "admin/realms/{realm-name}/authentication/flows" -URL_ADMIN_FLOW = URL_ADMIN_FLOWS + "/{id}" -URL_ADMIN_FLOWS_ALIAS = "admin/realms/{realm-name}/authentication/flows/{flow-id}" -URL_ADMIN_FLOWS_COPY = "admin/realms/{realm-name}/authentication/flows/{flow-alias}/copy" -URL_ADMIN_FLOWS_EXECUTIONS = ( +URL_ADMIN_FLOWS: str = "admin/realms/{realm-name}/authentication/flows" +URL_ADMIN_FLOW: str = URL_ADMIN_FLOWS + "/{id}" +URL_ADMIN_FLOWS_ALIAS: str = "admin/realms/{realm-name}/authentication/flows/{flow-id}" +URL_ADMIN_FLOWS_COPY: str = "admin/realms/{realm-name}/authentication/flows/{flow-alias}/copy" +URL_ADMIN_FLOWS_EXECUTIONS: str = ( "admin/realms/{realm-name}/authentication/flows/{flow-alias}/executions" ) -URL_ADMIN_FLOWS_EXECUTION = "admin/realms/{realm-name}/authentication/executions/{id}" -URL_ADMIN_FLOWS_EXECUTIONS_EXECUTION = ( +URL_ADMIN_FLOWS_EXECUTION: str = "admin/realms/{realm-name}/authentication/executions/{id}" +URL_ADMIN_FLOWS_EXECUTIONS_EXECUTION: str = ( "admin/realms/{realm-name}/authentication/flows/{flow-alias}/executions/execution" ) -URL_ADMIN_FLOWS_EXECUTIONS_FLOW = ( +URL_ADMIN_FLOWS_EXECUTIONS_FLOW: str = ( "admin/realms/{realm-name}/authentication/flows/{flow-alias}/executions/flow" ) -URL_ADMIN_AUTHENTICATOR_PROVIDERS = ( +URL_ADMIN_AUTHENTICATOR_PROVIDERS: str = ( "admin/realms/{realm-name}/authentication/authenticator-providers" ) -URL_ADMIN_AUTHENTICATOR_CONFIG_DESCRIPTION = ( +URL_ADMIN_AUTHENTICATOR_CONFIG_DESCRIPTION: str = ( "admin/realms/{realm-name}/authentication/config-description/{provider-id}" ) -URL_ADMIN_AUTHENTICATOR_CONFIG = "admin/realms/{realm-name}/authentication/config/{id}" +URL_ADMIN_AUTHENTICATOR_CONFIG: str = "admin/realms/{realm-name}/authentication/config/{id}" -URL_ADMIN_COMPONENTS = "admin/realms/{realm-name}/components" -URL_ADMIN_COMPONENT = "admin/realms/{realm-name}/components/{component-id}" -URL_ADMIN_KEYS = "admin/realms/{realm-name}/keys" +URL_ADMIN_COMPONENTS: str = "admin/realms/{realm-name}/components" +URL_ADMIN_COMPONENT: str = "admin/realms/{realm-name}/components/{component-id}" +URL_ADMIN_KEYS: str = "admin/realms/{realm-name}/keys" -URL_ADMIN_USER_FEDERATED_IDENTITIES = "admin/realms/{realm-name}/users/{id}/federated-identity" -URL_ADMIN_USER_FEDERATED_IDENTITY = ( +URL_ADMIN_USER_FEDERATED_IDENTITIES: str = "admin/realms/{realm-name}/users/{id}/federated-identity" +URL_ADMIN_USER_FEDERATED_IDENTITY: str = ( "admin/realms/{realm-name}/users/{id}/federated-identity/{provider}" ) -URL_ADMIN_EVENTS = "admin/realms/{realm-name}/events" -URL_ADMIN_EVENTS_CONFIG = URL_ADMIN_EVENTS + "/config" -URL_ADMIN_CLIENT_SESSION_STATS = "admin/realms/{realm-name}/client-session-stats" +URL_ADMIN_EVENTS: str = "admin/realms/{realm-name}/events" +URL_ADMIN_EVENTS_CONFIG: str = URL_ADMIN_EVENTS + "/config" +URL_ADMIN_CLIENT_SESSION_STATS: str = "admin/realms/{realm-name}/client-session-stats"