~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/config.py

  • Committer: Robert J. Tanner
  • Date: 2009-04-30 22:40:42 UTC
  • mfrom: (4323 +trunk)
  • mto: This revision was merged to the branch mainline in revision 4324.
  • Revision ID: tanner@real-time.com-20090430224042-53v45axtue5bw45l
Merge 1.14.1 back to trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
1079
1079
                trace.mutter("Using authentication section: %r", auth_def_name)
1080
1080
            break
1081
1081
 
 
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)
 
1087
 
1082
1088
        return credentials
1083
1089
 
1084
1090
    def set_credentials(self, name, host, user, scheme=None, password=None,
1126
1132
        config.update({name: values})
1127
1133
        self._save()
1128
1134
 
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.
1132
1138
 
1133
1139
        :param scheme: protocol
1140
1146
 
1141
1147
        :param path: the absolute path on the server (optional)
1142
1148
 
 
1149
        :param ask: Ask the user if there is no explicitly configured username 
 
1150
                    (optional)
 
1151
 
 
1152
        :param default: The username returned if none is defined (optional).
 
1153
 
1143
1154
        :return: The found user.
1144
1155
        """
1145
1156
        credentials = self.get_credentials(scheme, host, port, user=None,
1148
1159
            user = credentials['user']
1149
1160
        else:
1150
1161
            user = None
 
1162
        if user is None:
 
1163
            if ask:
 
1164
                if prompt is None:
 
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)
 
1170
                else:
 
1171
                    prompt_host = host
 
1172
                user = ui.ui_factory.get_username(prompt, host=prompt_host)
 
1173
            else:
 
1174
                user = default
1151
1175
        return user
1152
1176
 
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.
1210
1234
 
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.
 
1239
 
 
1240
    A fallback credential store is one that is queried if no credentials can be
 
1241
    found via authentication.conf.
1215
1242
    """
1216
1243
 
1217
1244
    def get_credential_store(self, encoding=None):
1220
1247
            cs = cs()
1221
1248
        return cs
1222
1249
 
 
1250
    def is_fallback(self, name):
 
1251
        """Check if the named credentials store should be used as fallback."""
 
1252
        return self.get_info(name)
 
1253
 
 
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.
 
1257
 
 
1258
        The first credentials store that can provide credentials wins.
 
1259
        """
 
1260
        credentials = None
 
1261
        for name in self.keys():
 
1262
            if not self.is_fallback(name):
 
1263
                continue
 
1264
            cs = self.get_credential_store(name)
 
1265
            credentials = cs.get_credentials(scheme, host, port, user,
 
1266
                                             path, realm)
 
1267
            if credentials is not None:
 
1268
                # We found some credentials
 
1269
                break
 
1270
        return credentials
 
1271
 
 
1272
    def register(self, key, obj, help=None, override_existing=False,
 
1273
                 fallback=False):
 
1274
        """Register a new object to a name.
 
1275
 
 
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 
 
1286
                used as fallback.
 
1287
        """
 
1288
        return super(CredentialStoreRegistry,
 
1289
                     self).register(key, obj, help, info=fallback,
 
1290
                                    override_existing=override_existing)
 
1291
 
 
1292
    def register_lazy(self, key, module_name, member_name,
 
1293
                      help=None, override_existing=False,
 
1294
                      fallback=False):
 
1295
        """Register a new credential store to be loaded on request.
 
1296
 
 
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
 
1301
                a callable.
 
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 
 
1306
                used as fallback.
 
1307
        """
 
1308
        return super(CredentialStoreRegistry, self).register_lazy(
 
1309
            key, module_name, member_name, help,
 
1310
            info=fallback, override_existing=override_existing)
 
1311
 
1223
1312
 
1224
1313
credential_store_registry = CredentialStoreRegistry()
1225
1314
 
1228
1317
    """An abstract class to implement storage for credentials"""
1229
1318
 
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)
1233
1322
 
 
1323
    def get_credentials(self, scheme, host, port=None, user=None, path=None,
 
1324
                        realm=None):
 
1325
        """Return the matching credentials from this credential store.
 
1326
 
 
1327
        This method is only called on fallback credential stores.
 
1328
        """
 
1329
        raise NotImplementedError(self.get_credentials)
 
1330
 
 
1331
 
1234
1332
 
1235
1333
class PlainTextCredentialStore(CredentialStore):
1236
1334
    """Plain text credential store for the authentication.conf file."""
1247
1345
 
1248
1346
class BzrDirConfig(object):
1249
1347
 
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()
1252
1351
 
1253
1352
    def set_default_stack_on(self, value):
1254
1353
        """Set the default stacking location.
1258
1357
        This policy affects all branches contained by this bzrdir, except for
1259
1358
        those under repositories.
1260
1359
        """
 
1360
        if self._config is None:
 
1361
            raise errors.BzrError("Cannot set configuration in %s" % self._bzrdir)
1261
1362
        if value is None:
1262
1363
            self._config.set_option('', 'default_stack_on')
1263
1364
        else:
1271
1372
        This policy affects all branches contained by this bzrdir, except for
1272
1373
        those under repositories.
1273
1374
        """
 
1375
        if self._config is None:
 
1376
            return None
1274
1377
        value = self._config.get_option('default_stack_on')
1275
1378
        if value == '':
1276
1379
            value = None
1321
1424
            configobj.setdefault(section, {})[name] = value
1322
1425
        self._set_configobj(configobj)
1323
1426
 
 
1427
    def _get_config_file(self):
 
1428
        try:
 
1429
            return self._transport.get(self._filename)
 
1430
        except errors.NoSuchFile:
 
1431
            return StringIO()
 
1432
 
1324
1433
    def _get_configobj(self):
1325
 
        try:
1326
 
            return ConfigObj(self._transport.get(self._filename),
1327
 
                             encoding='utf-8')
1328
 
        except errors.NoSuchFile:
1329
 
            return ConfigObj(encoding='utf-8')
 
1434
        return ConfigObj(self._get_config_file(), encoding='utf-8')
1330
1435
 
1331
1436
    def _set_configobj(self, configobj):
1332
1437
        out_file = StringIO()