o
    :F¶dvI  ã                   @   sò  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 d dlmZ d dl	m
Z
 d dlZd dlZd dlZd dlZd dlZd d	lmZ d dlZd d
lmZmZmZ d dlZd dlZd dlZd dlZd dlm  mZ dZdZdZ ej!dddej"dd„ ƒƒZ#e#j$dddej%dd &ej'j(¡dej%dddej%ddddej%de 
¡ ddej%d ej)d!d"ej%d#ej*d$d"ej%d%d&dej%d'd(dej%d)dd*dej+ej,ej-d+d„ ƒƒƒƒƒƒƒƒƒƒƒƒƒZ.e#j$d,d-dej%d.dd/dej+ej,ej-d0d,„ ƒƒƒƒƒZ/e#j$d1d2dej+ej,ej-d3d1„ ƒƒƒƒZ0e#j$d4d5dej+ej,ej-d6d4„ ƒƒƒƒZ1e#j$d7d8dej%d9dd:e 
¡ d;ej+ej%d<dd=dej,ej-d>d7„ ƒƒƒƒƒƒZ2e#j$d?d@dej%dAddBe 
¡ d;ej+ej%d<ddCdej,ej-dDdE„ ƒƒƒƒƒƒZ3dIdGdH„Z4dS )Jé    )Úprint_function)Úcli)Úcli_constants)Ú	cli_setup)Úcli_setup_bootstrap)Úcli_util)ÚPathN)Úrequests)ÚcopyÚmake_archiveÚrmtreeÚ_fileÚ_tokenÚzipZsessionzSession commands for CLI)Úhelpc                   C   s   d S ©N© r   r   r   ú7usr/lib/python3.10/site-packages/oci_cli/cli_session.pyÚsession_group!   s   r   ÚauthenticatezYCreates a CLI session using a browser based login flow. --region is a [required] argumentz--regionú,z--tenancy-namezName of the tenancyz--no-browserTzHTriggers user authentication without requiring interactive browser login)Zis_flagr   z--public-key-file-pathzcFull path of the public key PEM file that corresponds to the RSA key pair used for signing requests)Útyper   z--session-expiration-in-minuteszÎUser session expiration in minutes to which the requested user principal session token (UPST) is bounded. Valid values are from 5 to 60 for all realms. If not provided, a default value of 60 minutes if set.)Údefaultr   z--token-locationzlProvide the directory where you would like to store token and private/public key. Default is ~/.oci/sessionsz--profile-namez$Name of the profile you are creatingz--config-locationz&Path to the config for the new sessionz--use-passphrasezVProvide a passphrase to be used to encrypt the private key from the generated key pairc
              
   C   sô  | j d }|d u rt ¡ }d}
|rÐt|ƒttjƒkr$t d¡ t 	d¡ t|ƒttj
ƒk r7t d¡ t 	d¡ t dd| ¡}tj tj |	¡¡}t|ƒjddd	 |r|d}
zt |¡}W n tyx } zt d
¡ t 	d¡ W Y d }~nd }~ww d }nt ¡ }| ¡ }t |¡}tj|d d¡}dt | j d ¡i}||dœ}|jdd|i|¤Ž}t |j¡}|d }tj|dd}|d }|d }t  |||||||¡}nt !||¡}tj"||||dd|
d\}}t d #|¡¡ t dj#||tj$d¡ d S )NÚregionFz3Session expiration cannot be longer than 60 minutesé   z3Session expiration cannot be shorter than 5 minutesZidentity_data_planeZ	dataplaneT)ÚparentsÚexist_okz<Could not load public key from public-key-file-path provided)Ú
public_keyúUTF-8Zopc_request_idZ
request_id)Z	publicKeyZsessionExpirationInMinutesZ$generate_user_security_token_detailsÚtoken)ZverifyÚsubZtenant)Úprofile_nameÚconfigÚuse_passphraseZpersist_tokenZsession_authÚpersist_only_public_keyzConfig written to: {}z¯
    Try out your newly created session credentials with the following example command:

    oci iam region list --config-file {config_file} --profile {profile} --auth {auth}
