Exemplo n.º 1
0
def main():
    argument_spec = keycloak_argument_spec()

    client_role_spec = dict(
        clientId=dict(type='str', required=True),
        roles=dict(type='list', required=True),
    )
    meta_args = dict(
        realm=dict(type='str', default='master'),
        self=dict(type='str'),
        id=dict(type='str'),
        username=dict(type='str', required=True),
        firstName=dict(type='str'),
        lastName=dict(type='str'),
        email=dict(type='str'),
        enabled=dict(type='bool', default=True),
        emailVerified=dict(type='bool', default=False),
        federationLink=dict(type='str'),
        serviceAccountClientId=dict(type='str'),
        attributes=dict(type='dict'),
        access=dict(type='dict'),
        clientRoles=dict(type='list', default=[], options=client_role_spec),
        realmRoles=dict(type='list', default=[]),
        groups=dict(type='list', default=[]),
        disableableCredentialTypes=dict(type='list', default=[]),
        requiredActions=dict(type='list', default=[]),
        credentials=dict(type='list', default=[]),
        federatedIdentities=dict(type='list', default=[]),
        clientConsents=dict(type='list', default=[]),
        origin=dict(type='str'),
        state=dict(choices=["absent", "present"], default='present'),
        force=dict(type='bool', default=False),
    )
    argument_spec.update(meta_args)

    module = AnsibleModule(argument_spec=argument_spec,
                           supports_check_mode=True)

    result = dict(changed=False, msg='', user={})

    # Obtain access token, initialize API
    try:
        connection_header = get_token(
            base_url=module.params.get('auth_keycloak_url'),
            validate_certs=module.params.get('validate_certs'),
            auth_realm=module.params.get('auth_realm'),
            client_id=module.params.get('auth_client_id'),
            auth_username=module.params.get('auth_username'),
            auth_password=module.params.get('auth_password'),
            client_secret=module.params.get('auth_client_secret'),
        )
    except KeycloakError as e:
        module.fail_json(msg=str(e))

    kc = KeycloakAPI(module, connection_header)

    realm = module.params.get('realm')
    state = module.params.get('state')
    force = module.params.get('force')
    # Create a representation of the user received in parameters
    newUserRepresentation = {}
    newUserClientRolesRepresentation = {}
    newUserRepresentation["username"] = module.params.get('username')
    if module.params.get('self') is not None:
        newUserRepresentation["self"] = module.params.get('self')
    if module.params.get('id') is not None:
        newUserRepresentation["id"] = module.params.get('id')
    newUserRepresentation["enabled"] = module.params.get('enabled')
    newUserRepresentation["emailVerified"] = module.params.get('emailVerified')
    if module.params.get('firstName') is not None:
        newUserRepresentation["firstName"] = module.params.get('firstName')
    if module.params.get('lastName') is not None:
        newUserRepresentation["lastName"] = module.params.get('lastName')
    if module.params.get('email') is not None:
        newUserRepresentation["email"] = module.params.get('email')
    if module.params.get('federationLink') is not None:
        newUserRepresentation["federationLink"] = module.params.get(
            'federationLink')
    if module.params.get('serviceAccountClientId') is not None:
        newUserRepresentation["serviceAccountClientId"] = module.params.get(
            'serviceAccountClientId')
    if module.params.get('origin') is not None:
        newUserRepresentation["origin"] = module.params.get('origin')
    if module.params.get('credentials') is not None:
        newUserRepresentation["credentials"] = module.params.get('credentials')
    if module.params.get('disableableCredentialTypes') is not None:
        newUserRepresentation[
            "disableableCredentialTypes"] = module.params.get(
                'disableableCredentialTypes')
    if module.params.get('federatedIdentities') is not None:
        newUserRepresentation["federatedIdentities"] = module.params.get(
            'federatedIdentities')
    if module.params.get('requiredActions') is not None:
        newUserRepresentation["requiredActions"] = module.params.get(
            'requiredActions')
    if module.params.get('clientConsents') is not None:
        newUserRepresentation["clientConsents"] = module.params.get(
            'clientConsents')
    if module.params.get('attributes') is not None:
        newUserRepresentation["attributes"] = module.params.get('attributes')
    if module.params.get('access') is not None:
        newUserRepresentation["access"] = module.params.get('access')
    if module.params.get('clientRoles') is not None:
        newUserClientRolesRepresentation["clientRoles"] = module.params.get(
            'clientRoles')
    if module.params.get('realmRoles') is not None:
        newUserRepresentation["realmRoles"] = module.params.get('realmRoles')
    if module.params.get('groups') is not None:
        newUserRepresentation["groups"] = module.params.get('groups')

    changed = False
    userRepresentation = kc.search_user_by_username(
        username=newUserRepresentation["username"], realm=realm)

    if userRepresentation == {}:  # The user does not exist
        # Create the user
        if (state == 'present'):  # If state is present
            # Create the user
            userRepresentation = kc.create_user(
                newUserRepresentation=newUserRepresentation, realm=realm)
            # Add user ID to new representation
            newUserRepresentation['id'] = userRepresentation["id"]
            # Assign roles to user
            kc.assing_roles_to_user(
                user_id=newUserRepresentation["id"],
                userRealmRoles=newUserRepresentation['realmRoles'],
                userClientRoles=newUserClientRolesRepresentation[
                    'clientRoles'],
                realm=realm)
            # set user groups
            kc.update_user_groups_membership(
                newUserRepresentation=newUserRepresentation, realm=realm)
            # Get the updated user realm roles
            userRepresentation["realmRoles"] = kc.get_user_realm_roles(
                user_id=userRepresentation["id"], realm=realm)
            # Get the user clientRoles
            userRepresentation["clientRoles"] = kc.get_user_client_roles(
                user_id=userRepresentation["id"], realm=realm)
            # Get the user groups
            userRepresentation["groups"] = kc.get_user_groups(
                user_id=userRepresentation["id"], realm=realm)
            changed = True
            result["user"] = userRepresentation
        elif state == 'absent':  # Otherwise, the status is absent
            result["msg"] = 'User %s is absent' % (
                newUserRepresentation["username"])

    else:  # the user already exists
        if (state == 'present'):  # if desired state is present
            if force:  # If the force option is set to true
                # Delete the existing user
                kc.delete_user(user_id=userRepresentation["id"], realm=realm)
                changed = True
                # Recreate the user
                userRepresentation = kc.create_user(
                    newUserRepresentation=newUserRepresentation, realm=realm)
                # Add user ID to new representation
                newUserRepresentation['id'] = userRepresentation["id"]
            else:  # If the force option is false
                excludes = [
                    "access", "notBefore", "createdTimestamp", "totp",
                    "credentials", "disableableCredentialTypes", "realmRoles",
                    "clientRoles", "groups", "clientConsents",
                    "federatedIdentities", "requiredActions"
                ]
                # Add user ID to new representation
                newUserRepresentation['id'] = userRepresentation["id"]
                # Compare users
                if not (
                        isDictEquals(newUserRepresentation, userRepresentation,
                                     excludes)
                ):  # If the new user does not introduce a change to the existing user
                    # Update the user
                    userRepresentation = kc.update_user(
                        newUserRepresentation=newUserRepresentation,
                        realm=realm)
                    changed = True
            # Assign roles to user
            if kc.assing_roles_to_user(
                    user_id=newUserRepresentation["id"],
                    userRealmRoles=newUserRepresentation['realmRoles'],
                    userClientRoles=newUserClientRolesRepresentation[
                        'clientRoles'],
                    realm=realm):
                changed = True
            # set user groups
            if kc.update_user_groups_membership(
                    newUserRepresentation=newUserRepresentation, realm=realm):
                changed = True
            # Get the updated user realm roles
            userRepresentation["realmRoles"] = kc.get_user_realm_roles(
                user_id=userRepresentation["id"], realm=realm)
            # Get the user clientRoles
            userRepresentation["clientRoles"] = kc.get_user_client_roles(
                user_id=userRepresentation["id"], realm=realm)
            # Get the user groups
            userRepresentation["groups"] = kc.get_user_groups(
                user_id=userRepresentation["id"], realm=realm)
            result["user"] = userRepresentation
        elif state == 'absent':  # Status is absent
            # Delete user
            kc.delete_user(user_id=userRepresentation['id'], realm=realm)
            result["msg"] = 'User %s deleted' % (userRepresentation['id'])
            changed = True

    result['changed'] = changed
    module.exit_json(**result)
