a
    ϑ`q                     @   s   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Zd dl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mZ ddlmZmZ dd	lmZ eejj ed
ZdZdZG dd dZdS )    )unicode_literalsN)basename)join)urlparse   )errors)InvalidNameNoDefaultUrl)UPLOAD_TYPE_MAPPINGZrepo_cliZauthorZadminc                   @   s  e Zd ZdrddZedd Zdd Zd	d
 Zedd Zedd Z	edd Z
dsddZdd ZddddZejdddZdd Zdd Zdd  Zd!d" Zd#d$ Zd%d& Zdtd'd(Zd)d* Zd+d, Zd-d. Zdud1d2Zd3d4 Zd5d6 Zd7d8 Zd9d: Zd;d< Z d=d> Z!d?d@ Z"dvdBdCZ#dDdE Z$dFdG Z%dHdI Z&dwdJdKZ'dLdM Z(dxdNdOZ)dPdQ Z*dydTdUZ+dzdVdWZ,d{dXdYZ-d|dZd[Z.d}d\d]Z/d~d^d_Z0dd`daZ1ddcddZ2ddedfZ3dgdh Z4ddidjZ5e6dkdldmZ7dndo Z8dpdq Z9dS )RepoApiNTc                 C   s"   || _ || _|| _d | _d | _d S N)base_url
verify_ssl_access_token_jwt_urls)selfr   
user_tokenr    r   1lib/python3.9/site-packages/repo_cli/utils/api.py__init__   s
    zRepoApi.__init__c                 C   s   | j d u r| jst t| jddt| jdt| jddt| jddt| jdt| jdt| jdt| jddt| jdd	t| jddt| jdd
t| jdt| jddd| _ | j S )NZauth	authorizeaccounttokensloginlogoutchannels	artifactsz
token-infoscopescvessystemsettings)r   r   account_tokensr   r   r   r   user_channels
token_infouser_tokensr   r   system_settings)r   r   r	   r   r   r   r   r   urls&   s$    





zRepoApi.urlsc                 C   s   dj t dS )Nzrepo-cli-token-{hostname})hostname)formatsocketZgethostnamer'   r   r   r   get_user_token_name<   s    zRepoApi.get_user_token_namec                 C   s   |   ttj  tjdd |  d}tj| j	d t
|| j| jd}|jdkr~d|j|jf }t| t||
 d | _| jS )	N   )Zdays)name
expires_atr   r"   dataheadersverify   z?Error requesting a new user token! Server responded with %s: %stoken)r,   strdatetimeZnowdateZ	timedelta
get_scopesrequestspostr(   jsondumpsbearer_headersr   status_codecontentloggererrorr   RepoCLIErrorr   )r   r1   respmsgr   r   r   create_access_token?   s    "


zRepoApi.create_access_tokenc                 C   s   d| j  dd}|S )NzBearer application/json)ZAuthorizationContent-Type)r   )r   r2   r   r   r   r>   P   s    
zRepoApi.bearer_headersc                 C   sN   | j s
dS | j dd }tt|dt|d   }|d d }t|v S )NF.   =   Zrealm_accessroles)r   splitr<   loadsbase64Z	b64decodelen
ROLE_ADMIN)r   Zpayloadr1   rM   r   r   r   is_admin_jwtX   s     zRepoApi.is_admin_jwtc                 C   s   |   S r   )get_xauth_headersr'   r   r   r   xauth_headersc   s    zRepoApi.xauth_headersc                 C   s   d| j i}|r|| |S )NzX-Auth)r   update)r   Zextra_headersr2   r   r   r   rT   g   s    

zRepoApi.get_xauth_headersc                    s0  t d tj| jd | j| jd}|jdkrRd|j|jf }t 	| t
|| dg }t dt|  |r|    fdd	|D }|r,|d
 d }t| jd |}t d|  tj|d| j| jd}|jdkrd|j|jf }t 	| t
