mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-07-22 04:40:22 -07:00
[PR #5606/7ea544a6 backport][stable-6] New Module: Keycloak ClientSecret with PR changes (#5654)
New Module: Keycloak ClientSecret with PR changes (#5606)
* feat(plugins/keycloak): add get and create util function for client secret
* feat(plugins/keycloak): add client secret module
* chore: add maintainer in BOTMETA
* Update plugins/modules/identity/keycloak/keycloak_clientsecret.py
Co-authored-by: Felix Fontein <felix@fontein.de>
* Make changes to keycloak_clientsecret from PR
* Add SPDX identifier for keycloak_clientsecret
* Add copyright in keycloak_clientsecret for REUSE
* Add integration test for keycloak_clientsecret
* rm clientsecret from keycloak_clientsecret result
- end_state used instead
* keycloak_clientsecret: Undo meta/runtime.yml change
* Fix sanity tests for keycloak_clientsecret
* New keycloak_clientsecret_info module
- Replaces keycloak_clientsecret
- Module definition and some common logic moved into module_utils
- Update documentation, tests, etc.
- Add myself as author
* Misc fixes to keycloak_clientsecret_info
* Add keycloak_clientsecret_regenerate module
* keycloak_clientsecret* Update .github/BOTMETA.yml
* keycloak_clientsecret_regenerate: Fix sanity tests
* Fix README for keycloak_clientsecret integration test
* Separate out keycloak_clientsecret module_utils
* Keycloak_clientsecret module_utils: boilerplate
* Update plugins/modules/keycloak_clientsecret_info.py
Co-authored-by: Felix Fontein <felix@fontein.de>
* Update plugins/modules/keycloak_clientsecret_info.py
Co-authored-by: Felix Fontein <felix@fontein.de>
* Update plugins/modules/keycloak_clientsecret_info.py
Co-authored-by: Felix Fontein <felix@fontein.de>
* Update plugins/modules/keycloak_clientsecret_info.py
Co-authored-by: Felix Fontein <felix@fontein.de>
* Update plugins/modules/keycloak_clientsecret_info.py
Co-authored-by: Felix Fontein <felix@fontein.de>
* Update plugins/modules/keycloak_clientsecret_info.py
Co-authored-by: Felix Fontein <felix@fontein.de>
* keycloak_clientsecret: Add no_log to examples and docs
* keycloak_clientsecret: Update BOTMETA
* Update .github/BOTMETA.yml
Co-authored-by: Felix Fontein <felix@fontein.de>
Co-authored-by: fynncfchen <fynn.cfchen@gmail.com>
Co-authored-by: Fynnnnn <ethan.cfchen@gmail.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 7ea544a624
)
Co-authored-by: John Cant <a.johncant@gmail.com>
This commit is contained in:
parent
671f850069
commit
8a231e4b36
13 changed files with 692 additions and 0 deletions
|
@ -58,6 +58,8 @@ URL_CLIENT_USER_ROLEMAPPINGS = "{url}/admin/realms/{realm}/users/{id}/role-mappi
|
|||
URL_CLIENT_USER_ROLEMAPPINGS_AVAILABLE = "{url}/admin/realms/{realm}/users/{id}/role-mappings/clients/{client}/available"
|
||||
URL_CLIENT_USER_ROLEMAPPINGS_COMPOSITE = "{url}/admin/realms/{realm}/users/{id}/role-mappings/clients/{client}/composite"
|
||||
|
||||
URL_CLIENTSECRET = "{url}/admin/realms/{realm}/clients/{id}/client-secret"
|
||||
|
||||
URL_AUTHENTICATION_FLOWS = "{url}/admin/realms/{realm}/authentication/flows"
|
||||
URL_AUTHENTICATION_FLOW = "{url}/admin/realms/{realm}/authentication/flows/{id}"
|
||||
URL_AUTHENTICATION_FLOW_COPY = "{url}/admin/realms/{realm}/authentication/flows/{copyfrom}/copy"
|
||||
|
@ -1160,6 +1162,52 @@ class KeycloakAPI(object):
|
|||
self.module.fail_json(msg='Could not update protocolmappers for clientscope %s in realm %s: %s'
|
||||
% (mapper_rep, realm, str(e)))
|
||||
|
||||
def create_clientsecret(self, id, realm="master"):
|
||||
""" Generate a new client secret by id
|
||||
|
||||
:param id: id (not clientId) of client to be queried
|
||||
:param realm: client from this realm
|
||||
:return: dict of credential representation
|
||||
"""
|
||||
clientsecret_url = URL_CLIENTSECRET.format(url=self.baseurl, realm=realm, id=id)
|
||||
|
||||
try:
|
||||
return json.loads(to_native(open_url(clientsecret_url, method='POST', headers=self.restheaders, timeout=self.connection_timeout,
|
||||
validate_certs=self.validate_certs).read()))
|
||||
|
||||
except HTTPError as e:
|
||||
if e.code == 404:
|
||||
return None
|
||||
else:
|
||||
self.module.fail_json(msg='Could not obtain clientsecret of client %s for realm %s: %s'
|
||||
% (id, realm, str(e)))
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Could not obtain clientsecret of client %s for realm %s: %s'
|
||||
% (id, realm, str(e)))
|
||||
|
||||
def get_clientsecret(self, id, realm="master"):
|
||||
""" Obtain client secret by id
|
||||
|
||||
:param id: id (not clientId) of client to be queried
|
||||
:param realm: client from this realm
|
||||
:return: dict of credential representation
|
||||
"""
|
||||
clientsecret_url = URL_CLIENTSECRET.format(url=self.baseurl, realm=realm, id=id)
|
||||
|
||||
try:
|
||||
return json.loads(to_native(open_url(clientsecret_url, method='GET', headers=self.restheaders, timeout=self.connection_timeout,
|
||||
validate_certs=self.validate_certs).read()))
|
||||
|
||||
except HTTPError as e:
|
||||
if e.code == 404:
|
||||
return None
|
||||
else:
|
||||
self.module.fail_json(msg='Could not obtain clientsecret of client %s for realm %s: %s'
|
||||
% (id, realm, str(e)))
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Could not obtain clientsecret of client %s for realm %s: %s'
|
||||
% (id, realm, str(e)))
|
||||
|
||||
def get_groups(self, realm="master"):
|
||||
""" Fetch the name and ID of all groups on the Keycloak server.
|
||||
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2022, John Cant <a.johncant@gmail.com>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.identity.keycloak.keycloak import \
|
||||
keycloak_argument_spec
|
||||
|
||||
|
||||
def keycloak_clientsecret_module():
|
||||
"""
|
||||
Returns an AnsibleModule definition for modules that interact with a client
|
||||
secret.
|
||||
|
||||
:return: argument_spec dict
|
||||
"""
|
||||
argument_spec = keycloak_argument_spec()
|
||||
|
||||
meta_args = dict(
|
||||
realm=dict(default='master'),
|
||||
id=dict(type='str'),
|
||||
client_id=dict(type='str', aliases=['clientId']),
|
||||
)
|
||||
|
||||
argument_spec.update(meta_args)
|
||||
|
||||
module = AnsibleModule(
|
||||
argument_spec=argument_spec,
|
||||
supports_check_mode=True,
|
||||
required_one_of=([['id', 'client_id'],
|
||||
['token', 'auth_realm', 'auth_username', 'auth_password']]),
|
||||
required_together=([['auth_realm', 'auth_username', 'auth_password']]),
|
||||
mutually_exclusive=[
|
||||
['token', 'auth_realm'],
|
||||
['token', 'auth_username'],
|
||||
['token', 'auth_password']
|
||||
])
|
||||
|
||||
return module
|
||||
|
||||
|
||||
def keycloak_clientsecret_module_resolve_params(module, kc):
|
||||
"""
|
||||
Given an AnsibleModule definition for keycloak_clientsecret_*, and a
|
||||
KeycloakAPI client, resolve the params needed to interact with the Keycloak
|
||||
client secret, looking up the client by clientId if necessary via an API
|
||||
call.
|
||||
|
||||
:return: tuple of id, realm
|
||||
"""
|
||||
|
||||
realm = module.params.get('realm')
|
||||
id = module.params.get('id')
|
||||
client_id = module.params.get('client_id')
|
||||
|
||||
# only lookup the client_id if id isn't provided.
|
||||
# in the case that both are provided, prefer the ID, since it's one
|
||||
# less lookup.
|
||||
if id is None:
|
||||
# Due to the required_one_of spec, client_id is guaranteed to not be None
|
||||
client = kc.get_client_by_clientid(client_id, realm=realm)
|
||||
|
||||
if client is None:
|
||||
module.fail_json(
|
||||
msg='Client does not exist {client_id}'.format(client_id=client_id)
|
||||
)
|
||||
|
||||
id = client['id']
|
||||
|
||||
return id, realm
|
Loading…
Add table
Add a link
Reference in a new issue