Exemplo n.º 2
0
def main():
    """
    Module execution

    :return:
    """
    argument_spec = keycloak_argument_spec()

    protmapper_spec = dict(
        consentRequired=dict(type='bool'),
        consentText=dict(type='str'),
        id=dict(type='str'),
        name=dict(type='str'),
        protocol=dict(type='str', choices=['openid-connect', 'saml']),
        protocolMapper=dict(type='str'),
        config=dict(type='dict'),
        state=dict(type='str',
                   choices=['absent', 'present'],
                   default='present'),
    )
    clientrolecomposites_spec = dict(
        name=dict(type='str'),
        id=dict(type='str'),
    )
    clientroles_spec = dict(
        name=dict(type='str'),
        description=dict(type='str'),
        composite=dict(type='bool'),
        composites=dict(type='list',
                        elements='dict',
                        options=clientrolecomposites_spec),
        state=dict(type='str',
                   choices=['absent', 'present'],
                   default='present'),
    )
    realmscopemappings_spec = dict(name=dict(type='str'),
                                   state=dict(type='str',
                                              choices=['absent', 'present'],
                                              default='present'))
    clientrolescopemappings_spec = dict(name=dict(type='str'),
                                        state=dict(
                                            type='str',
                                            choices=['absent', 'present'],
                                            default='present'))
    clientsscopemappings_spec = dict(id=dict(type='str'),
                                     roles=dict(
                                         type='list',
                                         options=clientrolescopemappings_spec))
    scopemappings_spec = dict(realm=dict(type='list',
                                         options=realmscopemappings_spec),
                              clients=dict(type='list',
                                           options=clientsscopemappings_spec))
    meta_args = dict(
        state=dict(default='present', choices=['present', 'absent']),
        realm=dict(type='str', default='master'),
        id=dict(type='str'),
        client_id=dict(type='str', aliases=['clientId']),
        name=dict(type='str'),
        description=dict(type='str'),
        root_url=dict(type='str', aliases=['rootUrl']),
        admin_url=dict(type='str', aliases=['adminUrl']),
        base_url=dict(type='str', aliases=['baseUrl']),
        surrogate_auth_required=dict(type='bool',
                                     aliases=['surrogateAuthRequired']),
        enabled=dict(type='bool'),
        client_authenticator_type=dict(type='str',
                                       choices=['client-secret', 'client-jwt'],
                                       aliases=['clientAuthenticatorType']),
        secret=dict(type='str', no_log=True),
        registration_access_token=dict(type='str',
                                       aliases=['registrationAccessToken']),
        default_roles=dict(type='list', aliases=['defaultRoles']),
        redirect_uris=dict(type='list', aliases=['redirectUris']),
        web_origins=dict(type='list', aliases=['webOrigins']),
        not_before=dict(type='int', aliases=['notBefore']),
        bearer_only=dict(type='bool', aliases=['bearerOnly']),
        consent_required=dict(type='bool', aliases=['consentRequired']),
        standard_flow_enabled=dict(type='bool',
                                   aliases=['standardFlowEnabled']),
        implicit_flow_enabled=dict(type='bool',
                                   aliases=['implicitFlowEnabled']),
        direct_access_grants_enabled=dict(
            type='bool', aliases=['directAccessGrantsEnabled']),
        service_accounts_enabled=dict(type='bool',
                                      aliases=['serviceAccountsEnabled']),
        authorization_services_enabled=dict(
            type='bool', aliases=['authorizationServicesEnabled']),
        public_client=dict(type='bool', aliases=['publicClient']),
        frontchannel_logout=dict(type='bool', aliases=['frontchannelLogout']),
        protocol=dict(type='str',
                      choices=['openid-connect', 'saml'],
                      default='openid-connect'),
        attributes=dict(type='dict'),
        full_scope_allowed=dict(type='bool', aliases=['fullScopeAllowed']),
        node_re_registration_timeout=dict(
            type='int', aliases=['nodeReRegistrationTimeout']),
        registered_nodes=dict(type='dict', aliases=['registeredNodes']),
        client_template=dict(type='str', aliases=['clientTemplate']),
        use_template_config=dict(type='bool', aliases=['useTemplateConfig']),
        use_template_scope=dict(type='bool', aliases=['useTemplateScope']),
        use_template_mappers=dict(type='bool', aliases=['useTemplateMappers']),
        protocol_mappers=dict(type='list',
                              elements='dict',
                              options=protmapper_spec,
                              aliases=['protocolMappers']),
        authorization_settings=dict(type='dict',
                                    aliases=['authorizationSettings']),
        client_roles=dict(type='list',
                          elements='dict',
                          options=clientroles_spec,
                          aliases=['clientRoles', 'roles']),
        scope_mappings=dict(type='dict',
                            aliases=['scopeMappings'],
                            options=scopemappings_spec),
        force=dict(type='bool', default=False),
    )
    argument_spec.update(meta_args)

    module = AnsibleModule(argument_spec=argument_spec,
                           supports_check_mode=True,
                           required_one_of=([['client_id', 'id']]))

    result = dict(changed=False,
                  msg='',
                  diff={},
                  proposed={},
                  existing={},
                  end_state={},
                  clientSecret='')

    # Obtain access token, initialize API
    try:
        connection_header = get_token(
            base_url=module.params.get('auth_keycloak_url'),
            validate_certs=module.params.get('validate_certs'),
            auth_realm=module.params.get('auth_realm'),
            client_id=module.params.get('auth_client_id'),
            auth_username=module.params.get('auth_username'),
            auth_password=module.params.get('auth_password'),
            client_secret=module.params.get('auth_client_secret'),
        )
    except KeycloakError as e:
        module.fail_json(msg=str(e))

    kc = KeycloakAPI(module, connection_header)

    realm = module.params.get('realm')
    cid = module.params.get('id')
    state = module.params.get('state')

    # convert module parameters to client representation parameters (if they belong in there)
    client_params = [
        x for x in module.params
        if x not in list(keycloak_argument_spec().keys()) +
        ['state', 'realm', 'url', 'force'] and module.params.get(x) is not None
    ]
    keycloak_argument_spec().keys()
    # See whether the client already exists in Keycloak
    if cid is None:
        before_client = kc.get_client_by_clientid(
            module.params.get('client_id'), realm=realm)
        if before_client is not None:
            cid = before_client['id']
    else:
        before_client = kc.get_client_by_id(cid, realm=realm)

    if before_client is None:
        before_client = dict()

    # Build a proposed changeset from parameters given to this module
    changeset = dict()

    for client_param in client_params:
        new_param_value = module.params.get(client_param)

        # some lists in the Keycloak API are sorted, some are not.
        if isinstance(new_param_value, list):
            if client_param in ['attributes']:
                try:
                    new_param_value = sorted(new_param_value)
                except TypeError:
                    pass
        # Unfortunately, the ansible argument spec checker introduces variables with null values when
        # they are not specified
        if client_param == 'protocol_mappers':
            new_param_value = [
                dict((k, v) for k, v in x.items() if x[k] is not None)
                for x in new_param_value
            ]

        if client_param == 'roles':
            client_param = 'client_roles'
        changeset[camel(client_param)] = new_param_value

    newClientScopeMappings = {}
    newClientScopeRealm = {}
    newClientScopeClients = {}
    if module.params.get('scope_mappings') is not None:
        newClientScopeMappings["scope_mappings"] = module.params.get(
            'scope_mappings')
        if newClientScopeMappings["scope_mappings"]["realm"] is not None:
            newClientScopeRealm["realmRoles"] = newClientScopeMappings[
                "scope_mappings"]["realm"]
        if newClientScopeMappings["scope_mappings"]["clients"] is not None:
            newClientScopeClients["clientRoles"] = newClientScopeMappings[
                "scope_mappings"]["clients"]

    # Whether creating or updating a client, take the before-state and merge the changeset into it
    updated_client = before_client.copy()
    updated_client.update(changeset)

    result['proposed'] = sanitize_cr(changeset)
    result['existing'] = sanitize_cr(before_client)

    # If the client does not exist yet, before_client is still empty
    if before_client == dict():
        if state == 'absent':
            # do nothing and exit
            if module._diff:
                result['diff'] = dict(before='', after='')
            result['msg'] = 'Client does not exist, doing nothing.'
            module.exit_json(**result)

        # create new client
        result['changed'] = True
        if 'clientId' not in updated_client:
            module.fail_json(
                msg='client_id needs to be specified when creating a new client'
            )

        if module._diff:
            result['diff'] = dict(before='', after=sanitize_cr(updated_client))

        if module.check_mode:
            module.exit_json(**result)

        kc.create_client(updated_client, realm=realm)
        after_client = kc.get_client_by_clientid(updated_client['clientId'],
                                                 realm=realm)

        result['end_state'] = sanitize_cr(after_client)
        client_secret = kc.get_client_secret_by_id(after_client['id'],
                                                   realm=realm)
        if client_secret is not None:
            result['clientSecret'] = client_secret

        if module.params.get('scope_mappings') is not None:
            kc.assing_scope_roles_to_client(
                client_id=after_client['id'],
                clientScopeRealmRoles=newClientScopeRealm["realmRoles"],
                clientScopeClientRoles=newClientScopeClients["clientRoles"],
                realm=realm)
            result['changed'] = True
        result[
            'msg'] = 'Client %s has been created.' % updated_client['clientId']
        module.exit_json(**result)
    else:
        if state == 'present':
            # update existing client
            result['changed'] = True
            if module.check_mode:
                # We can only compare the current client with the proposed updates we have
                if module._diff:
                    result['diff'] = dict(before=sanitize_cr(before_client),
                                          after=sanitize_cr(updated_client))
                result['changed'] = (before_client != updated_client)

                module.exit_json(**result)

            kc.update_client(cid, updated_client, realm=realm)

            after_client = kc.get_client_by_id(cid, realm=realm)
            client_secret = kc.get_client_secret_by_id(cid, realm=realm)

            if client_secret is not None:
                result['clientSecret'] = client_secret
            if before_client == after_client:
                result['changed'] = False
            if module._diff:
                result['diff'] = dict(before=sanitize_cr(before_client),
                                      after=sanitize_cr(after_client))

            if module.params.get('scope_mappings') is not None:
                result['changed'] = kc.assing_scope_roles_to_client(
                    client_id=after_client['id'],
                    clientScopeRealmRoles=newClientScopeRealm["realmRoles"],
                    clientScopeClientRoles=newClientScopeClients[
                        "clientRoles"],
                    realm=realm)

            result['end_state'] = sanitize_cr(after_client)

            result['msg'] = 'Client %s has been updated.' % updated_client[
                'clientId']
            module.exit_json(**result)
        else:
            # Delete existing client
            result['changed'] = True
            if module._diff:
                result['diff']['before'] = sanitize_cr(before_client)
                result['diff']['after'] = ''

            if module.check_mode:
                module.exit_json(**result)

            kc.delete_client(cid, realm=realm)
            result['proposed'] = dict()
            result['end_state'] = dict()
            result['msg'] = 'Client %s has been deleted.' % before_client[
                'clientId']
            module.exit_json(**result)

    module.exit_json(**result)
