o
    ÞñÐaè  ã                   @   sÌ   d 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Zddl	m
Z
mZmZ ddlmZ e e¡Ze d¡ZdZG dd	„ d	ejƒZG d
d„ ded�ZG dd„ dƒZG dd„ deƒZdd„ Zejdd„ ƒZdS )z 
Keyring implementation support
é    N)ÚOptionalé   )ÚcredentialsÚerrorsÚutil)Ú
propertiesÚpriorityc                       s    e Zd ZdZ‡ fdd„Z‡  ZS )ÚKeyringBackendMetazn
    A metaclass that's both an ABCMeta and a type that keeps a registry of
    all (non-abstract) types.
    c                    s@   t ƒ  |||¡ t| dƒstƒ | _| j}| js| | ¡ d S d S )NÚ_classes)ÚsuperÚ__init__ÚhasattrÚsetr
   Ú__abstractmethods__Úadd)ÚclsÚnameÚbasesÚdictÚclasses©Ú	__class__© ú1/usr/lib/python3/dist-packages/keyring/backend.pyr      s   
ÿzKeyringBackendMeta.__init__)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Ú__classcell__r   r   r   r   r	      s    r	   c                	   @   sÖ   e Zd ZdZdd„ Zdd„ Zejedd„ ƒƒZ	edd	„ ƒZ
ejed
d„ ƒƒZdd„ Zejdededee fdd„ƒZejdedededdfdd„ƒZdededdfdd„Zdedee deej fdd„Zdd„ ZdS )ÚKeyringBackendz]The abstract base class of the keyring, every backend must implement
    this interface.
    c                 C   s   |   ¡  d S ©N)Úset_properties_from_env)Úselfr   r   r   r   ,   s   zKeyringBackend.__init__c                 C   ó   dS )a½  
        Each backend class must supply a priority, a number (float or integer)
        indicating the priority of the backend relative to all other backends.
        The priority need not be static -- it may (and should) vary based
        attributes of the environment in which is runs (platform, available
        packages, etc.).

        A higher number indicates a higher priority. The priority should raise
        a RuntimeError with a message indicating the underlying cause if the
        backend is not suitable for the current environment.

        As a rule of thumb, a priority between zero but less than one is
        suitable, but a priority of one or greater is recommended.
        Nr   ©r   r   r   r   r   0   s    zKeyringBackend.priorityc                 C   s8   t  ¡ �}| j W d   ƒ | S 1 sw   Y  | S r    )r   ÚExceptionRaisedContextr   )r   Úexcr   r   r   Úviable@   s   

ÿþzKeyringBackend.viablec                 C   s   t t d¡| jƒS )z6
        Return all subclasses deemed viable.
        r'   )ÚfilterÚoperatorÚ
attrgetterr
   r$   r   r   r   Úget_viable_backendsG   s   z"KeyringBackend.get_viable_backendsc                 C   s.   | j  d¡\}}}| dd¡}d || jg¡S )zr
        The keyring name, suitable for display.

        The name is derived from module and class name.
        Ú.Ú_ú )r   Ú
