From 2698a578df0292e19779e12b410c5fd4fe49f45f Mon Sep 17 00:00:00 2001 From: Helmut Merz Date: Fri, 25 Jul 2025 19:53:26 +0200 Subject: [PATCH] work in progress: send user data to external identity provider (zitadel) --- demo/config.py | 6 +++--- scopes/org/user.py | 37 ++++++++++++++++++++++++++++++++++++- scopes/tests/config.py | 4 ++++ scopes/web/auth/oidc.py | 4 ++-- scopes/web/client.py | 2 +- 5 files changed, 46 insertions(+), 7 deletions(-) diff --git a/demo/config.py b/demo/config.py index c2fa091..f40a010 100644 --- a/demo/config.py +++ b/demo/config.py @@ -34,6 +34,7 @@ oidc_params = dict( op_config_url=oidc_provider + '/.well-known/openid-configuration', op_uris=None, op_keys=None, + op_project_scope='urn:zitadel:iam:org:project:id:zitadel:aud', callback_url=getenv('OIDC_CALLBACK_URL', base_url + '/auth/callback'), client_id = oidc_client_id, cookie_name=getenv('OIDC_COOKIE_NAME', 'oidc_' + oidc_client_id), @@ -43,7 +44,6 @@ oidc_params = dict( private_key_file=getenv('OIDC_SERVICE_USER_PRIVATE_KEY_FILE', '.private-key.json'), ) -# access zitadel API -zitadel_params = dict( - private_key_file=getenv('ZITADEL_SERVICE_USER_PRIVATE_KEY_FILE', '.private-key.json') +oidc_provider_endpoints = dict( + user='v2/users/human', ) diff --git a/scopes/org/user.py b/scopes/org/user.py index 8179e47..4f853bf 100644 --- a/scopes/org/user.py +++ b/scopes/org/user.py @@ -1,8 +1,43 @@ # scopes.org.user -"""Basic user (principal) definitions + access to auth service (zitadel).""" +"""Basic user account (principal) definitions + access to identity provider.""" from scopes.web import client from scopes import util import config + + +@dataclass +class User: + + name: str + login: str + email: str + fullName: str + + +class ExtUser: + """All infos for exchanging user data with an external service. + + This base class implements the zitadel interface. For other + identity providers sublass accordingly. + """ + + provider = 'zitatel' + endpoints = dict( + users='v2/users', + ) + + def __init__(self, user, organization, userId=None, userIdPrefix=''): + self.user = user + + def asDict(self): + return dict(username=self.user.name) + + def send(self): + clt = client.ApiClient(config.oidc_provider) + data = self.asDict() + res = clt.post(config.oidc_provider_endpoints['users'], data) + + grants: List[str] diff --git a/scopes/tests/config.py b/scopes/tests/config.py index 19dac0f..ea11118 100644 --- a/scopes/tests/config.py +++ b/scopes/tests/config.py @@ -55,3 +55,7 @@ oidc_params = dict( cookie_crypt=getenv('OIDC_COOKIE_CRYPT', None), private_key_file=getenv('OIDC_SERVICE_USER_PRIVATE_KEY_FILE', '.private-key.json'), ) + +oidc_provider_endpoints = dict( + user='v2/users/human', +) diff --git a/scopes/web/auth/oidc.py b/scopes/web/auth/oidc.py index 76bd12d..5052c23 100644 --- a/scopes/web/auth/oidc.py +++ b/scopes/web/auth/oidc.py @@ -265,7 +265,7 @@ def authenticateClient(paramsName='oidc_params'): headers=dict(alg='RS256', kid=keyId)) data = dict( grant_type='urn:ietf:params:oauth:grant-type:jwt-bearer', - scope='openid urn:zitadel:iam:org:project:id:zitadel:aud', + scope=' '.join(('openid', params['op_project_scope'])) assertion=jwToken, ) headers = {'Content-Type': 'application/x-www-form-urlencoded'} @@ -276,7 +276,7 @@ def authenticateClient(paramsName='oidc_params'): logger.error('authenticateClient: %s', resp.text) return None tdata = resp.json() - print(tdata) + #print(tdata) return tdata['access_token'] def loadPrivateKeyData(fn='.private-key.json'): diff --git a/scopes/web/client.py b/scopes/web/client.py index 37e313f..8c081a8 100644 --- a/scopes/web/client.py +++ b/scopes/web/client.py @@ -21,7 +21,7 @@ class ApiClient: def post(self, endpoint, data): headers = self.authentication() # self.makeUrl(endpoint) - url = '/'.join(self.bareUrl, endpoint) + url = '/'.join(self.baseUrl, endpoint) resp = requests.post(url, data=data, headers=headers) # check: resp.status_code data = resp.json()