Exemplo n.º 3
0
def main():
    """
    Module execution

    :return:
    """
    argument_spec = keycloak_argument_spec()
    meta_args = dict(
        state=dict(default='present', choices=['present', 'absent']),
        realm=dict(default='master'),
        id=dict(type='str'),
        name=dict(type='str'),
        attributes=dict(type='dict'),
        path=dict(type='str'),
        attributes_list=dict(type='list'),
        realmRoles=dict(type='list'),
        clientRoles=dict(type='list'),
        syncLdapMappers=dict(type='bool', default=False),
        force=dict(type='bool', default=False),
    )

    argument_spec.update(meta_args)

    module = AnsibleModule(argument_spec=argument_spec,
                           supports_check_mode=True,
                           required_one_of=([['id', 'name']]))

    result = dict(changed=False, msg='', diff={}, group='')

    # Obtain access token, initialize API
    try:
        connection_header = get_token(
            base_url=module.params.get('auth_keycloak_url'),
            validate_certs=module.params.get('validate_certs'),
            auth_realm=module.params.get('auth_realm'),
            client_id=module.params.get('auth_client_id'),
            auth_username=module.params.get('auth_username'),
            auth_password=module.params.get('auth_password'),
            client_secret=module.params.get('auth_client_secret'),
        )
    except KeycloakError as e:
        module.fail_json(msg=str(e))

    kc = KeycloakAPI(module, connection_header)

    realm = module.params.get('realm')
    state = module.params.get('state')
    gid = module.params.get('id')
    name = module.params.get('name')
    attributes = module.params.get('attributes')
    # Add attribute received as a list to the attributes dict
    kc.add_attributes_list_to_attributes_dict(
        module.params.get('attributes_list'), attributes)
    syncLdapMappers = module.params.get('syncLdapMappers')
    groupRealmRoles = module.params.get('realmRoles')
    groupClientRoles = module.params.get('clientRoles')
    force = module.params.get('force')

    before_group = None  # current state of the group, for merging.

    # Synchronize LDAP group to Keycloak if syncLdapMappers is true
    if syncLdapMappers:
        kc.sync_ldap_groups("fedToKeycloak", realm=realm)
    # does the group already exist?
    if gid is None:
        before_group = kc.get_group_by_name(name, realm=realm)
    else:
        before_group = kc.get_group_by_groupid(gid, realm=realm)

    before_group = {} if before_group is None else before_group

    # attributes in Keycloak have their values returned as lists
    # via the API. attributes is a dict, so we'll transparently convert
    # the values to lists.
    if attributes is not None:
        for key, val in module.params['attributes'].items():
            module.params['attributes'][key] = [
                val
            ] if not isinstance(val, list) else val
    excludes = [
        'state', 'realm', 'force', 'attributes_list', 'realmRoles',
        'clientRoles', 'syncLdapMappers'
    ]
    group_params = [
        x for x in module.params
        if x not in list(keycloak_argument_spec().keys()) +
        excludes and module.params.get(x) is not None
    ]
    # build a changeset
    changeset = {}
    for param in group_params:
        new_param_value = module.params.get(param)
        old_value = before_group[param] if param in before_group else None
        if new_param_value != old_value:
            changeset[camel(param)] = new_param_value

    # prepare the new group
    updated_group = before_group.copy()
    updated_group.update(changeset)

    # if before_group is none, the group doesn't exist.
    if before_group == {}:
        if state == 'absent':
            # nothing to do.
            if module._diff:
                result['diff'] = dict(before='', after='')
            result['msg'] = 'Group does not exist; doing nothing.'
            result['group'] = dict()
            module.exit_json(**result)

        # for 'present', create a new group.
        result['changed'] = True
        if name is None:
            module.fail_json(
                msg='name must be specified when creating a new group')

        if module._diff:
            result['diff'] = dict(before='', after=updated_group)

        if module.check_mode:
            module.exit_json(**result)

        # do it for real!
        kc.create_group(updated_group, realm=realm)
        # Assing roles to group
        kc.assing_roles_to_group(groupRepresentation=updated_group,
                                 groupRealmRoles=groupRealmRoles,
                                 groupClientRoles=groupClientRoles,
                                 realm=realm)
        # Sync Keycloak groups to User Storages if syncLdapMappers is true
        if syncLdapMappers:
            kc.sync_ldap_groups("keycloakToFed", realm=realm)

        after_group = kc.get_group_by_name(name, realm)

        result['group'] = after_group
        result['msg'] = 'Group {name} has been created with ID {id}'.format(
            name=after_group['name'], id=after_group['id'])

    else:
        if state == 'present':
            # no changes
            if updated_group == before_group and not force:
                result['changed'] = False
                result['group'] = updated_group
                result['msg'] = "No changes required to group {name}.".format(
                    name=before_group['name'])
                module.exit_json(**result)

            # update the existing group
            result['changed'] = True

            if module._diff:
                result['diff'] = dict(before=before_group, after=updated_group)

            if module.check_mode:
                module.exit_json(**result)

            if force:
                # delete for real
                gid = before_group['id']
                kc.delete_group(groupid=gid, realm=realm)
                # remove id
                del (updated_group['id'])
                if "realmRoles" in updated_group:
                    del (updated_group['realmRoles'])
                if "clientRoles" in updated_group:
                    del (updated_group['clientRoles'])

                # create it again
                kc.create_group(updated_group, realm=realm)
            else:
                # do the update
                kc.update_group(updated_group, realm=realm)
            # Assing roles to group
            kc.assing_roles_to_group(groupRepresentation=updated_group,
                                     groupRealmRoles=groupRealmRoles,
                                     groupClientRoles=groupClientRoles,
                                     realm=realm)
            # Sync Keycloak groups to User Storages if syncLdapMappers is true
            if syncLdapMappers:
                kc.sync_ldap_groups("keycloakToFed", realm=realm)

            if force:
                after_group = kc.get_group_by_name(name, realm)
            else:
                after_group = kc.get_group_by_groupid(updated_group['id'],
                                                      realm=realm)

            result['group'] = after_group
            result['msg'] = "Group {id} has been updated".format(
                id=after_group['id'])

            module.exit_json(**result)

        elif state == 'absent':
            result['group'] = dict()

            if module._diff:
                result['diff'] = dict(before=before_group, after='')

            if module.check_mode:
                module.exit_json(**result)

            # delete for real
            gid = before_group['id']
            kc.delete_group(groupid=gid, realm=realm)
            # Sync Keycloak groups to User Storages if syncLdapMappers is true
            if syncLdapMappers:
                kc.sync_ldap_groups("keycloakToFed", realm=realm)

            result['changed'] = True
            result['msg'] = "Group {name} has been deleted".format(
                name=before_group['name'])

            module.exit_json(**result)

    module.exit_json(**result)
