Changeset 1430:146764b24c85

Show
Ignore:
Timestamp:
07/17/08 09:15:38 (6 months ago)
Author:
Nate Coraor <nate@bx.psu.edu>
branch:
default
Message:

Basic $REMOTE_USER support.

A database change is necessary:

ALTER TABLE galaxy_user ADD COLUMN external boolean;

To use:

http://g2.trac.bx.psu.edu/wiki/HowToInstall/ApacheProxy

I've tried to be as friendly as possible with respect to enabling and
disabling $REMOTE_USER support. If you have an existing server and
enable use_remote_user, users whose external login matches their Galaxy
username will have access to their existing history/session. If the
logins don't match, any existing credentials they had are destroyed.
Likewise, when disabled, users who weren't created automatically may
continue to access their histories/sessions. Automatically created
users are logged out, and can't log in unless enabled by an administrator.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • lib/galaxy/config.py

    r1371 r1430  
    3838        self.tool_secret = kwargs.get( "tool_secret", "" ) 
    3939        self.id_secret = kwargs.get( "id_secret", "USING THE DEFAULT IS NOT SECURE!" ) 
     40        self.use_remote_user = string_as_bool( kwargs.get( "use_remote_user", "False" ) ) 
     41        self.remote_user_maildomain = kwargs.get( "remote_user_maildomain", None ) 
    4042        self.template_path = resolve_path( kwargs.get( "template_path", "templates" ), self.root ) 
    4143        self.template_cache = resolve_path( kwargs.get( "template_cache_path", "database/compiled_templates" ), self.root ) 
  • lib/galaxy/model/__init__.py

    r1410 r1430  
    3131        self.email = email 
    3232        self.password = password 
     33        self.external = False 
    3334        # Relationships 
    3435        self.histories = [] 
  • lib/galaxy/model/mapping.py

    r1410 r1430  
    4444    Column( "update_time", DateTime, default=now, onupdate=now ), 
    4545    Column( "email", TrimmedString( 255 ), nullable=False ), 
    46     Column( "password", TrimmedString( 40 ), nullable=False ) ) 
     46    Column( "password", TrimmedString( 40 ), nullable=False ), 
     47    Column( "external", Boolean, default=False ) ) 
    4748 
    4849History.table = Table( "history", metadata, 
  • lib/galaxy/web/buildapp.py

    r823 r1430  
    9292    app = httpexceptions.make_middleware( app, conf ) 
    9393    log.debug( "Enabling 'httpexceptions' middleware" ) 
     94    # If we're using remote_user authentication, add middleware that 
     95    # protects Galaxy from improperly configured authentication in the 
     96    # upstream server 
     97    if asbool(conf.get( 'use_remote_user', False )): 
     98        from galaxy.web.framework.middleware.remoteuser import RemoteUser 
     99        app = RemoteUser( app, maildomain=conf.get( 'remote_user_maildomain', None ) ) 
     100        log.debug( "Enabling 'remote user' middleware" ) 
    94101    # The recursive middleware allows for including requests in other  
    95102    # requests or forwarding of requests, all on the server side. 
  • lib/galaxy/web/controllers/user.py

    r1382 r1430  
    7777            if not user: 
    7878                email_error = "No such user" 
     79            elif user.external: 
     80                return trans.show_error_message( "This account was created for use with an external authentication " 
     81                                               + "method.  Please contact your local Galaxy administrator to activate it." ) 
    7982            elif not user.check_password( password ): 
    8083                password_error = "Invalid password" 
  • lib/galaxy/web/framework/__init__.py

    r1429 r1430  
    237237        if self.__user is NOT_SET: 
    238238            self.__user = None 
    239             # See if we have a galaxysession cookie 
    240             secure_id = self.get_cookie( name='galaxysession' ) 
    241             if secure_id: 
    242                 session_key = self.security.decode_session_key( secure_id ) 
    243                 try: 
    244                     galaxy_session = self.app.model.GalaxySession.selectone_by( session_key=session_key ) 
    245                     if galaxy_session and galaxy_session.is_valid and galaxy_session.user_id: 
    246                         user = self.app.model.User.get( galaxy_session.user_id ) 
    247                         if user: 
    248                             self.__user = user 
    249                 except: 
    250                     # This should only occur in development if the cookie is not synced with the db 
    251                     pass 
     239            user = self.get_cookie_user() 
     240            if self.app.config.use_remote_user: 
     241                remote_user = self.get_remote_user() 
     242                if user is not None and user.email != remote_user.email: 
     243                    # The user has a cookie for a different user than the one 
     244                    # they've authed as. 
     245                    log.warning( "User logged in as '%s' externally, but has a cookie as '%s'," 
     246                               % ( remote_user.email, user.email ) + " invalidating session" ) 
     247                    self.logout_galaxy_session() 
     248                if user is None or ( user is not None and user.email != remote_user.email ): 
     249                    # The user has no cookie, was not logged in, or the above. 
     250                    self.set_user( remote_user ) 
     251                    self.make_associations() 
     252                self.__user = remote_user 
    252253            else: 
    253                 # See if we have a deprecated universe_user cookie 
    254                 # TODO: this should be eliminated some time after October 1, 2008 
    255                 # We'll keep it until then because the old universe cookies are valid for 90 days 
    256                 user_id = self.get_cookie( name='universe_user' ) 
    257                 if user_id: 
    258                     user = self.app.model.User.get( int( user_id ) ) 
     254                if user is not None and user.external: 
     255                    # use_remote_user is off, but the user still has a cookie 
     256                    # from when it was on.  Force the user to get a new 
     257                    # unauthenticated session. 
     258                    log.warning( "User '%s' is an external user with an existing " % user.email 
     259                               + "session, invalidating session since external auth is disabled" ) 
     260                    self.logout_galaxy_session() 
     261                else:    
     262                    self.__user = user 
     263        return self.__user 
     264    def get_remote_user( self ): 
     265        """Return the user in $HTTP_REMOTE_USER and create if necessary""" 
     266        # remote_user middleware ensures HTTP_REMOTE_USER exists 
     267        try: 
     268            user = self.app.model.User.selectone_by( email=self.environ[ 'HTTP_REMOTE_USER' ] ) 
     269        except: 
     270            user = self.app.model.User( email=self.environ[ 'HTTP_REMOTE_USER' ] ) 
     271            user.set_password_cleartext( 'external' ) 
     272            user.external = True 
     273            user.flush() 
     274            self.log_event( "Automatically created account '%s'" % user.email ) 
     275        return user 
     276    def get_cookie_user( self ): 
     277        """Return the user in the galaxysession cookie""" 
     278        __user = None 
     279        # See if we have a galaxysession cookie 
     280        secure_id = self.get_cookie( name='galaxysession' ) 
     281        if secure_id: 
     282            session_key = self.security.decode_session_key( secure_id ) 
     283            try: 
     284                galaxy_session = self.app.model.GalaxySession.selectone_by( session_key=session_key ) 
     285                if galaxy_session and galaxy_session.is_valid and galaxy_session.user_id: 
     286                    user = self.app.model.User.get( galaxy_session.user_id ) 
    259287                    if user: 
    260                         self.__user = user 
    261                     # Expire the universe_user cookie since it is deprecated 
    262                     self.set_cookie( name='universe_user', value='', age=0 ) 
    263         return self.__user 
     288                        __user = user 
     289            except: 
     290                # This should only occur in development if the cookie is not synced with the db 
     291                pass 
     292        else: 
     293            # See if we have a deprecated universe_user cookie 
     294            # TODO: this should be eliminated some time after October 1, 2008 
     295            # We'll keep it until then because the old universe cookies are valid for 90 days 
     296            user_id = self.get_cookie( name='universe_user' ) 
     297            if user_id: 
     298                user = self.app.model.User.get( int( user_id ) ) 
     299                if user: 
     300                    __user = user 
     301                # Expire the universe_user cookie since it is deprecated 
     302                self.set_cookie( name='universe_user', value='', age=0 ) 
     303        return __user 
    264304    def set_user( self, user ): 
    265305        """Set the current user if logged in.""" 
     
    451491        Fill in a template, putting any keyword arguments on the context. 
    452492        """ 
     493        # call get_user so we can invalidate sessions from external users, 
     494        # if external auth has been disabled. 
     495        self.get_user() 
    453496        if filename.endswith( ".mako" ): 
    454497            return self.fill_template_mako( filename, **kwargs ) 
  • templates/root/masthead.mako

    r1226 r1430  
    2424    | <a target="mainframe" href="/static/index_frame_history.html">history</a> --> 
    2525    &nbsp;&nbsp;&nbsp; 
    26     %if t.user: 
    27         Logged in as ${t.user.email}: <a target="galaxy_main" href="${h.url_for( controller='user', action='index' )}">manage</a> 
    28         | <a target="galaxy_main" href="${h.url_for( controller='user', action='logout' )}">logout</a> 
     26    %if app.config.use_remote_user: 
     27        Logged in as ${t.user.email} 
    2928    %else: 
    30         Account: <a target="galaxy_main" href="${h.url_for( controller='user', action='create' )}">create</a> 
    31         | <a target="galaxy_main" href="${h.url_for( controller='user', action='login' )}">login</a> 
     29        %if t.user: 
     30            Logged in as ${t.user.email}: <a target="galaxy_main" href="${h.url_for( controller='user', action='index' )}">manage</a> 
     31            | <a target="galaxy_main" href="${h.url_for( controller='user', action='logout' )}">logout</a> 
     32        %else: 
     33            Account: <a target="galaxy_main" href="${h.url_for( controller='user', action='create' )}">create</a> 
     34            | <a target="galaxy_main" href="${h.url_for( controller='user', action='login' )}">login</a> 
     35        %endif 
    3236    %endif 
    3337    &nbsp; 
  • universe_wsgi.ini.sample

    r1382 r1430  
    6464# Galaxy session security 
    6565id_secret = changethisinproductiontoo 
     66 
     67# Use user provided in an upstream server's $REMOTE_USER variable 
     68## use_remote_user = False 
     69# If use_remote_user is enabled and your external authentication 
     70# method just returns bare usernames, set a default mail domain 
     71## remote_user_maildomain = example.org 
    6672 
    6773# Configuration for debugging middleware