
    Vh=k                     |    d dl mZmZmZ eZdZdZdZd dl	m
Z
mZmZmZmZ d dlmZ d Zd Zd	 Zed
k(  r e        yy)    )absolute_importdivisionprint_functionaS1  
module: keycloak_realm

short_description: Allows administration of Keycloak realm using Keycloak API

version_added: 3.0.0

description:
  - This module allows the administration of Keycloak realm using the Keycloak REST API. It requires access to the REST API
    using OpenID Connect; the user connecting and the realm being used must have the requisite access rights. In a default
    Keycloak installation, admin-cli and an admin user would work, as would a separate realm definition with the scope tailored
    to your needs and a user having the expected roles.
  - The names of module options are snake_cased versions of the camelCase ones found in the Keycloak API and its documentation
    at U(https://www.keycloak.org/docs-api/8.0/rest-api/index.html). Aliases are provided so camelCased versions can be used
    as well.
  - The Keycloak API does not always sanity check inputs, for example you can set SAML-specific settings on an OpenID Connect
    client for instance and also the other way around. B(Be careful). If you do not specify a setting, usually a sensible
    default is chosen.
attributes:
  check_mode:
    support: full
  diff_mode:
    support: full
  action_group:
    version_added: 10.2.0

options:
  state:
    description:
      - State of the realm.
      - On V(present), the realm will be created (or updated if it exists already).
      - On V(absent), the realm will be removed if it exists.
    choices: ['present', 'absent']
    default: 'present'
    type: str

  id:
    description:
      - The realm to create.
    type: str
  realm:
    description:
      - The realm name.
    type: str
  access_code_lifespan:
    description:
      - The realm access code lifespan.
    aliases:
      - accessCodeLifespan
    type: int
  access_code_lifespan_login:
    description:
      - The realm access code lifespan login.
    aliases:
      - accessCodeLifespanLogin
    type: int
  access_code_lifespan_user_action:
    description:
      - The realm access code lifespan user action.
    aliases:
      - accessCodeLifespanUserAction
    type: int
  access_token_lifespan:
    description:
      - The realm access token lifespan.
    aliases:
      - accessTokenLifespan
    type: int
  access_token_lifespan_for_implicit_flow:
    description:
      - The realm access token lifespan for implicit flow.
    aliases:
      - accessTokenLifespanForImplicitFlow
    type: int
  account_theme:
    description:
      - The realm account theme.
    aliases:
      - accountTheme
    type: str
  action_token_generated_by_admin_lifespan:
    description:
      - The realm action token generated by admin lifespan.
    aliases:
      - actionTokenGeneratedByAdminLifespan
    type: int
  action_token_generated_by_user_lifespan:
    description:
      - The realm action token generated by user lifespan.
    aliases:
      - actionTokenGeneratedByUserLifespan
    type: int
  admin_events_details_enabled:
    description:
      - The realm admin events details enabled.
    aliases:
      - adminEventsDetailsEnabled
    type: bool
  admin_events_enabled:
    description:
      - The realm admin events enabled.
    aliases:
      - adminEventsEnabled
    type: bool
  admin_theme:
    description:
      - The realm admin theme.
    aliases:
      - adminTheme
    type: str
  attributes:
    description:
      - The realm attributes.
    type: dict
  browser_flow:
    description:
      - The realm browser flow.
    aliases:
      - browserFlow
    type: str
  browser_security_headers:
    description:
      - The realm browser security headers.
    aliases:
      - browserSecurityHeaders
    type: dict
  brute_force_protected:
    description:
      - The realm brute force protected.
    aliases:
      - bruteForceProtected
    type: bool
  client_authentication_flow:
    description:
      - The realm client authentication flow.
    aliases:
      - clientAuthenticationFlow
    type: str
  client_scope_mappings:
    description:
      - The realm client scope mappings.
    aliases:
      - clientScopeMappings
    type: dict
  default_default_client_scopes:
    description:
      - The realm default default client scopes.
    aliases:
      - defaultDefaultClientScopes
    type: list
    elements: str
  default_groups:
    description:
      - The realm default groups.
    aliases:
      - defaultGroups
    type: list
    elements: str
  default_locale:
    description:
      - The realm default locale.
    aliases:
      - defaultLocale
    type: str
  default_optional_client_scopes:
    description:
      - The realm default optional client scopes.
    aliases:
      - defaultOptionalClientScopes
    type: list
    elements: str
  default_roles:
    description:
      - The realm default roles.
    aliases:
      - defaultRoles
    type: list
    elements: str
  default_signature_algorithm:
    description:
      - The realm default signature algorithm.
    aliases:
      - defaultSignatureAlgorithm
    type: str
  direct_grant_flow:
    description:
      - The realm direct grant flow.
    aliases:
      - directGrantFlow
    type: str
  display_name:
    description:
      - The realm display name.
    aliases:
      - displayName
    type: str
  display_name_html:
    description:
      - The realm display name HTML.
    aliases:
      - displayNameHtml
    type: str
  docker_authentication_flow:
    description:
      - The realm docker authentication flow.
    aliases:
      - dockerAuthenticationFlow
    type: str
  duplicate_emails_allowed:
    description:
      - The realm duplicate emails allowed option.
    aliases:
      - duplicateEmailsAllowed
    type: bool
  edit_username_allowed:
    description:
      - The realm edit username allowed option.
    aliases:
      - editUsernameAllowed
    type: bool
  email_theme:
    description:
      - The realm email theme.
    aliases:
      - emailTheme
    type: str
  enabled:
    description:
      - The realm enabled option.
    type: bool
  enabled_event_types:
    description:
      - The realm enabled event types.
    aliases:
      - enabledEventTypes
    type: list
    elements: str
  events_enabled:
    description:
      - Enables or disables login events for this realm.
    aliases:
      - eventsEnabled
    type: bool
    version_added: 3.6.0
  events_expiration:
    description:
      - The realm events expiration.
    aliases:
      - eventsExpiration
    type: int
  events_listeners:
    description:
      - The realm events listeners.
    aliases:
      - eventsListeners
    type: list
    elements: str
  failure_factor:
    description:
      - The realm failure factor.
    aliases:
      - failureFactor
    type: int
  internationalization_enabled:
    description:
      - The realm internationalization enabled option.
    aliases:
      - internationalizationEnabled
    type: bool
  login_theme:
    description:
      - The realm login theme.
    aliases:
      - loginTheme
    type: str
  login_with_email_allowed:
    description:
      - The realm login with email allowed option.
    aliases:
      - loginWithEmailAllowed
    type: bool
  max_delta_time_seconds:
    description:
      - The realm max delta time in seconds.
    aliases:
      - maxDeltaTimeSeconds
    type: int
  max_failure_wait_seconds:
    description:
      - The realm max failure wait in seconds.
    aliases:
      - maxFailureWaitSeconds
    type: int
  minimum_quick_login_wait_seconds:
    description:
      - The realm minimum quick login wait in seconds.
    aliases:
      - minimumQuickLoginWaitSeconds
    type: int
  not_before:
    description:
      - The realm not before.
    aliases:
      - notBefore
    type: int
  offline_session_idle_timeout:
    description:
      - The realm offline session idle timeout.
    aliases:
      - offlineSessionIdleTimeout
    type: int
  offline_session_max_lifespan:
    description:
      - The realm offline session max lifespan.
    aliases:
      - offlineSessionMaxLifespan
    type: int
  offline_session_max_lifespan_enabled:
    description:
      - The realm offline session max lifespan enabled option.
    aliases:
      - offlineSessionMaxLifespanEnabled
    type: bool
  otp_policy_algorithm:
    description:
      - The realm otp policy algorithm.
    aliases:
      - otpPolicyAlgorithm
    type: str
  otp_policy_digits:
    description:
      - The realm otp policy digits.
    aliases:
      - otpPolicyDigits
    type: int
  otp_policy_initial_counter:
    description:
      - The realm otp policy initial counter.
    aliases:
      - otpPolicyInitialCounter
    type: int
  otp_policy_look_ahead_window:
    description:
      - The realm otp policy look ahead window.
    aliases:
      - otpPolicyLookAheadWindow
    type: int
  otp_policy_period:
    description:
      - The realm otp policy period.
    aliases:
      - otpPolicyPeriod
    type: int
  otp_policy_type:
    description:
      - The realm otp policy type.
    aliases:
      - otpPolicyType
    type: str
  otp_supported_applications:
    description:
      - The realm otp supported applications.
    aliases:
      - otpSupportedApplications
    type: list
    elements: str
  password_policy:
    description:
      - The realm password policy.
    aliases:
      - passwordPolicy
    type: str
  organizations_enabled:
    description:
      - Enables support for experimental organization feature.
    aliases:
      - organizationsEnabled
    type: bool
    version_added: 10.0.0
  permanent_lockout:
    description:
      - The realm permanent lockout.
    aliases:
      - permanentLockout
    type: bool
  quick_login_check_milli_seconds:
    description:
      - The realm quick login check in milliseconds.
    aliases:
      - quickLoginCheckMilliSeconds
    type: int
  refresh_token_max_reuse:
    description:
      - The realm refresh token max reuse.
    aliases:
      - refreshTokenMaxReuse
    type: int
  registration_allowed:
    description:
      - The realm registration allowed option.
    aliases:
      - registrationAllowed
    type: bool
  registration_email_as_username:
    description:
      - The realm registration email as username option.
    aliases:
      - registrationEmailAsUsername
    type: bool
  registration_flow:
    description:
      - The realm registration flow.
    aliases:
      - registrationFlow
    type: str
  remember_me:
    description:
      - The realm remember me option.
    aliases:
      - rememberMe
    type: bool
  reset_credentials_flow:
    description:
      - The realm reset credentials flow.
    aliases:
      - resetCredentialsFlow
    type: str
  reset_password_allowed:
    description:
      - The realm reset password allowed option.
    aliases:
      - resetPasswordAllowed
    type: bool
  revoke_refresh_token:
    description:
      - The realm revoke refresh token option.
    aliases:
      - revokeRefreshToken
    type: bool
  smtp_server:
    description:
      - The realm smtp server.
    aliases:
      - smtpServer
    type: dict
  ssl_required:
    description:
      - The realm ssl required option.
    choices: ['all', 'external', 'none']
    aliases:
      - sslRequired
    type: str
  sso_session_idle_timeout:
    description:
      - The realm sso session idle timeout.
    aliases:
      - ssoSessionIdleTimeout
    type: int
  sso_session_idle_timeout_remember_me:
    description:
      - The realm sso session idle timeout remember me.
    aliases:
      - ssoSessionIdleTimeoutRememberMe
    type: int
  sso_session_max_lifespan:
    description:
      - The realm sso session max lifespan.
    aliases:
      - ssoSessionMaxLifespan
    type: int
  sso_session_max_lifespan_remember_me:
    description:
      - The realm sso session max lifespan remember me.
    aliases:
      - ssoSessionMaxLifespanRememberMe
    type: int
  supported_locales:
    description:
      - The realm supported locales.
    aliases:
      - supportedLocales
    type: list
    elements: str
  user_managed_access_allowed:
    description:
      - The realm user managed access allowed option.
    aliases:
      - userManagedAccessAllowed
    type: bool
  verify_email:
    description:
      - The realm verify email option.
    aliases:
      - verifyEmail
    type: bool
  wait_increment_seconds:
    description:
      - The realm wait increment in seconds.
    aliases:
      - waitIncrementSeconds
    type: int

extends_documentation_fragment:
  - community.general.keycloak
  - community.general.keycloak.actiongroup_keycloak
  - community.general.attributes

author:
  - Christophe Gilles (@kris2kris)
aG  
- name: Create or update Keycloak realm (minimal example)
  community.general.keycloak_realm:
    auth_client_id: admin-cli
    auth_keycloak_url: https://auth.example.com/auth
    auth_realm: master
    auth_username: USERNAME
    auth_password: PASSWORD
    realm: unique_realm_name
    state: present

- name: Delete a Keycloak realm
  community.general.keycloak_realm:
    auth_client_id: admin-cli
    auth_keycloak_url: https://auth.example.com/auth
    auth_realm: master
    auth_username: USERNAME
    auth_password: PASSWORD
    realm: unique_realm_name
    state: absent
a  
msg:
  description: Message as to what action was taken.
  returned: always
  type: str
  sample: "Realm testrealm has been updated"

proposed:
  description: Representation of proposed realm.
  returned: always
  type: dict
  sample: {realm: "test"}

existing:
  description: Representation of existing realm (sample is truncated).
  returned: always
  type: dict
  sample: {"adminUrl": "http://www.example.com/admin_url", "attributes": {"request.object.signature.alg": "RS256"}}

end_state:
  description: Representation of realm after module execution (sample is truncated).
  returned: on success
  type: dict
  sample: {"adminUrl": "http://www.example.com/admin_url", "attributes": {"request.object.signature.alg": "RS256"}}
)KeycloakAPIcamelkeycloak_argument_spec	get_tokenKeycloakError)AnsibleModulec                     | j                         } d| v rt        t        | d               | d<   d| v rt        t        | d               | d<   d| v rt        t        | d               | d<   | S )z Re-sorts any properties where the order is important so that diff's is minimised and the change detection is more effective.

    :param realmrep: the realmrep dict to be sanitized
    :return: normalised realmrep dict
    enabledEventTypesotpSupportedApplicationssupportedLocales)copylistsorted)realmreps    t/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/general/plugins/modules/keycloak_realm.pynormalise_crr   @  s}     }}Hh&(,VH=P4Q-R(S$%!X-/3F8D^;_4`/a+,X%'+F8<N3O,P'Q#$O    c                     | j                         }d|v rd|d<   d|v r%d|d   v r|d   j                         |d<   d|d   d<   t        |      S )z Removes probably sensitive details from a realm representation.

    :param realmrep: the realmrep dict to be sanitized
    :return: sanitized realmrep dict
    secretz********
attributeszsaml.signing.private.key)r   r   )r   results     r   sanitize_crr   U  si     ]]_F6%xv%)==#),#7#<#<#>F< ?IF< !;<r   c            
      V   t               } t        di dt        dddg      dt        d      dt        d      d	t        d
dg      dt        d
dg      dt        d
dg      dt        d
dgd      dt        d
dgd      dt        ddg      dt        d
dgd      dt        d
dgd      dt        ddg      d t        dd!g      d"t        dd#g      d$t        d%      d&t        dd'g      d(t        d%d)g      d*t        dd+g      d,t        dd-g      d.t        d%d/g      d0t        d1dd2g3      d4t        d1dd5g3      d6t        dd7g      d8t        d1dd9g3      d:t        d1dd;g3      d<t        dd=g      d>t        dd?g      d@t        ddAg      dBt        ddCg      dDt        ddEg      dFt        ddGg      dHt        ddIg      dJt        ddKg      dLt        d      dMt        d1ddNg3      dOt        ddPg      dQt        d
dRg      dSt        d1ddTg3      dUt        d
dVg      dWt        ddXg      dYt        ddZg      d[t        dd\g      d]t        d
d^g      d_t        d
d`g      dat        d
dbg      dct        d
ddg      det        d
dfg      dgt        d
dhg      dit        ddjg      dkt        ddlg      dmt        d
dng      dot        d
dpg      dqt        d
drg      dst        d
dtg      dut        ddvg      dwt        d1ddxg3      dyt        ddzgd      d{t        dd|g      d}t        dd~g      dt        d
dg      dt        d
dgd      dt        ddg      dt        ddg      dt        ddg      dt        ddg      dt        ddg      dt        ddgd      dt        ddg      dt        d%dg      dt        g ddg      dt        d
dg      dt        d
dg      dt        d
dg      dt        d
dg      dt        d1ddg3      dt        ddg      dt        ddg      dt        d
dg      }| j                  |       t        | dg dg dgg dgddi      }t        ddi i i i       }	 t	        |j
                        }t        |      }|j
                  j                  d      }|j
                  j                  d      }t        t               j                               dgz   }	|j
                  D 
