"""Connector to the ows-pdp microservice.""" import logging from json import JSONDecodeError from typing import Optional import httpx from owsclient import OwsClient from pydantic import ValidationError from python_pdp_sdk.backends.exceptions import PdpAuthenticationError from python_pdp_sdk.connectors.ows_pdp.models.check_resources_request import ( CheckResourcesRequest, ) from python_pdp_sdk.connectors.ows_pdp.models.check_resources_response import ( CheckResourcesResponse, ) from python_pdp_sdk.connectors.ows_pdp.models.get_allowed_tenants_request import ( GetAllowedTenantsRequest, ) from python_pdp_sdk.connectors.ows_pdp.models.get_allowed_tenants_response import ( GetAllowedTenantsResponse, ) from python_pdp_sdk.connectors.ows_pdp.models.roles_response import RolesResponse logger = logging.getLogger(__name__) class OwsPdpClient: """Connector to ows-pdp microservice.""" ows_client: OwsClient service_name = "ows-pdp" def __init__(self, ows_client: OwsClient) -> None: """Init method.""" self.ows_client = ows_client def check_my_resources( self, check_resources_request: CheckResourcesRequest ) -> CheckResourcesResponse: """Check resources for the authenticated principal.""" response = self.ows_client.post( self.service_name, path="/identity/self/check/resources/", json=check_resources_request.to_dict(), ) if response is None: logger.error( "Received unexpected response when checking resources", extra={ "library": { "name": "python-pdp-sdk", "language": "python", }, }, ) raise httpx.RequestError( message="Received unexpected response when checking resources" ) # Check for authentication failure (401) if response.status_code == 401: logger.warning( "Authentication failed when checking resources (401): %s", str(response.content), extra={ "library": { "name": "python-pdp-sdk", "language": "python", }, }, ) raise PdpAuthenticationError( f"Authentication failed when checking resources: {str(response.content)}" ) # Check for other non-200 status codes if response.status_code != 200: logger.warning( "Request to check resources failed with status %s: %s", response.status_code, str(response.content), extra={ "library": { "name": "python-pdp-sdk", "language": "python", }, }, ) raise httpx.RequestError( message=f"Request to check resources failed with status {response.status_code}: {str(response.content)}" ) try: result = CheckResourcesResponse.from_json( str(response.content, encoding="utf-8") ) except (JSONDecodeError, ValidationError) as e: raise httpx.DecodingError( f"Response from check resources could not be parsed: {str(response.content)}" ) from e if not result: raise httpx.DecodingError( f"Response from check resources could not be parsed: {str(response.content)}" ) return result def get_my_roles(self) -> RolesResponse: """Get the authenticated user's roles.""" raise NotImplementedError def get_allowed_tenants( self, get_allowed_tenants_request: GetAllowedTenantsRequest ) -> Optional[GetAllowedTenantsResponse]: """Get allowed tenants for resource type - action.""" response = self.ows_client.post( self.service_name, path="/identity/self/allowed-tenants/", json=get_allowed_tenants_request.to_dict(), ) if response is None: logger.error( "Received unexpected response when getting allowed tenants", extra={ "library": { "name": "python-pdp-sdk", "language": "python", }, }, ) raise httpx.RequestError( message="Received unexpected response when getting allowed tenants" ) # Check for authentication failure (401) if response.status_code == 401: logger.warning( "Authentication failed when getting allowed tenants (401): %s", str(response.content), extra={ "library": { "name": "python-pdp-sdk", "language": "python", }, }, ) raise PdpAuthenticationError( f"Authentication failed when getting allowed tenants: {str(response.content)}" ) # Check for other non-200 status codes if response.status_code != 200: logger.warning( "Request to get allowed tenants failed with status %s: %s", response.status_code, str(response.content), extra={ "library": { "name": "python-pdp-sdk", "language": "python", }, }, ) raise httpx.RequestError( message=f"Request to get allowed tenants failed with status {response.status_code}: {str(response.content)}" ) try: result = GetAllowedTenantsResponse.from_json( str(response.content, encoding="utf-8") ) except (JSONDecodeError, ValidationError) as e: raise httpx.DecodingError( f"Response from get allowed tenants could not be parsed: {str(response.content)}" ) from e if not result: raise httpx.DecodingError( f"Response from get allowed tenants could not be parsed: {str(response.content)}" ) return result