Add keycloak_authz_authorization scope module (#6256)

* Add keycloak_authz_authorization scope module

This module allows managing Keycloak client authorization scopes. The client has
to have authorization enable for this to work.

* botmeta: make mattock maintainer of keycloak_authz_authorization_scope

* botmeta: add mattock to team_keycloak

* keycloak_authz_authorization_scope: documentation and code layout fixes

* keycloak_authz_authorization_scope: do not fail on names with whitespace

* keycloak_authz_authorization_scope: use url quote method

Co-authored-by: Felix Fontein <felix@fontein.de>

* keycloak_authz_authorization_scope: style fixes to documentation

* keycloak_authz_authorization_scope: do not claim check/diff mode support

* keycloak_authz_authorization_scope: fix documentation

* keycloak_authz_authorization_scope: support check_mode and diff_mode

* keycloak_authz_authorization_scope: use more common terminology

Most keycloak modules use before_<object_type> and desired_<object_type> to
designate current and desired states of objects. Do the same for authorization
scopes.

* keycloak_authz_authorization_scope: fixes to check_mode and docs

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
This commit is contained in:
Samuli Seppänen 2023-04-23 15:07:58 +03:00 committed by GitHub
parent e7cc996470
commit bc228d82be
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 604 additions and 1 deletions

View file

@ -90,6 +90,9 @@ URL_IDENTITY_PROVIDER_MAPPER = "{url}/admin/realms/{realm}/identity-provider/ins
URL_COMPONENTS = "{url}/admin/realms/{realm}/components"
URL_COMPONENT = "{url}/admin/realms/{realm}/components/{id}"
URL_AUTHZ_AUTHORIZATION_SCOPE = "{url}/admin/realms/{realm}/clients/{client_id}/authz/resource-server/scope/{id}"
URL_AUTHZ_AUTHORIZATION_SCOPES = "{url}/admin/realms/{realm}/clients/{client_id}/authz/resource-server/scope"
def keycloak_argument_spec():
"""
@ -2331,3 +2334,44 @@ class KeycloakAPI(object):
except Exception as e:
self.module.fail_json(msg='Unable to delete component %s in realm %s: %s'
% (cid, realm, str(e)))
def get_authz_authorization_scope_by_name(self, name, client_id, realm):
url = URL_AUTHZ_AUTHORIZATION_SCOPES.format(url=self.baseurl, client_id=client_id, realm=realm)
search_url = "%s/search?name=%s" % (url, quote(name))
try:
return json.loads(to_native(open_url(search_url, method='GET', http_agent=self.http_agent, headers=self.restheaders,
timeout=self.connection_timeout,
validate_certs=self.validate_certs).read()))
except Exception:
return False
def create_authz_authorization_scope(self, payload, client_id, realm):
"""Create an authorization scope for a Keycloak client"""
url = URL_AUTHZ_AUTHORIZATION_SCOPES.format(url=self.baseurl, client_id=client_id, realm=realm)
try:
return open_url(url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout,
data=json.dumps(payload), validate_certs=self.validate_certs)
except Exception as e:
self.module.fail_json(msg='Could not create authorization scope %s for client %s in realm %s: %s' % (payload['name'], client_id, realm, str(e)))
def update_authz_authorization_scope(self, payload, id, client_id, realm):
"""Update an authorization scope for a Keycloak client"""
url = URL_AUTHZ_AUTHORIZATION_SCOPE.format(url=self.baseurl, id=id, client_id=client_id, realm=realm)
try:
return open_url(url, method='PUT', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout,
data=json.dumps(payload), validate_certs=self.validate_certs)
except Exception as e:
self.module.fail_json(msg='Could not create update scope %s for client %s in realm %s: %s' % (payload['name'], client_id, realm, str(e)))
def remove_authz_authorization_scope(self, id, client_id, realm):
"""Remove an authorization scope from a Keycloak client"""
url = URL_AUTHZ_AUTHORIZATION_SCOPE.format(url=self.baseurl, id=id, client_id=client_id, realm=realm)
try:
return open_url(url, method='DELETE', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout,
validate_certs=self.validate_certs)
except Exception as e:
self.module.fail_json(msg='Could not delete scope %s for client %s in realm %s: %s' % (id, client_id, realm, str(e)))