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)zSet 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@   )zDelete 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
