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 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
|
"""
core.py
Created by Kang Zhang on 2009-07-09
"""
import os
try:
import configparser as config_parser
except ImportError:
import ConfigParser as config_parser
import imp
import sys
from keyring import logger
from keyring import backend
from keyring.util import platform
from keyring.util import loc_compat
def set_keyring(keyring):
"""Set current keyring backend.
"""
global _keyring_backend
if isinstance(keyring, backend.KeyringBackend):
_keyring_backend = keyring
else:
raise TypeError("The keyring must be a subclass of KeyringBackend")
def get_keyring():
"""Get current keyring backend.
"""
return _keyring_backend
def get_password(service_name, username):
"""Get password from the specified service
"""
return _keyring_backend.get_password(service_name, username)
def set_password(service_name, username, password):
"""Set password for the user in the specified service
"""
_keyring_backend.set_password(service_name, username, password)
def init_backend():
"""Load a keyring from a config file or for the default platform.
First try to load the keyring in the config file, if it has not
been declared, assign a default keyring according to the platform.
"""
# select a backend according to the config file
keyring = load_config()
# if the user doesn't specify a keyring, we apply a default one
if keyring is None:
keyrings = backend.get_all_keyring()
# rank according to the supported result
keyrings.sort(key = lambda x: -x.supported())
# get the most recommended one
keyring = keyrings[0]
set_keyring(keyring)
def load_keyring(keyring_path, keyring_name):
"""Load the specified keyring name from the specified path
`keyring_path` can be None and it will not interfere with the loading
process.
"""
def load_module(name, path):
"""Load the specified module from the disk.
"""
path_list = name.split('.')
module_info = imp.find_module(path_list[0], path)
module_file, pathname, description = module_info
module = imp.load_module(path_list[0], module_file,
pathname, description)
if module_file:
module_file.close()
if len(path_list) > 1:
# for the class name containing dots
sub_name = '.'.join(path_list[1:])
sub_path = path
try:
sub_path = path + module.__path__
except AttributeError:
return module
return load_module(sub_name, sub_path)
return module
try:
# avoid import the imported modules
module = sys.modules[keyring_name[:keyring_name.rfind('.')]]
except KeyError:
module = load_module(keyring_name, sys.path+[keyring_path])
keyring_class = keyring_name.split('.')[-1].strip()
keyring_temp = getattr(module, keyring_class)()
return keyring_temp
def load_config():
"""Load a keyring using the config file.
The config file can be in the current working directory, or in the user's
home directory.
"""
keyring = None
filename = 'keyringrc.cfg'
local_path = os.path.join(os.getcwd(), filename)
legacy_path = os.path.join(os.path.expanduser("~"), filename)
config_path = os.path.join(platform.data_root(), filename)
loc_compat.relocate_file(legacy_path, config_path)
# search from current working directory and the data root
keyring_cfg_candidates = [local_path, config_path]
# initialize the keyring_config with the first detected config file
keyring_cfg = None
for path in keyring_cfg_candidates:
keyring_cfg = path
if os.path.exists(path):
break
if os.path.exists(keyring_cfg):
config = config_parser.RawConfigParser()
config.read(keyring_cfg)
# load the keyring-path option
try:
if config.has_section("backend"):
keyring_path = config.get("backend", "keyring-path").strip()
else:
keyring_path = None
except config_parser.NoOptionError:
keyring_path = None
# load the keyring class name, and then load this keyring
try:
if config.has_section("backend"):
keyring_name = config.get("backend", "default-keyring").strip()
else:
raise config_parser.NoOptionError('backend', 'default-keyring')
keyring = load_keyring(keyring_path, keyring_name)
except (config_parser.NoOptionError, ImportError):
logger.warning("Keyring config file contains incorrect values.\n" +
"Config file: %s" % keyring_cfg)
return keyring
# init the _keyring_backend
init_backend()
|