""" Middleware for handling $REMOTE_USER if use_remote_user is enabled. """ import socket errorpage = """ Galaxy

%s

%s

""" UCSC_MAIN_SERVERS = ( 'hgw1.cse.ucsc.edu', 'hgw2.cse.ucsc.edu', 'hgw3.cse.ucsc.edu', 'hgw4.cse.ucsc.edu', 'hgw5.cse.ucsc.edu', 'hgw6.cse.ucsc.edu', 'hgw7.cse.ucsc.edu', 'hgw8.cse.ucsc.edu', ) UCSC_ARCHAEA_SERVERS = ( 'lowepub.cse.ucsc.edu', ) class RemoteUser( object ): def __init__( self, app, maildomain=None, ucsc_display_sites=[], admin_users=[] ): self.app = app self.maildomain = maildomain self.allow_ucsc_main = False self.allow_ucsc_archaea = False self.admin_users = admin_users if 'main' in ucsc_display_sites or 'test' in ucsc_display_sites: self.allow_ucsc_main = True if 'archaea' in ucsc_display_sites: self.allow_ucsc_archaea = True def __call__( self, environ, start_response ): # Allow through UCSC if the UCSC display links are enabled if ( self.allow_ucsc_main or self.allow_ucsc_archaea ) 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 ( self.allow_ucsc_main and host in UCSC_MAIN_SERVERS ) or \ ( self.allow_ucsc_archaea and host in UCSC_ARCHAEA_SERVERS ): environ[ 'HTTP_REMOTE_USER' ] = 'ucsc_browser_display@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.

Please contact your local Galaxy administrator. The variable remote_user_maildomain must be set before you may access Galaxy. """ return self.error( start_response, title, message ) if path_info.startswith( '/user/create' ) and environ[ 'HTTP_REMOTE_USER' ] in self.admin_users: pass # admins can create users elif path_info.startswith( '/user/api_keys' ): pass # api keys can be managed when remote_user is in use elif path_info.startswith( '/user' ): title = "Access to Galaxy user controls is disabled" message = """ User controls are disabled when Galaxy is configured for external authentication. """ 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.

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)]