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	   Ú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'.
        Ú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ÚlogÚwarning)r   ÚcredÚ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_passwordr4   r   ©r   r3   r2   Ú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   Útargetr9   Úer   r   r   r7   k   s   ÿü€ýzWinVaultKeyring._get_passwordc                 C   sH   |   |¡}|r|d }|  ||¡}|  |||j¡ |  ||t|ƒ¡ d S r5   )r7   r4   Ú_set_passwordr   r   )r   r3   r2   ÚpasswordÚexisting_pwÚexisting_usernamerD   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)r<   r=   r6   r#   ÚCommentÚPersistr   )Údictr	   r@   ÚpersistÚ	CredWrite)r   rD   r2   rG   Ú
credentialr   r   r   rF   ƒ   s   úzWinVaultKeyring._set_passwordc                 C   sV   |   ||¡}d}||fD ]}|  |¡}|r"|d |kr"d}|  |¡ q|s)t|ƒ‚d S )NFr6   T)r4   r7   Ú_delete_passwordr   )r   r3   r2   ÚcompoundÚdeletedrD   rH   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 )Nr;   r>   Ú
CredDelete)r	   rU   r@   r   rA   rB   rC   )r   rD   rE   r   r   r   rQ   ™   s   €ýz WinVaultKeyring._delete_passwordc                 C   s@   d }|r|   |  ||¡¡}|s|   |¡}|sd S t|d |jƒS r5   )r7   r4   r   r   r8   r   r   r   Úget_credential¡   s   
zWinVaultKeyring.get_credentialN)r   r    r!   Ú__doc__r
   rN   r   ÚClassPropertyÚclassmethodr0   Ústaticmethodr4   r:   r7   rJ   rF   rT   rQ   rV   r   r   r   r   r+   ?   s    

r+   )ÚloggingÚutilr   Úbackendr   Úcredentialsr   Úerrorsr   r   r-   Úwin32ctypes.pywin32r   r	   r   ÚImportErrorÚ	getLoggerr&   r
   rM   r"   r+   r   r   r   r   Ú<module>   s*    

ú€ø
