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dictZ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   Z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!   Z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!   r6   r7   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   ZPasswordSetErrorr!   r6   r7   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.
        r>   )r   ZPasswordDeleteErrorr9   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   ZSimpleCredentialr?   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 )NZKEYRING_PROPERTY_)	partitionlower)itemkeyvalueZprer1   r   r   r   r   parse   s   z5KeyringBackend.set_properties_from_env.<locals>.parseN)r&   maposenvironitemssetattr)r!   rH   Zpropsr   rG   r   r   r   r       s
   z&KeyringBackend.set_properties_from_env)r   r   r   r   r   r   r   ZClassPropertyclassmethodr%   r)   r   r5   abcabstractmethodstrr   r:   r@   rA   r   Z
CredentialrB   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!   rG   r   r   r   encrypt   r;   zCrypter.encryptc                 C   r"   )zDecrypt the value.Nr   rT   r   r   r   decrypt   r;   zCrypter.decryptN)r   r   r   r   rO   rP   rU   rV   r   r   r   r   rS      s    
rS   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   rT   r   r   r   rU         zNullCrypter.encryptc                 C   rX   r   r   rT   r   r   r   rV      rY   zNullCrypter.decryptN)r   r   r   r   rU   rV   r   r   r   r   rW      s    rW   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)	metadataZentry_pointslogdebugr   loadcallable	ExceptionZ	exception)ZepZ	init_funcr   r   r   _load_plugins   s   ra   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)ra   r   r)   r   Zsuppress_exceptions	TypeErrorlist)Zviable_classesZringsr   r   r   get_all_keyring   s   re   )r   rJ   rO   Zloggingr'   typingr   Zimportlib_metadatar[    r   r   r   r   Z	getLoggerr   r\   r(   Zby_priorityZ_limitABCMetar	   r   rS   rW   ra   oncere   r   r   r   r   <module>   s&    

u