cg c]#  }
|
|	vr|j
                  j                  |
      |
% }}
|j                  |      }|i }i }|D ]+  }|j
                  j                  |      }||t        |      <   - |j                         }|j                  |       t!        |      |d<   t!        |      }||d<   |s|dk(  r=|j"                  rt        dd      |d<   d|d<   i |d<   d|d<    |j$                  di | d|d<   |j"                  rt        dt!        |            |d<   |j&                  r |j$                  di | |j)                  |       |j                  |d         }t!        |      |d<   d|d   z  |d<    |j$                  di | nZ|dk(  rd|d<   |j&                  r^t+        |      }t+        |      }|j"                  r"t        t!        |      t!        |            |d<   ||k7  |d<    |j$                  di | |j-                  ||       |j                  |      }||k(  rd|d<   t!        |      |d<   |j"                  rt        |t!        |            |d<   d|d   z  |d<    |j$                  di | nfd|d<   |j"                  rt        |d      |d<   |j&                  r |j$                  di | |j/                  |       i |d<   i |d<   d|d   z  |d<    |j$                  di | y# t        $ r&}|j                  t        |             Y d}~d}~ww xY wc c}
w )z(
    Module execution

    :return:
    statepresentabsent)defaultchoicesidstr)typerealmaccess_code_lifespanintaccessCodeLifespan)r$   aliasesaccess_code_lifespan_loginaccessCodeLifespanLogin access_code_lifespan_user_actionaccessCodeLifespanUserActionaccess_token_lifespanaccessTokenLifespanF)r$   r)   no_log'access_token_lifespan_for_implicit_flow"accessTokenLifespanForImplicitFlowaccount_themeaccountTheme(action_token_generated_by_admin_lifespan#actionTokenGeneratedByAdminLifespan'action_token_generated_by_user_lifespan"actionTokenGeneratedByUserLifespanadmin_events_details_enabledbooladminEventsDetailsEnabledadmin_events_enabledadminEventsEnabledadmin_theme
