1 new commit in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/changeset/21ec1290ad02/ changeset: 21ec1290ad02 user: inithello date: 2012-06-27 15:47:32 summary: Added remote authentication to the toolshed. affected #: 3 files diff -r 9576fb8cd71e8ad16e9a6426c0c42dc6aba63716 -r 21ec1290ad02beb9c33516dcc4d5d4a732559414 lib/galaxy/web/framework/__init__.py --- a/lib/galaxy/web/framework/__init__.py +++ b/lib/galaxy/web/framework/__init__.py @@ -498,8 +498,10 @@ # remote user authenticates, we'll look for this information, and if missing, create it. if not self.app.security_agent.get_private_user_role( user ): self.app.security_agent.create_private_user_role( user ) - if not user.default_permissions: - self.app.security_agent.user_set_default_permissions( user, history=True, dataset=True ) + if 'webapp' not in self.environ or self.environ['webapp'] != 'community': + if not user.default_permissions: + self.app.security_agent.user_set_default_permissions( user ) + self.app.security_agent.user_set_default_permissions( user, history=True, dataset=True ) elif user is None: username = remote_user_email.split( '@', 1 )[0].lower() random.seed() @@ -520,7 +522,8 @@ self.sa_session.flush() self.app.security_agent.create_private_user_role( user ) # We set default user permissions, before we log in and set the default history permissions - self.app.security_agent.user_set_default_permissions( user ) + if 'webapp' not in self.environ or self.environ['webapp'] != 'community': + self.app.security_agent.user_set_default_permissions( user ) #self.log_event( "Automatically created account '%s'", user.email ) return user def __update_session_cookie( self, name='galaxysession' ): diff -r 9576fb8cd71e8ad16e9a6426c0c42dc6aba63716 -r 21ec1290ad02beb9c33516dcc4d5d4a732559414 lib/galaxy/webapps/community/buildapp.py --- a/lib/galaxy/webapps/community/buildapp.py +++ b/lib/galaxy/webapps/community/buildapp.py @@ -17,6 +17,7 @@ import galaxy.webapps.community.model.mapping import galaxy.web.framework from galaxy.webapps.community.framework.middleware import hg +from galaxy import util log = logging.getLogger( __name__ ) @@ -102,6 +103,15 @@ # other middleware): app = httpexceptions.make_middleware( app, conf ) log.debug( "Enabling 'httpexceptions' middleware" ) + # If we're using remote_user authentication, add middleware that + # protects Galaxy from improperly configured authentication in the + # upstream server + if asbool(conf.get( 'use_remote_user', False )): + from galaxy.webapps.community.framework.middleware.remoteuser import RemoteUser + app = RemoteUser( app, maildomain = conf.get( 'remote_user_maildomain', None ), + display_servers = util.listify( conf.get( 'display_servers', '' ) ), + admin_users = conf.get( 'admin_users', '' ).split( ',' ) ) + log.debug( "Enabling 'remote user' middleware" ) # The recursive middleware allows for including requests in other # requests or forwarding of requests, all on the server side. if asbool(conf.get('use_recursive', True)): diff -r 9576fb8cd71e8ad16e9a6426c0c42dc6aba63716 -r 21ec1290ad02beb9c33516dcc4d5d4a732559414 lib/galaxy/webapps/community/framework/middleware/remoteuser.py --- /dev/null +++ b/lib/galaxy/webapps/community/framework/middleware/remoteuser.py @@ -0,0 +1,93 @@ +""" +Middleware for handling $REMOTE_USER if use_remote_user is enabled. +""" + +import socket + +errorpage = """ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html lang="en"> + <head> + <title>Galaxy</title> + <style type="text/css"> + body { + min-width: 500px; + text-align: center; + } + .errormessage { + font: 75%% verdana, "Bitstream Vera Sans", geneva, arial, helvetica, helve, sans-serif; + padding: 10px; + margin: 100px auto; + min-height: 32px; + max-width: 500px; + border: 1px solid #AA6666; + background-color: #FFCCCC; + text-align: left; + } + </style> + </head> + <body> + <div class="errormessage"> + <h4>%s</h4> + <p>%s</p> + </div> + </body> +</html> +""" + +class RemoteUser( object ): + def __init__( self, app, maildomain=None, display_servers=None, admin_users=None ): + self.app = app + self.maildomain = maildomain + self.display_servers = display_servers or [] + self.admin_users = admin_users or [] + def __call__( self, environ, start_response ): + environ[ 'webapp' ] = 'community' + # Allow display servers + if self.display_servers and environ.has_key( 'REMOTE_ADDR' ): + try: + host = socket.gethostbyaddr( environ[ 'REMOTE_ADDR' ] )[0] + except( socket.error, socket.herror, socket.gaierror, socket.timeout ): + # in the event of a lookup failure, deny access + host = None + if host in self.display_servers: + environ[ 'HTTP_REMOTE_USER' ] = 'remote_display_server@%s' % ( self.maildomain or 'example.org' ) + return self.app( environ, start_response ) + # Apache sets REMOTE_USER to the string '(null)' when using the + # Rewrite* method for passing REMOTE_USER and a user is + # un-authenticated. Any other possible values need to go here as well. + path_info = environ.get('PATH_INFO', '') + if environ.has_key( 'HTTP_REMOTE_USER' ) and environ[ 'HTTP_REMOTE_USER' ] != '(null)': + if not environ[ 'HTTP_REMOTE_USER' ].count( '@' ): + if self.maildomain is not None: + environ[ 'HTTP_REMOTE_USER' ] += '@' + self.maildomain + else: + title = "Access to Galaxy is denied" + message = """ + Galaxy is configured to authenticate users via an external + method (such as HTTP authentication in Apache), but only a + username (not an email address) was provided by the + upstream (proxy) server. Since Galaxy usernames are email + addresses, a default mail domain must be set.</p> + <p>Please contact your local Galaxy administrator. The + variable <code>remote_user_maildomain</code> must be set + before you may access Galaxy. + """ + return self.error( start_response, title, message ) + return self.app( environ, start_response ) + elif path_info.startswith( '/api/' ): + # The API handles its own authentication via keys + return self.app( environ, start_response ) + else: + title = "Access to Galaxy is denied" + message = """ + Galaxy is configured to authenticate users via an external + method (such as HTTP authentication in Apache), but a username + was not provided by the upstream (proxy) server. This is + generally due to a misconfiguration in the upstream server.</p> + <p>Please contact your local Galaxy administrator. + """ + return self.error( start_response, title, message ) + def error( self, start_response, title="Access denied", message="Please contact your local Galaxy administrator." ): + start_response( '403 Forbidden', [('Content-type', 'text/html')] ) + return [errorpage % (title, message)] Repository URL: https://bitbucket.org/galaxy/galaxy-central/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email.