|| d  | _}t d |S d S )Nz[API] Getting access token.. r"   r2   r3   r4   z9Error retrieving user token! Server responded with %s: %sitemsz![LOGIN] Access token retrieved.. c                    s   g | ]}|d   kr|qS r.   r   ).0r   Zuser_token_namer   r   
<listcomp>z   s   z,RepoApi.get_access_token.<locals>.<listcomp>r   idz"[ACCESS_TOKEN] Refreshing token.. z{}r0   z9Error refreshing user token! Server responded with %s: %sr5   z[ACCESS_TOKEN] Token Refreshed)rA   debugr:   getr(   r>   r   r?   r@   rB   r   rC   r<   rQ   r,   r   putr   )r   Z
token_resprE   r%   Ztoken_to_refreshZrefresh_urlZ	new_tokenr   r[   r   get_access_tokenm   s<    







zRepoApi.get_access_tokenZURL)returnc                 C   sv   t  }td |j| jd | jdd}|jdkrXtd td|j  t	
 t|jd }|jd	d
}|S )Nz"[LOGIN] Getting authorize endpointr   F)r3   Zallow_redirectsi.  z([LOGIN] Error getting auth configurationServer responded with response ZLocation )query)r:   SessionrA   r^   r_   r(   r   r?   infor   ZWrongRepoAuthSetupr   r2   _replace)r   srD   urlr   r   r   get_authorize_url   s    


zRepoApi.get_authorize_urlc                 C   s   ||d}t  }td| d |j| jd t|ddi| jd}td |j	d	krt
d
 td|j	 d|j  t | d  | _}|S )z5 Login using direct grant and returns the jwt token. )usernamepasswordz[LOGIN] Authenticating user ...r   rH   rG   r0   z[LOGIN] Doner4   z[LOGIN] Error logging in...rc   
Data: r5   )r:   rf   rA   r^   r;   r(   r<   r=   r   r?   rg   r@   r   Unauthorizedr   )r   rl   rm   r1   ri   rD   Z	jwt_tokenr   r   r   r      s    $


zRepoApi.loginc                 C   s,   |   }|s(td |  }td |S )z/ Returns user token, used with X-Auth headers. z/[LOGIN] Access token not found. Creating one...z[LOGIN] Done.)ra   rA   r^   rF   )r   r   r   r   r   get_user_token   s    

zRepoApi.get_user_tokenc                 C   s>   | j d }td|  tj|| j| jd}| |dd S )Nr   z+[UPLOAD] Getting user default channel from rW   getting account detailsZdefault_channel_namer(   rA   r^   r:   r_   rU   r   _manage_responser   rj   responser   r   r   get_default_channel   s    
zRepoApi.get_default_channelc                 C   s>   | j d }td|  tj|| j| jd}| |dd S )Nr   z#[UPLOAD] Getting current user from rW   rr   rl   rs   ru   r   r   r   get_current_user   s    
zRepoApi.get_current_userc           
      C   s   |t vrtd| t | }t| jd|d}t|}t|}t	d| j
 d| j  |t|dfd |fd |jfd}td| d	| d
 tj||| j| jd}	|	S )Nz%s upload is not supportedr   r   z[UPLOAD] Using token  on rb)r@   Zfiletypesizez
Uploading z artifact to rn   )filesr2   r3   )r
   r   rC   r   r   osstatr   rA   r^   r   openst_sizerg   r:   r;   rU   r   )
r   filepathchannelZpackage_typeZartifact_typerj   ZstatinfofilenameZmultipart_form_datarv   r   r   r   upload_file   s    
zRepoApi.upload_filec                 C   s   |}t d| d| j  d|v r\|d\}}t| jd |d}d|i}| ddi}n$t| jd }d|i}| ddi}| |d  tj	|||| j
d	}| j|d
| dgdS )a  Create a new channel with name `channel` on the repo server at `base_url` using `token`
        to authenticate.

        Args:
              channel(str): name of the channel to be created

        Returns:
              response (http response object)
        zCreating channel ry   /r   subchannelsr.   rH   rG   r<   r2   r3   zcreating channel    success_codes)rA   r^   r   rN   r   r(   rT   _validate_channel_namer:   r;   r   rt   )r   r   Z_channel
subchannelrj   r1   r2   rv   r   r   r   create_channel   s    
zRepoApi.create_channelc                 C   s   |  |}td| d| j  td| j  tj|| ddi| jd}|j	dv rt
d| d	 td
|j	 d|j  n6d| d|j	 d|j }t| |j	dv rt |S )NzRemoving channel ry   Using token rH   rG   rW   )   Channel z successfully removedServer responded with ro   zError removing z#.Server responded with status code .
Error details:     )_get_channel_urlrA   r^   r   r   r:   deleterT   r   r?   rg   r@   rB   r   rp   )r   r   rj   rv   rE   r   r   r   remove_channel   s     



zRepoApi.remove_channelc                 K   s   d|vr|  | | |}td| d| j  td| j  tj||| ddi| j	d}|std| d	}|j
d
v rt| td|j
 d|j  n6d| d|j
 d|j }t| |j
