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
|
"""
core.py
Created by Kang Zhang on 2009-07-09
"""
import os
import ConfigParser
import imp
import sys
import backend
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 spcified service
"""
return _keyring_backend.set_password(service_name, username, password)
def init_backend():
"""first try to load the keyring in the config file, if it has not
been decleared, assign a defult keyring according to the platform.
"""
#select a backend according to the config file
keyring_impl = load_config()
# if the user dose not specify a keyring, we apply a default one
if keyring_impl is None:
keyrings = backend.get_all_keyring()
# rank according the supported
keyrings.sort(lambda x, y: y.supported() - x.supported())
# get the most recommend one
keyring_impl = keyrings[0]
set_keyring(keyring_impl)
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_impl = None
# search from current working directory and the home folder
keyring_cfg_list = [os.path.join(os.getcwd(), "keyringrc.cfg"),
os.path.join(os.path.expanduser("~"), "keyringrc.cfg")]
# initial the keyring_cfg with the fist detected config file
keyring_cfg = None
for path in keyring_cfg_list:
keyring_cfg = path
if os.path.exists(path):
break
if os.path.exists(keyring_cfg):
config = ConfigParser.RawConfigParser()
config.read(keyring_cfg)
# load the keyring-path option
try:
keyring_path = config.get("backend", "keyring-path").strip()
except ConfigParser.NoOptionError:
keyring_path = None
# load the keyring class name, and load it
try:
keyring_name = config.get("backend", "default-keyring").strip()
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()
exec "keyring_temp = module." + keyring_class + "() " in locals()
keyring_impl = keyring_temp
except (ConfigParser.NoOptionError, ImportError):
logger.warning("Keyring Config file does not write correctly.\n" + \
"Config file: %s" % keyring_cfg)
return keyring_impl
# init the _keyring_backend
init_backend()
|