def url( *args, **kwargs ): route_name = kwargs.pop( '__route_name__', None ) # Only include sort/filter arguments if not linking to another # page. This is a bit of a hack. if 'action' in kwargs: new_kwargs = dict() else: new_kwargs = dict( extra_url_args ) # Extend new_kwargs with first argument if found if len(args) > 0: new_kwargs.update( args[0] ) new_kwargs.update( kwargs ) # We need to encode item ids if 'id' in new_kwargs: id = new_kwargs[ 'id' ] if isinstance( id, list ): new_kwargs[ 'id' ] = [ trans.security.encode_id( i ) for i in id ] else: new_kwargs[ 'id' ] = trans.security.encode_id( id ) # The url_for invocation *must* include a controller and action. if 'controller' not in new_kwargs: new_kwargs['controller'] = trans.controller if 'action' not in new_kwargs: new_kwargs['action'] = trans.action if route_name: return url_for( route_name, **new_kwargs ) return url_for( **new_kwargs )
def url(*args, **kwargs): route_name = kwargs.pop('__route_name__', None) # Only include sort/filter arguments if not linking to another # page. This is a bit of a hack. if 'action' in kwargs: new_kwargs = dict() else: new_kwargs = dict(extra_url_args) # Extend new_kwargs with first argument if found if len(args) > 0: new_kwargs.update(args[0]) new_kwargs.update(kwargs) # We need to encode item ids if 'id' in new_kwargs: id = new_kwargs['id'] if isinstance(id, list): new_kwargs['id'] = [ trans.security.encode_id(i) for i in id ] else: new_kwargs['id'] = trans.security.encode_id(id) # The url_for invocation *must* include a controller and action. if 'controller' not in new_kwargs: new_kwargs['controller'] = trans.controller if 'action' not in new_kwargs: new_kwargs['action'] = trans.action if route_name: return url_for(route_name, **new_kwargs) return url_for(**new_kwargs)
def decorator(self, trans, *args, **kwargs): if trans.get_user(): return func(self, trans, *args, **kwargs) else: redirect_url = url_for(controller=trans.controller, action=trans.action) query_string = trans.environ.get('QUERY_STRING', '') if query_string: redirect_url = f"{redirect_url}?{query_string}" href = url_for(controller='login', redirect=redirect_url) return trans.show_error_message( f'You must be <a target="galaxy_main" href="{href}">logged in</a> to {verb}.', use_panels=use_panels)
def decorator( self, trans, *args, **kwargs ): if trans.get_user(): return func( self, trans, *args, **kwargs ) else: return trans.show_error_message( 'You must be <a target="galaxy_main" href="%s">logged in</a> to %s.' % ( url_for( controller='user', action='login', webapp=webapp ), verb ), use_panels=use_panels )
def launch_proxy_command(self, config): args = [ "gxproxy", # Must be on path. TODO: wheel? "--listenAddr", '%s:%d' % ( config.dynamic_proxy_bind_ip, config.dynamic_proxy_bind_port, ), "--listenPath", "/".join(((config.cookie_path or url_for('/')), config.dynamic_proxy_prefix)), "--cookieName", "galaxysession", "--storage", config.proxy_session_map.replace('.sqlite', '.xml'), # just in case. "--apiKey", config.dynamic_proxy_golang_api_key, "--noAccess", config.dynamic_proxy_golang_noaccess, "--cleanInterval", config.dynamic_proxy_golang_clean_interval, "--dockerAddr", config.dynamic_proxy_golang_docker_address, ] if config.dynamic_proxy_debug: args.append("--verbose") return args
def get_cookie(self, name='galaxysession'): """Convenience method for getting a session cookie""" try: # If we've changed the cookie during the request return the new value if name in self.response.cookies: return self.response.cookies[name].value else: if name not in self.request.cookies and TOOL_RUNNER_SESSION_COOKIE in self.request.cookies: # TOOL_RUNNER_SESSION_COOKIE value is the encoded galaxysession cookie. # We decode it here and pretend it's the galaxysession tool_runner_path = url_for(controller="tool_runner") if self.request.path.startswith(tool_runner_path): return self.security.decode_guid(self.request.cookies[TOOL_RUNNER_SESSION_COOKIE].value) return self.request.cookies[name].value except Exception: return None
def set_cookie(self, value, name="galaxysession", path="/", age=90, version="1"): self._set_cookie(value, name=name, path=path, age=age, version=version) if name == "galaxysession": # Set an extra sessioncookie that will only be sent and be accepted on the tool_runner path. # Use the id_secret to encode the sessioncookie, so if a malicious site # obtains the sessioncookie they can only run tools. self._set_cookie( value, name=TOOL_RUNNER_SESSION_COOKIE, path=url_for(controller="tool_runner"), age=age, version=version, encode_value=True, ) tool_runner_cookie = self.response.cookies[TOOL_RUNNER_SESSION_COOKIE] tool_runner_cookie["SameSite"] = "None" tool_runner_cookie["secure"] = True
def __init__(self, environ, app, webapp, session_cookie=None): self.app = app self.webapp = webapp self.security = webapp.security base.DefaultWebTransaction.__init__(self, environ) self.setup_i18n() self.expunge_all() config = self.app.config self.debug = asbool(config.get('debug', False)) x_frame_options = getattr(config, 'x_frame_options', None) if x_frame_options: self.response.headers['X-Frame-Options'] = x_frame_options # Flag indicating whether we are in workflow building mode (means # that the current history should not be used for parameter values # and such). self.workflow_building_mode = False # Flag indicating whether this is an API call and the API key user is an administrator self.api_inherit_admin = False self.__user = None self.galaxy_session = None self.error_message = None if self.environ.get('is_api_request', False): # With API requests, if there's a key, use it and associate the # user with the transaction. # If not, check for an active session but do not create one. # If an error message is set here, it's sent back using # trans.show_error in the response -- in expose_api. self.error_message = self._authenticate_api(session_cookie) elif self.app.name == "reports": self.galaxy_session = None else: # This is a web request, get or create session. self._ensure_valid_session(session_cookie) if self.galaxy_session: # When we've authenticated by session, we have to check the # following. # Prevent deleted users from accessing Galaxy if config.use_remote_user and self.galaxy_session.user.deleted: self.response.send_redirect( url_for('/static/user_disabled.html')) if config.require_login: self._ensure_logged_in_user(environ, session_cookie)
def __init__( self, environ, app, webapp, session_cookie=None): self.app = app self.webapp = webapp self.security = webapp.security base.DefaultWebTransaction.__init__( self, environ ) self.setup_i18n() self.expunge_all() self.debug = asbool( self.app.config.get( 'debug', False ) ) # Flag indicating whether we are in workflow building mode (means # that the current history should not be used for parameter values # and such). self.workflow_building_mode = False # Flag indicating whether this is an API call and the API key user is an administrator self.api_inherit_admin = False self.__user = None self.galaxy_session = None self.error_message = None if self.environ.get('is_api_request', False): # With API requests, if there's a key, use it and associate the # user with the transaction. # If not, check for an active session but do not create one. # If an error message is set here, it's sent back using # trans.show_error in the response -- in expose_api. self.error_message = self._authenticate_api( session_cookie ) elif self.app.name == "reports": self.galaxy_session = None else: # This is a web request, get or create session. self._ensure_valid_session( session_cookie ) if self.galaxy_session: # When we've authenticated by session, we have to check the # following. # Prevent deleted users from accessing Galaxy if self.app.config.use_remote_user and self.galaxy_session.user.deleted: self.response.send_redirect( url_for( '/static/user_disabled.html' ) ) if self.app.config.require_login: self._ensure_logged_in_user( environ, session_cookie )
def url(*args, **kwargs): # Only include sort/filter arguments if not linking to another # page. This is a bit of a hack. if "action" in kwargs: new_kwargs = dict() else: new_kwargs = dict(extra_url_args) # Extend new_kwargs with first argument if found if len(args) > 0: new_kwargs.update(args[0]) new_kwargs.update(kwargs) # We need to encode item ids if "id" in new_kwargs: id = new_kwargs["id"] if isinstance(id, list): new_kwargs["id"] = [trans.security.encode_id(i) for i in id] else: new_kwargs["id"] = trans.security.encode_id(id) # The url_for invocation *must* include a controller and action. if "controller" not in new_kwargs: new_kwargs["controller"] = trans.controller if "action" not in new_kwargs: new_kwargs["action"] = trans.action return url_for(**new_kwargs)
def _ensure_logged_in_user(self, environ, session_cookie): # The value of session_cookie can be one of # 'galaxysession' or 'galaxycommunitysession' # Currently this method does nothing unless session_cookie is 'galaxysession' if session_cookie == 'galaxysession' and self.galaxy_session.user is None: # TODO: re-engineer to eliminate the use of allowed_paths # as maintenance overhead is far too high. allowed_paths = (url_for(controller='root', action='index'), url_for(controller='root', action='tool_menu'), url_for(controller='root', action='masthead'), url_for(controller='root', action='history'), url_for(controller='user', action='api_keys'), url_for(controller='user', action='create'), url_for(controller='user', action='index'), url_for(controller='user', action='login'), url_for(controller='user', action='logout'), url_for(controller='user', action='manage_user_info'), url_for(controller='user', action='set_default_permissions'), url_for(controller='user', action='reset_password'), url_for(controller='user', action='openid_auth'), url_for(controller='user', action='openid_process'), url_for(controller='user', action='openid_associate'), url_for(controller='library', action='browse'), url_for(controller='history', action='list'), url_for(controller='dataset', action='list')) display_as = url_for(controller='root', action='display_as') if self.app.datatypes_registry.get_display_sites( 'ucsc') and self.request.path == display_as: try: host = socket.gethostbyaddr(self.environ['REMOTE_ADDR'])[0] except (socket.error, socket.herror, socket.gaierror, socket.timeout): host = None if host in UCSC_SERVERS: return external_display_path = url_for(controller='', action='display_application') if self.request.path.startswith(external_display_path): request_path_split = self.request.path.split('/') try: if (self.app.datatypes_registry.display_applications.get( request_path_split[-5]) and request_path_split[-4] in self.app. datatypes_registry.display_applications.get( request_path_split[-5]).links and request_path_split[-3] != 'None'): return except IndexError: pass if self.request.path not in allowed_paths: self.response.send_redirect( url_for(controller='root', action='index'))
def _ensure_logged_in_user( self, environ, session_cookie ): # The value of session_cookie can be one of # 'galaxysession' or 'galaxycommunitysession' # Currently this method does nothing unless session_cookie is 'galaxysession' if session_cookie == 'galaxysession' and self.galaxy_session.user is None: # TODO: re-engineer to eliminate the use of allowed_paths # as maintenance overhead is far too high. allowed_paths = ( url_for( controller='root', action='index' ), url_for( controller='root', action='tool_menu' ), url_for( controller='root', action='masthead' ), url_for( controller='root', action='history' ), url_for( controller='user', action='api_keys' ), url_for( controller='user', action='create' ), url_for( controller='user', action='index' ), url_for( controller='user', action='login' ), url_for( controller='user', action='logout' ), url_for( controller='user', action='manage_user_info' ), url_for( controller='user', action='set_default_permissions' ), url_for( controller='user', action='reset_password' ), url_for( controller='user', action='openid_auth' ), url_for( controller='user', action='openid_process' ), url_for( controller='user', action='openid_associate' ), url_for( controller='library', action='browse' ), url_for( controller='history', action='list' ), url_for( controller='dataset', action='list' ) ) display_as = url_for( controller='root', action='display_as' ) if self.app.datatypes_registry.get_display_sites('ucsc') and self.request.path == display_as: try: host = socket.gethostbyaddr( self.environ[ 'REMOTE_ADDR' ] )[0] except( socket.error, socket.herror, socket.gaierror, socket.timeout ): host = None if host in UCSC_SERVERS: return external_display_path = url_for( controller='', action='display_application' ) if self.request.path.startswith( external_display_path ): request_path_split = self.request.path.split( '/' ) try: if (self.app.datatypes_registry.display_applications.get( request_path_split[-5] ) and request_path_split[-4] in self.app.datatypes_registry.display_applications.get( request_path_split[-5] ).links and request_path_split[-3] != 'None'): return except IndexError: pass if self.request.path not in allowed_paths: self.response.send_redirect( url_for( controller='root', action='index' ) )
def __init__( self, environ, app, webapp, session_cookie=None): self.app = app self.webapp = webapp self.security = webapp.security base.DefaultWebTransaction.__init__( self, environ ) self.setup_i18n() self.expunge_all() config = self.app.config self.debug = asbool( config.get( 'debug', False ) ) x_frame_options = getattr( config, 'x_frame_options', None ) if x_frame_options: self.response.headers['X-Frame-Options'] = x_frame_options # Flag indicating whether we are in workflow building mode (means # that the current history should not be used for parameter values # and such). self.workflow_building_mode = False # Flag indicating whether this is an API call and the API key user is an administrator self.api_inherit_admin = False self.__user = None self.galaxy_session = None self.error_message = None if self.environ.get('is_api_request', False): # With API requests, if there's a key, use it and associate the # user with the transaction. # If not, check for an active session but do not create one. # If an error message is set here, it's sent back using # trans.show_error in the response -- in expose_api. self.error_message = self._authenticate_api( session_cookie ) elif self.app.name == "reports": self.galaxy_session = None else: # This is a web request, get or create session. self._ensure_valid_session( session_cookie ) if self.galaxy_session: # When we've authenticated by session, we have to check the # following. # Prevent deleted users from accessing Galaxy if config.use_remote_user and self.galaxy_session.user.deleted: self.response.send_redirect( url_for( '/static/user_disabled.html' ) ) if config.require_login: self._ensure_logged_in_user( environ, session_cookie ) if config.session_duration: # TODO DBTODO All ajax calls from the client need to go through # a single point of control where we can do things like # redirect/etc. This is API calls as well as something like 40 # @web.json requests that might not get handled well on the # clientside. # # Make sure we're not past the duration, and either log out or # update timestamp. now = datetime.datetime.now() if self.galaxy_session.last_action: expiration_time = self.galaxy_session.last_action + datetime.timedelta(minutes=config.session_duration) else: expiration_time = now self.galaxy_session.last_action = now - datetime.timedelta(seconds=1) self.sa_session.add(self.galaxy_session) self.sa_session.flush() if expiration_time < now: # Expiration time has passed. self.handle_user_logout() if self.environ.get('is_api_request', False): self.response.status = 401 self.user = None self.galaxy_session = None else: self.response.send_redirect( url_for( controller='user', action='login', message="You have been logged out due to inactivity. Please log in again to continue using Galaxy.", status='info', use_panels=True ) ) else: self.galaxy_session.last_action = now self.sa_session.add(self.galaxy_session) self.sa_session.flush()
def cookie_path(self): return self.app.config.cookie_path or url_for('/')
def _ensure_logged_in_user(self, environ, session_cookie): # The value of session_cookie can be one of # 'galaxysession' or 'galaxycommunitysession' # Currently this method does nothing unless session_cookie is 'galaxysession' if session_cookie == 'galaxysession' and self.galaxy_session.user is None: # TODO: re-engineer to eliminate the use of allowed_paths # as maintenance overhead is far too high. allowed_paths = [ # client app route # TODO: might be better as '/:username/login', '/:username/logout' url_for(controller='root', action='login'), # mako app routes url_for(controller='user', action='login'), url_for(controller='user', action='logout'), url_for(controller='user', action='reset_password'), url_for(controller='user', action='change_password'), # TODO: do any of these still need to bypass require login? url_for(controller='user', action='api_keys'), url_for(controller='user', action='create'), url_for(controller='user', action='index'), url_for(controller='user', action='manage_user_info'), url_for(controller='user', action='set_default_permissions'), ] # append the welcome url to allowed paths if we'll show it at the login screen if self.app.config.show_welcome_with_login: allowed_paths.append(url_for(controller='root', action='welcome')) # prevent redirect when UCSC server attempts to get dataset contents as 'anon' user display_as = url_for(controller='root', action='display_as') if self.app.datatypes_registry.get_display_sites('ucsc') and self.request.path == display_as: try: host = socket.gethostbyaddr(self.environ['REMOTE_ADDR'])[0] except(socket.error, socket.herror, socket.gaierror, socket.timeout): host = None if host in UCSC_SERVERS: return # prevent redirect for external, enabled display applications getting dataset contents external_display_path = url_for(controller='', action='display_application') if self.request.path.startswith(external_display_path): request_path_split = self.request.path.split('/') try: if (self.app.datatypes_registry.display_applications.get(request_path_split[-5]) and request_path_split[-4] in self.app.datatypes_registry.display_applications.get(request_path_split[-5]).links and request_path_split[-3] != 'None'): return except IndexError: pass # redirect to root if the path is not in the list above if self.request.path not in allowed_paths: login_url = url_for(controller='root', action='login', redirect=self.request.path) self.response.send_redirect(login_url)
def __init__(self, environ, app, webapp, session_cookie=None): self.app = app self.webapp = webapp self.security = webapp.security base.DefaultWebTransaction.__init__(self, environ) self.setup_i18n() self.expunge_all() config = self.app.config self.debug = asbool(config.get('debug', False)) x_frame_options = getattr(config, 'x_frame_options', None) if x_frame_options: self.response.headers['X-Frame-Options'] = x_frame_options # Flag indicating whether we are in workflow building mode (means # that the current history should not be used for parameter values # and such). self.workflow_building_mode = False # Flag indicating whether this is an API call and the API key user is an administrator self.api_inherit_admin = False self.__user = None self.galaxy_session = None self.error_message = None # set any cross origin resource sharing headers if configured to do so self.set_cors_headers() if self.environ.get('is_api_request', False): # With API requests, if there's a key, use it and associate the # user with the transaction. # If not, check for an active session but do not create one. # If an error message is set here, it's sent back using # trans.show_error in the response -- in expose_api. self.error_message = self._authenticate_api(session_cookie) elif self.app.name == "reports": self.galaxy_session = None else: # This is a web request, get or create session. self._ensure_valid_session(session_cookie) if self.galaxy_session: # When we've authenticated by session, we have to check the # following. # Prevent deleted users from accessing Galaxy if config.use_remote_user and self.galaxy_session.user.deleted: self.response.send_redirect(url_for('/static/user_disabled.html')) if config.require_login: self._ensure_logged_in_user(environ, session_cookie) if config.session_duration: # TODO DBTODO All ajax calls from the client need to go through # a single point of control where we can do things like # redirect/etc. This is API calls as well as something like 40 # @web.json requests that might not get handled well on the # clientside. # # Make sure we're not past the duration, and either log out or # update timestamp. now = datetime.datetime.now() if self.galaxy_session.last_action: expiration_time = self.galaxy_session.last_action + datetime.timedelta(minutes=config.session_duration) else: expiration_time = now self.galaxy_session.last_action = now - datetime.timedelta(seconds=1) self.sa_session.add(self.galaxy_session) self.sa_session.flush() if expiration_time < now: # Expiration time has passed. self.handle_user_logout() if self.environ.get('is_api_request', False): self.response.status = 401 self.user = None self.galaxy_session = None else: self.response.send_redirect(url_for(controller='user', action='login', message="You have been logged out due to inactivity. Please log in again to continue using Galaxy.", status='info', use_panels=True)) else: self.galaxy_session.last_action = now self.sa_session.add(self.galaxy_session) self.sa_session.flush()
def _ensure_logged_in_user( self, environ, session_cookie ): # The value of session_cookie can be one of # 'galaxysession' or 'galaxycommunitysession' # Currently this method does nothing unless session_cookie is 'galaxysession' if session_cookie == 'galaxysession' and self.galaxy_session.user is None: # TODO: re-engineer to eliminate the use of allowed_paths # as maintenance overhead is far too high. allowed_paths = [ # client app route # TODO: might be better as '/:username/login', '/:username/logout' url_for( controller='root', action='login' ), # mako app routes url_for( controller='user', action='login' ), url_for( controller='user', action='logout' ), url_for( controller='user', action='reset_password' ), url_for( controller='user', action='change_password' ), # required to log in w/ openid url_for( controller='user', action='openid_auth' ), url_for( controller='user', action='openid_process' ), url_for( controller='user', action='openid_associate' ), # TODO: do any of these still need to bypass require login? url_for( controller='user', action='api_keys' ), url_for( controller='user', action='create' ), url_for( controller='user', action='index' ), url_for( controller='user', action='manage_user_info' ), url_for( controller='user', action='set_default_permissions' ), ] # append the welcome url to allowed paths if we'll show it at the login screen if self.app.config.show_welcome_with_login: allowed_paths.append( url_for( controller='root', action='welcome' ) ) # prevent redirect when UCSC server attempts to get dataset contents as 'anon' user display_as = url_for( controller='root', action='display_as' ) if self.app.datatypes_registry.get_display_sites('ucsc') and self.request.path == display_as: try: host = socket.gethostbyaddr( self.environ[ 'REMOTE_ADDR' ] )[0] except( socket.error, socket.herror, socket.gaierror, socket.timeout ): host = None if host in UCSC_SERVERS: return # prevent redirect for external, enabled display applications getting dataset contents external_display_path = url_for( controller='', action='display_application' ) if self.request.path.startswith( external_display_path ): request_path_split = self.request.path.split( '/' ) try: if (self.app.datatypes_registry.display_applications.get( request_path_split[-5] ) and request_path_split[-4] in self.app.datatypes_registry.display_applications.get( request_path_split[-5] ).links and request_path_split[-3] != 'None'): return except IndexError: pass # redirect to root if the path is not in the list above if self.request.path not in allowed_paths: login_url = url_for( controller='root', action='login', redirect=self.request.path ) self.response.send_redirect( login_url )
def qualified_url_for_path(self, path): return url_for(path, qualified=True)
def url_builder(*args, **kwargs) -> str: """Wrapper around the uWSGI version of the function for reversing URLs.""" return url_for(*args, **kwargs)
def url_builder(*args, **kwargs) -> str: """Wrapper around the WSGI version of the function for reversing URLs.""" kwargs.update(kwargs.pop('query_params', {})) return url_for(*args, **kwargs)
def cookie_path(self): # Cookies for non-root paths should not end with `/` -> https://stackoverflow.com/questions/36131023/setting-a-slash-on-cookie-path return (self.app.config.cookie_path or url_for('/')).rstrip('/') or '/'
def qualified_url_builder(path): return url_for(path, qualified=True)