916
917
# XXX: Really needs a better name, as this is not part of the tree! -- mbp 20080507
918
919
def __init__(self, branch):
919
self._config = branch._get_config()
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')
920
924
self.branch = branch
922
926
def _get_parser(self, file=None):
1079
1083
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)
1088
1086
return credentials
1090
1088
def set_credentials(self, name, host, user, scheme=None, password=None,
1132
1130
config.update({name: values})
1135
def get_user(self, scheme, host, port=None, realm=None, path=None,
1136
prompt=None, ask=False, default=None):
1133
def get_user(self, scheme, host, port=None,
1134
realm=None, path=None, prompt=None):
1137
1135
"""Get a user from authentication file.
1139
1137
:param scheme: protocol
1159
1152
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)
1177
1157
def get_password(self, scheme, host, user, port=None,
1232
1212
A credential store provides access to credentials via the password_encoding
1233
1213
field in authentication.conf sections.
1235
Except for stores provided by bzr itself, most stores are expected to be
1215
Except for stores provided by bzr itself,most stores are expected to be
1236
1216
provided by plugins that will therefore use
1237
1217
register_lazy(password_encoding, module_name, member_name, help=help,
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.
1218
info=info) to install themselves.
1244
1221
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)
1313
1228
credential_store_registry = CredentialStoreRegistry()
1317
1232
"""An abstract class to implement storage for credentials"""
1319
1234
def decode_password(self, credentials):
1320
"""Returns a clear text password for the provided credentials."""
1235
"""Returns a password for the provided credentials in clear text."""
1321
1236
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)
1333
1239
class PlainTextCredentialStore(CredentialStore):
1334
1240
"""Plain text credential store for the authentication.conf file."""
1346
1252
class BzrDirConfig(object):
1348
def __init__(self, bzrdir):
1349
self._bzrdir = bzrdir
1350
self._config = bzrdir._get_config()
1254
def __init__(self, transport):
1255
self._config = TransportConfig(transport, 'control.conf')
1352
1257
def set_default_stack_on(self, value):
1353
1258
"""Set the default stacking location.
1424
1325
configobj.setdefault(section, {})[name] = value
1425
1326
self._set_configobj(configobj)
1427
def _get_config_file(self):
1328
def _get_configobj(self):
1429
return self._transport.get(self._filename)
1330
return ConfigObj(self._transport.get(self._filename),
1430
1332
except errors.NoSuchFile:
1433
def _get_configobj(self):
1434
return ConfigObj(self._get_config_file(), encoding='utf-8')
1333
return ConfigObj(encoding='utf-8')
1436
1335
def _set_configobj(self, configobj):
1437
1336
out_file = StringIO()