Commits

Joel Rivera committed 0bac37d

Add support for the automatic unix account creation.

Comments (0)

Files changed (3)

lib/galaxy/web/framework/ext/globus/middleware.py

+import pwd
 import logging
+import subprocess
 from Cookie import BaseCookie
 from cgi import parse_qs
 
     NOT_AUTHORIZED = 4
     NOT_ALLOWED = 5
 
-    def __init__(self, app, nexclient, nexsecret, nexserver=None, groupid=None):
+    def __init__(self, app, nexclient, nexsecret,  nexserver=None,
+                 groupid=None, gaccount_cmd=None):
         if nexclient is None or nexsecret is None:
             raise Exception(
                 "Unable to set Globus User Authentication middlerware. "
                 "The nexus client 'globus_nexus_client' and client secret "
                 "'globus_nexus_secret' are required.")
+        self.gaccount_cmd = gaccount_cmd
+        self.groupid = groupid
         if nexserver is None:
             nexserver = self.default_nexus_server
-        self.groupid = groupid
         self.nexus_client = nexus.Client({'server': nexserver,
                                           'client': nexclient,
                                           'client_secret': nexsecret})
         start_response('303 See other', headers)
         return ''
 
+    def _create_unix_account(self, user):
+        """Create the account with the command "self.gaccount_cmd"
+        if the property is None raise an Exception, in general
+        this method does not try to be very friendly, just explicitly
+        raise and log the exceptions.
+
+        The command gets executed with sudo -n CMD USER, no password prompt
+        is expected.
+        """
+        if self.gaccount_cmd is None:
+            msg = ("'globus_gaccount' is not set, unable to "
+                   "create account for the user %s" % user)
+            log.error(msg)
+            raise Exception(msg)
+        cmdparts = ['sudo', '-n', self.gaccount_cmd, user]
+        try:
+            cmd  = subprocess.Popen(cmdparts, stdout=subprocess.PIPE,
+                                    stderr=subprocess.PIPE)
+            stdout, stderr = cmd.communicate()
+            if cmd.returncode:
+                msg = ('Unable to create account for user %s '
+                       'rcode: %s\n'
+                       'stdout: %s\n'
+                       'stderr: %s' % \
+                       (user, cmd.returncode, stdout, stderr))
+                raise Exception(msg)
+        except OSError as e:
+            msg = ('Unable to create account for user %s '
+                   'OSError: %s' % (user, e))
+            log.error(msg)
+            raise OSError(msg)
+
+        
     def _do_login(self, session, start_response, environ, code):
         tokens = self._fetch_access_tokens(code) 
         user = self.nexus_client.get_user_using_access_token(tokens['access'])
                 return self._user_not_in_group(user['username'], start_response)
         environ['HTTP_REMOTE_USER'] = user['username']
         def add_to_active_users(_session, _user, _tokens):
+            username = _user['username']
+            try:
+                pwd.getpwnam(username)
+            except KeyError:
+                self._create_unix_account(username)
+                try:
+                    pwd.getpwnam(username) # validate.
+                except KeyError:
+                    msg = (
+                        'Unable to create the local account "%s".\n'
+                        'This exception should not be reached, '
+                        '_create_unix_account is not working fine.'
+                        % username)
+                    log.error(msg)
+                    raise Exception(msg)
             self.active_users[_session] = (_user, _tokens)
             
         def custom_start_response(status, headers, exc_info=None):

lib/galaxy/webapps/galaxy/buildapp.py

     gparams = (conf.get('globus_nexus_client', None),
                conf.get('globus_nexus_secret', None),
                conf.get('globus_nexus_server', None),
-               conf.get('globus_group_id', None))
+               conf.get('globus_group_id', None),
+               conf.get('globus_gaccount', None))
     app = globus.middleware.UserAuthentication(app, *gparams)
     if debug:
         # Middleware to check for WSGI compliance

universe_wsgi.ini

 globus_nexus_client = galaxytest
 #globus_nexus_secret = 
 #globus_group_id =
+#globus_gaccount =
 
 # this value changes how the user_ftp_dir is determined:
 #  - normally it is set by doing os.path.join(ftp_upload_dir, user.email)