©Úconfig_fileÚprofileÚauthr   )%Úobjr   Zprompt_for_regionÚintr   ÚOCI_CLI_UPST_TOKEN_MAX_TTLÚclickÚechoÚsysÚexitZOCI_CLI_UPST_TOKEN_MIN_TTLr   Úbuild_clientÚosÚpathÚnormpathÚ
expanduserr   ÚmkdirZget_public_key_from_fileÚ	ExceptionZgenerate_keyr   Zpublic_key_to_fingerprintZserialize_keyÚdecodeZuse_or_generate_request_idZgenerate_user_security_tokenZto_dictÚdataÚjwtr   ZUserSessionZcreate_user_sessionZpersist_user_sessionÚformatÚOCI_CLI_AUTH_SESSION_TOKEN)Úctxr   Ztenancy_namer!   Zconfig_locationr#   Z
no_browserZpublic_key_file_pathZsession_expiration_in_minutesZtoken_locationr$   ÚclientZ
token_pathr   ÚeÚprivate_keyZfingerprintZpublic_key_serializedÚkwargsZ_detailsÚresultÚresponser   Z
token_dataZ	user_ocidZtenancy_ocidZuser_sessionr'   r"   r   r   r   r   '   s^   





€þ

ÿþ
üÚvalidatez*Tests whether a CLI session is still validz--localzAOnly perform local validation of session by checking expiry time.c              
   C   sŠ  t j| jd< t | j¡}| jd }| d¡}|s(tjd |¡t	j
d t	 d¡ tj |¡s>tjd |¡t	j
d t	 d¡ t|dƒ}| ¡ }W d   ƒ n1 sRw   Y  tjj d |¡}|rs| ¡ srtjd	t	j
d t	 d¡ n7t d
d
| ¡}z| ¡  W n) tjjy© }	 z|	jdkrtjdt	j
d t	 d¡ n|	‚W Y d }	~	nd }	~	ww | ¡ }tj |d ¡ d¡}
tjd|
 t	j
d d S )Nr(   r'   Úsecurity_token_filezAERROR: No security_token_file was found in config for profile: {}©Úfiler   z*ERROR: 'security_token_file' not found: {}ÚrzSession has expiredZidentityé‘  z%Session was deemed invalid by serviceÚexpz%Y-%m-%d %H:%M:%SzSession is valid until )r   r;   r)   r   Úbuild_configÚgetr,   r-   r:   r.   Ústderrr/   r1   r2   ÚexistsÚopenÚreadÚocir(   Úsecurity_token_containerZSecurityTokenContainerÚvalidr0   Zlist_regionsÚ
exceptionsZServiceErrorÚstatusZget_jwtÚdatetimeÚfromtimestampÚstrftime)r<   ÚlocalÚclient_configr!   Zsecurity_token_locationrD   r   rQ   r=   Zservice_errorZexpiry_timer   r   r   rC   y   sB   




ÿ
€
þ€ýÚ	terminatezpTerminates a CLI session by removing the entry from the config and removing all referenced resources (e.g. keys)c                 C   s  t  | j¡}| d¡}|stjdtjd t d¡ t	j
 | jd ¡}| jd }t ¡ }| |¡ dd„ | ¡ D ƒ}|d	krKtjd
tjd t d¡ ||vr\tjdtjd t d¡ t ||¡ t	j
 tj|¡}t	j
 |¡rxtt	j
 |¡ƒ tjd ||¡tjd d S )NrD   zVERROR: Cannot terminate a profile that does not have a value for 'security_token_file'rE   r   r&   r'   c                 S   ó   g | ]\}}|‘qS r   r   ©Ú.0ÚkeyÚvaluer   r   r   Ú
<listcomp>·   ó    zterminate.<locals>.<listcomp>ÚDEFAULTz'ERROR: Cannot terminate DEFAULT profilezERROR: Profile does not existz0Successfully removed profile: {} from config: {})r   rJ   r)   rK   r,   r-   r.   rL   r/   r1   r2   r4   ÚconfigparserÚConfigParserrO   Úitemsr   Úremove_profile_from_configÚjoinÚDEFAULT_TOKEN_DIRECTORYrM   r   Úabspathr:   )r<   rY   r   r&   Zprofile_name_to_terminater"   Úcurrent_profilesZprofile_to_terminater   r   r   rZ   ¦   s*   





