o
    a                  	   @   s   d dl Z ddlmZ ddlmZ ddlmZ ddlmZm	Z	 e	 .Z
zd dlmZ d dlmZ ej W n eyG   d dlZd dlZej Y nw W d   n1 sRw   Y  e eZG d	d
 d
ZG dd deZG dd deZdS )    N   )
properties)KeyringBackend)SimpleCredential)PasswordDeleteErrorExceptionRaisedContext)
pywintypes)	win32credc                   @   s   e Zd ZdddZdd ZdS )PersistenceNc                 C   s   t |dtjS )N_persist)getattrr	   ZCRED_PERSIST_ENTERPRISE)selfkeyringtype r   :/usr/lib/python3/dist-packages/keyring/backends/Windows.py__get__   s   zPersistence.__get__c                 C   s8   t |trd|dd  }tt|}t|d| dS )z
        Set the persistence value on the Keyring. Value may be
        one of the win32cred.CRED_PERSIST_* constants or a
        string representing one of those constants. For example,
        'local machine' or 'session'.
        ZCRED_PERSIST_ _r   N)
isinstancestrreplaceupperr   r	   setattr)r   r   valueattrr   r   r   __set__    s   

zPersistence.__set__)N)__name__
__module____qualname__r   r   r   r   r   r   r
      s    
r
   c                   @   s   e Zd Zedd ZdS )DecodingCredentialc                 C   s@   | d }z| dW S  ty   | d}td | Y S w )zM
        Attempt to decode the credential blob as UTF-16 then UTF-8.
        CredentialBlobzutf-16zutf-8zkRetrieved an UTF-8 encoded credential. Please be aware that this library only writes credentials in UTF-16.)decodeUnicodeDecodeErrorlogZwarning)r   ZcredZdecoded_cred_utf8r   r   r   r   .   s   
zDecodingCredential.valueN)r   r   r   propertyr   r   r   r   r   r    -   s    r    c                   @   sl   e Zd ZdZe Zejedd Z	e
dd Zdd Zdd	 Zd
d Zdd Zdd Zdd Zdd ZdS )WinVaultKeyringaf  
    WinVaultKeyring stores encrypted passwords using the Windows Credential
    Manager.

    Requires pywin32

    This backend does some gymnastics to simulate multi-user support,
    which WinVault doesn't support natively. See
    https://github.com/jaraco/keyring/issues/47#issuecomment-75763152
    for details on the implementation, but here's the gist:

    Passwords are stored under the service name unless there is a collision
    (another password with the same service name but different user name),
    in which case the previous password is moved into a compound name:
    {username}@{service}
    c                 C   s   t rtddS )zA
        If available, the preferred backend on Windows.
        zRequires Windows and pywin32   )missing_depsRuntimeError)clsr   r   r   priorityS   s   zWinVaultKeyring.priorityc                 C   s   |  d| S )N@r   )usernameservicer   r   r   _compound_name]   s   zWinVaultKeyring._compound_namec                 C   s:   |  |}|r|d |kr|  | ||}|sd S |jS NUserName)_get_passwordr/   r   r   r.   r-   resr   r   r   get_passworda   s   
zWinVaultKeyring.get_passwordc              
   C   sZ   zt jt j|d}W t|S  tjy, } z|jdkr'|jdkr'W Y d }~d S  d }~ww )NType
TargetName  CredRead)r	   r:   CRED_TYPE_GENERICr   errorwinerrorfuncnamer    )r   targetr4   er   r   r   r2   k   s   zWinVaultKeyring._get_passwordc                 C   sH   |  |}|r|d }| ||}| |||j | ||t| d S r0   )r2   r/   _set_passwordr   r   )r   r.   r-   passwordexisting_pwZexisting_usernamer?   r   r   r   set_passwordv   s   
zWinVaultKeyring.set_passwordc                 C   s(   t tj|||d| jd}t|d d S )NzStored using python-keyring)r7   r8   r1   r!   CommentZPersistr   )dictr	   r;   persistZ	CredWrite)r   r?   r-   rB   Z
credentialr   r   r   rA      s   zWinVaultKeyring._set_passwordc                 C   sV   |  ||}d}||fD ]}| |}|r"|d |kr"d}| | q|s)t|d S )NFr1   T)r/   r2   _delete_passwordr   )r   r.   r-   ZcompoundZdeletedr?   rC   r   r   r   delete_password   s   

zWinVaultKeyring.delete_passwordc              
   C   sV   zt jt j|d W d S  tjy* } z|jdkr%|jdkr%W Y d }~d S  d }~ww )Nr6   r9   
CredDelete)r	   rJ   r;   r   r<   r=   r>   )r   r?   r@   r   r   r   rH      s   z WinVaultKeyring._delete_passwordc                 C   s@   d }|r|  | ||}|s|  |}|sd S t|d |jS r0   )r2   r/   r   r   r3   r   r   r   get_credential   s   
zWinVaultKeyring.get_credentialN)r   r   r   __doc__r
   rG   r   ZClassPropertyclassmethodr+   staticmethodr/   r5   r2   rD   rA   rI   rH   rK   r   r   r   r   r&   ?   s    

r&   )Zloggingutilr   Zbackendr   Zcredentialsr   errorsr   r   r(   Zwin32ctypes.pywin32r   r	   r   ImportErrorZ	getLoggerr$   r
   rF   r    r&   r   r   r   r   <module>   s*    


