U
    lHJe%                     @   s   d dl Z d dlZd dlZd dlmZ d dlmZmZmZ d dlm	Z	m
Z
mZmZmZ d dlmZ e
 ZeeeZG dd dZG dd	 d	eZG d
d dZdS )    N)datetime)AnyDictOptional)defaultsevent_logger
exceptionssystemutil)PublicMachineTokenDatac                   @   s~   e Zd ZejdfeeedddZeedddZ	eeddd	Z
ed
d ZedddZee dddZdd ZdS )UAFileT)name	directoryprivatec                 C   s*   || _ || _|| _tj| j | j| _d S N)
_directoryZ
_file_name_is_privateospathjoin_path)selfr   r   r    r   6/usr/lib/python3/dist-packages/uaclient/files/files.py__init__   s    zUAFile.__init__returnc                 C   s   | j S r   )r   r   r   r   r   r      s    zUAFile.pathc                 C   s   | j S r   )r   r   r   r   r   
is_private   s    zUAFile.is_privatec                 C   s   t j| jS r   )r   r   existsr   r   r   r   
is_present"   s    zUAFile.is_present)contentc                 C   sr   | j rtjntj}z6tj| jtjkr:tj	| jdd nt	| j W n t
k
r\   Y nX t| j|| d S )Ni  )mode)r   r   ZROOT_READABLE_MODEZWORLD_READABLE_MODEr   r   basenamer   PRIVATE_SUBDIRmakedirsOSErrorr	   Z
write_file)r   r!   Z	file_moder   r   r   write&   s    zUAFile.writec                 C   s<   d }zt | j}W n" tk
r6   td| j Y nX |S )Nz(Tried to load %s but file does not exist)r	   	load_filer   FileNotFoundErrorLOGdebug)r   r!   r   r   r   read7   s    zUAFile.readc                 C   s   t | j d S r   )r	   Zensure_file_absentr   r   r   r   r   delete?   s    zUAFile.deleteN)__name__
__module____qualname__r   DEFAULT_DATA_DIRstrboolr   propertyr   r   r    r'   r   r,   r-   r   r   r   r   r      s    
r   c                       s"   e Zd Zed fddZ  ZS )UserCacheFile)r   c                    s   t  j|t dd d S )NF)r   r   )superr   r	   Zget_user_cache_dir)r   r   	__class__r   r   r   D   s
      zUserCacheFile.__init__)r.   r/   r0   r2   r   __classcell__r   r   r7   r   r5   C   s   r5   c                   @   s*  e Zd Zejdfeee dddZedddZ	dd	 Z
ee d
ddZedd Zedd Zdd Zeee d
ddZedd ZeedddZeee d
ddZedd Zeee d
ddZed d
d!d"Zed d
d#d$Zed%d
d&d'Zed(d) Zed*d+ ZdS ),MachineTokenFileN)r   machine_token_overlay_pathc                 C   sF   t j}t||d t j | _t||d| _|| _d | _d | _d | _	d S )N/F)
r   ZMACHINE_TOKEN_FILEr   r$   private_filepublic_filer;   _machine_token_entitlements_contract_expiry_datetime)r   r   r;   	file_namer   r   r   r   K   s     zMachineTokenFile.__init__)private_contentc                 C   sr   t  rftj|t jd}| j| t|j	dd}tj|t jd}| j
| d| _d| _d| _nt dS )z8Update the machine_token file for both pub/private filesclsF)Z	keep_noneN)r
   we_are_currently_rootjsondumpsZDatetimeAwareJSONEncoderr=   r'   r   Z	from_dictZto_dictr>   r?   r@   rA   r   NonRootUserError)r   rC   Zprivate_content_strZpublic_contentZpublic_content_strr   r   r   r'   Z   s(      zMachineTokenFile.writec                 C   s<   t  r0| j  | j  d| _d| _d| _nt	 dS )z!Delete both pub and private filesN)
r
   rF   r>   r-   r=   r?   r@   rA   r   rI   r   r   r   r   r-   r   s    

zMachineTokenFile.deleter   c                 C   sT   t  r| j}n| j}| }|s&d S ztj|t jd}W n tk
rN   Y nX |S NrD   )	r
   rF   r=   r>   r,   rG   loadsDatetimeAwareJSONDecoder	Exception)r   Zfile_handlerr!   r   r   r   r,   ~   s    zMachineTokenFile.readc                 C   s$   t  r| jjo| jjS | jjS d S r   )r
   rF   r>   r    r=   r   r   r   r   r       s    zMachineTokenFile.is_presentc                 C   sB   | j s<|  }|r6| jr6| | j}|r6tj||d || _ | j S )zAReturn the machine-token if cached in the machine token response.)Z	base_dictZoverlay_dict)r?   r,   r;   parse_machine_token_overlayr
   Zdepth_first_merge_overlay_dict)r   r!   Zmachine_token_overlayr   r   r   machine_token   s    