ÚrefreshzRefreshes a CLI sessionc           
   	   C   s  t  | j¡}| d¡}|stjdtjd t d¡ t	j
 |¡}t	j
 |¡s3t d |¡¡ t d¡ t|dƒ}| ¡ }W d   ƒ n1 sGw   Y  ztj | d¡| d¡¡}W n tjjyy   t  ¡ |d< tj | d¡| d¡¡}Y nw tjj ||¡}d	jtj d
| d¡¡d}tjdj|dtjd tj|ddit d|i¡|d}|jdkråt  |j! "d¡¡d }	t|dƒ}| #|	¡ W d   ƒ n1 sÑw   Y  t  $|¡ tjdtjd d S |jdkrùtjdtjd t d¡ d S t d t%|j! "d¡ƒ¡¡ t d¡ d S )NrD   zTERROR: Cannot refresh a profile that does not have a value for 'security_token_file'rE   r   zEERROR: Cannot refresh token, 'security_token_file' does not exist: {}rG   Zkey_fileZpass_phrasez${endpoint}/v1/authentication/refreshr(   r   )Zendpointz.Attempting to refresh token from {refresh_url})Úrefresh_urlzcontent-typezapplication/jsonZcurrentToken)Úheadersr8   r(   éÈ   r   r   ÚwzSuccessfully refreshed tokenrH   zwYour session is no longer valid and cannot be refreshed. Please use 'oci session authenticate' to create a new session.z+ERROR: Failed to refresh sesison. Error: {})&r   rJ   r)   rK   r,   r-   r.   rL   r/   r1   r2   r4   rM   r:   rN   rO   rP   ZsignerZload_private_key_from_filerS   ZMissingPrivateKeyPassphraseZprompt_for_passphraser(   ZsignersZSecurityTokenSignerÚregionsZendpoint_forr	   ÚpostÚjsonÚdumpsZstatus_codeÚloadsÚcontentr7   ÚwriteÚ"apply_user_only_access_permissionsÚstr)
r<   rY   rD   Z expanded_security_token_locationr   r?   r(   rl   rB   Zrefreshed_tokenr   r   r   rk   Ë   sT   



ÿþÿÿø
ÿ

Úexportz«Exports a CLI session into a zip that can be imported.
The session exported is the active profile (specified either by defaults or the --config-file / --profile arguments.z--output-filez_The name of the export file to create, including the path, minus any format-specific extension.)Úrequiredr   r   z--forcez[If the ouptut zip already exists, overwrite the existing zip without a confirmation prompt.c                 C   s’  t j | jd ¡}| jd }t ¡ }| |¡ dd„ ||  ¡ D ƒ}d|vr3tj	dt
jd t
 d¡ |d	 t }t j |¡rV|sVt d
 |¡¡sVtj	dt
jd t
 d¡ tj	d ||¡t
jd zTt ¡ }tt j |d¡dƒ}	t ¡ }t|ƒ||< | |	¡ W d   ƒ n1 s‹w   Y  t |¡D ]\}
}|
 ttf¡r©tt j |¡|ƒ q•t|t|d}W t|ƒ nt|ƒ w tj	d |¡t
jd d S )Nr&   r'   c                 S   s   i | ]\}}||“qS r   r   r\   r   r   r   Ú
<dictcomp>  s    zexport.<locals>.<dictcomp>rD   zhERROR: Specified profile is not a valid token profile. Please specify valid token profile with --profilerE   r   Ú.z4File {} already exists, do you want to overwrite it?zExport canceled.r   z*Exporting profile: {} from config file: {}r"   ro   )Úroot_dirzExport file written to: {})r1   r2   r4   r)   rc   rd   rO   re   r,   r-   r.   rL   r/   ÚZIP_FILE_FORMATrM   Zconfirmr:   ÚtempfileÚmkdtemprN   rg   Ú$translate_config_filepaths_to_prefixrv   ÚsixÚ	iteritemsÚendswithÚCONFIG_KEY_FILE_SUFFIXÚTOKEN_FILE_SUFFIXr
   r   r   )r<   Úoutput_fileÚforcer&   r'   r"   Zprofile_to_exportÚzip_filenameÚtemp_dir_nameZexport_config_filer^   r_   Úarchive_namer   r   r   ry     s8   



