"""Application configuration.""" import logging import os from os.path import abspath, dirname, join, pardir import boto3 from confluent_kafka.schema_registry import SchemaRegistryClient from dotenv import load_dotenv from owsclient import OwsClient from owsrequest.ows_client import correlation_id_getter, request_context_getter from python_pdp_sdk.backends.authorization_backend import ( AuthorizationBackend, PdpAuthorizationBackend, ) from python_pdp_sdk.connectors.ows_pdp.ows_pdp import OwsPdpClient from secrets_manager.flask_ext import FlaskSecretsManager from payee.connectors.secure_data.manager import get_cryptographic_materials_provider from payee.constants.constants import ( DOCUMENTS_ALTAFONTE_APP_BRAND, DOCUMENTS_AWAL_APP_BRAND, DOCUMENTS_ORCHARD_APP_BRAND, ) # Load environment variables from a .env file if present dotenv_path = abspath(join(dirname(__file__), pardir, '.env')) load_dotenv(dotenv_path) class Config: """Base application configuration. Subclass and override for specific environments. """ # Service information SERVICE_NAME = 'ows-payee' SERVICE_VERSION = '1.0.0' SERVICE_PROFILE_HEADERS = { 'Orchard-Profile-Id': '133641', 'Orchard-Profile-Type': 'AbacusProfile', 'Orchard-Identity-Id': 'bee3c0db-1776-4854-a9b5-5e21214f4c78', 'Orchard-Roles': 'administrator', } # Production environment PROD_ENVIRONMENT = 'prod' DEV_ENVIRONMENT = 'dev' QA_ENVIRONMENT = 'qa' UAT_ENVIRONMENT = 'uat' ENVIRONMENT = os.environ.get('Environment', DEV_ENVIRONMENT) # Errors and loggers SENTRY_ENVIRONMENT = ( 'production' if ENVIRONMENT == PROD_ENVIRONMENT else ENVIRONMENT ) SENTRY = os.environ.get('SENTRY_DSN') or None LOGGER_LEVEL = os.environ.get('LOGGER_LEVEL', logging.INFO) LOGGER_NAME = 'ows1' ONLY_LOG_ACCESS_ERRORS = False # Generic handlers HEALTH_CHECK = '/hello/' # Swagger documentation path SWAGGER_FILE_PATH = 'spec/ows_payee-1.0.0.yaml' # Mysql database connection MYSQL_DB_USER = os.environ.get('MYSQL_DB_USER') MYSQL_DB_PASS = os.environ.get('MYSQL_DB_PASS') MYSQL_DB_HOST = os.environ.get('MYSQL_DB_HOST') MYSQL_DB_NAME = os.environ.get('MYSQL_DB_NAME', 'royalty_accounting') MYSQL_DB_PORT = os.environ.get('MYSQL_DB_PORT', '3306') MYSQL_DB_PORT = int(MYSQL_DB_PORT) TESTING_OBJECT_PREFIX = 'orcd_autotest' ERROR_ENTITY_DOES_NOT_EXIST = '{object_type} {object_id} does not exist.' ERROR_PERMISSION_DENIED = 'Permission denied.' SQLALCHEMY_ENGINE_OPTIONS = {'pool_size': 15, 'pool_timeout': 1, 'max_overflow': 0} AWS_DEFAULT_REGION = os.environ.get('AWS_DEFAULT_REGION', 'us-east-1') # Secure document manager SDM_CONFIG = { 'KMS_KEY_ID': os.environ.get('KMS_KEY_ID'), 'CMP': None, 'DYNAMODB_TABLE_NAME': os.environ.get('DYNAMODB_TABLE_NAME'), 'DYNAMODB_CONNECTION': { 'region_name': os.environ.get('DYNAMODB_REGION', AWS_DEFAULT_REGION), }, } DYNAMODB_URL = os.environ.get('DYNAMODB_URL') if DYNAMODB_URL and ENVIRONMENT not in [ QA_ENVIRONMENT, UAT_ENVIRONMENT, PROD_ENVIRONMENT, ]: SDM_CONFIG['DYNAMODB_CONNECTION'].update({'endpoint_url': DYNAMODB_URL}) PAYONEER_API_URL = os.environ.get( 'PAYONEER_API_URL', 'https://api.sandbox.payoneer.com' ) PAYONEER_API_BASE_AUTH_URL = os.environ.get( 'PAYONEER_API_AUTH_URL', 'https://login.sandbox.payoneer.com' ) PAYONEER_AUTH_TOKEN_ARN = os.environ.get('PAYONEER_AUTH_TOKEN_ARN') PAYONEER_CLIENT_ID = os.environ.get('PAYONEER_CLIENT_ID') PAYONEER_CLIENT_SECRET = os.environ.get('PAYONEER_CLIENT_SECRET') PAYONEER_WFORM_CLIENT_CREDS = os.environ.get('PAYONEER_WFORM_CLIENT_CREDS') PAYONEER_REDIRECT_URL = { DOCUMENTS_ORCHARD_APP_BRAND: os.environ.get('PAYONEER_REDIRECT_URL_ORCHARD'), DOCUMENTS_AWAL_APP_BRAND: os.environ.get('PAYONEER_REDIRECT_URL_AWAL'), DOCUMENTS_ALTAFONTE_APP_BRAND: os.environ.get( 'PAYONEER_REDIRECT_URL_ALTAFONTE' ), } PAYONEER_REDIRECT_TIME = os.environ.get('PAYONEER_REDIRECT_TIME', 10) PAYONEER_SHARED_SECRET = os.environ.get('PAYONEER_SHARED_SECRET', '') PAYONEER_STATUS_URL = os.environ.get( 'PAYONEER_STATUS_URL', 'https://status.payoneer.com' ) MAX_BACKOFF_TRIES = int(os.environ.get('MAX_BACKOFF_TRIES', 3)) OWS_PAYEE_S3_BUCKET = os.environ.get('OWS_PAYEE_S3_BUCKET') PDF_FILES_FOLDER = os.environ.get('PDF_FILES_FOLDER', 'pdf_files') # Time in seconds for the S3 URL to remain valid S3_PRESIGNED_URL_EXPIRATION_TIME = os.environ.get( 'S3_PRESIGNED_URL_EXPIRATION_TIME', 30 ) # Kafka config KAFKA_BOOTSTRAP_SERVERS = os.environ.get('KAFKA_BOOTSTRAP_SERVERS') SCHEMA_REGISTRY_URL = os.environ.get( 'SCHEMA_REGISTRY_URL', 'https://dev-schema-registry.dev.theorchard.io' ) KAFKA_PRODUCERS_BY_ACTION_NAME = {} # Segment config SEGMENT_WRITE_KEY = os.environ.get('SEGMENT_WRITE_KEY') # m2m identities to limit access to the endpoints with sensitive data # we keep this in env vars because we need to provide access for extra # identities on QA env to support e2e ad integration testing flows BANK_DETAILS_SERVICE_IDENTITIES = os.environ.get( 'BANK_DETAILS_SERVICE_IDENTITIES', '' ).split(',') TAX_FORM_SERVICE_IDENTITIES = os.environ.get( 'TAX_FORM_SERVICE_IDENTITIES', '' ).split(',') PAYONEER_SERVICE_IDENTITIES = os.environ.get( 'PAYONEER_SERVICE_IDENTITIES', '' ).split(',') # HMRC config HMRC_API_URL = os.environ.get( 'HMRC_API_URL', 'https://test-api.service.hmrc.gov.uk' ) HMRC_API_AUTH_TOKEN_ARN = os.environ.get('HMRC_API_AUTH_TOKEN_ARN') HMRC_API_CLIENT_ID = os.environ.get('HMRC_API_CLIENT_ID') HMRC_API_CLIENT_SECRET = os.environ.get('HMRC_API_CLIENT_SECRET') # FlaskSecretsManager fails if we try to retrieve secrets outside of the config # Since we need to retrieve the latest token, we use a normal client secrets_manager_client = None s3_client = None if Config.ENVIRONMENT in ( Config.PROD_ENVIRONMENT, Config.UAT_ENVIRONMENT, Config.QA_ENVIRONMENT, ): secrets_manager_client = boto3.client( service_name='secretsmanager', region_name=Config.AWS_DEFAULT_REGION ) s3_client = boto3.client(service_name='s3', region_name=Config.AWS_DEFAULT_REGION) flask_secrets_manager_client = FlaskSecretsManager( application_context=False, environment=Config.ENVIRONMENT, service_name=Config.SERVICE_NAME, force_remote=True if Config.ENVIRONMENT == Config.DEV_ENVIRONMENT else False, ) def get_cred_value(cred_name): """Return secrets value for given cred_name.""" return flask_secrets_manager_client.get_cred(cred_name) if Config.ENVIRONMENT in ( Config.PROD_ENVIRONMENT, Config.QA_ENVIRONMENT, Config.UAT_ENVIRONMENT, ): Config.PAYONEER_CLIENT_ID = get_cred_value('payoneer_client_id') Config.PAYONEER_CLIENT_SECRET = get_cred_value('payoneer_client_secret') Config.PAYONEER_SHARED_SECRET = get_cred_value('payoneer_shared_secret') Config.PAYONEER_WFORM_CLIENT_CREDS = get_cred_value('payoneer_wform_client_creds') Config.SEGMENT_WRITE_KEY = get_cred_value('segment_write_key') Config.MYSQL_DB_PASS = get_cred_value('MYSQL_DB_PASS') Config.HMRC_API_CLIENT_ID = get_cred_value('hmrc_api_client_id') Config.HMRC_API_CLIENT_SECRET = get_cred_value('hmrc_api_client_secret') schema_registry_client = SchemaRegistryClient({'url': Config.SCHEMA_REGISTRY_URL}) cmp = get_cryptographic_materials_provider(Config) def setup_ows_client() -> OwsClient: """Set up ows-client.""" return OwsClient( environment=Config.ENVIRONMENT, service_name=Config.SERVICE_NAME, correlation_id_getter=correlation_id_getter, request_context_getter=request_context_getter, ) def setup_authorization_backend(ows_client: OwsClient) -> AuthorizationBackend: """Set up Authorization Backend.""" return PdpAuthorizationBackend(ows_pdp_client=OwsPdpClient(ows_client=ows_client)) ows_client = setup_ows_client() authorization_backend = setup_authorization_backend(ows_client)