[X2Go-Commits] [x2gobroker] 02/02: Finalize API documentation.
git-admin at x2go.org
git-admin at x2go.org
Thu Jan 31 20:52:04 CET 2019
This is an automated email from the git hooks/post-receive script.
x2go pushed a commit to branch master
in repository x2gobroker.
commit 3ec8cdae957979fe8dd994b37da7aa26b2a20a40
Author: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
Date: Thu Jan 31 20:50:08 2019 +0100
Finalize API documentation.
---
debian/changelog | 1 +
x2gobroker/agent.py | 37 +++++++---
x2gobroker/authmechs/base_authmech.py | 1 -
x2gobroker/authservice.py | 8 ++
x2gobroker/basicauth.py | 3 +
x2gobroker/brokers/base_broker.py | 69 +++++++++++++++---
x2gobroker/brokers/inifile_broker.py | 70 ++++++++++++++++++
x2gobroker/brokers/zeroconf_broker.py | 33 +++++++++
x2gobroker/client/plain.py | 28 +++++++
x2gobroker/nameservices/base_nameservice.py | 93 ++++++++++++++++++++++++
x2gobroker/nameservices/libnss_nameservice.py | 40 ++++++++++
x2gobroker/nameservices/testsuite_nameservice.py | 45 +++++++++++-
x2gobroker/optional_scripts/base_script.py | 37 ++++++++++
x2gobroker/web/extras.py | 7 ++
x2gobroker/web/json.py | 38 ++++++++--
x2gobroker/web/plain.py | 36 +++++++--
x2gobroker/web/uccs.py | 48 ++++++++++++
x2gobroker/x2gobroker_exceptions.py | 21 +++++-
18 files changed, 577 insertions(+), 38 deletions(-)
diff --git a/debian/changelog b/debian/changelog
index 04df2b4..694f32f 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -99,6 +99,7 @@ x2gobroker (0.0.4.0-0x2go1) UNRELEASED; urgency=medium
Popen.terminate() (which is unneeded anyway) the process after its
execution.
- Ignore SSH broker events for now. Not sure if we will ever support that.
+ - Finalize API documentation.
* debian/*:
+ Trigger Makefile's install target and install those files. Drop debhelper
from-source-installation magic.
diff --git a/x2gobroker/agent.py b/x2gobroker/agent.py
index 22a5527..3647b8b 100644
--- a/x2gobroker/agent.py
+++ b/x2gobroker/agent.py
@@ -48,6 +48,9 @@ def has_remote_broker_agent_setup():
- Check for available SSH private keys.
- Nothing else, so far...
+ :returns: ``True``, if the broker supports remote broker agent calls
+ :rtype: ``bool``
+
"""
home = os.path.expanduser("~")
if os.path.exists(os.path.join(home, '.ssh', 'id_rsa')):
@@ -76,6 +79,10 @@ def call_broker_agent(username, task, cmdline_args=[], remote_agent=None, logger
:raises X2GoBrokerAgentException: if the call to the remote broker agents fails.
+ :returns: ``(<success>, <data>)``, a tuple with the <success> flag as first item
+ and the data retrieved from the broker agent as second item
+ :rtype: ``tuple``
+
"""
if remote_agent in ('LOCAL', None):
result = _call_local_broker_agent(username=username, task=task, cmdline_args=cmdline_args, logger=logger)
@@ -99,6 +106,10 @@ def _call_local_broker_agent(username, task, cmdline_args=[], logger=None):
:raises X2GoBrokerAgentException: if the call to the remote broker agents fails.
+ :returns: ``(<success>, <data>)``, a tuple with the <success> flag as first item
+ and the data retrieved from the broker agent as second item
+ :rtype: ``tuple``
+
"""
if logger is None:
logger = logger_broker
@@ -173,6 +184,10 @@ def _call_remote_broker_agent(username, task, cmdline_args=[], remote_agent=None
:raises X2GoBrokerAgentException: if the call to the remote broker agents fails.
+ :returns: ``(<success>, <data>)``, a tuple with the <success> flag as first item
+ and the data retrieved from the broker agent as second item
+ :rtype: ``tuple``
+
"""
if logger is None:
logger = logger_broker
@@ -288,7 +303,7 @@ def list_sessions(username, remote_agent=None, logger=None, **kwargs):
:param logger: logger instance to report log messages to
:type logger: :class:`logging.<Some>Logger`
- :returns: (<success>, <list-of-sessions>), a tuple with the <success> flag as first item
+ :returns: ``(<success>, <list-of-sessions>)``, a tuple with the <success> flag as first item
and a session ``list`` as second item
:rtype: ``tuple``
@@ -311,7 +326,7 @@ def suspend_session(username, session_name, remote_agent=None, logger=None, **kw
:param logger: logger instance to report log messages to
:type logger: :class:`logging.<Some>Logger`
- :returns: (<success>, ), a tuple with the <success> flag as first item
+ :returns: ``(<success>, [])``, a tuple with the <success> flag as first item
:rtype: ``tuple``
"""
@@ -333,7 +348,7 @@ def terminate_session(username, session_name, remote_agent=None, logger=None, **
:param logger: logger instance to report log messages to
:type logger: :class:`logging.<Some>Logger`
- :returns: (<success>, ), a tuple with the <success> flag as first item
+ :returns: ``(<success>, [])``, a tuple with the <success> flag as first item
:rtype: ``tuple``
"""
@@ -356,7 +371,7 @@ def has_sessions(username, remote_agent=None, logger=None, **kwargs):
:param logger: logger instance to report log messages to
:type logger: :class:`logging.<Some>Logger`
- :returns: (<success>, <has-running-sessions>, <has-suspended-session>), a tuple of two Boolean values
+ :returns: ``(<success>, <has-running-sessions>, <has-suspended-session>)``, a tuple of two Boolean values
:rtype: ``tuple``
"""
@@ -385,7 +400,7 @@ def find_busy_servers(username, remote_agent=None, logger=None, **kwargs):
:param logger: logger instance to report log messages to
:type logger: :class:`logging.<Some>Logger`
- :returns: (<success>, <server-usage>), a tuple with the <success> flag as first item
+ :returns: ``(<success>, <server-usage>)``, a tuple with the <success> flag as first item
and a dict reflecting the relative server usage
:rtype: ``tuple``
@@ -418,7 +433,7 @@ def check_load(remote_agent=None, logger=None, **kwargs):
:param logger: logger instance to report log messages to
:type logger: :class:`logging.<Some>Logger`
- :returns: (<success>, <load-factor>), a tuple with the <success> flag as first item
+ :returns: ``(<success>, <load-factor>)``, a tuple with the <success> flag as first item
and the queried server's load factor as second item
:rtype: ``tuple``
@@ -475,7 +490,7 @@ def add_authorized_key(username, pubkey_hash, authorized_keys_file='%h/.x2go/aut
:param logger: logger instance to report log messages to
:type logger: :class:`logging.<Some>Logger`
- :returns: (<success>, ), a tuple with the <success> flag as first item
+ :returns: ``(<success>, [])``, a tuple with the <success> flag as first item
:rtype: ``tuple``
"""
@@ -501,7 +516,7 @@ def delete_authorized_key(username, pubkey_hash, authorized_keys_file='%h/.x2go/
:param logger: logger instance to report log messages to
:type logger: :class:`logging.<Some>Logger`
- :returns: (<success>, ), a tuple with the <success> flag as first item
+ :returns: ``(<success>, [])``, a tuple with the <success> flag as first item
:rtype: ``tuple``
"""
@@ -536,7 +551,7 @@ def get_servers(username, remote_agent=None, logger=None, **kwargs):
:param logger: logger instance to report log messages to
:type logger: :class:`logging.<Some>Logger`
- :returns: (<success>, <server-list>), a tuple with the <success> flag as first item
+ :returns: ``(<success>, <server-list>)``, a tuple with the <success> flag as first item
and the list of used X2Go Servers as second item
:rtype: ``tuple``
@@ -572,7 +587,7 @@ def tasks_available(username, remote_agent=None, logger=None, **kwargs):
:param logger: logger instance to report log messages to
:type logger: :class:`logging.<Some>Logger`
- :returns: (<success>, <server-list>), a tuple with the <success> flag as first item
+ :returns: ``(<success>, <server-list>)``, a tuple with the <success> flag as first item
and a list of available broker agent tasks as second item
:rtype: ``tuple``
@@ -597,7 +612,7 @@ def genkeypair(local_username, client_address, key_type='RSA', logger=None):
:param logger: logger instance to report log messages to
:type logger: :class:`logging.<Some>Logger`
- :returns: two-item tuple: (<pubkey>, <privkey>)
+ :returns: two-item tuple: ``(<pubkey>, <privkey>)``
:rtype: ``tuple``
"""
diff --git a/x2gobroker/authmechs/base_authmech.py b/x2gobroker/authmechs/base_authmech.py
index 2973e23..47d006d 100644
--- a/x2gobroker/authmechs/base_authmech.py
+++ b/x2gobroker/authmechs/base_authmech.py
@@ -49,6 +49,5 @@ class X2GoBrokerAuthMech(object):
:returns: Authentication failure (always!)
:rtype: ``bool``
-
"""
return False
diff --git a/x2gobroker/authservice.py b/x2gobroker/authservice.py
index 2bac9bc..01cbf95 100644
--- a/x2gobroker/authservice.py
+++ b/x2gobroker/authservice.py
@@ -135,6 +135,10 @@ class AuthClient(asyncore.dispatcher_with_send):
self.logger.info('authentication failure for \'{user}\' with password \'<hidden>\' against PAM service \'{service}\''.format(user=user, service=service))
def handle_close(self):
+ """\
+ Close the connected :class:``AuthClient`` connection.
+
+ """
self.close()
@@ -170,5 +174,9 @@ class AuthService(asyncore.dispatcher_with_send):
self.listen(1)
def handle_accept(self):
+ """\
+ Handle accepted connection requests.
+
+ """
conn, _ = self.accept()
AuthClient(conn, logger=self.logger)
diff --git a/x2gobroker/basicauth.py b/x2gobroker/basicauth.py
index d48117b..f4da6aa 100644
--- a/x2gobroker/basicauth.py
+++ b/x2gobroker/basicauth.py
@@ -28,6 +28,9 @@ def require_basic_auth(realm, validate_callback):
"""\
Handler for ``http(s)://`` BasisAuth processing.
+ This function is used as a decorator for web request handler classes
+ (such as tornado.web.RequestHandler).
+
:param realm: authentication realm
:type realm: ``str``
:param validate_callback: callback function for validating credentials
diff --git a/x2gobroker/brokers/base_broker.py b/x2gobroker/brokers/base_broker.py
index 562620c..f70c558 100644
--- a/x2gobroker/brokers/base_broker.py
+++ b/x2gobroker/brokers/base_broker.py
@@ -1039,7 +1039,8 @@ class X2GoBroker(object):
:param profile_id: choose remote agent for this profile ID
:type profile_id: ``str``
- :param exclude_agents: a list of remote agent dict objects to be exclude from the random choice
+ :param exclude_agents: a list of remote agent dict objects to be exclude
+ from the random choice
:type exclude_agents: ``list``
:returns: remote agent to use for queries for profile ID
@@ -1280,7 +1281,8 @@ class X2GoBroker(object):
def list_profiles(self, username):
"""\
- Retrieve a list of available session profiles for the authenticated user.
+ Retrieve a list of available session profiles for the
+ authenticated user.
:param username: query session profile list for this user
:type username: ``str``
@@ -1299,12 +1301,14 @@ class X2GoBroker(object):
def select_session(self, profile_id, username=None, pubkey=None):
"""\
- Start/resume a session by selecting a profile name offered by the X2Go client.
+ Start/resume a session by selecting a profile name offered by the
+ X2Go client.
- The X2Go server that the session is launched on is selected automatically by the X2Go session
- broker.
+ The X2Go server that the session is launched on is selected
+ automatically by the X2Go session broker.
- :param profile_id: the selected profile ID. This matches one of the dictionary keys offered by the ``list_profiles`` method
+ :param profile_id: the selected profile ID. This matches one of the dictionary
+ keys offered by the ``list_profiles`` method
:type profile_id: ``str``
:param username: specify X2Go Server username that this operation runs for
:type username: ``str``
@@ -1312,6 +1316,9 @@ class X2GoBroker(object):
temporarily install into a remote X2Go Server for non-interactive login
:type pubkey: ``str``
+ :returns: the seclected session (X2Go session ID)
+ :rtype: ``str``
+
"""
try:
profile = self.get_profile(profile_id)
@@ -1706,21 +1713,59 @@ class X2GoBroker(object):
def change_password(self, new='', old=''):
"""\
- Modify the authenticated user's password on the X2Go infrastructure (normally, one user
- in one X2Go site setup should have the same password on all machines).
+ Modify the authenticated user's password on the X2Go
+ infrastructure (normally, one user in one X2Go site setup should
+ have the same password on all machines).
+
+ This function is a dummy function and needs to be overridden in
+ specific broker backend implementations
+
+ :param new: the new password that is to be set
+ :type new: ``str``
+ :param old: the currently set password
+ :type old: ``str``
+
+ :returns: whether the password change has been successful
+ :rtype: ``bool``
"""
return False
def run_optional_script(self, script_type, username, password, task, profile_id, ip, cookie, authed=None, server=None):
"""\
- Run all optional scripts of type script_type. Called with 3 different script types:
+ Run all optional scripts of type script_type. Called with 3
+ different script types:
- pre_auth_scripts - before authentication happens
- - post_auth_scripts - after authentication but before anything else occurs
- - select_session_scripts - after load balancing before a specific server is sent to the client
+ - post_auth_scripts - after authentication but before
+ anything else occurs
+ - select_session_scripts - after load balancing before a
+ specific server is sent to the client
+
+ These scripts allow for both addional actions to be performed as
+ well as the mangling of any relevant fields.
- These scripts allow for both addional actions to be performed as well as the mangling of any relevant fields.
+ :param script_type: name of the script type to be executed (``pre_auth_scripts``, ``post_auth_scripts``, ``select_session_scripts``)
+ :type script_type: ``str``
+ :param username: name of the X2Go session user a script will run for
+ :type username: ``str``
+ :param password: password for the X2Go session
+ :type password: ``str``
+ :param task: the broker task that currently being processed
+ :type task: ``str``
+ :param profile_id: the session profile ID that is being operated upon
+ :type profile_id: ``str``
+ :param ip: the client machine's IP address
+ :type ip: ``str``
+ :param cookie: the currently valid authentication cookie
+ :type cookie: ``str``
+ :param authed: authentication status (already authenticated or not)
+ :type authed: ``bool``
+ :param server: hostname or IP address of the X2Go server being operated upon
+ :type server: ``str``
+
+ :returns: Pass-through of the return value returned by the to-be-run optional script (i.e., success or failure)
+ :rtype: ``bool``
"""
diff --git a/x2gobroker/brokers/inifile_broker.py b/x2gobroker/brokers/inifile_broker.py
index 72ddd9f..918d0d7 100644
--- a/x2gobroker/brokers/inifile_broker.py
+++ b/x2gobroker/brokers/inifile_broker.py
@@ -37,11 +37,21 @@ import x2gobroker.x2gobroker_exceptions
from configparser import NoSectionError
class X2GoBroker(base.X2GoBroker):
+ """\
+ :class:`x2gobroker.brokers.inifile_broker.X2GoBroker` implements a broker backend
+ retrieving its session profile and ACL configuration from a file in
+ INI file format.
+
+ """
backend_name = 'inifile'
def __init__(self, profile_config_file=None, profile_config_defaults=None, **kwargs):
"""\
+ Initialize a new INI file based X2GoBroker instance to control
+ X2Go session through an X2Go Client with an intermediate session
+ broker
+
:param profile_config_file: path to the backend's session profile configuration (x2gobroker-sessionprofiles.conf)
:type profile_config_file: ``str``
:param profile_config_defaults: Default settings for session profile configuration parameters.
@@ -55,11 +65,32 @@ class X2GoBroker(base.X2GoBroker):
self.session_profiles = x2gobroker.config.X2GoBrokerConfigFile(config_files=profile_config_file, defaults=profile_config_defaults)
def get_profile_ids(self):
+ """\
+ Retrieve the complete list of session profile IDs.
+
+ With the ``inifile`` broker backend, the profile IDs are the
+ names of the INI file's sections.
+ :returns: list of profile IDs
+ :rtype: ``list``
+
+ """
return self.session_profiles.list_sections()
def get_profile_defaults(self):
+ """\
+ Get the session profile defaults, i.e. profile options that all
+ configured session profiles have in common.
+ The defaults are hard-coded in :mod:`x2gobroker.defaults` for class
+ :class:`x2gobroker.brokers.base_broker.X2GoBroker`. With the ``inifile``
+ backend, they can be overridden/customized under the INI file's
+ ``[DEFAULT]`` section.
+
+ :returns: a dictionary containing the session profile defaults
+ :rtype: ``dict``
+
+ """
profile_defaults = self.session_profiles.get_defaults()
for key in list(profile_defaults.keys()):
if key.startswith('acl-'):
@@ -70,7 +101,20 @@ class X2GoBroker(base.X2GoBroker):
return profile_defaults
def get_profile(self, profile_id):
+ """\
+ Get the session profile for profile ID <profile_id>.
+
+ With the ``inifile`` broker backend, the session profile
+ parameters are the given ``<parameter>=<value>`` pairs under the section
+ ``[<profile_id>]``.
+
+ :param profile_id: the ID of a profile
+ :type profile_id: ``str``
+ :returns: a dictionary representing the session profile for ID <profile_id>
+ :rtype: ``dict``
+
+ """
try:
profile = self.session_profiles.get_section(profile_id)
except NoSectionError:
@@ -118,7 +162,20 @@ class X2GoBroker(base.X2GoBroker):
return profile
def get_profile_broker(self, profile_id):
+ """\
+ Get broker-specific session profile options from the session profile with profile ID <profile_id>.
+
+ With the ``inifile`` broker backend, these broker specific
+ options are ``<param>=<value>`` pairs prefixed like this:
+ ``broker-<param>=<value>``
+
+ :param profile_id: the ID of a profile
+ :type profile_id: ``str``
+
+ :returns: a dictionary representing the session profile for ID <profile_id>
+ :rtype: ``dict``
+ """
profile = self.session_profiles.get_section(profile_id)
for key in list(profile.keys()):
if not key.startswith('broker-'):
@@ -128,7 +185,20 @@ class X2GoBroker(base.X2GoBroker):
return profile
def get_profile_acls(self, profile_id):
+ """\
+ Get the ACLs for session profile with profile ID <profile_id>.
+
+ With the ``inifile`` broker backend, these ACL specific options
+ are ``<param>=<value>`` pairs prefixed like this:
+ ``acl-<param>=<value>``
+ :param profile_id: the ID of a profile
+ :type profile_id: ``str``
+
+ :returns: a dictionary representing the ACLs for session profile with ID <profile_id>
+ :rtype: ``dict``
+
+ """
profile = self.session_profiles.get_section(profile_id)
for key in list(profile.keys()):
if not key.startswith('acl-'):
diff --git a/x2gobroker/brokers/zeroconf_broker.py b/x2gobroker/brokers/zeroconf_broker.py
index 656f0dc..697a800 100644
--- a/x2gobroker/brokers/zeroconf_broker.py
+++ b/x2gobroker/brokers/zeroconf_broker.py
@@ -34,7 +34,20 @@ class X2GoBroker(base.X2GoBroker):
backend_name = 'zeroconf'
def list_profiles(self, username):
+ """\
+ Retrieve a list of session profiles for the authenticated user.
+
+ With the ``zeroconf`` broker backend, this list of session profiles is
+ hard-coded. This if for testing purposes, only.
+
+ :param username: query session profile list for this user
+ :type username: ``str``
+
+ :returns: list of profile dictionaries
+ :rtype: ``dict``
+
+ """
_list_of_profiles = {
uuid.uuid4(): {
'user': '',
@@ -81,7 +94,27 @@ class X2GoBroker(base.X2GoBroker):
return list_of_profiles
def select_session(self, profile_id, username=None, **kwargs):
+ """\
+ Start/resume a session by selecting a profile name offered by the
+ X2Go client.
+
+ With the ``zeroconf`` broker backend, the X2Go server that the
+ session is launched on is hard-coded (localhost, port 22). This
+ is for testing purposes only.
+
+ :param profile_id: the selected profile ID. This matches one of the dictionary
+ keys offered by the ``list_profiles`` method
+ :type profile_id: ``str``
+ :param username: specify X2Go Server username that this operation runs for
+ :type username: ``str``
+ :param pubkey: The broker clients may send us a public key that we may
+ temporarily install into a remote X2Go Server for non-interactive login
+ :type pubkey: ``str``
+
+ :returns: the seclected session (X2Go session ID)
+ :rtype: ``str``
+ """
selectprofile_output = {
'server': 'localhost',
'port': 22,
diff --git a/x2gobroker/client/plain.py b/x2gobroker/client/plain.py
index fc8ddd9..ec4e8d5 100644
--- a/x2gobroker/client/plain.py
+++ b/x2gobroker/client/plain.py
@@ -30,8 +30,36 @@ def _override_do_authenticate(username='', password=''):
return True
class X2GoBrokerClient(object):
+ """\
+ Implementation of a command line interface to X2Go Session Broker.
+ This CLI can be evoked over an SSH connection. This provides the
+ so-called SSH mode for X2Go Session Broker.
+
+ """
def get(self, args):
+ """\
+
+ Analogy to the http request get method of the HTTP X2Go Session
+ Broker, this method expects a set of arguments (i.e., an instance
+ of :class:``argparse.ArgumentParser``) and process the given
+ arguments.
+
+ Well-known arguments are:
+
+ * ``args.user`` - broker user on whose behalf to operate
+ * ``args.login`` - X2Go Server user for whom to perform the task
+ * ``args.auth_cookie`` - authentication cookie
+ * ``args.task`` - broker backend task to perform
+ * ``args.profile_id`` - session profile ID
+
+ :param args: an :class:``argparse.ArgumentParser`` object provide by the ``x2gobroker`` command line script
+ :type args: ``obj``
+
+ :returns: output as expected by the calling client side
+ :rtype: ``str``
+
+ """
backend = args.backend
if not backend:
diff --git a/x2gobroker/nameservices/base_nameservice.py b/x2gobroker/nameservices/base_nameservice.py
index 0dc99a2..2f7920b 100644
--- a/x2gobroker/nameservices/base_nameservice.py
+++ b/x2gobroker/nameservices/base_nameservice.py
@@ -20,28 +20,121 @@
class X2GoBrokerNameService(object):
def has_user(self, username):
+ """\
+ Provide information, if the broker knows a given user (or not).
+
+ :param username: name of the user to check
+ :type username: ``str``
+
+ :returns: ``True`` if the user is known to the broker, ``False`` if not
+ :rtype: ``bool``
+
+ """
return username in self.get_users()
def get_users(self):
+ """\
+ Retrieve list of users known to the broker.
+
+ :returns: list of known user names
+ :rtype: ``list``
+
+ """
return []
def get_primary_group(self, username):
+ """\
+ Get the primary group of a given user. If the nameservices
+ backend in use does not support primary groups, an empty string
+ will be returned.
+
+ :param username: name of the user to get the primary group for
+ :type username: ``str``
+
+ :returns: name of the primary group of the given user
+ :rtype: ``str``
+
+ """
return ''
def has_group(self, group):
+ """\
+ Provide information, if the broker knows a given group (or not).
+
+ :param group: name of the group to check
+ :type group: ``str``
+
+ :returns: ``True`` if the group is known to the broker, ``False`` if not
+ :rtype: ``bool``
+
+ """
return group in self.get_groups()
def get_groups(self):
+ """\
+ Retrieve list of groups known to the broker.
+
+ :returns: list of known group names
+ :rtype: ``list``
+
+ """
return []
def is_group_member(self, username, group, primary_groups=False):
+ """\
+ Check, if a given user is member of a given group.
+
+ Optionally, primary group memberships can be considered (or not).
+
+ :param username: name of the user to check
+ :type username: ``str``
+ :param group: name of the group to check
+ :type group: ``str``
+ :param primary_groups: take primary group membership into consideration
+ or not
+ :type primary_groups: ``bool``
+
+ :returns: ``True`` if the user is member of the given group, ``False`` if not
+ :rtype: ``bool``
+
+ """
_members = self.get_group_members(group, primary_groups=primary_groups)
return username in _members
def get_group_members(self, group, primary_groups=False):
+ """\
+ Retrieve a list of users being members of a given group.
+
+ Optionally, primary group memberships can be considered (or not).
+
+ :param group: name of the group to retrieve members of
+ :type group: ``str``
+ :param primary_groups: take primary group membership into consideration
+ or not
+ :type primary_groups: ``bool``
+
+ :returns: list of users that are members of the given group
+ :rtype: ``list``
+
+ """
return []
def get_user_groups(self, username, primary_groups=False):
+ """\
+ Retrieve a list of groups that a given user is member of.
+
+ Optionally, primary group memberships can be considered (or not).
+
+ :param username: name of the user to retrieve groupm memberships of
+ :type username: ``str``
+ :param primary_groups: take primary group membership into consideration
+ or not
+ :type primary_groups: ``bool``
+
+ :returns: list of groups that the given user is member of
+ :rtype: ``list``
+
+ """
_groups = []
for _group in self.get_groups():
if self.is_group_member(username=username, group=_group, primary_groups=primary_groups):
diff --git a/x2gobroker/nameservices/libnss_nameservice.py b/x2gobroker/nameservices/libnss_nameservice.py
index 5db99e9..3c7622a 100644
--- a/x2gobroker/nameservices/libnss_nameservice.py
+++ b/x2gobroker/nameservices/libnss_nameservice.py
@@ -30,16 +30,56 @@ _grp = grp.getgrall()
class X2GoBrokerNameService(base.X2GoBrokerNameService):
def get_users(self):
+ """\
+ Retrieve list of users from the POSIX nameservices system.
+
+ :returns: list of known user names
+ :rtype: ``list``
+
+ """
return [ p.pw_name for p in _pwd ]
def get_primary_group(self, username):
+ """\
+ Get the primary group of a given POSIX user.
+
+ :param username: name of the user to get the primary group for
+ :type username: ``str``
+
+ :returns: name of the primary group of the given user
+ :rtype: ``str``
+
+ """
prim_gid_number = [ p.pw_gid for p in _pwd if p.pw_name == username ][0]
return [ g.gr_name for g in _grp if g.gr_gid == prim_gid_number ][0]
def get_groups(self):
+ """\
+ Retrieve list of groups from the POSIX nameservices system.
+
+ :returns: list of known group names
+ :rtype: ``list``
+
+ """
return [ g.gr_name for g in _grp ]
def get_group_members(self, group, primary_groups=False):
+ """\
+ Retrieve a list of POSIX users being members of a given POSIX
+ group.
+
+ Optionally, primary group memberships can be considered (or not).
+
+ :param group: name of the group to retrieve members of
+ :type group: ``str``
+ :param primary_groups: take primary group membership into consideration
+ or not
+ :type primary_groups: ``bool``
+
+ :returns: list of users that are members of the given group
+ :rtype: ``list``
+
+ """
_members_from_primgroups = []
if primary_groups:
for username in self.get_users():
diff --git a/x2gobroker/nameservices/testsuite_nameservice.py b/x2gobroker/nameservices/testsuite_nameservice.py
index a6be6ad..70e5d96 100644
--- a/x2gobroker/nameservices/testsuite_nameservice.py
+++ b/x2gobroker/nameservices/testsuite_nameservice.py
@@ -33,15 +33,59 @@ _groups = {
class X2GoBrokerNameService(base.X2GoBrokerNameService):
def get_users(self):
+ """\
+ Retrieve hard-coded list of users that we can use for
+ unit testing.
+
+ :returns: list of known user names
+ :rtype: ``list``
+
+ """
return _users
def get_primary_group(self, username):
+ """\
+ In POSIX, the primary group name is equal to the user name.
+ As this is the only straw we can grab during unit tests, we
+ return the username here.
+
+ :param username: name of the user to get the primary group for
+ :type username: ``str``
+
+ :returns: name of the primary group of the given user
+ :rtype: ``str``
+
+ """
return username
def get_groups(self):
+ """\
+ Retrieve hard-coded list of groups that we can use for unit
+ testing.
+
+ :returns: list of known group names
+ :rtype: ``list``
+
+ """
return list(_groups.keys()) + _users
def get_group_members(self, group, primary_groups=False):
+ """\
+ Retrieve a list of users being members of a given group. For unit
+ testing, the group membership relations have been hard-coded.
+
+ Optionally, primary group memberships can be considered (or not).
+
+ :param group: name of the group to retrieve members of
+ :type group: ``str``
+ :param primary_groups: take primary group membership into consideration
+ or not
+ :type primary_groups: ``bool``
+
+ :returns: list of users that are members of the given group
+ :rtype: ``list``
+
+ """
_members = []
if group in list(_groups.keys()):
_members.extend(_groups[group])
@@ -50,4 +94,3 @@ class X2GoBrokerNameService(base.X2GoBrokerNameService):
if group == self.get_primary_group(username):
_members.append(username)
return _members
-
diff --git a/x2gobroker/optional_scripts/base_script.py b/x2gobroker/optional_scripts/base_script.py
index 4a64160..92b31e5 100755
--- a/x2gobroker/optional_scripts/base_script.py
+++ b/x2gobroker/optional_scripts/base_script.py
@@ -19,6 +19,43 @@
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
class X2GoBrokerOptionalScript(object):
+ """\
+ X2Go Session Broker supports running optional Python code that a site admin
+ can add to the broker installation files.
+
+ All those optional scripts need to be inherited from this class.
+
+ """
def run_me(self, username, password, task, profile_id, ip, cookie, authed, server):
+ """\
+ Dummy :function:``run_me()`` function. If you deploy your own
+ optional scripts with X2Go Session Broker, make sure that your
+ class overrides this function. The broker frontends will try to
+ execute code presented under this method name at pre-auth,
+ post-auth and session-selected.
+
+ :param script_type: name of the script type to be executed (``pre_auth_scripts``, ``post_auth_scripts``, ``select_session_scripts``)
+ :type script_type: ``str``
+ :param username: name of the X2Go session user a script will run for
+ :type username: ``str``
+ :param password: password for the X2Go session
+ :type password: ``str``
+ :param task: the broker task that currently being processed
+ :type task: ``str``
+ :param profile_id: the session profile ID that is being operated upon
+ :type profile_id: ``str``
+ :param ip: the client machine's IP address
+ :type ip: ``str``
+ :param cookie: the currently valid authentication cookie
+ :type cookie: ``str``
+ :param authed: authentication status (already authenticated or not)
+ :type authed: ``bool``
+ :param server: hostname or IP address of the X2Go server being operated upon
+ :type server: ``str``
+
+ :returns: Pass-through of the return value returned by the to-be-run optional script (i.e., success or failure)
+ :rtype: ``bool``
+
+ """
return username, password, task, profile_id, ip, cookie, authed, server
diff --git a/x2gobroker/web/extras.py b/x2gobroker/web/extras.py
index 4e1e8fd..627ff78 100644
--- a/x2gobroker/web/extras.py
+++ b/x2gobroker/web/extras.py
@@ -34,7 +34,10 @@ class _RequestHandler(tornado.web.RequestHandler):
class X2GoBrokerItWorks(_RequestHandler):
+ """\
+ HTTP request handler that simply replies with an "It works" page.
+ """
http_header_items = {
'Content-Type': 'text/plain; charset=utf-8',
'Expires': '+1h',
@@ -54,7 +57,11 @@ class X2GoBrokerItWorks(_RequestHandler):
class X2GoBrokerPubKeyService(_RequestHandler):
+ """\
+ HTTP request handler that provides X2Go Session Broker's SSH public
+ keys, if any are configured.
+ """
http_header_items = {
'Content-Type': 'text/plain; charset=utf-8',
'Expires': '+1h',
diff --git a/x2gobroker/web/json.py b/x2gobroker/web/json.py
index a802866..8e1853b 100644
--- a/x2gobroker/web/json.py
+++ b/x2gobroker/web/json.py
@@ -37,7 +37,16 @@ class _RequestHandler(tornado.web.RequestHandler):
class X2GoBrokerWeb(_RequestHandler):
+ """\
+ HTTP request handler that provides the JSON web frontend of the X2Go
+ Session Broker.
+ Currently, Python X2Go and all derived X2Go Client applications use
+ this web frontend / communication protocol format..
+
+ :raises tornado.web.HTTPError: on authentication failure a 401 error is raised
+
+ """
http_header_items = {
'Content-Type': 'text/json; charset=utf-8',
'Expires': '+1h',
@@ -48,20 +57,38 @@ class X2GoBrokerWeb(_RequestHandler):
for http_header_item in list(self.http_header_items.keys()):
self.set_header(http_header_item, self.http_header_items[http_header_item])
- def get(self, backend):
+ def get(self, path):
+ """\
+ Implementation of the JSON based broker communication protocol as
+ used by Python X2Go (via POST requests).
+
+ In debug mode you can test the broker's functionality using a
+ normal web browser via GET requests.
+
+ :param path: URL path
+ :type path: ``str``
+
+ """
if x2gobroker.defaults.X2GOBROKER_DEBUG:
logger_broker.warn('GET http request detected, if unwanted: disable X2GOBROKER_DEBUG')
- return self.post(backend)
+ return self.post(path)
raise tornado.web.HTTPError(405)
- def post(self, backend):
+ def post(self, path):
+ """\
+ Implementation of the JSON based broker communication protocol as
+ used by Python X2Go (via POST requests).
+
+ :param path: URL path
+ :type path: ``str``
+ """
self._gen_http_header()
- if not backend:
+ if not path:
backend = x2gobroker.defaults.X2GOBROKER_DEFAULT_BACKEND
else:
- backend = backend.rstrip('/')
+ backend = path.rstrip('/')
if '/' in backend:
backend = backend.split('/')[0]
@@ -201,4 +228,3 @@ class X2GoBrokerWeb(_RequestHandler):
return
raise tornado.web.HTTPError(401)
-
diff --git a/x2gobroker/web/plain.py b/x2gobroker/web/plain.py
index 9b1a17e..6183672 100644
--- a/x2gobroker/web/plain.py
+++ b/x2gobroker/web/plain.py
@@ -33,7 +33,15 @@ class _RequestHandler(tornado.web.RequestHandler):
class X2GoBrokerWeb(_RequestHandler):
+ """\
+ HTTP request handler that provides the plain text web frontend of the
+ X2Go Session Broker.
+ Currently, X2Go Client uses this webfrontend / communication protocol format.
+
+ :raises tornado.web.HTTPError: on authentication failure a 401 error is raised
+
+ """
http_header_items = {
'Content-Type': 'text/plain; charset=utf-8',
'Expires': '+1h',
@@ -44,20 +52,38 @@ class X2GoBrokerWeb(_RequestHandler):
for http_header_item in list(self.http_header_items.keys()):
self.set_header(http_header_item, self.http_header_items[http_header_item])
- def get(self, backend):
+ def get(self, path):
+ """\
+ Implementation of the plain text broker communication protocol as
+ used by X2Go Client (via POST requests).
+
+ In debug mode you can test the broker's functionality using a
+ normal web browser via GET requests.
+
+ :param path: URL path
+ :type path: ``str``
+
+ """
if x2gobroker.defaults.X2GOBROKER_DEBUG:
logger_broker.warn('GET http request detected, if unwanted: disable X2GOBROKER_DEBUG')
- return self.post(backend)
+ return self.post(path)
raise tornado.web.HTTPError(405)
- def post(self, backend):
+ def post(self, path):
+ """\
+ Implementation of the plain text broker communication protocol as
+ used by X2Go Client (via POST requests).
+
+ :param path: URL path
+ :type path: ``str``
+ """
self._gen_http_header()
- if not backend:
+ if not path:
backend = x2gobroker.defaults.X2GOBROKER_DEFAULT_BACKEND
else:
- backend = backend.rstrip('/')
+ backend = path.rstrip('/')
if '/' in backend:
backend = backend.split('/')[0]
diff --git a/x2gobroker/web/uccs.py b/x2gobroker/web/uccs.py
index 5bef36e..c1189f5 100644
--- a/x2gobroker/web/uccs.py
+++ b/x2gobroker/web/uccs.py
@@ -30,7 +30,18 @@ import x2gobroker.basicauth
def credentials_validate(username, password):
+ """\
+ Helper function to validate some given credentials.
+ :param username: the username
+ :type username: ``str``
+ :param password: the user's password
+ :type password: ``str``
+
+ :returns: ``(<username>, <success>)`` tuple
+ :rtype: ``(str, bool)``
+
+ """
import x2gobroker.brokers.base_broker
# FIXME: with the below hack, the backend broker detection in X2GoBrokerWeb is disabled, only global options
# from x2gobroker.conf are available here...
@@ -54,19 +65,50 @@ class _RequestHandler(tornado.web.RequestHandler):
class X2GoBrokerWeb(_RequestHandler):
def get(self, path):
+ """\
+ With the UCCS protocol, a HEAD request is sent to the server's
+ base URL (sort of as an is-alive ping).
+
+ If X2Go Session Broker runs in debug mode, the processing of
+ the HEAD request reponse is also made available to GET requests.
+ This means, you can open the base URL in a normal web browser and
+ get a reply.
+
+ :param path: URL path
+ :type path: ``str``
+
+ """
if x2gobroker.defaults.X2GOBROKER_DEBUG:
logger_broker.warn('GET http request detected, if unwanted: disable X2GOBROKER_DEBUG')
return self.head(path)
raise tornado.web.HTTPError(405)
def head(self, path):
+ """\
+ With the UCCS protocol, a HEAD request is sent to the server's
+ base URL (sort of as an is-alive ping).
+
+ :param path: URL path
+ :type path: ``str``
+
+ """
self.write(str(datetime.datetime.utcnow()))
return
@x2gobroker.basicauth.require_basic_auth('Authentication required', credentials_validate)
class X2GoBrokerWebAPI(tornado.web.RequestHandler):
+ """\
+ HTTP request handler that provides the UCCS web frontend of the
+ X2Go Session Broker.
+
+ Currently, Arctica Greeter with Remote Logon Service uses this
+ webfrontend / communication protocol format.
+ :raises tornado.web.HTTPError: on authentication failure a 401
+ error is raised; on invalid API versions, a 404 error is raised.
+
+ """
def __init__(self, *args, **kwargs):
# latest API version is 5
self.api_version = 5
@@ -85,7 +127,13 @@ class X2GoBrokerWebAPI(tornado.web.RequestHandler):
self.set_header(http_header_item, self.http_header_items[http_header_item])
def get(self, *args, **kwargs):
+ """\
+ Implementation of the UCCS broker API versions 4 (final) and 5 (in development).
+
+ :param path: URL path
+ :type path: ``str``
+ """
self._gen_http_header()
backend = args[0]
diff --git a/x2gobroker/x2gobroker_exceptions.py b/x2gobroker/x2gobroker_exceptions.py
index b766089..b6e866e 100644
--- a/x2gobroker/x2gobroker_exceptions.py
+++ b/x2gobroker/x2gobroker_exceptions.py
@@ -20,9 +20,26 @@
from x2gobroker.loggers import logger_error
class X2GoBrokerBaseException(BaseException):
+ """\
+ Base exception for all X2Go Session Broker exceptions."
+
+ """
def __init__(self, *args, **kwargs):
BaseException.__init__(self, *args, **kwargs)
logger_error.error('exception raised: {exception}("{msg}")'.format(exception=type(self).__name__, msg=str(self)))
-class X2GoBrokerAgentException(X2GoBrokerBaseException): pass
-class X2GoBrokerProfileException(X2GoBrokerBaseException): pass
+class X2GoBrokerAgentException(X2GoBrokerBaseException):
+ """\
+ X2Go Broker Agent exception class. Used for failures during broker
+ <-> broker agent communications.
+
+ """
+ pass
+
+class X2GoBrokerProfileException(X2GoBrokerBaseException):
+ """\
+ X2Go Broker exception class for session profile problems. Used for
+ failures when parsing and processing session profiles.
+
+ """
+ pass
--
Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/x2gobroker.git
More information about the x2go-commits
mailing list