ý€Úimportz&Imports a CLI session from an archive.z--session-archivezThe session archive to import.zkIf the profile being imported already exists, overwrite the existing profile without a confirmation prompt.c                 C   sˆ  t j |¡stjd |¡tjd t d¡ t j 	| j
d ¡}| j
d }t ¡ }| |¡ dd„ | ¡ D ƒ}zît ¡ }t |¡Ö}| |¡ t j |d¡}	t j |	¡sctjd	 |¡tjd t d¡ t ¡ }
|
 |	¡ d
d„ |
 ¡ D ƒ}t|ƒdk rˆtjdtjd t d¡ t|ƒd }|| }|
| }d|vr§tjdtjd t d¡ |r¯t ||¡ ||v rÃ|sÃt d |¡¡}||v rÃ|rµt j tj|¡}t j |¡sÖt  |¡ t |¡D ]#\}}| ttf¡rþt j ||¡}t j ||¡}t ||ƒ t! "|¡ qÛt#||ƒ}tj$d||dœ|¤Ž W d   ƒ n	1 sw   Y  W t%|ƒ nt%|ƒ w tjd ||¡tjd t dj||t&j'd¡ d S )NzFile {} does not exist.rE   r   r&   r'   c                 S   r[   r   r   r\   r   r   r   r`   ?  ra   z"import_session.<locals>.<listcomp>r"   z=Session archive {} is invalid. Did not contain file 'config'.c                 S   r[   r   r   r\   r   r   r   r`   N  ra   z;ERROR: The archived config does not contain valid profiles.rD   zbERROR: Cannot import non token based profile (profile must contain value for security_token_file).z†Config already contains a profile with the same name as the archived profile: {}. Provide an alternative name for the imported profile)Úfilenamer!   z"Imported profile {} written to: {}z°
    Try out your newly imported session credentials with the following example command:

    oci iam region list --config-file {config_file} --profile {profile} --auth {auth}
r%   r   )(r1   r2   rM   r,   r-   r:   r.   rL   r/   r4   r)   rc   rd   rO   re   r   r€   ÚzipfileÚZipFileÚ
extractallrg   Úlenr   rf   Úpromptrh   Úmakedirsr‚   rƒ   r„   r…   r†   r
   r   rw   r   Zwrite_configr   r   r;   )r<   Zsession_archiverˆ   r&   r'   r"   rj   rŠ   ÚzfZarchived_config_locationZarchived_configZarchived_profilesZ
profile_noZarchived_profile_nameZarchived_profileZimported_resources_dirr^   r_   Znew_file_locationZexisting_file_locationr   r   r   Úimport_session/  sh   







ÿ


€
Ð€2
ür•   Ú c                 C   sR   i }t  | ¡D ]\}}| ttf¡r"tj |¡}tj ||¡||< q|||< q|S r   )	r‚   rƒ   r„   r…   r†   r1   r2   Úbasenamerg   )r"   ÚprefixZtranslated_configr^   r_   r—   r   r   r   r     s   
r   )r–   )5Ú
__future__r   Zoci_cli.cli_rootr   Úoci_clir   r   r   r   Úpathlibr   r,   rc   rr   rP   r1   Zoci._vendorr	   r‚   Úshutilr
   r   r   r.   r   rŽ   rU   Zoci._vendor.jwtÚ_vendorr9   r…   r†   r~   ÚgroupZhelp_option_groupr   ÚcommandÚoptionrg   rp   ZREGIONSr+   rh   Úhelp_optionZpass_contextZwrap_exceptionsr   rC   rZ   rk   ry   r•   r   r   r   r   r   Ú<module>   sŽ   "E(!3&L