/usr/lib/python3/dist-packages/keyring/backend.py is in python3-keyring 3.5-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | """
Keyring implementation support
"""
from __future__ import absolute_import
import abc
from keyring import errors
from keyring.util import properties
from keyring.py27compat import add_metaclass, filter
import keyring.util
class KeyringBackendMeta(abc.ABCMeta):
"""
A metaclass that's both an ABCMeta and a type that keeps a registry of
all (non-abstract) types.
"""
def __init__(cls, name, bases, dict):
super(KeyringBackendMeta, cls).__init__(name, bases, dict)
if not hasattr(cls, '_classes'):
cls._classes = set()
classes = cls._classes
if not cls.__abstractmethods__:
classes.add(cls)
@add_metaclass(KeyringBackendMeta)
class KeyringBackend(object):
"""The abstract base class of the keyring, every backend must implement
this interface.
"""
#@abc.abstractproperty
def priority(cls):
"""
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.
"""
@properties.ClassProperty
@classmethod
def viable(cls):
with errors.ExceptionRaisedContext() as exc:
cls.priority
return not bool(exc)
@abc.abstractmethod
def get_password(self, service, username):
"""Get password of the username for the service
"""
return None
@abc.abstractmethod
def set_password(self, service, username, password):
"""Set password for the username of the service
"""
raise errors.PasswordSetError("reason")
# for backward-compatibility, don't require a backend to implement
# delete_password
#@abc.abstractmethod
def delete_password(self, service, username):
"""Delete the password for the username of the service.
"""
raise errors.PasswordDeleteError("reason")
class Crypter(object):
"""Base class providing encryption and decryption
"""
@abc.abstractmethod
def encrypt(self, value):
"""Encrypt the value.
"""
pass
@abc.abstractmethod
def decrypt(self, value):
"""Decrypt the value.
"""
pass
class NullCrypter(Crypter):
"""A crypter that does nothing
"""
def encrypt(self, value):
return value
def decrypt(self, value):
return value
@keyring.util.once
def get_all_keyring():
"""
Return a list of all implemented keyrings that can be constructed without
parameters.
"""
# ensure that all keyring backends are loaded
for mod_name in ('file', 'Gnome', 'Google', 'keyczar', 'kwallet', 'multi',
'OS_X', 'pyfs', 'SecretService', 'Windows'):
# use fromlist to cause the module to resolve under Demand Import
__import__('keyring.backends.'+mod_name, fromlist=('__name__',))
def is_class_viable(keyring_cls):
try:
keyring_cls.priority
except RuntimeError:
return False
return True
all_classes = KeyringBackend._classes
viable_classes = filter(is_class_viable, all_classes)
return list(keyring.util.suppress_exceptions(viable_classes,
exceptions=TypeError))
|