o
    pj                     @  s   d Z ddlmZ ddlZddlmZmZ ddlmZ ddlm	Z	 ddl
mZ ddlmZ dd	lmZmZmZ ed
ZG dd dZdS )z'Tenant/app-scoped credential lifecycle.    )annotationsN)datetimetimezone)Any)select)get_control_plane_session)VersionedAESCipher)AppTenantTenantSecretz^[a-z][a-z0-9_.-]{1,63}$c                   @  s   e Zd ZdZd&d'ddZddd	d(ddZddd)ddZddd*ddZddd+ddZe	d,ddZ
e	d-d d!Ze	d.d"d#Ze	d/d$d%ZdS )0SecretsManagerz=Store write-only credentials encrypted with tenant-bound AAD.NcipherVersionedAESCipher | NonereturnNonec                 C  s   |pt  | _d S N)r   from_environmentr   )selfr    r   *bridge_platform/secrets/secrets_manager.py__init__   s   zSecretsManager.__init__)app_idactor_id	tenant_idstrsecret_namesecret_valuer   
str | Noner   r   c          	      C  s   |  || | jj|| |||d}t M}| ||| || ||| }|d u r<t	||||j
d}|| |j
|_|j|_d|ttj d|_|  || |W  d    S 1 sfw   Y  d S )Naad)r   r   r   secret_value_encryptedzAES-256-GCM)	algorithm
updated_by
updated_at)_validate_inputr   encrypt_aadr   _validate_scopeexecute_queryscalar_one_or_noner   
ciphertextaddr    key_versionr   nowr   utc	isoformatmetadata_jsoncommitrefresh)	r   r   r   r   r   r   	encryptedsessionrecordr   r   r   
put_secret   s0   

$zSecretsManager.put_secret)r   c                C  sx   t  /}|| ||| }|d u r	 W d    d S | jj|j| |||dW  d    S 1 s5w   Y  d S )Nr   )r   r(   r)   r*   r   decryptr    r&   r   r   r   r   r5   r6   r   r   r   
get_secret6   s   $zSecretsManager.get_secretlist[dict[str, Any]]c                C  s   t  4}tttj|k}|d ur|tj|k}||tjtj	 
 }dd |D W  d    S 1 s:w   Y  d S )Nc                 S  s(   g | ]}|j |jd |j|j dqS )T)r   r   
configuredr-   r#   )r   r   r-   r#   r0   ).0r6   r   r   r   
<listcomp>F   s    
z7SecretsManager.list_secret_metadata.<locals>.<listcomp>)r   r   r   wherer   r   r(   order_byr   scalarsall)r   r   r   r5   	statementrecordsr   r   r   list_secret_metadata@   s   $z#SecretsManager.list_secret_metadataboolc                C  sr   t  ,}|| ||| }|d u r	 W d    dS || |  	 W d    dS 1 s2w   Y  d S )NFT)r   r(   r)   r*   deleter2   r9   r   r   r   delete_secretN   s   
$zSecretsManager.delete_secretc                 C  s*   t ttj| ktj|ktj|kdS )N   )r   r   r?   r   r   r   limitr   r   r   r   r   r   r)   W   s   zSecretsManager._querybytesc                 C  s    d|  d|pd d|  dS )Nztenant=z app=-z secret=utf-8)encoderK   r   r   r   r&   _   s    zSecretsManager._aadc                 C  s4   t | s	td|rt|ddkrtdd S )NzInvalid secret namerN   i @  z3Secret value must contain between 1 and 16384 bytes)SECRET_NAME_PATTERN	fullmatch
ValueErrorlenrO   )r   r   r   r   r   r$   c   s
   
zSecretsManager._validate_inputc                 C  sH   |  t|d u rtd| |r |  t|d u r"td| d S d S )NzTenant not found: zApp not found: )getr
   LookupErrorr	   )r5   r   r   r   r   r   r'   j   s
   zSecretsManager._validate_scoper   )r   r   r   r   )r   r   r   r   r   r   r   r   r   r   r   r   )r   r   r   r   r   r   r   r   )r   r   r   r   r   r;   )r   r   r   r   r   r   r   rF   )r   r   r   r   r   r   )r   r   r   r   r   r   r   rL   )r   r   r   r   r   r   )r   r   r   r   r   r   )__name__
__module____qualname____doc__r   r7   r:   rE   rH   staticmethodr)   r&   r$   r'   r   r   r   r   r      s     
	r   )rY   
__future__r   rer   r   typingr   
sqlalchemyr   config.control_planer   "bridge_platform.secrets.encryptionr   bridge_platform.tenants.modelsr	   r
   r   compilerP   r   r   r   r   r   <module>   s    