rpartitionÚreplaceÚjoinr   )r   ÚparentÚsepÚmod_namer   r   r   r   N   s   zKeyringBackend.namec                 C   s   t | ƒ}d |j|j|j¡S )Nz{}.{} (priority: {:g}))ÚtypeÚformatr   r   r   )r"   Úkeyring_classr   r   r   Ú__str__Z   s   ÿzKeyringBackend.__str__ÚserviceÚusernameÚreturnc                 C   r#   )z,Get password of the username for the serviceNr   ©r"   r9   r:   r   r   r   Úget_password`   ó   zKeyringBackend.get_passwordÚpasswordNc                 C   ó
   t  d¡‚)z†Set password for the username of the service.

        If the backend cannot store passwords, raise
        PasswordSetError.
        Úreason)r   ÚPasswordSetError©r"   r9   r:   r?   r   r   r   Úset_passworde   s   
zKeyringBackend.set_passwordc                 C   r@   )z‘Delete the password for the username of the service.

        If the backend cannot delete passwords, raise
        PasswordDeleteError.
        rA   )r   ÚPasswordDeleteErrorr<   r   r   r   Údelete_passwordq   s   
zKeyringBackend.delete_passwordc                 C   s,   |dur|   ||¡}|durt ||¡S dS )a   Gets the username and password for the service.
        Returns a Credential instance.

        The *username* argument is optional and may be omitted by
        the caller or ignored by the backend. Callers must use the
        returned username.
        N)r=   r   ÚSimpleCredentialrC   r   r   r   Úget_credential|   s
   zKeyringBackend.get_credentialc                 C   s<   dd„ }t dt|tj ¡ ƒƒ}|D ]
\}}t| ||ƒ qdS )z6For all KEYRING_PROPERTY_* env var, set that property.c                 S   s(   | \}}|  d¡\}}}|o| ¡ |fS )NÚKEYRING_PROPERTY_)Ú	partitionÚlower)ÚitemÚkeyÚvalueÚprer3   r   r   r   r   Úparse’   s   z5KeyringBackend.set_properties_from_env.<locals>.parseN)r(   ÚmapÚosÚenvironÚitemsÚsetattr)r"   rP   Úpropsr   rN   r   r   r   r!   �   s
   ÿz&KeyringBackend.set_properties_from_env)r   r   r   r   r   r   r   ÚClassPropertyÚclassmethodr'   r+   r   r8   ÚabcÚabstractmethodÚstrr   r=   rD   rF   r   Ú
CredentialrH   r!   r   r   r   r   r   '   s4    

þý
ür   )Ú	metaclassc                   @   s,   e Zd ZdZejdd„ ƒZejdd„ ƒZdS )ÚCrypterz.Base class providing encryption and decryptionc                 C   r#   )zEncrypt the value.Nr   ©r"   rN   r   r   r   ÚencryptŸ   r>   zCrypter.encryptc                 C   r#   )zDecrypt the value.Nr   r_   r   r   r   Údecrypt¤   r>   zCrypter.decryptN)r   r   r   r   rY   rZ   r`   ra   r   r   r   r   r^   œ   s    
r^   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )ÚNullCrypterzA crypter that does nothingc                 C   ó   |S r    r   r_   r   r   r   r`   ­   ó   zNullCrypter.encryptc                 C   rc   r    r   r_   r   r   r   ra   °   rd   zNullCrypter.decryptN)r   r   r   r   r`   ra   r   r   r   r   rb   ª   s    rb   c               	   C   sb   t jdd�D ](} zt d| j¡ |  ¡ }t|ƒr|ƒ  W q ty.   t d| › d�¡ Y qw dS )aù  
    Locate all setuptools entry points by the name 'keyring backends'
    and initialize them.
    Any third-party library may register an entry point by adding the
    following to their setup.cfg::

        [options.entry_points]
        keyring.backends =
            plugin_name = mylib.mymodule:initialize_func

    `plugin_name` can be anything, and is only used to display the name
    of the plugin at initialization time.

    `initialize_func` is optional, but will be invoked if callable.
    zkeyring.backends)Úgroupz
Loading %szError initializing plugin r,   N)	ÚmetadataÚentry_pointsÚlogÚdebugr   ÚloadÚcallableÚ	ExceptionÚ	exception)ÚepÚ	init_funcr   r   r   Ú_load_plugins´   s   €ÿúrp   c                  C   s$   t ƒ  t ¡ } tj| td�}t|ƒS )zc
    Return a list of all implemented keyrings that can be constructed without
    parameters.
    )Ú
exceptions)rp   r   r+   r   Úsuppress_exceptionsÚ	TypeErrorÚlist)Úviable_classesÚringsr   r   r   Úget_all_keyringÎ   s   rw   )r   rR   rY   Úloggingr)   Útypingr   Úimportlib_metadatarf   Ú r   r   r   r   Ú	getLoggerr   rh   r*   Úby_priorityÚ_limitÚABCMetar	   r   r^   rb   rp   Úoncerw   r   r   r   r   Ú<module>   s&    

u
