This is an automated email from the git hooks/post-receive script. x2go pushed a commit to branch brokerclient in repository python-x2go. commit 6af69935177f1d3bbae432b4a783d06de1dd2176 Author: Mike Gabriel <mike.gabriel@das-netzwerkteam.de> Date: Tue Mar 18 01:05:05 2014 +0100 more work on the broker implementation --- x2go/backends/control/plain.py | 5 + x2go/backends/profiles/base.py | 130 ++++++++++++++++++----- x2go/backends/profiles/file.py | 8 ++ x2go/backends/profiles/httpbroker.py | 195 ++++++++++++++++++++++++---------- x2go/client.py | 43 +++++--- x2go/defaults.py | 2 +- x2go/inifiles.py | 4 +- x2go/registry.py | 1 + x2go/utils.py | 27 +++-- 9 files changed, 306 insertions(+), 109 deletions(-) diff --git a/x2go/backends/control/plain.py b/x2go/backends/control/plain.py index bb0ec98..fa756df 100644 --- a/x2go/backends/control/plain.py +++ b/x2go/backends/control/plain.py @@ -51,6 +51,7 @@ import x2go.defaults as defaults import x2go.checkhosts as checkhosts from x2go.defaults import BACKENDS as _BACKENDS +from x2go.defaults import CURRENT_LOCAL_USER as _current_user import x2go._paramiko x2go._paramiko.monkey_patch_paramiko() @@ -817,6 +818,10 @@ class X2GoControlSession(paramiko.SSHClient): """ _fake_hostname = None + if not username: + self.logger('no username specified, cannot connect without username', loglevel=log.loglevel_ERROR) + raise paramiko.AuthenticationException('no username specified, cannot connect without username') + if type(password) not in (types.StringType, types.UnicodeType): password = '' if type(sshproxy_password) not in (types.StringType, types.UnicodeType): diff --git a/x2go/backends/profiles/base.py b/x2go/backends/profiles/base.py index 8364c93..641e5e4 100644 --- a/x2go/backends/profiles/base.py +++ b/x2go/backends/profiles/base.py @@ -36,7 +36,7 @@ from x2go.defaults import X2GO_DESKTOPSESSIONS as _X2GO_DESKTOPSESSIONS import x2go.log as log import x2go.utils as utils -from x2go.x2go_exceptions import X2GoNotImplementedYetException +from x2go.x2go_exceptions import X2GoProfileException class X2GoSessionProfiles(): @@ -64,8 +64,6 @@ class X2GoSessionProfiles(): self._cached_profile_names = [] self._profiles_need_profile_id_renewal = [] self.write_user_config = False - self.config_files = None - self.user_config_file = None if logger is None: self.logger = log.X2GoLogger(loglevel=loglevel) @@ -76,7 +74,7 @@ class X2GoSessionProfiles(): if utils._checkSessionProfileDefaults(session_profile_defaults): self.defaultSessionProfile = session_profile_defaults - self.session_profiles = self.populate_session_profiles() + self.populate_session_profiles() def __call__(self, profile_id_or_name): """\ @@ -92,14 +90,20 @@ class X2GoSessionProfiles(): _profile_id = self.check_profile_id_or_name(self, profile_id_or_name) return self.get_profile_config(profile_id=_profile_id) - def init_profile_cache(self, profile_id): + def init_profile_cache(self, profile_id_or_name): """\ Some session profile backends (e.g. the broker backends cache dynamic session profile data). On new connections, it is recommented to (re-)initialize these caches. + @param profile_id_or_name: profile ID or profile name + @type profile_id_or_name: C{str} + """ - return self._init_profile_cache(profile_id) + profile_id = self.check_profile_id_or_name(profile_id_or_name) + + # allow backend specific clean-up + self._init_profile_cache(profile_id) def _init_profile_cache(self, profile_id): """\ @@ -118,7 +122,7 @@ class X2GoSessionProfiles(): @rtype: C{dict} """ - return self. _populate_session_profiles() + self.session_profiles = self. _populate_session_profiles() def _populate_session_profiles(self): """\ @@ -145,6 +149,7 @@ class X2GoSessionProfiles(): """ _profile_id = self.check_profile_id_or_name(profile_id_or_name) + if not self._profile_metatypes.has_key(_profile_id) or force: _config = self.get_profile_config(_profile_id) if _config['host']: @@ -174,6 +179,70 @@ class X2GoSessionProfiles(): else: return self._profile_metatypes[_profile_id] + def is_mutable(self, profile_id_or_name): + """\ + Check if a given profile name (or ID) is mutable or not. + + @param profile_id_or_name: profile name or profile ID + @type profile_id_or_name: C{str} + + @return: C{True} if the session profile of the specified name/ID is mutable + @rtype: C{bool} + + """ + try: + profile_id = self.check_profile_id_or_name(profile_id_or_name) + return self._is_mutable(profile_id) + except X2GoProfileException: + return None + + def _is_mutable(self, profile_id): + """\ + Inherit from this base class and provide your own decision making + code here if a given profile ID is mutable or not. + + @param profile_id: profile ID + @type profile_id: C{str} + + @return: C{True} if the session profile of the specified ID is mutable + @rtype: C{bool} + + """ + return False + + def supports_mutable_profiles(self): + """\ + Check if the current session profile backend supports + mutable session profiles. + + @return: list of mutable profiles + @rtype: C{list) + + """ + return self._supports_mutable_profiles() + + def _supports_mutable_profiles(self): + """\ + Inherit from this base class and provide your own decision making + code here if a your session profile backend supports mutable + session profiles or not. + + @return: list of mutable profiles + @rtype: C{list) + + """ + return False + + def mutable_profile_ids(self): + """\ + List all mutable session profiles. + + @return: List up all session profile IDs of mutable session profiles. + @rtype: C{bool} + + """ + return [ p for p in self.profile_ids if self._is_mutable(p) ] + def write(self): """\ Store session profile data to the storage backend. @@ -239,31 +308,31 @@ class X2GoSessionProfiles(): _profile_id = profile_id or self.check_profile_id_or_name(profile_id_or_name) _profile_config = {} for option in self._get_profile_options(_profile_id): - _profile_config[option] = self._get_profile_parameter(_profile_id, option, key_type=self.get_profile_option_type(option)) - - if parameter is not None: - if parameter in _profile_config.keys(): + value = self._get_profile_parameter(_profile_id, option, key_type=self.get_profile_option_type(option)) - value = _profile_config[parameter] + if option == 'export': + _strvalue = value.replace(',', ';').strip().strip('"').strip().strip(';').strip() + value = {} + if _strvalue: + _export_paths = _strvalue.split(';') + for _path in _export_paths: + if not re.match('.*:(0|1)$', _path): _path = '%s:1' % _path + _auto_export_path = re.match('.*:1$', _path) and True or False + _export_path = ':'.join(_path.split(':')[:-1]) + value[_export_path] = _auto_export_path - if parameter == 'export': - _strvalue = value.replace(',', ';').strip().strip('"').strip().strip(';').strip() - value = {} - if _strvalue: - _export_paths = _strvalue.split(';') - for _path in _export_paths: - if not re.match('.*:(0|1)$', _path): _path = '%s:1' % _path - _auto_export_path = re.match('.*:1$', _path) and True or False - _export_path = ':'.join(_path.split(':')[:-1]) - value[_export_path] = _auto_export_path + if type(value) is types.StringType: + value = unicode(value) - if type(value) is types.StringType: - value = unicode(value) + _profile_config[option] = value + if parameter is not None: + if parameter in _profile_config.keys(): + value = _profile_config[parameter] return value - else: raise X2GoProfileException('no such session profile parameter: %s' % parameter) + return _profile_config def default_profile_config(self): @@ -462,11 +531,14 @@ class X2GoSessionProfiles(): except X2GoProfileException: profile_id = profile_id_or_name + if not self.is_mutable(profile_id): + raise X2GoProfileException("session profile cannot be modified, it is marked as immutable") + if option == 'name': profile_name = value current_profile_name = self.get_value(profile_id, option) if not profile_name: - raise X2GoProfileException('profile name for profile id %s may not be empty' % profile_id) + raise X2GoProfileException('profile name for profile id %s must not be empty' % profile_id) else: self._cached_profile_names = [] if profile_name != current_profile_name and profile_name in self.profile_names: @@ -484,6 +556,10 @@ class X2GoSessionProfiles(): _config = self.get_profile_config(profile_id=profile_id) if _config.has_key('host') and _config['host'] != value: self._profiles_need_profile_id_renewal.append(profile_id) + if type(value) is types.TupleType: + value = list(value) + if type(value) is not types.ListType: + value = value.split(',') self._update_value(profile_id, option, value) @@ -608,7 +684,7 @@ class X2GoSessionProfiles(): @rtype: C{list} """ - return u'localhost' + return [u'localhost'] def get_server_port(self, profile_id): """\ diff --git a/x2go/backends/profiles/file.py b/x2go/backends/profiles/file.py index 7147295..0f08336 100644 --- a/x2go/backends/profiles/file.py +++ b/x2go/backends/profiles/file.py @@ -92,6 +92,12 @@ class X2GoSessionProfiles(base.X2GoSessionProfiles, inifiles.X2GoIniFile): self.get_profile_metatype(session_profile) return session_profiles + def _is_mutable(self, profile_id): + return True + + def _supports_mutable_profiles(self): + return True + def _write(self): self._write_user_config = self.write_user_config return inifiles.X2GoIniFile.write(self) @@ -100,6 +106,8 @@ class X2GoSessionProfiles(base.X2GoSessionProfiles, inifiles.X2GoIniFile): self.iniConfig.remove_section(profile_id) def _update_value(self, profile_id, option, value): + if option == 'host': + value = ','.join(value) inifiles.X2GoIniFile.update_value(self, profile_id, option, value) def _get_profile_parameter(self, profile_id, option, key_type): diff --git a/x2go/backends/profiles/httpbroker.py b/x2go/backends/profiles/httpbroker.py index e4e3dfd..569e851 100644 --- a/x2go/backends/profiles/httpbroker.py +++ b/x2go/backends/profiles/httpbroker.py @@ -26,9 +26,9 @@ applications. """ __NAME__ = 'x2gosessionprofiles-pylib' -import copy import re import requests +import copy import types try: import simplejson as json except ImportError: import json @@ -49,6 +49,7 @@ class X2GoSessionProfiles(base.X2GoSessionProfiles): broker_url="http://localhost:8080/json/", broker_username=None, broker_password=None, + broker_noauth=False, logger=None, loglevel=log.loglevel_DEFAULT, **kwargs): """\ @@ -58,6 +59,11 @@ class X2GoSessionProfiles(base.X2GoSessionProfiles): @type session_profile_defaults: C{dict} @param broker_url: URL for accessing the X2Go Session Broker @type broker_url: C{str} + @param broker_password: use this password for authentication against the X2Go Session Broker (avoid + password string in the C{broker_URL} parameter is highly recommended) + @type broker_password: C{str} + @param broker_noauth: the X2Go Session Broker accepts connections without authentication + @type broker_noauth: C{bool} @param logger: you can pass an L{X2GoLogger} object to the L{X2GoSessionProfilesHTTPSBROKER} constructor @type logger: L{X2GoLogger} instance @@ -66,28 +72,46 @@ class X2GoSessionProfiles(base.X2GoSessionProfiles): @type loglevel: C{int} """ - match = re.match('^(?P<protocol>(http(|s)))://(|(?P<user>[a-zA-Z0-9_\.-]+)(|:(?P<password>.*))@)(?P<hostname>[a-zA-Z0-9\.-]+)(|:(?P<port>[0-9]+))($|/(?P<path>.*)$)', broker_url) - p = match.groupdict() - if p['user']: - self.broker_username = p['user'] + self.broker_noauth = broker_noauth + if broker_url.upper() != "HTTP": + match = re.match('^(?P<protocol>(http(|s)))://(|(?P<user>[a-zA-Z0-9_\.-]+)(|:(?P<password>.*))@)(?P<hostname>[a-zA-Z0-9\.-]+)(|:(?P<port>[0-9]+))($|/(?P<path>.*)$)', broker_url) + p = match.groupdict() + if p['user']: + self.broker_username = p['user'] + else: + self.broker_username = broker_username + if not self.broker_noauth: + if p['password']: + self.broker_password = p['password'] + else: + self.broker_password = broker_password + else: + self.broker_password = None + + # fine-tune the URL + p['path'] = "/{path}".format(**p) + if p['port'] is not None: + p['port'] = ":{port}".format(**p) + + self.broker_url = "{protocol}://{hostname}{port}{path}".format(**p) + else: self.broker_username = broker_username - if p['password']: - self.broker_password = p['password'] - else: self.broker_password = broker_password - - # fine-tune the URL - p['path'] = "/{path}".format(**p) - if p['port'] is not None: - p['port'] = ":{port}".format(**p) - - self.broker_url = "{protocol}://{hostname}{port}{path}".format(**p) + self.broker_url = broker_url base.X2GoSessionProfiles.__init__(self, session_profile_defaults=session_profile_defaults, logger=logger, loglevel=loglevel) - self.logger("Using session broker at URL: %s" % self.broker_url, log.loglevel_NOTICE) + if self.broker_url != "HTTP": + self.logger("Using session broker at URL: %s" % self.broker_url, log.loglevel_NOTICE) self._broker_profile_cache = {} + self._mutable_profile_ids = None + self._broker_auth_successful = None + + self._broker_type = "http" + + def get_broker_noauth(self): + return self.broker_noauth def get_broker_username(self): return self.broker_username @@ -95,47 +119,92 @@ class X2GoSessionProfiles(base.X2GoSessionProfiles): def get_broker_url(self): return self.broker_url + def set_broker_url(self, broker_url): + self.broker_url = broker_url + + def get_broker_type(self): + return self._broker_type + def broker_simpleauth(self, broker_username, broker_password): - request_data = { - 'user': broker_username, - 'password': broker_password, - } - r = requests.post(self.broker_url, data=request_data) - if r.status_code == 200: - self.broker_username = broker_username - self.broker_password = broker_password - return True + if self.broker_url is not None: + request_data = { + 'user': broker_username or '', + 'password': broker_password or '', + } + r = requests.post(self.broker_url, data=request_data) + if r.status_code == 200: + self.broker_username = broker_username or '' + self.broker_password = broker_password or '' + self._broker_auth_successful = True + return True + self._broker_auth_successful = False return False - def broker_listprofiles(self): - request_data = { - 'task': 'listprofiles', - 'user': self.broker_username, - 'password': self.broker_password, - } - r = requests.post(self.broker_url, data=request_data) - if r.status_code == 200 and r.headers['content-type'].startswith("text/json"): - payload = json.loads(r.text) - return payload['profiles'] if payload['task'] == 'listprofiles' else {} + def broker_disconnect(self): + _profile_ids = copy.deepcopy(self.profile_ids) + + # forget nearly everything... + for profile_id in _profile_ids: + self.init_profile_cache(profile_id) + try: del self._profile_metatypes[profile_id] + except KeyError: pass + try: self._profiles_need_profile_id_renewal.remove(profile_id) + except ValueError: pass + try: self._cached_profile_names.remove(self.to_profile_name(profile_id)) + except ValueError: pass + try: self._cached_profile_ids.remove(profile_id) + except ValueError: pass + del self.session_profiles[profile_id] + self._mutable_profile_ids = None + self._broker_auth_successful = False + self.broker_password = None + + def is_broker_authenticated(self): + if self._broker_auth_successful is None: + # do a test auth against the given broker URL + self.broker_simpleauth(self.broker_username, self.broker_password) + return self._broker_auth_successful - def broker_selectsession(self, profile_id): - if not self._broker_profile_cache.has_key(profile_id) or not self._broker_profile_cache[profile_id]: + def broker_listprofiles(self): + if self.broker_url is not None: request_data = { - 'task': 'selectsession', - 'profile-id': profile_id, + 'task': 'listprofiles', 'user': self.broker_username, 'password': self.broker_password, } r = requests.post(self.broker_url, data=request_data) if r.status_code == 200 and r.headers['content-type'].startswith("text/json"): payload = json.loads(r.text) - self._broker_profile_cache[profile_id] = payload['selected_session'] if payload['task'] == 'selectsession' else {} + if payload.has_key('mutable_profile_ids'): + self._mutable_profile_ids = payload['mutable_profile_ids'] + self._broker_auth_successful = True + return payload['profiles'] if payload['task'] == 'listprofiles' else {} + self._broker_auth_successful = False + return {} - return self._broker_profile_cache[profile_id] + def broker_selectsession(self, profile_id): + if self.broker_url is not None: + if not self._broker_profile_cache.has_key(profile_id) or not self._broker_profile_cache[profile_id]: + request_data = { + 'task': 'selectsession', + 'profile-id': profile_id, + 'user': self.broker_username, + 'password': self.broker_password, + } + r = requests.post(self.broker_url, data=request_data) + if r.status_code == 200 and r.headers['content-type'].startswith("text/json"): + payload = json.loads(r.text) + self._broker_profile_cache[profile_id] = payload['selected_session'] if payload['task'] == 'selectsession' else {} + self._broker_auth_successful = True + else: + self._broker_auth_successful = False + self._broker_profile_cache[profile_id] + return self._broker_profile_cache[profile_id] + return {} def _init_profile_cache(self, profile_id): - if self._broker_profile_cache.has_key(profile_id): - del self._broker_profile_cache.has_key[profile_id] + if self._broker_profile_cache.has_key(unicode(profile_id)): + del self._broker_profile_cache[unicode(profile_id)] def _populate_session_profiles(self): """\ @@ -146,22 +215,38 @@ class X2GoSessionProfiles(base.X2GoSessionProfiles): @rtype: C{dict} """ - session_profiles = self.broker_listprofiles() - _session_profiles = copy.deepcopy(session_profiles) - - for session_profile in _session_profiles: - session_profile = unicode(session_profile) - for key, default_value in self.defaultSessionProfile.iteritems(): - key = unicode(key) - if type(default_value) is types.StringType: - default_value = unicode(default_value) - if not session_profiles[session_profile].has_key(key): - session_profiles[session_profile][key] = default_value + if self.broker_noauth or \ + self.broker_username and self.broker_password: + + session_profiles = self.broker_listprofiles() + _session_profiles = copy.deepcopy(session_profiles) + + for session_profile in _session_profiles: + session_profile = unicode(session_profile) + for key, default_value in self.defaultSessionProfile.iteritems(): + key = unicode(key) + if type(default_value) is types.StringType: + default_value = unicode(default_value) + if not session_profiles[session_profile].has_key(key): + session_profiles[session_profile][key] = default_value + + else: + session_profiles = {} return session_profiles + def _is_mutable(self, profile_id): + if type(self._mutable_profile_ids) is types.ListType and profile_id in self._mutable_profile_ids: + return True + return False + + def _supports_mutable_profiles(self): + if type(self._mutable_profile_ids) is types.ListType: + return True + return False + def _write(self): - print "not suported" + print "not suported, yet" def _delete_profile(self, profile_id): del self.session_profiles[unicode(profile_id)] diff --git a/x2go/client.py b/x2go/client.py index b7eec91..b1fa978 100644 --- a/x2go/client.py +++ b/x2go/client.py @@ -183,6 +183,8 @@ class X2GoClient(object): settings_backend=_BACKENDS['X2GoClientSettings']['default'], printing_backend=_BACKENDS['X2GoClientPrinting']['default'], broker_url=None, + broker_password=None, + broker_noauth=False, client_rootdir=None, sessions_rootdir=None, ssh_rootdir=None, @@ -216,6 +218,12 @@ class X2GoClient(object): @type settings_backend: C{str} @param printing_backend: X2Go client printing backend to use @type printing_backend: C{str} + @param broker_url: URL pointing to the X2Go Session Broker + @type broker_url: C{str} + @param broker_password: use this password for authentication against the X2Go Session Broker + @type broker_password: C{str} + @param broker_noauth: accessing the X2Go Session Broker works without credentials + @type broker_noauth: C{bool} @param client_rootdir: client base dir (default: ~/.x2goclient) @type client_rootdir: C{str} @param sessions_rootdir: sessions base dir (default: ~/.x2go) @@ -270,9 +278,9 @@ class X2GoClient(object): self.list_backend = utils._get_backend_class(list_backend, "X2GoServerSessionList") self.proxy_backend = utils._get_backend_class(proxy_backend, "X2GoProxy") if broker_url is not None: - if broker_url.startswith('ssh://'): + if broker_url.lower().startswith('ssh'): profiles_backend = 'sshbroker' - elif broker_url.startswith('http://') or broker_url.startswith('https://'): + elif broker_url.lower().startswith('http'): profiles_backend = 'httpbroker' self.profiles_backend = utils._get_backend_class(profiles_backend, "X2GoSessionProfiles") self.settings_backend = utils._get_backend_class(settings_backend, "X2GoClientSettings") @@ -294,7 +302,7 @@ class X2GoClient(object): _settings_config_file = os.path.join(self.client_rootdir, _X2GO_SETTINGS_FILENAME) _printing_config_file = os.path.join(self.client_rootdir, _X2GO_PRINTING_FILENAME) _xconfig_config_file = os.path.join(self.client_rootdir, _X2GO_XCONFIG_FILENAME) - self.session_profiles = self.profiles_backend(config_files=[_sessions_config_file], logger=self.logger, broker_url=broker_url) + self.session_profiles = self.profiles_backend(config_files=[_sessions_config_file], logger=self.logger, broker_url=broker_url, broker_password=broker_password, broker_noauth=broker_noauth) self.client_settings = self.settings_backend(config_files=[_settings_config_file], logger=self.logger) self.client_printing = self.printing_backend(config_files=[_printing_config_file], client_instance=self, logger=self.logger) else: @@ -870,22 +878,27 @@ class X2GoClient(object): @rtype: C{str} """ + _p = None # detect profile name and profile id properly if profile_id and self.session_profiles.has_profile_id(profile_id): _p = profile_id elif profile_name and self.session_profiles.has_profile_name(profile_name): _p = profile_name - elif profile_id and self.session_profiles.check_profile_id_or_name(profile_id): - _p = self.session_profiles.check_profile_id_or_name(profile_id) - elif profile_name and self.session_profiles.check_profile_id_or_name(profile_name): - _p = self.session_profiles.check_profile_id_or_name(profile_name) - else: - _p = None - + elif profile_id: + try: + _p = self.session_profiles.check_profile_id_or_name(profile_id) + except x2go_exceptions.X2GoProfileException: + pass + elif profile_name: + try: + _p = self.session_profiles.check_profile_id_or_name(profile_name) + except x2go_exceptions.X2GoProfileException: + pass if _p: - _profile_id = self.session_profiles.check_profile_id_or_name(_p) _profile_name = self.session_profiles.to_profile_name(_profile_id) + else: + _profile_id = None # test if session_name has already been registered. If yes, return it immediately. if type(session_name) is types.StringType: @@ -896,10 +909,10 @@ class X2GoClient(object): if known_hosts is None: known_hosts = os.path.join(_LOCAL_HOME, self.ssh_rootdir, 'known_hosts') - if _p: + if _profile_id: # initialize session profile cache - self.session_profiles.init_profile_cache(profile_id) + self.session_profiles.init_profile_cache(_profile_id) _params = self.session_profiles.to_session_params(profile_id=_profile_id) del _params['profile_name'] @@ -909,8 +922,8 @@ class X2GoClient(object): if k in kwargs.keys(): _params[k] = kwargs[k] - server = self.session_profiles.get_server_hostname(_p) - _params['port'] = self.session_profiles.get_server_port(_p) + server = self.session_profiles.get_server_hostname(_profile_id) + _params['port'] = self.session_profiles.get_server_port(_profile_id) del _params['server'] _params['client_instance'] = self diff --git a/x2go/defaults.py b/x2go/defaults.py index 59373f4..ee785a5 100644 --- a/x2go/defaults.py +++ b/x2go/defaults.py @@ -296,7 +296,7 @@ X2GO_SESSIONPROFILE_DEFAULTS = { 'usekbd': True, 'layout': 'us', 'type': 'pc105/us', 'variant': '', 'sound': False, 'soundsystem': 'pulse', 'startsoundsystem': False, 'soundtunnel':True, 'defsndport':True, 'sndport':4713, 'name': 'NEW_PROFILE', 'icon': ':icons/128x128/x2gosession.png', - 'host': 'server.mydomain', 'user': CURRENT_LOCAL_USER, 'key': '', 'sshport': 22, 'krblogin': False, 'forwardsshagent': False, + 'host': ['server.mydomain'], 'user': CURRENT_LOCAL_USER, 'key': '', 'sshport': 22, 'krblogin': False, 'forwardsshagent': False, 'rootless': True, 'applications': X2GO_GENERIC_APPLICATIONS, 'command':'TERMINAL', 'published': False, 'directrdp': False, 'directrdpsettings': '', 'rdpclient': 'rdesktop', 'rdpport': 3389, 'rdpoptions': '-u X2GO_USER -p X2GO_PASSWORD', 'rdpserver': '', diff --git a/x2go/inifiles.py b/x2go/inifiles.py index e363bee..1bc10d4 100644 --- a/x2go/inifiles.py +++ b/x2go/inifiles.py @@ -52,7 +52,6 @@ class X2GoIniFile(object): always contain the same fields. """ - user_config_file = None def __init__(self, config_files, defaults=None, logger=None, loglevel=log.loglevel_DEFAULT): """\ @@ -70,6 +69,7 @@ class X2GoIniFile(object): @type loglevel: C{int} """ + self.user_config_file = None self._write_user_config = True # make sure a None type gets turned into list type @@ -102,8 +102,8 @@ class X2GoIniFile(object): if not os.path.exists(file_name): utils.touch_file(file_name) _create_file = True + self.user_config_file = file_name break - self.load() if _create_file: diff --git a/x2go/registry.py b/x2go/registry.py index 66ad62f..ffe0708 100644 --- a/x2go/registry.py +++ b/x2go/registry.py @@ -560,6 +560,7 @@ class X2GoSessionRegistry(object): try: del _params['profile_id'] except: pass + print _params['port'] s = session.X2GoSession(server=server, control_session=control_session, profile_id=profile_id, profile_name=profile_name, session_name=session_name, diff --git a/x2go/utils.py b/x2go/utils.py index 13b2fe6..7f182ed 100644 --- a/x2go/utils.py +++ b/x2go/utils.py @@ -272,18 +272,27 @@ def _convert_SessionProfileOptions_2_SessionParams(options): _export = _params['export'] del _params['export'] - # fix for wrong export field usage in PyHoca-GUI/CLI and python-x2go before 20110923 - _export = _export.replace(",", ";") + if type(_export) is types.DictType: - _export = _export.strip().strip('"').strip().strip(';').strip() - _export_list = [ f for f in _export.split(';') if f ] + # since Python X2Go 0.5.0.0 + _params['share_local_folders'] = _export.keys() + + else: + + # before Python X2Go 0.5.0.0 (analysing the INI file's format for the export field) - _params['share_local_folders'] = [] - for _shared_folder in _export_list: # fix for wrong export field usage in PyHoca-GUI/CLI and python-x2go before 20110923 - if not ":" in _shared_folder: _shared_folder = "%s:1" % _shared_folder - if _shared_folder.split(":")[-1] == "1": - _params['share_local_folders'].append(":".join(_shared_folder.split(":")[:-1])) + _export = _export.replace(",", ";") + + _export = _export.strip().strip('"').strip().strip(';').strip() + _export_list = [ f for f in _export.split(';') if f ] + + _params['share_local_folders'] = [] + for _shared_folder in _export_list: + # fix for wrong export field usage in PyHoca-GUI/CLI and python-x2go before 20110923 + if not ":" in _shared_folder: _shared_folder = "%s:1" % _shared_folder + if _shared_folder.split(":")[-1] == "1": + _params['share_local_folders'].append(":".join(_shared_folder.split(":")[:-1])) if options['fullscreen']: _params['geometry'] = 'fullscreen' -- Alioth's /srv/git/_hooks_/post-receive-email on /srv/git/code.x2go.org/python-x2go.git