adminThemer   dictbrowser_flowbrowserFlowbrowser_security_headersbrowserSecurityHeadersbrute_force_protectedbruteForceProtectedclient_authentication_flowclientAuthenticationFlowclient_scope_mappingsclientScopeMappingsdefault_default_client_scopesr   defaultDefaultClientScopes)r$   elementsr)   default_groupsdefaultGroupsdefault_localedefaultLocaledefault_optional_client_scopesdefaultOptionalClientScopesdefault_rolesdefaultRolesdefault_signature_algorithmdefaultSignatureAlgorithmdirect_grant_flowdirectGrantFlowdisplay_namedisplayNamedisplay_name_htmldisplayNameHtmldocker_authentication_flowdockerAuthenticationFlowduplicate_emails_allowedduplicateEmailsAllowededit_username_allowededitUsernameAllowedemail_theme
emailThemeenabledenabled_event_typesr   events_enabledeventsEnabledevents_expirationeventsExpirationevents_listenerseventsListenersfailure_factorfailureFactorinternationalization_enabledinternationalizationEnabledlogin_theme
loginThemelogin_with_email_allowedloginWithEmailAllowedmax_delta_time_secondsmaxDeltaTimeSecondsmax_failure_wait_secondsmaxFailureWaitSeconds minimum_quick_login_wait_secondsminimumQuickLoginWaitSeconds
not_before	notBeforeoffline_session_idle_timeoutofflineSessionIdleTimeoutoffline_session_max_lifespanofflineSessionMaxLifespan$offline_session_max_lifespan_enabled offlineSessionMaxLifespanEnabledotp_policy_algorithmotpPolicyAlgorithmotp_policy_digitsotpPolicyDigitsotp_policy_initial_counterotpPolicyInitialCounterotp_policy_look_ahead_windowotpPolicyLookAheadWindowotp_policy_periodotpPolicyPeriodotp_policy_typeotpPolicyTypeotp_supported_applicationsr   password_policypasswordPolicyorganizations_enabledorganizationsEnabledpermanent_lockoutpermanentLockoutquick_login_check_milli_secondsquickLoginCheckMilliSecondsrefresh_token_max_reuserefreshTokenMaxReuseregistration_allowedregistrationAllowedregistration_email_as_usernameregistrationEmailAsUsernameregistration_flowregistrationFlowremember_me
rememberMereset_credentials_flowresetCredentialsFlowreset_password_allowedresetPasswordAllowedrevoke_refresh_tokenrevokeRefreshTokensmtp_server
smtpServerssl_required)externalallnonesslRequired)r!   r)   sso_session_idle_timeoutssoSessionIdleTimeout$sso_session_idle_timeout_remember_messoSessionIdleTimeoutRememberMesso_session_max_lifespanssoSessionMaxLifespan$sso_session_max_lifespan_remember_messoSessionMaxLifespanRememberMesupported_localesr   user_managed_access_alloweduserManagedAccessAllowedverify_emailverifyEmailwait_increment_secondswaitIncrementSecondsT)r"   r%   rf   )token
auth_realmauth_usernameauth_password)r   r   r   refresh_tokenr   )argument_specsupports_check_moderequired_one_ofrequired_togetherrequired_by )changedmsgdiffproposedexisting	end_state)r   N)r%   r   r   )beforeafterr   r   r   z$Realm does not exist, doing nothing.r   zRealm %s has been created.zRealm %s has been updated.zRealm %s has been deleted. )r   r@   updater   r	   paramsr
   	fail_jsonr#   r   getr   keysget_realm_by_idr   r   r   _diff	exit_json
