Skip to content

Commit

Permalink
use custom response codes for tenant-related authorization errors
Browse files Browse the repository at this point in the history
  • Loading branch information
byewokko committed Jun 12, 2024
1 parent 5dc6067 commit a0dba0e
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 10 deletions.
19 changes: 15 additions & 4 deletions seacatauth/openidconnect/handler/authorize.py
Original file line number Diff line number Diff line change
Expand Up @@ -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":
Expand Down Expand Up @@ -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(
Expand Down
9 changes: 3 additions & 6 deletions seacatauth/openidconnect/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -427,21 +427,18 @@ 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.
"""
try:
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:
Expand Down
2 changes: 2 additions & 0 deletions seacatauth/tenant/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down

0 comments on commit a0dba0e

Please sign in to comment.