1079
1079
trace.mutter("Using authentication section: %r", auth_def_name)
1082
if credentials is None:
1083
# No credentials were found in authentication.conf, try the fallback
1084
# credentials stores.
1085
credentials = credential_store_registry.get_fallback_credentials(
1086
scheme, host, port, user, path, realm)
1082
1088
return credentials
1084
1090
def set_credentials(self, name, host, user, scheme=None, password=None,
1126
1132
config.update({name: values})
1129
def get_user(self, scheme, host, port=None,
1130
realm=None, path=None, prompt=None):
1135
def get_user(self, scheme, host, port=None, realm=None, path=None,
1136
prompt=None, ask=False, default=None):
1131
1137
"""Get a user from authentication file.
1133
1139
:param scheme: protocol
1148
1157
user = credentials['user']
1163
# Create a default prompt suitable for most cases
1164
prompt = scheme.upper() + ' %(host)s username'
1165
# Special handling for optional fields in the prompt
1166
if port is not None:
1167
prompt_host = '%s:%d' % (host, port)
1170
user = ui.ui_factory.get_username(prompt, host=prompt_host)
1174
default = getpass.getuser()
1153
1178
def get_password(self, scheme, host, user, port=None,
1208
1233
A credential store provides access to credentials via the password_encoding
1209
1234
field in authentication.conf sections.
1211
Except for stores provided by bzr itself,most stores are expected to be
1236
Except for stores provided by bzr itself, most stores are expected to be
1212
1237
provided by plugins that will therefore use
1213
1238
register_lazy(password_encoding, module_name, member_name, help=help,
1214
info=info) to install themselves.
1239
fallback=fallback) to install themselves.
1241
A fallback credential store is one that is queried if no credentials can be
1242
found via authentication.conf.
1217
1245
def get_credential_store(self, encoding=None):
1251
def is_fallback(self, name):
1252
"""Check if the named credentials store should be used as fallback."""
1253
return self.get_info(name)
1255
def get_fallback_credentials(self, scheme, host, port=None, user=None,
1256
path=None, realm=None):
1257
"""Request credentials from all fallback credentials stores.
1259
The first credentials store that can provide credentials wins.
1262
for name in self.keys():
1263
if not self.is_fallback(name):
1265
cs = self.get_credential_store(name)
1266
credentials = cs.get_credentials(scheme, host, port, user,
1268
if credentials is not None:
1269
# We found some credentials
1273
def register(self, key, obj, help=None, override_existing=False,
1275
"""Register a new object to a name.
1277
:param key: This is the key to use to request the object later.
1278
:param obj: The object to register.
1279
:param help: Help text for this entry. This may be a string or
1280
a callable. If it is a callable, it should take two
1281
parameters (registry, key): this registry and the key that
1282
the help was registered under.
1283
:param override_existing: Raise KeyErorr if False and something has
1284
already been registered for that key. If True, ignore if there
1285
is an existing key (always register the new value).
1286
:param fallback: Whether this credential store should be
1289
return super(CredentialStoreRegistry,
1290
self).register(key, obj, help, info=fallback,
1291
override_existing=override_existing)
1293
def register_lazy(self, key, module_name, member_name,
1294
help=None, override_existing=False,
1296
"""Register a new credential store to be loaded on request.
1298
:param module_name: The python path to the module. Such as 'os.path'.
1299
:param member_name: The member of the module to return. If empty or
1300
None, get() will return the module itself.
1301
:param help: Help text for this entry. This may be a string or
1303
:param override_existing: If True, replace the existing object
1304
with the new one. If False, if there is already something
1305
registered with the same key, raise a KeyError
1306
:param fallback: Whether this credential store should be
1309
return super(CredentialStoreRegistry, self).register_lazy(
1310
key, module_name, member_name, help,
1311
info=fallback, override_existing=override_existing)
1224
1314
credential_store_registry = CredentialStoreRegistry()
1228
1318
"""An abstract class to implement storage for credentials"""
1230
1320
def decode_password(self, credentials):
1231
"""Returns a password for the provided credentials in clear text."""
1321
"""Returns a clear text password for the provided credentials."""
1232
1322
raise NotImplementedError(self.decode_password)
1324
def get_credentials(self, scheme, host, port=None, user=None, path=None,
1326
"""Return the matching credentials from this credential store.
1328
This method is only called on fallback credential stores.
1330
raise NotImplementedError(self.get_credentials)
1235
1334
class PlainTextCredentialStore(CredentialStore):
1236
1335
"""Plain text credential store for the authentication.conf file."""
1248
1347
class BzrDirConfig(object):
1250
def __init__(self, transport):
1251
self._config = TransportConfig(transport, 'control.conf')
1349
def __init__(self, bzrdir):
1350
self._bzrdir = bzrdir
1351
self._config = bzrdir._get_config()
1253
1353
def set_default_stack_on(self, value):
1254
1354
"""Set the default stacking location.
1321
1425
configobj.setdefault(section, {})[name] = value
1322
1426
self._set_configobj(configobj)
1428
def _get_config_file(self):
1430
return self._transport.get(self._filename)
1431
except errors.NoSuchFile:
1324
1434
def _get_configobj(self):
1326
return ConfigObj(self._transport.get(self._filename),
1328
except errors.NoSuchFile:
1329
return ConfigObj(encoding='utf-8')
1435
return ConfigObj(self._get_config_file(), encoding='utf-8')
1331
1437
def _set_configobj(self, configobj):
1332
1438
out_file = StringIO()