check_modecreate_realmr   update_realmdelete_realm)r   	meta_argsmoduler   connection_headerekcr%   r   params_to_ignorexrealm_paramsbefore_realm	changesetrealm_paramnew_param_valuedesired_realmbefore_realm_sanitizedafter_realmbefore_normdesired_norms                        r   mainr   e  si    +,M P9y(.CDP UP 	P
 "u7K6LMP $(U=V<W#XP *.5CaBb)cP #8M7NW\]P 15%JnIox}0~P /?@P 265KpJqz  2AP 15%JnIox}0~P &*v@[?\%]P "v8L7MNP el^<P  V$!P" u}o>#P$ "&6<T;U!V%P& #9N8OP'P( $(U=W<X#Y)P* #9N8OP+P, '+QmPn&o-P. %/ARS/P0 0AB1P2 (,%RoQp'q3P4 @PQ5P6 %)e>Y=Z$[7P8 E4E3FG9P: u}o>;P< E4E3FG=P> $(U=W<X#Y?P@ "&6<T;U!VAPB #9N8OPCPD el^<EPF &!GPH !fuGZF[\IPJ /1BCKPL E4F3GHMPN 6EDUCVWOPP 0ABQPR &*v@]?^%_SPT el^<UPV "&6<S;T!UWPX  $9N8OPYPZ "&5;R:S!T[P\ *.5CaBb)c]P^ U[M:_P` &*u?Z>[%\aPb &*u?Z>[%\cPd .2vHjGk-lePf "u7K6LMgPh E4E3FGiPj $(U=V<W#XkPl &*u?Y>Z%[mPn E4E3FGoPp %/1BCqPr $(VeNhMi#jsPt %2B1CERuPv #9O8PQwPx F5G4HIyPz )-%B_A`(a{P| !%%:P9QZ_ `}P~ "v8M7NOP@ (,B_A`'aAPB E4F3GHCPD f|n=EPF  $9O8PQGPH  $:P9QZ_`IPJ "v8L7MNKPL f|n=MPN "=WOPP "&5;R:S!TQPR .2uGhFi-jSPT "&5;R:S!TUPV .2uGhFi-jWPX FUEWDXYYPZ %)f?Y>Z$[[P\ v?]P^  $9O8PQ_PId #/3-G-f-h/_.`(7'FF %Rb2VXYF%%fmm4 
V.	/BMMg&EMMg&E 2499;<yH  &}} 6! 00MM%%a(4  6L 6
 %%E%2L I# 8 --++K8(7	%$%8
 !%%'M#$Y/F:(6/F: H||!%Rr!:v %F9"$F;BF5MF&v& !y<<!;}3MNF6NF&v& 	&((w)?@)+6{4}W7MMu"6" I !%F9  *<8+M:<<%)[1I0;L0I&KF6N%0L%@y!   *6* OOMO7,,5,9K{*$)y!"-k":F;||!%-C,7,D"Fv 9=;QQF5MF&v& !%F9||!%-C2!Nv     *6* OO%O(!#F:"$F;8<;PPF5MFvm  %SV$$%6s   .a4 8(b&4	b#=bb#__main__N)
__future__r   r   r   r$   __metaclass__DOCUMENTATIONEXAMPLESRETURNUansible_collections.community.general.plugins.module_utils.identity.keycloak.keycloakr   r   r   r	   r
   ansible.module_utils.basicr   r   r   r   __name__r   r   r   <module>r      s\    A @}~,
45 5 4*  _D zF r   