dv rt |S )NZprivacyzUpdating channel ry   r   rH   rG   r   r   z successfully updated.r4      r   ro   zError creating z$ .Server responded with status code r   r   )r   r   rA   r^   r   r   r:   r`   rT   r   r?   rg   r@   rB   r   rp   )r   r   Zsuccess_messager1   rj   rv   rE   r   r   r   update_channel  s(    





zRepoApi.update_channelc                 C   s   d|v S )a  Return True if channel is a path to a subchannel, False otherwise. For example:

        >> is_subchannel("main")
            False
        >> is_subchannel("main/stage")
            True

        Args:
            channel (str): name of the channel

        Returns:
            (bool)r   r   )r   r   r   r   r   is_subchannel!  s    zRepoApi.is_subchannelc                 C   sB   |  |r.|d\}}t| jd |d|}nt| jd |}|S )zReturn a channel url based on the fact that it's a normal channel or
         a subchannel

        Args:
            channel (str): name of the channel

        Returns:
            (str) url
        r   r   r   )r   rN   r   r(   )r   r   r   rj   r   r   r   r   0  s
    

zRepoApi._get_channel_urlc                 C   sP   t d| d| j  | |}tj|| ddi| jd}| |d| S )NGetting channel ry   rH   rG   rW   getting channel )	rA   r^   r   r   r:   r_   rT   r   rt   r   r   rj   rv   r   r   r   get_channelB  s    
zRepoApi.get_channelr   2   c                 C   s^   t d| d| j  t| |d||f }tj|| ddi| jd}| 	|d| S )Nr   z	 history zhistory?offset=%s&limit=%srH   rG   rW   r   )
rA   r^   r   r   r   r:   r_   rT   r   rt   )r   r   offsetlimitrj   rv   r   r   r   get_channel_historyH  s    zRepoApi.get_channel_historyc                 C   s@   t d| j  tj| jd | ddi| jd}| |dS )NzGetting user channels from r#   rH   rG   rW   zgetting user channels)	rA   r^   r   r:   r_   r(   rT   r   rt   r   rv   r   r   r   list_user_channelsN  s
    zRepoApi.list_user_channelsc                 C   sZ   t d| d| j  t| jd |d}tj|| ddi| jd}| 	|d| d	S )
Nr   z subchannels on r   r   rH   rG   rW   r   z subchannel)
rA   r^   r   r   r(   r:   r_   rT   r   rt   r   r   r   r   get_channel_subchannelsT  s    zRepoApi.get_channel_subchannelsc
                 C   sv   t | |d}
|||||||d}|	r0|	|d< tj|
t|| ddi| jd}| j|d| d| d	gd
gdS )Nmirrorsmirror_namesource_rootZmirror_modecronZmirror_typefiltersrun_nowproxyrH   rG   r0   creating mirror  on channel r   r   r   auth_fail_codes)	r   r   r:   r;   r<   r=   rT   r   rt   )r   r   r   r.   moder   type_r   r   r   rj   mirror_detailsrD   r   r   r   create_mirrorZ  s    	$zRepoApi.create_mirrorc                 C   sx   t | |d|}|||||||	d}|
r2|
|d< tj|t|| ddi| jd}| j|d| d| d	gd
gdS )Nr   r   r   rH   rG   r0   r   r   r   r   r   )	r   r   r:   r`   r<   r=   rT   r   rt   )r   Z	mirror_idr   r   r.   r   r   r   r   r   r   rj   r   rD   r   r   r   update_mirrork  s    	$zRepoApi.update_mirrorc                 C   s6   t | |d}tj|| j| jd}| |d| S )Nr   rW   zcreating mirrors on channel r   r   r:   r_   rU   r   rt   r   r   rj   rD   r   r   r   get_mirrors|  s    zRepoApi.get_mirrorsc                 C   s>   t | |d|}tj|| j| jd}| |d| d| S )Nr   rW   Getting mirror r   r   r   r   r   rj   rD   r   r   r   
get_mirror  s    zRepoApi.get_mirrorc                 C   sD   t | |d|}tj|| j| jd}| j|d| d| dgdS )Nr   rW   r   r   r   r   )r   r   r:   r   rU   r   rt   r   r   r   r   delete_mirror  s
    zRepoApi.delete_mirrorrd   c                 C   s   |s
