o
    pj                     @  s   d Z ddlmZ ddlZddlZddlmZmZ ddlm	Z	m
Z
mZ ddlmZ ddlmZmZ ddlmZ dd	lmZmZ dd
lmZ G dd dZdS )z;Runtime API gateway for tenant-aware SaaS request handling.    )annotationsN)Requestjsonify)AuthenticatedIdentityAuthenticationErrorauthenticate_request)subscription_allows_app)get_platform_loggerlog_structured)build_request_context)QuotaExceededconsume)resolve_tenantc                   @  s4   e Zd ZdZdddZdddddZdddZdS )
APIGatewayz?Resolve tenant context and dispatch requests into app handlers.returnNonec                 C  s   t d| _d S )Napi_gateway)r	   logger)self r   A/var/www/html/flask_server/bridge_platform/gateway/api_gateway.py__init__   s   zAPIGateway.__init__N)trusted_identityflask_requestr   app_namestractionr   AuthenticatedIdentity | Nonec                C  s^  z|pt |}t||j}t||||jd}W n ty4 } ztdt|ddfW  Y d}~S d}~w tyP } ztdt|ddfW  Y d}~S d}~w t	yl } ztdt|ddfW  Y d}~S d}~w t
y } ztdt|ddfW  Y d}~S d}~w ty } ztdd	| dd
fW  Y d}~S d}~ww |jdpd }	|	r|	|krtdd|	 d| ddfS |j|d krtddddfS |jdpd }
|
r|
|jkrtddddfS ||d< |j|d< t|jdp|jdpd|d< t|j|stdd| ddfS |d dds4tdd| ddfS |du rWd| d}||jvrWd |jvrWtdd!| ddfS zt|j|d"||d# d$d% W n# ty } ztdd&t||j d'd(fW  Y d}~S d}~ww t| jd)|d# |d* d |d ||j|j|d|jd+
 | |||S ),z:Handle one incoming request through the SaaS runtime flow.)app_iduser_iderrorstatusmessagei  Ni    i  zGateway failure:   zX-App-ID zX-App-ID mismatch: header=z path=	tenant_idz(JWT tenant does not match request tenantz	X-User-IDz$X-User-ID does not match JWT subjectidentityr   caller_app_idr   wordpress_bridgerequesting_appz!Subscription does not allow app: 
app_configenabledFzApp is not enabled: zapp:z:invokezapp:*:invokezMissing required scope: requests
request_id)r   r/   )r'   r   metricmetadataquota_exceeded)r"   coder#   quotai  gateway_requesttenant)r/   r'   r   r   methodpathr   remote_addr)r   r   r'   r   subjectr   r   r   
ValueErrorLookupErrorPermissionError	Exceptionheadersgetstripclaimsr   scopesr   r   decisionto_dictr
   r   r7   r8   r9   route_to_app)r   r   r   r   r   r(   tenant_datacontextexcheader_app_idheader_user_idrequired_scoper   r   r   handle   s   	
""""$




zAPIGateway.handlerH   dict[str, object]c           
      C  s  t jd| d u rtdd| ddfS z
t d| }W n! tyB } ztdd| d| ddfW  Y d }~S d }~ww t|d	d }|d u rYtdd
| ddfS z|||}W n@ ty } z4t| jd|	dt
|	dtr|	dp~i 	dnd ||t|d tdt|ddfW  Y d }~S d }~ww t
|tr|\}}	t
|trt||	fS ||	fS t
|trt|S |S )Nzapps.r    zUnknown app: r!   r$   zFailed to load app z: r%   handle_requestz$App does not expose handle_request: gateway_app_errorr/   r6   r'   )r/   r'   r   r   r#   )	importlibutil	find_specr   import_moduler>   getattrr
   r   r@   
isinstancedictr   tuple)
r   rH   r   r   modulerI   handlerresultpayloadstatus_coder   r   r   rF      sD   *&"	


zAPIGateway.route_to_app)r   r   )r   r   r   r   r   r   r   r   )rH   rN   r   r   r   r   )__name__
__module____qualname____doc__r   rM   rF   r   r   r   r   r      s    
	er   )ra   
__future__r   rQ   importlib.utilflaskr   r   bridge_platform.auth.jwt_authr   r   r   $bridge_platform.entitlements.servicer   'bridge_platform.logging.platform_loggerr	   r
   'bridge_platform.gateway.request_contextr   bridge_platform.quotas.servicer   r   'bridge_platform.tenants.tenant_resolverr   r   r   r   r   r   <module>   s    