461
457
def __init__(self, location):
462
458
name_generator = locations_config_filename
463
if (not os.path.exists(name_generator()) and
459
if (not os.path.exists(name_generator()) and
464
460
os.path.exists(branches_config_filename())):
465
461
if sys.platform == 'win32':
466
warning('Please rename %s to %s'
467
% (branches_config_filename(),
468
locations_config_filename()))
462
trace.warning('Please rename %s to %s'
463
% (branches_config_filename(),
464
locations_config_filename()))
470
warning('Please rename ~/.bazaar/branches.conf'
471
' to ~/.bazaar/locations.conf')
466
trace.warning('Please rename ~/.bazaar/branches.conf'
467
' to ~/.bazaar/locations.conf')
472
468
name_generator = branches_config_filename
473
469
super(LocationConfig, self).__init__(name_generator)
474
470
# local file locations are looked up by local path, rather than
928
930
self.branch.control_files.put('branch.conf', out_file)
930
932
self.branch.unlock()
935
class AuthenticationConfig(object):
936
"""The authentication configuration file based on a ini file.
938
Implements the authentication.conf file described in
939
doc/developers/authentication-ring.txt.
942
def __init__(self, _file=None):
943
self._config = None # The ConfigObj
945
self._filename = authentication_config_filename()
946
self._input = self._filename = authentication_config_filename()
948
# Tests can provide a string as _file
949
self._filename = None
952
def _get_config(self):
953
if self._config is not None:
956
# FIXME: Should we validate something here ? Includes: empty
957
# sections are useless, at least one of
958
# user/password/password_encoding should be defined, etc.
960
# Note: the encoding below declares that the file itself is utf-8
961
# encoded, but the values in the ConfigObj are always Unicode.
962
self._config = ConfigObj(self._input, encoding='utf-8')
963
except configobj.ConfigObjError, e:
964
raise errors.ParseConfigError(e.errors, e.config.filename)
968
"""Save the config file, only tests should use it for now."""
969
conf_dir = os.path.dirname(self._filename)
970
ensure_config_dir_exists(conf_dir)
971
self._get_config().write(file(self._filename, 'wb'))
973
def _set_option(self, section_name, option_name, value):
974
"""Set an authentication configuration option"""
975
conf = self._get_config()
976
section = conf.get(section_name)
979
section = conf[section]
980
section[option_name] = value
983
def get_credentials(self, scheme, host, port=None, user=None, path=None):
984
"""Returns the matching credentials from authentication.conf file.
986
:param scheme: protocol
988
:param host: the server address
990
:param port: the associated port (optional)
992
:param user: login (optional)
994
:param path: the absolute path on the server (optional)
996
:return: A dict containing the matching credentials or None.
998
- name: the section name of the credentials in the
999
authentication.conf file,
1000
- user: can't de different from the provided user if any,
1001
- password: the decoded password, could be None if the credential
1002
defines only the user
1003
- verify_certificates: https specific, True if the server
1004
certificate should be verified, False otherwise.
1007
for auth_def_name, auth_def in self._get_config().items():
1008
a_scheme, a_host, a_user, a_path = map(
1009
auth_def.get, ['scheme', 'host', 'user', 'path'])
1012
a_port = auth_def.as_int('port')
1016
raise ValueError("'port' not numeric in %s" % auth_def_name)
1018
a_verify_certificates = auth_def.as_bool('verify_certificates')
1020
a_verify_certificates = True
1023
"'verify_certificates' not boolean in %s" % auth_def_name)
1026
if a_scheme is not None and scheme != a_scheme:
1028
if a_host is not None:
1029
if not (host == a_host
1030
or (a_host.startswith('.') and host.endswith(a_host))):
1032
if a_port is not None and port != a_port:
1034
if (a_path is not None and path is not None
1035
and not path.startswith(a_path)):
1037
if (a_user is not None and user is not None
1038
and a_user != user):
1039
# Never contradict the caller about the user to be used
1044
credentials = dict(name=auth_def_name,
1045
user=a_user, password=auth_def['password'],
1046
verify_certificates=a_verify_certificates)
1047
self.decode_password(credentials,
1048
auth_def.get('password_encoding', None))
1049
if 'auth' in debug.debug_flags:
1050
trace.mutter("Using authentication section: %r", auth_def_name)
1055
def get_user(self, scheme, host, port=None,
1056
realm=None, path=None, prompt=None):
1057
"""Get a user from authentication file.
1059
:param scheme: protocol
1061
:param host: the server address
1063
:param port: the associated port (optional)
1065
:param realm: the realm sent by the server (optional)
1067
:param path: the absolute path on the server (optional)
1069
:return: The found user.
1071
credentials = self.get_credentials(scheme, host, port, user=None,
1073
if credentials is not None:
1074
user = credentials['user']
1079
def get_password(self, scheme, host, user, port=None,
1080
realm=None, path=None, prompt=None):
1081
"""Get a password from authentication file or prompt the user for one.
1083
:param scheme: protocol
1085
:param host: the server address
1087
:param port: the associated port (optional)
1091
:param realm: the realm sent by the server (optional)
1093
:param path: the absolute path on the server (optional)
1095
:return: The found password or the one entered by the user.
1097
credentials = self.get_credentials(scheme, host, port, user, path)
1098
if credentials is not None:
1099
password = credentials['password']
1102
# Prompt user only if we could't find a password
1103
if password is None:
1105
# Create a default prompt suitable for most of the cases
1106
prompt = '%s' % scheme.upper() + ' %(user)s@%(host)s password'
1107
# Special handling for optional fields in the prompt
1108
if port is not None:
1109
prompt_host = '%s:%d' % (host, port)
1112
password = ui.ui_factory.get_password(prompt,
1113
host=prompt_host, user=user)
1116
def decode_password(self, credentials, encoding):