def main():
    """
    Module execution
    :returm:
    """
    argument_spec = keycloak_argument_spec()
    meta_args = dict(
        realm=dict(type='str', required=True),
        alias=dict(type='str', required=True),
        providerId=dict(type='str'),
        copyFrom=dict(type='str'),
        authenticationExecutions=dict(type='list'),
        state=dict(choices=["absent", "present"], default='present'),
        force=dict(type='bool', default=False),
    )
    argument_spec.update(meta_args)

    module = AnsibleModule(argument_spec=argument_spec,
                           supports_check_mode=True)

    result = dict(changed=False, msg='', flow={})
    # Obtain access token, initialize API
    try:
        connection_header = get_token(
            base_url=module.params.get('auth_keycloak_url'),
            validate_certs=module.params.get('validate_certs'),
            auth_realm=module.params.get('auth_realm'),
            client_id=module.params.get('auth_client_id'),
            auth_username=module.params.get('auth_username'),
            auth_password=module.params.get('auth_password'),
            client_secret=module.params.get('auth_client_secret'),
        )
    except KeycloakError as e:
        module.fail_json(msg=str(e))

    kc = KeycloakAPI(module, connection_header)
    realm = module.params.get('realm')
    state = module.params.get('state')
    force = module.params.get('force')

    newAuthenticationRepresentation = {}
    newAuthenticationRepresentation["alias"] = module.params.get("alias")
    newAuthenticationRepresentation["copyFrom"] = module.params.get("copyFrom")
    newAuthenticationRepresentation["providerId"] = module.params.get("providerId")
    newAuthenticationRepresentation["authenticationExecutions"] = module.params.get("authenticationExecutions")

    changed = False

    authenticationRepresentation = kc.get_authentication_flow_by_alias(alias=newAuthenticationRepresentation["alias"], realm=realm)

    if authenticationRepresentation == {}:  # Authentication flow does not exist
        if (state == 'present'):  # If desired state is prenset
            # If copyFrom is defined, create authentication flow from a copy
            if "copyFrom" in newAuthenticationRepresentation and newAuthenticationRepresentation["copyFrom"] is not None:
                authenticationRepresentation = kc.copy_auth_flow(config=newAuthenticationRepresentation, realm=realm)
            else:  # Create an empty authentication flow
                authenticationRepresentation = kc.create_empty_auth_flow(config=newAuthenticationRepresentation, realm=realm)
            # If the authentication still not exist on the server, raise an exception.
            if authenticationRepresentation is None:
                result['msg'] = "Authentication just created not found: " + str(newAuthenticationRepresentation)
                module.fail_json(**result)
            # Configure the executions for the flow
            kc.create_or_update_executions(config=newAuthenticationRepresentation, realm=realm)
            changed = True
            # Get executions created
            executionsRepresentation = kc.get_executions_representation(config=newAuthenticationRepresentation, realm=realm)
            if executionsRepresentation is not None:
                authenticationRepresentation["authenticationExecutions"] = executionsRepresentation
            result['changed'] = changed
            result['flow'] = authenticationRepresentation
        elif state == 'absent':  # If desired state is absent.
            result['msg'] = newAuthenticationRepresentation["alias"] + ' absent'
    else:  # The authentication flow already exist
        if (state == 'present'):  # if desired state is present
            if force:  # If force option is true
                # Delete the actual authentication flow
                kc.delete_authentication_flow_by_id(id=authenticationRepresentation["id"], realm=realm)
                changed = True
                # If copyFrom is defined, create authentication flow from a copy
                if "copyFrom" in newAuthenticationRepresentation and newAuthenticationRepresentation["copyFrom"] is not None:
                    authenticationRepresentation = kc.copy_auth_flow(config=newAuthenticationRepresentation, realm=realm)
                else:  # Create an empty authentication flow
                    authenticationRepresentation = kc.create_empty_auth_flow(config=newAuthenticationRepresentation, realm=realm)
                # If the authentication still not exist on the server, raise an exception.
                if authenticationRepresentation is None:
                    result['msg'] = "Authentication just created not found: " + str(newAuthenticationRepresentation)
                    result['changed'] = changed
                    module.fail_json(**result)
            # Configure the executions for the flow
            if kc.create_or_update_executions(config=newAuthenticationRepresentation, realm=realm):
                changed = True
            # Get executions created
            executionsRepresentation = kc.get_executions_representation(config=newAuthenticationRepresentation, realm=realm)
            if executionsRepresentation is not None:
                authenticationRepresentation["authenticationExecutions"] = executionsRepresentation
            result['flow'] = authenticationRepresentation
            result['changed'] = changed
        elif state == 'absent':  # If desired state is absent
            # Delete the authentication flow alias.
            kc.delete_authentication_flow_by_id(id=authenticationRepresentation["id"], realm=realm)
            changed = True
            result['msg'] = 'Authentication flow: ' + newAuthenticationRepresentation['alias'] + ' id: ' + authenticationRepresentation["id"] + ' is deleted'
            result['changed'] = changed

    module.exit_json(**result)