zMachineTokenFile.machine_tokenc                 C   s   t |}tj|tjdS rJ   )r	   r(   rG   rK   r
   rL   )r   r;   Zmachine_token_overlay_contentr   r   r   rN      s    z,MachineTokenFile.parse_machine_token_overlayc                 C   s   t | jr| jd d S d S )NmachineTokenInfoZaccountInfor3   rO   r   r   r   r   account   s    
zMachineTokenFile.accountc                 C   s*   | j r| j S | jsi S | | j| _ | j S )z9Return configured entitlements keyed by entitlement named)r@   rO   get_entitlements_from_tokenr   r   r   r   entitlements   s    zMachineTokenFile.entitlements)rO   c           	      C   s   ddl m} | si S i }| di d}|s2i S tdd | dg D }tdd |d	g D }| D ]4\}}d
|i}||kr|| |d< || |||< qn|S )zReturn a dictionary of entitlements keyed by entitlement name.

        Return an empty dict if no entitlements are present.
        r   )apply_contract_overridesrP   contractInfoc                 s   s"   | ]}| d | dfV  qdS )typetokenNget.0er   r   r   	<genexpr>   s   z?MachineTokenFile.get_entitlements_from_token.<locals>.<genexpr>resourceTokensc                 s   s   | ]}| d |fV  qdS )rW   NrY   r[   r   r   r   r^      s   ZresourceEntitlementsZentitlementZresourceToken)Zuaclient.contractrU   rZ   dictitems)	rO   rU   rT   rV   Ztokens_by_nameZent_by_nameZentitlement_nameZ	ent_valueZentitlement_cfgr   r   r   rS      s0    


z,MachineTokenFile.get_entitlements_from_tokenc                 C   s,   | j s&| jdi di dd| _ | j S )z6Return a datetime of the attached contract expiration.rP   rV   ZeffectiveToN)rA   rO   rZ   r   r   r   r   contract_expiry_datetime   s      z)MachineTokenFile.contract_expiry_datetimec                 C   s
   t | jS )z<Report whether this machine configuration is attached to UA.rQ   r   r   r   r   is_attached   s    zMachineTokenFile.is_attachedc                 C   s*   | j dkrdS | j  t   }|jS )a  Report num days until contract expiration based on effectiveTo

        :return: A positive int representing the number of days the attached
            contract remains in effect. Return a negative int for the number
            of days beyond contract's effectiveTo date.
        N)rb   dater   ZutcnowZdays)r   Zdeltar   r   r   contract_remaining_days   s    
z(MachineTokenFile.contract_remaining_dayszOptional[str]c                 C   s   | j r| j di dS d S )NactivityInfoZactivityTokenrO   rZ   r   r   r   r   activity_token  s
    zMachineTokenFile.activity_tokenc                 C   s   | j r| j di dS d S )Nrf   Z
activityIDrg   r   r   r   r   activity_id
  s    zMachineTokenFile.activity_idzOptional[int]c                 C   s   | j r| j di dS d S )Nrf   ZactivityPingIntervalrg   r   r   r   r   activity_ping_interval  s
    z'MachineTokenFile.activity_ping_intervalc                 C   s&   | j r"| j di di dS d S )NrP   rV   idrg   r   r   r   r   contract_id  s     zMachineTokenFile.contract_idc                 C   s   | j r| j dg S d S )Nr_   rg   r   r   r   r   resource_tokens"  s    z MachineTokenFile.resource_tokens)r.   r/   r0   r   r1   r2   r   r   r`   r'   r-   r,   r4   r    rO   rN   rR   rT   staticmethodr   rS   r   rb   rc   intre   rh   ri   rj   rl   rm   r   r   r   r   r:   J   sH   

	
#

	r:   )rG   Zloggingr   r   typingr   r   r   Zuaclientr   r   r   r	   r
   Zuaclient.contract_data_typesr   Zget_event_loggerZeventZ	getLoggerZreplace_top_level_logger_namer.   r*   r   r5   r:   r   r   r   r   <module>   s   5