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*    