def main():
    argument_spec = keycloak_argument_spec()

    composites_spec = dict(name=dict(type='str', required=True),
                           clientId=dict(type='str'))
    meta_args = dict(
        realm=dict(type='str', default='master'),
        name=dict(type='str', required=True),
        description=dict(type='str', default=None),
        composite=dict(type='bool', default=False),
        clientRole=dict(type='bool', default=False),
        containerId=dict(type='str', required=False),
        composites=dict(type='list', default=[], options=composites_spec),
        state=dict(choices=["absent", "present"], default='present'),
        force=dict(type='bool', default=False),
    )
    argument_spec.update(meta_args)

    module = AnsibleModule(argument_spec=argument_spec,
                           supports_check_mode=True)

    result = dict(changed=False, msg='', role={}, composites=None)

    # Obtain access token, initialize API
    try:
        connection_header = get_token(
            base_url=module.params.get('auth_keycloak_url'),
            validate_certs=module.params.get('validate_certs'),
            auth_realm=module.params.get('auth_realm'),
            client_id=module.params.get('auth_client_id'),
            auth_username=module.params.get('auth_username'),
            auth_password=module.params.get('auth_password'),
            client_secret=module.params.get('auth_client_secret'),
        )
    except KeycloakError as e:
        module.fail_json(msg=str(e))

    kc = KeycloakAPI(module, connection_header)

    realm = module.params.get('realm')
    state = module.params.get('state')
    force = module.params.get('force')
    newComposites = None

    # Create representation for the new role
    newRoleRepresentation = {}
    newRoleRepresentation["name"] = module.params.get('name')
    if module.params.get('description') is not None:
        newRoleRepresentation["description"] = module.params.get('description')
    newRoleRepresentation["composite"] = module.params.get('composite')
    newRoleRepresentation["clientRole"] = module.params.get('clientRole')
    newRoleRepresentation["containerId"] = module.params.get(
        'containerId') if module.params.get(
            'containerId') is not None else realm
    if module.params.get('composites') is not None:
        newComposites = module.params.get('composites')

    changed = False

    # Search the role on Keycloak server.
    roleRepresentation = kc.search_realm_role_by_name(
        name=newRoleRepresentation["name"], realm=realm)
    if roleRepresentation == {}:  # If role does not exists
        if (state == 'present'):  # If desired state is present
            # Create Role
            kc.create_realm_role(newRoleRepresentation=newRoleRepresentation,
                                 realm=realm)
            # Create composites
            kc.create_or_update_realm_role_composites(
                newComposites=newComposites,
                newRoleRepresentation=newRoleRepresentation,
                realm=realm)
            # Get created role
            roleRepresentation = kc.get_realm_role(
                name=newRoleRepresentation["name"], realm=realm)
            # Get created composites
            composites = kc.get_realm_role_composites_with_client_id(
                name=newRoleRepresentation["name"], realm=realm)
            changed = True
            result['role'] = roleRepresentation
            result['composites'] = composites
        elif state == 'absent':  # If desired state is absent
            result["msg"] = "Realm role %s is absent in realm %s" % (
                newRoleRepresentation["name"], realm)

    else:  # If role already exists
        if (state == 'present'):  # If desired state is present
            if force:  # If force option is true
                # Delete the existing role
                kc.delete_realm_role(name=roleRepresentation["name"],
                                     realm=realm)
                # Create role again
                kc.create_realm_role(
                    newRoleRepresentation=newRoleRepresentation, realm=realm)
                changed = True
            else:  # If force option is false
                # Compare roles
                if not (isDictEquals(
                        newRoleRepresentation,
                        roleRepresentation)):  # If new role introduce changes
                    # Update the role
                    kc.update_realm_role(
                        newRoleRepresentation=newRoleRepresentation,
                        realm=realm)
                    changed = True
            # Manage composites
            if kc.create_or_update_realm_role_composites(
                    newComposites=newComposites,
                    newRoleRepresentation=newRoleRepresentation,
                    realm=realm):
                changed = True
            # Get created role
            roleRepresentation = kc.get_realm_role(
                name=newRoleRepresentation["name"], realm=realm)
            # Get composites
            composites = kc.get_realm_role_composites_with_client_id(
                name=newRoleRepresentation["name"], realm=realm)
            result["role"] = roleRepresentation
            result["composites"] = composites
        elif state == 'absent':  # If desired state is absent
            # Delete role
            kc.delete_realm_role(name=newRoleRepresentation["name"],
                                 realm=realm)
            changed = True
            result["msg"] = "Realm role %s is deleted in realm %s" % (
                newRoleRepresentation["name"], realm)
    result['changed'] = changed
    module.exit_json(**result)
