174
177
"""Get a generic option - no special process, no default."""
175
178
return self._get_user_option(option_name)
180
def get_user_option_as_bool(self, option_name):
181
"""Get a generic option as a boolean - no special process, no default.
183
:return None if the option doesn't exist or its value can't be
184
interpreted as a boolean. Returns True or False ortherwise.
186
s = self._get_user_option(option_name)
187
return ui.bool_from_string(s)
177
189
def gpg_signing_command(self):
178
190
"""What program should be used to sign signatures?"""
179
191
result = self._gpg_signing_command()
813
821
return osutils.pathjoin(config_dir(), 'ignore')
825
"""Return the directory name to store crash files.
827
This doesn't implicitly create it.
829
On Windows it's in the config directory; elsewhere in the XDG cache directory.
831
if sys.platform == 'win32':
832
return osutils.pathjoin(config_dir(), 'Crash')
834
return osutils.pathjoin(xdg_cache_dir(), 'crash')
838
# See http://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
839
# Possibly this should be different on Windows?
840
e = os.environ.get('XDG_CACHE_DIR', None)
844
return os.path.expanduser('~/.cache')
816
847
def _auto_user_id():
817
848
"""Calculate automatic user identification.
917
948
# XXX: Really needs a better name, as this is not part of the tree! -- mbp 20080507
919
950
def __init__(self, branch):
920
# XXX: Really this should be asking the branch for its configuration
921
# data, rather than relying on a Transport, so that it can work
922
# more cleanly with a RemoteBranch that has no transport.
923
self._config = TransportConfig(branch._transport, 'branch.conf')
951
self._config = branch._get_config()
924
952
self.branch = branch
926
954
def _get_parser(self, file=None):
1083
1110
trace.mutter("Using authentication section: %r", auth_def_name)
1113
if credentials is None:
1114
# No credentials were found in authentication.conf, try the fallback
1115
# credentials stores.
1116
credentials = credential_store_registry.get_fallback_credentials(
1117
scheme, host, port, user, path, realm)
1086
1119
return credentials
1088
1121
def set_credentials(self, name, host, user, scheme=None, password=None,
1130
1163
config.update({name: values})
1133
def get_user(self, scheme, host, port=None,
1134
realm=None, path=None, prompt=None):
1166
def get_user(self, scheme, host, port=None, realm=None, path=None,
1167
prompt=None, ask=False, default=None):
1135
1168
"""Get a user from authentication file.
1137
1170
:param scheme: protocol
1152
1190
user = credentials['user']
1196
# Create a default prompt suitable for most cases
1197
prompt = scheme.upper() + ' %(host)s username'
1198
# Special handling for optional fields in the prompt
1199
if port is not None:
1200
prompt_host = '%s:%d' % (host, port)
1203
user = ui.ui_factory.get_username(prompt, host=prompt_host)
1157
1208
def get_password(self, scheme, host, user, port=None,
1212
1263
A credential store provides access to credentials via the password_encoding
1213
1264
field in authentication.conf sections.
1215
Except for stores provided by bzr itself,most stores are expected to be
1266
Except for stores provided by bzr itself, most stores are expected to be
1216
1267
provided by plugins that will therefore use
1217
1268
register_lazy(password_encoding, module_name, member_name, help=help,
1218
info=info) to install themselves.
1269
fallback=fallback) to install themselves.
1271
A fallback credential store is one that is queried if no credentials can be
1272
found via authentication.conf.
1221
1275
def get_credential_store(self, encoding=None):
1281
def is_fallback(self, name):
1282
"""Check if the named credentials store should be used as fallback."""
1283
return self.get_info(name)
1285
def get_fallback_credentials(self, scheme, host, port=None, user=None,
1286
path=None, realm=None):
1287
"""Request credentials from all fallback credentials stores.
1289
The first credentials store that can provide credentials wins.
1292
for name in self.keys():
1293
if not self.is_fallback(name):
1295
cs = self.get_credential_store(name)
1296
credentials = cs.get_credentials(scheme, host, port, user,
1298
if credentials is not None:
1299
# We found some credentials
1303
def register(self, key, obj, help=None, override_existing=False,
1305
"""Register a new object to a name.
1307
:param key: This is the key to use to request the object later.
1308
:param obj: The object to register.
1309
:param help: Help text for this entry. This may be a string or
1310
a callable. If it is a callable, it should take two
1311
parameters (registry, key): this registry and the key that
1312
the help was registered under.
1313
:param override_existing: Raise KeyErorr if False and something has
1314
already been registered for that key. If True, ignore if there
1315
is an existing key (always register the new value).
1316
:param fallback: Whether this credential store should be
1319
return super(CredentialStoreRegistry,
1320
self).register(key, obj, help, info=fallback,
1321
override_existing=override_existing)
1323
def register_lazy(self, key, module_name, member_name,
1324
help=None, override_existing=False,
1326
"""Register a new credential store to be loaded on request.
1328
:param module_name: The python path to the module. Such as 'os.path'.
1329
:param member_name: The member of the module to return. If empty or
1330
None, get() will return the module itself.
1331
:param help: Help text for this entry. This may be a string or
1333
:param override_existing: If True, replace the existing object
1334
with the new one. If False, if there is already something
1335
registered with the same key, raise a KeyError
1336
:param fallback: Whether this credential store should be
1339
return super(CredentialStoreRegistry, self).register_lazy(
1340
key, module_name, member_name, help,
1341
info=fallback, override_existing=override_existing)
1228
1344
credential_store_registry = CredentialStoreRegistry()
1232
1348
"""An abstract class to implement storage for credentials"""
1234
1350
def decode_password(self, credentials):
1235
"""Returns a password for the provided credentials in clear text."""
1351
"""Returns a clear text password for the provided credentials."""
1236
1352
raise NotImplementedError(self.decode_password)
1354
def get_credentials(self, scheme, host, port=None, user=None, path=None,
1356
"""Return the matching credentials from this credential store.
1358
This method is only called on fallback credential stores.
1360
raise NotImplementedError(self.get_credentials)
1239
1364
class PlainTextCredentialStore(CredentialStore):
1240
1365
"""Plain text credential store for the authentication.conf file."""
1252
1377
class BzrDirConfig(object):
1254
def __init__(self, transport):
1255
self._config = TransportConfig(transport, 'control.conf')
1379
def __init__(self, bzrdir):
1380
self._bzrdir = bzrdir
1381
self._config = bzrdir._get_config()
1257
1383
def set_default_stack_on(self, value):
1258
1384
"""Set the default stacking location.
1325
1455
configobj.setdefault(section, {})[name] = value
1326
1456
self._set_configobj(configobj)
1458
def _get_config_file(self):
1460
return self._transport.get(self._filename)
1461
except errors.NoSuchFile:
1328
1464
def _get_configobj(self):
1330
return ConfigObj(self._transport.get(self._filename),
1332
except errors.NoSuchFile:
1333
return ConfigObj(encoding='utf-8')
1465
return ConfigObj(self._get_config_file(), encoding='utf-8')
1335
1467
def _set_configobj(self, configobj):
1336
1468
out_file = StringIO()