From a0dba0eb75f80dafcbc8f8e72768b3d1a00e9847 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robin=20Hru=C5=A1ka?= Date: Wed, 12 Jun 2024 11:37:45 +0200 Subject: [PATCH] use custom response codes for tenant-related authorization errors --- seacatauth/openidconnect/handler/authorize.py | 19 +++++++++++++++---- seacatauth/openidconnect/service.py | 9 +++------ seacatauth/tenant/service.py | 2 ++ 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/seacatauth/openidconnect/handler/authorize.py b/seacatauth/openidconnect/handler/authorize.py index a595b62a..d5b377a7 100644 --- a/seacatauth/openidconnect/handler/authorize.py +++ b/seacatauth/openidconnect/handler/authorize.py @@ -454,12 +454,17 @@ async def authorization_code_flow( has_access_to_all_tenants=self.OpenIdConnectService.RBACService.can_access_all_tenants( root_session.Authorization.Authz) ) + except exceptions.NoTenantsError: + raise OAuthAuthorizeError( + AuthErrorResponseCode.NoTenants, client_id, + redirect_uri=redirect_uri, + state=state, + ) except exceptions.AccessDeniedError: raise OAuthAuthorizeError( - AuthErrorResponseCode.AccessDenied, client_id, + AuthErrorResponseCode.TenantAccessDenied, client_id, redirect_uri=redirect_uri, state=state, - struct_data={"reason": "tenant_not_found"} ) if auth_token_type == "openid": @@ -516,12 +521,18 @@ async def authorization_code_flow( requested_scope, anonymous_cid, has_access_to_all_tenants=self.OpenIdConnectService.RBACService.can_access_all_tenants(authz) ) + except exceptions.NoTenantsError: + raise OAuthAuthorizeError( + AuthErrorResponseCode.NoTenants, client_id, + redirect_uri=redirect_uri, + state=state, + ) except exceptions.AccessDeniedError: raise OAuthAuthorizeError( - AuthErrorResponseCode.AccessDenied, client_id, + AuthErrorResponseCode.TenantAccessDenied, client_id, redirect_uri=redirect_uri, state=state, - struct_data={"reason": "tenant_not_found"}) + ) if auth_token_type == "openid": new_session = await self.OpenIdConnectService.create_anonymous_oidc_session( diff --git a/seacatauth/openidconnect/service.py b/seacatauth/openidconnect/service.py index a76df555..ddc4b7f1 100644 --- a/seacatauth/openidconnect/service.py +++ b/seacatauth/openidconnect/service.py @@ -427,7 +427,7 @@ async def get_accessible_tenant_from_scope( scope: typing.Iterable, credentials_id: str, has_access_to_all_tenants: bool = False - ): + ) -> typing.Optional[str]: """ Extract tenants from requested scope and return the first accessible one. """ @@ -435,13 +435,10 @@ async def get_accessible_tenant_from_scope( tenants: set = await self.TenantService.get_tenants_by_scope( scope, credentials_id, has_access_to_all_tenants) except exceptions.TenantNotFoundError as e: - L.error("Tenant not found", struct_data={"tenant": e.Tenant}) + L.error("Tenant not found.", struct_data={"tenant": e.Tenant}) raise exceptions.AccessDeniedError(subject=credentials_id) except exceptions.TenantAccessDeniedError as e: - L.error("Tenant access denied", struct_data={"tenant": e.Tenant, "cid": credentials_id}) - raise exceptions.AccessDeniedError(subject=credentials_id) - except exceptions.NoTenantsError: - L.error("Tenant access denied", struct_data={"cid": credentials_id}) + L.log(asab.LOG_NOTICE, "Tenant access denied.", struct_data={"tenant": e.Tenant, "cid": credentials_id}) raise exceptions.AccessDeniedError(subject=credentials_id) if tenants: diff --git a/seacatauth/tenant/service.py b/seacatauth/tenant/service.py index 7306d7bc..92541cd7 100644 --- a/seacatauth/tenant/service.py +++ b/seacatauth/tenant/service.py @@ -319,6 +319,8 @@ async def get_tenants_by_scope(self, scope: list, credential_id: str, has_access elif has_access_to_all_tenants: await self.get_tenant(tenant) tenants.add(tenant) + elif not user_tenants: + raise exceptions.NoTenantsError(credential_id) else: raise exceptions.TenantAccessDeniedError(tenant, credential_id)