dg}|sddg}|j |v r6|j dkr.d S | S d| d|j  d|j }|j dkrft| n
t| |j |v rt td| i S )	Nr4   r   r   r   zError z$. Server responded with status code r   z%s operation failed.)	r?   r<   r@   rA   r^   rB   r   rp   rC   )r   rv   actionr   r   rE   r   r   r   rt     s(    




zRepoApi._manage_responsec                 C   s`   t j| jd | j| jd}|jdv r,| S d|j d|j }t	| |jdv r\t
 i S )Nr$   rW   r   z;Error getting token info.Server responded with status code r   r   )r:   r_   r(   rU   r   r?   r<   r@   rA   rB   r   rp   r   rv   rE   r   r   r   get_token_info  s    


zRepoApi.get_token_infoc                 C   s`   t j| jd | j| jd}|jdv r,| S d|j d|j }t	| |jdv r\t
 g S )Nr"   rW   r   z<Error getting user tokens.Server responded with status code r   r   )r:   r_   r(   r>   r   r?   r<   r@   rA   rB   r   rp   r   r   r   r   get_user_tokens  s    


zRepoApi.get_user_tokensc                 C   s6   t | jd |}tj|| j| jd}| j|ddgdS )Nr"   rW   zremoving user tokenr   r   )r   r(   r:   r   r>   r   rt   )r   r5   rj   rv   r   r   r   remove_user_token  s    zRepoApi.remove_user_tokenc                 C   sV   ||d}|r||d< |r"||d< t j| jd t|| j| jd}| j|ddgdS )	N)r.   r/   r   	resourcesr"   r0   zcreating user tokenr4   r   )r:   r;   r(   r<   r=   r>   r   rt   )r   r.   Z
expirationr   r   r1   rv   r   r   r   create_user_token  s    zRepoApi.create_user_tokenc                 C   s*   t j| jd | j| jd}| |dd S )Nr   rW   zgetting scopes)r:   r_   r(   r>   r   rt   r   r   r   r   r9     s    zRepoApi.get_scopesc                 C   s   t | |dd}||d}|rHd|v r@|d\|d< |d< n||d< tj|t|| ddi| jd	}| j	|d
| dgg ddS )Nr   Zbulk)r   rX   r   target_channelZtarget_subchannelrH   rG   r0   z%s articfactsr   )r   r   i  r   )
r   r   rN   r:   r`   r<   r=   rT   r   rt   )r   r   r   r   r   rj   r1   rD   r   r   r   channel_artifacts_bulk_actions  s    z&RepoApi.channel_artifacts_bulk_actionsc                 C   s8   t | |d}tj|| j| jd}| |ddg S )Nr   rW   zgetting artifactsrX   r   r   r   r   r   get_channel_artifacts  s    zRepoApi.get_channel_artifactsFd   c	                    s   | j | j| j| j| j| jd}	g }
d}|r2|g}n| |} fdd|D }|D ]}t| |d |d}t	j
|| j| jd}| |d}|d	 }|d
 D ]@}|	  |||}|rdD ]}||v r|| ||< q|
| qqR|
|fS )N)ZcondaZcranZpythonZanaconda_projectZanaconda_envZnotebookr   c                    s,   g | ]$}|d  dkr|d  kr|d qS )Z
file_countr   familyr.   r   )rZ   pkgr   r   r   r\         z7RepoApi.get_channel_artifacts_files.<locals>.<listcomp>r   r|   rW   zgetting articfactstotal_countrX   )Z
cve_statusZ	cve_score)_parse_conda_file_parse_cran_file_parse_python_file_parse_project_file_parse_environment_file_parse_notebook_filer   r   r   r:   r_   rU   r   rt   append)r   r   r   packageversionr   
return_rawr   r   Zfile_family_parsersZartifact_filesr   Zpackagesr1   rj   rD   r|   	file_datarecZ	cve_fieldr   r   r   get_channel_artifacts_files  s4    
z#RepoApi.get_channel_artifacts_filesc                    s   |d  dp|d d  |r. d |kr.d S |rB d |krBd S |rL|}n:|d |d d}| fd	d
dD    dd|d< |S )Nmetadatazrepodata_record.jsonz
index.jsonr   fnr.   ckeyr.   r   c                    s   i | ]}|  |d qS )rd   )r_   )rZ   keymetar   r   
<dictcomp>#  r   z-RepoApi._parse_conda_file.<locals>.<dictcomp>)r   r   Zsubdirrd   platform)r_   rV   )r   r   r   r   r   r   r   r   r   r     s    zRepoApi._parse_conda_filec                 C   s   |d }|d  dd }|r.|d |kr.d S |r>||kr>d S |rH|}n:|d |d d}|| |d|d< ||d	< d
|d< |S )Nr   r   r   ZVersionr.   r   r   r   n/ar   rN   rV   pop)r   r   r   r   r   r   r   r   r   r   r   r   (  s    
zRepoApi._parse_cran_filec                 C   s\   |d j dddd }|d d}t|tr8d|}|d	 |d ||rN|nd
d d}|S )Nr   r   rJ   maxsplitr   r   	platforms,r.   r   r.   r   r   r   r   )rN   r_   
isinstancelistr   )r   r   r   r   r   r   r   r   r   r   r   r   <  s    


zRepoApi._parse_project_filec                 C   s2   |d j dddd }|d |d |dd d}|S 	Nr   r   rJ   r   r   r.   r   r   rN   r   r   r   r   r   r   r   r   r   r   r   J  s    zRepoApi._parse_environment_filec                 C   s2   |d j dddd }|d |d |dd d}|S r   r   r   r   r   r   r   U  s    zRepoApi._parse_notebook_filec                 C   s   |d }|d  dd }|r.|d |kr.d S |r>||kr>d S |rH|}n:|d |d d}|| |d|d< ||d< d	|d
< |S )Nr   r   r   r   r   r.   r   artifact_filenamer   r   r   )r   r   r   r   r   r   r   r   r   r   r   r   `  s    
zRepoApi._parse_python_file-download_countc                 C   s8   d| j d ||||f }tj|| j| jd}| |dS )Nz"%s?q=%s&limit=%s&offset=%s&sort=%sr   rW   zsearching artifactsr(   r:   r_   rU   r   rt   )r   re   r   r   sortrj   rv   r   r   r   get_artifactsu  s    zRepoApi.get_artifactsc                 C   s4   d| j d ||f }tj|| j| jd}| |dS )Nz%s?offset=%s&limit=%sr   rW   zgetting cvesr   )r   r   r   rj   rv   r   r   r   get_cves{  s    zRepoApi.get_cvesc                 C   s2   d| j d |f }tj|| j| jd}| |dS )Nz%s/%sr   rW   zgetting cve idr   )r   cve_idrj   rv   r   r   r   get_cve  s    zRepoApi.get_cvec                 C   s6   d| j d |||f }tj|| j| jd}| |dS )Nz%s/%s/files?offset=%s&limit=%sr   rW   zgetting cve filesr   )r   r   r   r   rj   rv   r   r   r   get_cve_files  s    zRepoApi.get_cve_filesrY   c                 C   sL   t d|sHtd}t|t|}dd| }t| t|d S )Nz^[a-z][a-z0-9_-]*$z!"#$%&'()*+,./:;<=>?@[\]^`{|}~z'Channel name contains invalid sequence z, )	rematchsetr   intersectionr   rA   rB   r   )r   r.   Zinvalid_charsZinvalid_lettersZerror_messager   r   r   r     s    
zRepoApi._validate_channel_namec                 C   s"   t j| jd | jd}| |dS )Nr&   )r2   zgetting system settings)r:   r_   r(   rU   rt   r   r   r   r   get_system_settings  s
    zRepoApi.get_system_settingsc                 C   s6   t j| jd t|| ddi| jd}| |dS )Nr&   rH   rG   r0   zupdating system settings)r:   r`   r(   r<   r=   rT   r   rt   )r   r!   rv   r   r   r   update_system_settings  s    zRepoApi.update_system_settings)NT)N)N)r   r   )rd   NN)NN)N)NNNFr   r   )F)F)F)F)F)F)r   r   r   )r   r   )r   r   ):__name__
__module____qualname__r   propertyr(   r,   rF   r>   rS   rU   rT   ra   rk   r:   ZResponser   rq   rw   rx   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rt   r   r   r   r   r9   r   r   r   r   r   r   r   r   r   r   r   r   r   r6   r   r  r  r   r   r   r   r      sr   






#




  
$









r   )Z
__future__r   rP   r7   r<   loggingr}   r   r+   Zos.pathr   	posixpathr   urllib.parser   r:   Zurllib3rd   r   r   r	   Zutils.configr
   Zdisable_warnings
exceptionsZInsecureRequestWarningZ	getLoggerrA   ZROLE_AUTHORrR   r   r   r   r   r   <module>   s(   
