B
    oh\                 @   s   d Z ddlmZ ddlZddlZddlZddlZddlmZm	Z	m
Z
 ddl
mZ ddlmZmZ eZeeZedZdZG d	d
 d
ejZeeG dd 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
    )absolute_importN   )credentialserrorsutil)
properties)add_metaclassfilter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| ||| t| ds&t | _| j}| js<||  d S )N_classes)superr   __init__hasattrsetr   __abstractmethods__add)clsnamebasesdictclasses)	__class__ .lib/python3.7/site-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ejedd Zedd Z	ejedd	 Z
d
d Zejdd Zejdd Z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 )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
   /   s    zKeyringBackend.priorityc          	   C   s$   t  }| j W d Q R X t| S )N)r   ZExceptionRaisedContextr
   bool)r   excr   r   r   viable?   s    
zKeyringBackend.viablec             C   s   t td| jS )z6
        Return all subclasses deemed viable.
        r#   )r	   operator
attrgetterr   )r   r   r   r   get_viable_backendsF   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   M   s    zKeyringBackend.namec             C   s   t | }d|j|j|jf S )Nz%s.%s (priority: %g))typer   r   r
   )selfZkeyring_classr   r   r   __str__Y   s    zKeyringBackend.__str__c             C   s   dS )z5Get password of the username for the service
        Nr   )r1   serviceusernamer   r   r   get_password_   s    zKeyringBackend.get_passwordc             C   s   t ddS )zSet password for the username of the service.

        If the backend cannot store passwords, raise
        NotImplementedError.
        reasonN)r   ZPasswordSetError)r1   r3   r4   passwordr   r   r   set_passworde   s    zKeyringBackend.set_passwordc             C   s   t ddS )zDelete the password for the username of the service.

        If the backend cannot store passwords, raise
        NotImplementedError.
        r6   N)r   ZPasswordDeleteError)r1   r3   r4   r   r   r   delete_passwordq   s    zKeyringBackend.delete_passwordc             C   s,   |dk	r(|  ||}|dk	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)r5   r   ZSimpleCredential)r1   r3   r4   r7   r   r   r   get_credential|   s    	zKeyringBackend.get_credentialN)r   r   r   r   r
   r   ZClassPropertyclassmethodr#   r&   r   r2   abcabstractmethodr5   r8   r9   r:   r   r   r   r   r    (   s   r    c               @   s,   e Zd ZdZejdd Zejdd ZdS )Crypterz3Base class providing encryption and decryption
    c             C   s   dS )zEncrypt the value.
        Nr   )r1   valuer   r   r   encrypt   s    zCrypter.encryptc             C   s   dS )zDecrypt the value.
        Nr   )r1   r?   r   r   r   decrypt   s    zCrypter.decryptN)r   r   r   r   r<   r=   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 nothing
    c             C   s   |S )Nr   )r1   r?   r   r   r   r@      s    zNullCrypter.encryptc             C   s   |S )Nr   )r1   r?   r   r   r   rA      s    zNullCrypter.decryptN)r   r   r   r   r@   rA   r   r   r   r   rB      s   rB   c           	   C   sn   d} t j| d}xX|D ]P}y(td|j | }t|r@|  W q tk
rd   td|  Y qX 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.py::

        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 %s.N)	entrypointsZget_group_allloginfor   loadcallable	ExceptionZ	exception)rC   Zentry_pointsZepZ	init_funcr   r   r   _load_plugins   s    

rJ   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)rJ   r    r&   r   Zsuppress_exceptions	TypeErrorlist)Zviable_classesZringsr   r   r   get_all_keyring   s    rN   )r   Z
__future__r   r<   Zloggingr$   rD    r   r   r   r   Z
py27compatr   r	   r0   Z__metaclass__Z	getLoggerr   rE   r%   Zby_priorityZ_limitABCMetar   r    r>   rB   rJ   oncerN   r   r   r   r   <module>   s$   

g