def main():
    argument_spec = keycloak_argument_spec()
    smtp_spec = {
        "replyToDisplayName": {
            "type": "str"
        },
        "starttls": {
            "type": "str",
            "choices": ["true", "false"],
            "default": "false"
        },
        "auth": {
            "type": "str",
            "choices": ["true", "false"],
            "default": "false"
        },
        "port": {
            "type": "str",
            "default": "25"
        },
        "host": {
            "type": "str"
        },
        "replyTo": {
            "type": "str"
        },
        "from": {
            "type": "str"
        },
        "fromDisplayName": {
            "type": "str"
        },
        "envelopeFrom": {
            "type": "str"
        },
        "ssl": {
            "type": "str",
            "choices": ["true", "false"],
            "default": "false"
        },
        "user": {
            "type": "str"
        },
        "password": {
            "type": "str",
            "no_log": True
        }
    }
    eventconfig_spec = {
        "eventsEnabled": {
            "type": "bool"
        },
        "eventsListeners": {
            "type": "list"
        },
        "adminEventsEnabled": {
            "type": "bool"
        },
        "adminEventsDetailsEnabled": {
            "type": "bool"
        },
        "eventsExpiration": {
            "type": "int"
        },
        "enabledEventTypes": {
            "type":
            "list",
            "choices": [
                "SEND_RESET_PASSWORD", "UPDATE_TOTP", "REMOVE_TOTP",
                "REVOKE_GRANT", "LOGIN_ERROR", "CLIENT_LOGIN",
                "RESET_PASSWORD_ERROR", "IMPERSONATE_ERROR",
                "CODE_TO_TOKEN_ERROR", "CUSTOM_REQUIRED_ACTION",
                "UPDATE_PROFILE_ERROR", "IMPERSONATE", "LOGIN",
                "UPDATE_PASSWORD_ERROR", "REGISTER", "LOGOUT",
                "CLIENT_REGISTER", "UPDATE_PASSWORD",
                "FEDERATED_IDENTITY_LINK_ERROR", "CLIENT_DELETE",
                "IDENTITY_PROVIDER_FIRST_LOGIN", "VERIFY_EMAIL",
                "CLIENT_DELETE_ERROR", "CLIENT_LOGIN_ERROR",
                "REMOVE_FEDERATED_IDENTITY_ERROR", "EXECUTE_ACTIONS",
                "SEND_IDENTITY_PROVIDER_LINK_ERROR", "SEND_VERIFY_EMAIL",
                "EXECUTE_ACTIONS_ERROR", "REMOVE_FEDERATED_IDENTITY",
                "IDENTITY_PROVIDER_POST_LOGIN", "UPDATE_EMAIL",
                "REGISTER_ERROR", "REVOKE_GRANT_ERROR", "LOGOUT_ERROR",
                "UPDATE_EMAIL_ERROR", "CLIENT_UPDATE_ERROR", "UPDATE_PROFILE",
                "FEDERATED_IDENTITY_LINK", "CLIENT_REGISTER_ERROR",
                "SEND_VERIFY_EMAIL_ERROR", "SEND_IDENTITY_PROVIDER_LINK",
                "RESET_PASSWORD", "REMOVE_TOTP_ERROR", "VERIFY_EMAIL_ERROR",
                "SEND_RESET_PASSWORD_ERROR", "CLIENT_UPDATE",
                "IDENTITY_PROVIDER_POST_LOGIN_ERROR",
                "CUSTOM_REQUIRED_ACTION_ERROR", "UPDATE_TOTP_ERROR",
                "CODE_TO_TOKEN", "IDENTITY_PROVIDER_FIRST_LOGIN_ERROR"
            ]
        }
    }
    meta_args = dict(
        realm=dict(type='str', default='master'),
        displayName=dict(type='str', required=True, aliases=['name']),
        displayNameHtml=dict(type='str', default="", aliases=['namehtml']),
        loginTheme=dict(type="str"),
        adminTheme=dict(type="str"),
        emailTheme=dict(type="str"),
        accountTheme=dict(type="str"),
        internationalizationEnabled=dict(type="bool"),
        supportedLocales=dict(type="list"),
        defaultLocale=dict(type="str"),
        accessCodeLifespan=dict(type='int', default=60),
        accessCodeLifespanLogin=dict(type='int', default=1800),
        accessCodeLifespanUserAction=dict(type='int', default=300),
        notBefore=dict(type='int', default=0),
        revokeRefreshToken=dict(type='bool', default=False),
        accessTokenLifespan=dict(type='int', default=300),
        accessTokenLifespanForImplicitFlow=dict(type='int', default=900),
        ssoSessionIdleTimeout=dict(type='int', default=1800),
        ssoSessionMaxLifespan=dict(type='int', default=36000),
        offlineSessionIdleTimeout=dict(type='int', default=2592000),
        enabled=dict(type='bool', default=True),
        sslRequired=dict(type='str', default="external"),
        registrationAllowed=dict(type='bool', default=False),
        registrationEmailAsUsername=dict(type='bool', default=False),
        rememberMe=dict(type='bool', default=False),
        verifyEmail=dict(type='bool', default=False),
        loginWithEmailAllowed=dict(type='bool', default=True),
        duplicateEmailsAllowed=dict(type='bool', default=False),
        resetPasswordAllowed=dict(type='bool', default=False),
        editUsernameAllowed=dict(type='bool', default=False),
        bruteForceProtected=dict(type='bool', default=False),
        permanentLockout=dict(type='bool', default=False),
        maxFailureWaitSeconds=dict(type='int', default=900),
        minimumQuickLoginWaitSeconds=dict(type='int', default=60),
        waitIncrementSeconds=dict(type='int', default=60),
        quickLoginCheckMilliSeconds=dict(type='int', default=1000),
        maxDeltaTimeSeconds=dict(type='int', default=43200),
        failureFactor=dict(type='int', default=30),
        defaultRoles=dict(type='list',
                          default=["offline_access", "uma_authorization"]),
        requiredCredentials=dict(type='list', default=["password"]),
        passwordPolicy=dict(type='str', default="hashIterations(20000)"),
        otpPolicyType=dict(type='str', default="totp"),
        otpPolicyAlgorithm=dict(type='str', default="HmacSHA1"),
        otpPolicyInitialCounter=dict(type='int', default=0),
        otpPolicyDigits=dict(type='int', default=6),
        otpPolicyLookAheadWindow=dict(type='int', default=1),
        otpPolicyPeriod=dict(type='int', default=30),
        smtpServer=dict(type='dict', default={}, options=smtp_spec),
        eventsConfig=dict(type='dict', options=eventconfig_spec),
        browserFlow=dict(type='str', default="browser"),
        registrationFlow=dict(type='str', default="registration"),
        directGrantFlow=dict(type='str', default="direct grant"),
        resetCredentialsFlow=dict(type='str', default="reset credentials"),
        clientAuthenticationFlow=dict(type='str', default="clients"),
        state=dict(choices=["absent", "present"], default='present'),
        force=dict(type='bool', default=False),
        attributes=dict(type='dict', default=None),
        browserSecurityHeaders=dict(type='dict', default=None))

    argument_spec.update(meta_args)

    module = AnsibleModule(argument_spec=argument_spec,
                           supports_check_mode=True)

    result = dict(changed=False, msg='', realm={}, eventsConfig={})

    # Obtain access token, initialize API
    try:
        connection_header = get_token(
            base_url=module.params.get('auth_keycloak_url'),
            validate_certs=module.params.get('validate_certs'),
            auth_realm=module.params.get('auth_realm'),
            client_id=module.params.get('auth_client_id'),
            auth_username=module.params.get('auth_username'),
            auth_password=module.params.get('auth_password'),
            client_secret=module.params.get('auth_client_secret'),
        )
    except KeycloakError as e:
        module.fail_json(msg=str(e))

    kc = KeycloakAPI(module, connection_header)

    defaultAttributes = dict(
        _browser_header=dict(contentSecurityPolicy=dict(
            type='unicode', default="frame-src 'self'"),
                             xContentTypeOptions=dict(type='unicode',
                                                      default="nosniff"),
                             xFrameOptions=dict(type='unicode',
                                                default="SAMEORIGIN"),
                             xRobotsTag=dict(type='unicode', default="none"),
                             xXSSProtection=dict(type='unicode',
                                                 default="1; mode=block")),
        actionTokenGeneratedByAdminLifespan=dict(type='int', default=43200),
        actionTokenGeneratedByUserLifespan=dict(type='int', default=300),
        displayName=dict(type='unicode', default=module.params.get('name')),
        displayNameHtml=dict(type='unicode',
                             default=module.params.get('namehtml')),
    )
    defaultBrowserSecurityHeaders = dict(
        contentSecurityPolicy=dict(type='unicode', default="frame-src 'self'"),
        xContentTypeOptions=dict(type='unicode', default="nosniff"),
        xFrameOptions=dict(type='unicode', default="SAMEORIGIN"),
        xRobotsTag=dict(type='unicode', default="none"),
        xXSSProtection=dict(type='unicode', default="1; mode=block"))

    state = module.params.get('state')
    force = module.params.get('force')

    # Create a realm representation form module parameters
    newRealmRepresentation = {}
    newRealmRepresentation["id"] = module.params.get('realm')
    newRealmRepresentation["realm"] = module.params.get('realm')
    newRealmRepresentation["displayName"] = module.params.get('displayName')
    newRealmRepresentation["displayNameHtml"] = module.params.get(
        'displayNameHtml')
    if module.params.get("loginTheme") is not None:
        newRealmRepresentation["loginTheme"] = module.params.get("loginTheme")
    if module.params.get("adminTheme") is not None:
        newRealmRepresentation["adminTheme"] = module.params.get("adminTheme")
    if module.params.get("emailTheme") is not None:
        newRealmRepresentation["emailTheme"] = module.params.get("emailTheme")
    if module.params.get("accountTheme") is not None:
        newRealmRepresentation["accountTheme"] = module.params.get(
            "accountTheme")
    newRealmRepresentation["accessCodeLifespan"] = module.params.get(
        'accessCodeLifespan')
    newRealmRepresentation["accessCodeLifespanLogin"] = module.params.get(
        'accessCodeLifespanLogin')
    newRealmRepresentation["accessCodeLifespanUserAction"] = module.params.get(
        'accessCodeLifespanUserAction')
    newRealmRepresentation["notBefore"] = module.params.get('notBefore')
    newRealmRepresentation["revokeRefreshToken"] = module.params.get(
        'revokeRefreshToken')
    newRealmRepresentation["accessTokenLifespan"] = module.params.get(
        'accessTokenLifespan')
    newRealmRepresentation[
        "accessTokenLifespanForImplicitFlow"] = module.params.get(
            'accessTokenLifespanForImplicitFlow')
    newRealmRepresentation["ssoSessionIdleTimeout"] = module.params.get(
        'ssoSessionIdleTimeout')
    newRealmRepresentation["ssoSessionMaxLifespan"] = module.params.get(
        'ssoSessionMaxLifespan')
    newRealmRepresentation["offlineSessionIdleTimeout"] = module.params.get(
        'offlineSessionIdleTimeout')
    newRealmRepresentation["enabled"] = module.params.get('enabled')
    newRealmRepresentation["sslRequired"] = module.params.get('sslRequired')
    newRealmRepresentation["registrationAllowed"] = module.params.get(
        'registrationAllowed')
    newRealmRepresentation["registrationEmailAsUsername"] = module.params.get(
        'registrationEmailAsUsername')
    newRealmRepresentation["rememberMe"] = module.params.get('rememberMe')
    newRealmRepresentation["verifyEmail"] = module.params.get('verifyEmail')
    newRealmRepresentation["loginWithEmailAllowed"] = module.params.get(
        'loginWithEmailAllowed')
    newRealmRepresentation["duplicateEmailsAllowed"] = module.params.get(
        'duplicateEmailsAllowed')
    newRealmRepresentation["resetPasswordAllowed"] = module.params.get(
        'resetPasswordAllowed')
    newRealmRepresentation["editUsernameAllowed"] = module.params.get(
        'editUsernameAllowed')
    newRealmRepresentation["bruteForceProtected"] = module.params.get(
        'bruteForceProtected')
    newRealmRepresentation["permanentLockout"] = module.params.get(
        'permanentLockout')
    newRealmRepresentation["maxFailureWaitSeconds"] = module.params.get(
        'maxFailureWaitSeconds')
    newRealmRepresentation["minimumQuickLoginWaitSeconds"] = module.params.get(
        'minimumQuickLoginWaitSeconds')
    newRealmRepresentation["waitIncrementSeconds"] = module.params.get(
        'waitIncrementSeconds')
    newRealmRepresentation["quickLoginCheckMilliSeconds"] = module.params.get(
        'quickLoginCheckMilliSeconds')
    newRealmRepresentation["maxDeltaTimeSeconds"] = module.params.get(
        'maxDeltaTimeSeconds')
    newRealmRepresentation["failureFactor"] = module.params.get(
        'failureFactor')
    newRealmRepresentation["defaultRoles"] = module.params.get('defaultRoles')
    newRealmRepresentation["requiredCredentials"] = module.params.get(
        'requiredCredentials')
    newRealmRepresentation["passwordPolicy"] = module.params.get(
        'passwordPolicy')
    newRealmRepresentation["otpPolicyType"] = module.params.get(
        'otpPolicyType')
    newRealmRepresentation["otpPolicyAlgorithm"] = module.params.get(
        'otpPolicyAlgorithm')
    newRealmRepresentation["otpPolicyInitialCounter"] = module.params.get(
        'otpPolicyInitialCounter')
    newRealmRepresentation["otpPolicyDigits"] = module.params.get(
        'otpPolicyDigits')
    newRealmRepresentation["otpPolicyLookAheadWindow"] = module.params.get(
        'otpPolicyLookAheadWindow')
    newRealmRepresentation["otpPolicyPeriod"] = module.params.get(
        'otpPolicyPeriod')
    newRealmRepresentation["smtpServer"] = module.params.get('smtpServer')
    remove_arguments_with_value_none(newRealmRepresentation["smtpServer"])
    if module.params.get("supportedLocales") is not None:
        if module.params.get("internationalizationEnabled") is not None:
            newRealmRepresentation[
                "internationalizationEnabled"] = module.params.get(
                    "internationalizationEnabled")
        else:
            newRealmRepresentation["internationalizationEnabled"] = True
        newRealmRepresentation["supportedLocales"] = module.params.get(
            "supportedLocales")
        if module.params.get("defaultLocale") is not None:
            newRealmRepresentation["defaultLocale"] = module.params.get(
                "defaultLocale")
    else:
        newRealmRepresentation["internationalizationEnabled"] = False
    newRealmRepresentation["browserFlow"] = module.params.get('browserFlow')
    newRealmRepresentation["registrationFlow"] = module.params.get(
        'registrationFlow')
    newRealmRepresentation["directGrantFlow"] = module.params.get(
        'directGrantFlow')
    newRealmRepresentation["resetCredentialsFlow"] = module.params.get(
        'resetCredentialsFlow')
    newRealmRepresentation["clientAuthenticationFlow"] = module.params.get(
        'clientAuthenticationFlow')
    if module.params.get("eventsExpiration") is not None:
        newRealmRepresentation["eventsExpiration"] = module.params.get(
            'eventsExpiration')
    # Read Events configuration for the Realm
    newEventsConfig = module.params.get("eventsConfig")
    remove_arguments_with_value_none(newEventsConfig)
    if module.params.get("browserSecurityHeaders") is not None:
        newRealmRepresentation["browserSecurityHeaders"] = module.params.get(
            "browserSecurityHeaders")

    changed = False
    # Find realm on Keycloak server
    realmRepresentation = kc.search_realm(
        realm=newRealmRepresentation["realm"])
    if realmRepresentation == {}:  # Realm does not exist
        if (state == 'present'):  # If desired state is present
            # Create the realm
            result["realm"] = kc.create_realm(
                newRealmRepresentation=newRealmRepresentation)
            if newEventsConfig is not None:
                eventsConfig = kc.update_realm_events_config(
                    realm=newRealmRepresentation["realm"],
                    newEventsConfig=newEventsConfig)
                result["eventsConfig"] = eventsConfig
            changed = True
        else:  # if desired state is absent
            result['msg'] = 'Realm %s is absent' % (
                newRealmRepresentation["realm"])

    else:  # Realm already exists
        if (state == 'present'):  # If desired state is present
            if force:  # If force option is true
                # Delete the existing realm
                kc.delete_realm(newRealmRepresentation["realm"])
                # Create realm
                realmRepresentation = kc.create_realm(
                    newRealmRepresentation=newRealmRepresentation)
                changed = True
            else:  # If force option is false
                # Compare realms
                if not isDictEquals(newRealmRepresentation, realmRepresentation
                                    ):  # If new realm introduces changes
                    # Update REALM
                    realmRepresentation = kc.update_realm(
                        newRealmRepresentation=newRealmRepresentation)
                    changed = True
                else:
                    realmRepresentation = kc.get_realm(
                        realm=newRealmRepresentation["realm"])
            if newEventsConfig is not None:  # If there is event configuration
                # Get the existing events config
                eventsConfig = kc.get_realm_events_config(
                    realm=newRealmRepresentation["realm"])
                if not isDictEquals(newEventsConfig,
                                    eventsConfig):  # If realm needs changed
                    # Update event config
                    eventsConfig = kc.update_realm_events_config(
                        realm=newRealmRepresentation["realm"],
                        newEventsConfig=newEventsConfig)
                result["eventsConfig"] = eventsConfig
            result["realm"] = realmRepresentation
        else:  # If desired state is absent
            # Delete Realm
            kc.delete_realm(newRealmRepresentation["realm"])
            changed = True
            result["msg"] = 'Realm %s deleted' % (
                newRealmRepresentation["realm"])
    result["changed"] = changed
    module.exit_json(**result)