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
1159
user = credentials['user']
1165
# Create a default prompt suitable for most cases
1166
prompt = scheme.upper() + ' %(host)s username'
1167
# Special handling for optional fields in the prompt
1168
if port is not None:
1169
prompt_host = '%s:%d' % (host, port)
1172
user = ui.ui_factory.get_username(prompt, host=prompt_host)
1153
1177
def get_password(self, scheme, host, user, port=None,
1208
1232
A credential store provides access to credentials via the password_encoding
1209
1233
field in authentication.conf sections.
1211
Except for stores provided by bzr itself,most stores are expected to be
1235
Except for stores provided by bzr itself, most stores are expected to be
1212
1236
provided by plugins that will therefore use
1213
1237
register_lazy(password_encoding, module_name, member_name, help=help,
1214
info=info) to install themselves.
1238
fallback=fallback) to install themselves.
1240
A fallback credential store is one that is queried if no credentials can be
1241
found via authentication.conf.
1217
1244
def get_credential_store(self, encoding=None):
1250
def is_fallback(self, name):
1251
"""Check if the named credentials store should be used as fallback."""
1252
return self.get_info(name)
1254
def get_fallback_credentials(self, scheme, host, port=None, user=None,
1255
path=None, realm=None):
1256
"""Request credentials from all fallback credentials stores.
1258
The first credentials store that can provide credentials wins.
1261
for name in self.keys():
1262
if not self.is_fallback(name):
1264
cs = self.get_credential_store(name)
1265
credentials = cs.get_credentials(scheme, host, port, user,
1267
if credentials is not None:
1268
# We found some credentials
1272
def register(self, key, obj, help=None, override_existing=False,
1274
"""Register a new object to a name.
1276
:param key: This is the key to use to request the object later.
1277
:param obj: The object to register.
1278
:param help: Help text for this entry. This may be a string or
1279
a callable. If it is a callable, it should take two
1280
parameters (registry, key): this registry and the key that
1281
the help was registered under.
1282
:param override_existing: Raise KeyErorr if False and something has
1283
already been registered for that key. If True, ignore if there
1284
is an existing key (always register the new value).
1285
:param fallback: Whether this credential store should be
1288
return super(CredentialStoreRegistry,
1289
self).register(key, obj, help, info=fallback,
1290
override_existing=override_existing)
1292
def register_lazy(self, key, module_name, member_name,
1293
help=None, override_existing=False,
1295
"""Register a new credential store to be loaded on request.
1297
:param module_name: The python path to the module. Such as 'os.path'.
1298
:param member_name: The member of the module to return. If empty or
1299
None, get() will return the module itself.
1300
:param help: Help text for this entry. This may be a string or
1302
:param override_existing: If True, replace the existing object
1303
with the new one. If False, if there is already something
1304
registered with the same key, raise a KeyError
1305
:param fallback: Whether this credential store should be
1308
return super(CredentialStoreRegistry, self).register_lazy(
1309
key, module_name, member_name, help,
1310
info=fallback, override_existing=override_existing)
1224
1313
credential_store_registry = CredentialStoreRegistry()
1228
1317
"""An abstract class to implement storage for credentials"""
1230
1319
def decode_password(self, credentials):
1231
"""Returns a password for the provided credentials in clear text."""
1320
"""Returns a clear text password for the provided credentials."""
1232
1321
raise NotImplementedError(self.decode_password)
1323
def get_credentials(self, scheme, host, port=None, user=None, path=None,
1325
"""Return the matching credentials from this credential store.
1327
This method is only called on fallback credential stores.
1329
raise NotImplementedError(self.get_credentials)
1235
1333
class PlainTextCredentialStore(CredentialStore):
1236
1334
"""Plain text credential store for the authentication.conf file."""
1248
1346
class BzrDirConfig(object):
1250
def __init__(self, transport):
1251
self._config = TransportConfig(transport, 'control.conf')
1348
def __init__(self, bzrdir):
1349
self._bzrdir = bzrdir
1350
self._config = bzrdir._get_config()
1253
1352
def set_default_stack_on(self, value):
1254
1353
"""Set the default stacking location.
1321
1424
configobj.setdefault(section, {})[name] = value
1322
1425
self._set_configobj(configobj)
1427
def _get_config_file(self):
1429
return self._transport.get(self._filename)
1430
except errors.NoSuchFile:
1324
1433
def _get_configobj(self):
1326
return ConfigObj(self._transport.get(self._filename),
1328
except errors.NoSuchFile:
1329
return ConfigObj(encoding='utf-8')
1434
return ConfigObj(self._get_config_file(), encoding='utf-8')
1331
1436
def _set_configobj(self, configobj):
1332
1437
out_file = StringIO()