def get_api_user( security: IdEncodingHelper = depends(IdEncodingHelper), user_manager: UserManager = depends(UserManager), key: Optional[str] = Query(None), x_api_key: Optional[str] = Header(None), run_as: Optional[EncodedDatabaseIdField] = Header( default=None, title='Run as User', description= ('The user ID that will be used to effectively make this API call. ' 'Only admins and designated users can make API calls on behalf of other users.' ))) -> Optional[User]: api_key = key or x_api_key if not api_key: return None user = user_manager.by_api_key(api_key=api_key) if run_as: if user_manager.user_can_do_run_as(user): try: decoded_run_as_id = security.decode_id(run_as) except Exception: raise UserInvalidRunAsException return user_manager.by_id(decoded_run_as_id) else: raise UserCannotRunAsException return user
def get_api_user(security: IdEncodingHelper = depends(IdEncodingHelper), user_manager: UserManager = depends(UserManager), key: Optional[str] = Query(None), x_api_key: Optional[str] = Header(None), run_as: Optional[EncodedDatabaseIdField] = Header( None, title='Run as User', description='Admins and ')) -> Optional[User]: api_key = key or x_api_key if not api_key: return None user = user_manager.by_api_key(api_key=api_key) if run_as: if user_manager.user_can_do_run_as(user): try: decoded_run_as_id = security.decode_id(run_as) except Exception: raise UserInvalidRunAsException return user_manager.by_id(decoded_run_as_id) else: raise UserCannotRunAsException return user
class GalaxyWebTransaction(base.DefaultWebTransaction, context.ProvidesAppContext, context.ProvidesUserContext, context.ProvidesHistoryContext): """ Encapsulates web transaction specific state for the Galaxy application (specifically the user's "cookie" session and history) """ def __init__(self, environ, app, webapp, session_cookie=None): self.app = app self.webapp = webapp self.security = webapp.security self.user_manager = UserManager(app) self.session_manager = GalaxySessionManager(app.model) 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 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='root', 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 setup_i18n(self): locales = [] if 'HTTP_ACCEPT_LANGUAGE' in self.environ: # locales looks something like: ['en', 'en-us;q=0.7', 'ja;q=0.3'] client_locales = self.environ['HTTP_ACCEPT_LANGUAGE'].split(',') for locale in client_locales: try: locales.append(Locale.parse(locale.split(';')[0].strip(), sep='-').language) except Exception as e: log.debug("Error parsing locale '%s'. %s: %s", locale, type(e), e) if not locales: # Default to English locales = 'en' t = Translations.load(dirname='locale', locales=locales, domain='ginga') self.template_context.update(dict(_=t.ugettext, n_=t.ugettext, N_=t.ungettext)) def set_cors_allow(self, name=None, value=None): acr = 'Access-Control-Request-' if name is None: for key in self.request.headers.keys(): if key.startswith(acr): self.set_cors_allow(name=key[len(acr):], value=value) else: resp_name = f'Access-Control-Allow-{name}' if value is None: value = self.request.headers.get(acr + name, None) if value: self.response.headers[resp_name] = value elif resp_name in self.response.headers: del self.response.headers[resp_name] def set_cors_origin(self, origin=None): if origin is None: origin = self.request.headers.get("Origin", None) if origin: self.response.headers['Access-Control-Allow-Origin'] = origin elif 'Access-Control-Allow-Origin' in self.response.headers: del self.response.headers['Access-Control-Allow-Origin'] def set_cors_headers(self): """Allow CORS requests if configured to do so by echoing back the request's 'Origin' header (if any) as the response header 'Access-Control-Allow-Origin' Preflight OPTIONS requests to the API work by routing all OPTIONS requests to a single method in the authenticate API (options method), setting CORS headers, and responding OK. NOTE: raising some errors (such as httpexceptions), will remove the header (e.g. client will get both CORS error and 404 inside that) """ # do not set any access control headers if not configured for it (common case) if not self.app.config.get('allowed_origin_hostnames', None): return # do not set any access control headers if there's no origin header on the request origin_header = self.request.headers.get("Origin", None) if not origin_header: return # singular match def matches_allowed_origin(origin, allowed_origin): if isinstance(allowed_origin, str): return origin == allowed_origin match = allowed_origin.match(origin) return match and match.group() == origin # check for '*' or compare to list of allowed def is_allowed_origin(origin): # localhost uses no origin header (== null) if not origin: return False for allowed_origin in self.app.config.allowed_origin_hostnames: if allowed_origin == '*' or matches_allowed_origin(origin, allowed_origin): return True return False # boil origin header down to hostname origin = urlparse(origin_header).hostname # check against the list of allowed strings/regexp hostnames, echo original if cleared if is_allowed_origin(origin): self.set_cors_origin(origin=origin_header) def get_user(self): """Return the current user if logged in or None.""" user = self.__user if not user and self.galaxy_session: user = self.galaxy_session.user self.__user = user return user def set_user(self, user): """Set the current user.""" if self.galaxy_session: if user.bootstrap_admin_user: self.galaxy_session.user = user self.sa_session.add(self.galaxy_session) self.sa_session.flush() self.__user = user user = property(get_user, set_user) 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: return self.request.cookies[name].value except Exception: return None def set_cookie(self, value, name='galaxysession', path='/', age=90, version='1'): """Convenience method for setting a session cookie""" # The galaxysession cookie value must be a high entropy 128 bit random number encrypted # using a server secret key. Any other value is invalid and could pose security issues. self.response.cookies[name] = unicodify(value) self.response.cookies[name]['path'] = path self.response.cookies[name]['max-age'] = 3600 * 24 * age # 90 days tstamp = time.localtime(time.time() + 3600 * 24 * age) self.response.cookies[name]['expires'] = time.strftime('%a, %d-%b-%Y %H:%M:%S GMT', tstamp) self.response.cookies[name]['version'] = version https = self.request.environ["wsgi.url_scheme"] == "https" if https: self.response.cookies[name]['secure'] = True try: self.response.cookies[name]['httponly'] = True except CookieError as e: log.warning(f"Error setting httponly attribute in cookie '{name}': {e}") if self.app.config.cookie_domain is not None: self.response.cookies[name]['domain'] = self.app.config.cookie_domain def _authenticate_api(self, session_cookie): """ Authenticate for the API via key or session (if available). """ api_key = self.request.params.get('key', None) or self.request.headers.get('x-api-key', None) secure_id = self.get_cookie(name=session_cookie) api_key_supplied = self.environ.get('is_api_request', False) and api_key if api_key_supplied: # Sessionless API transaction, we just need to associate a user. try: user = self.user_manager.by_api_key(api_key) except AuthenticationFailed as e: return str(e) self.set_user(user) elif secure_id: # API authentication via active session # Associate user using existing session # This will throw an exception under remote auth with anon users. try: self._ensure_valid_session(session_cookie) except Exception: log.exception("Exception during Session-based API authentication, this was most likely an attempt to use an anonymous cookie under remote authentication (so, no user), which we don't support.") self.user = None self.galaxy_session = None else: # Anonymous API interaction -- anything but @expose_api_anonymous will fail past here. self.user = None self.galaxy_session = None def _ensure_valid_session(self, session_cookie, create=True): """ Ensure that a valid Galaxy session exists and is available as trans.session (part of initialization) Support for universe_session and universe_user cookies has been removed as of 31 Oct 2008. """ # Try to load an existing session secure_id = self.get_cookie(name=session_cookie) galaxy_session = None prev_galaxy_session = None user_for_new_session = None invalidate_existing_session = False # Track whether the session has changed so we can avoid calling flush # in the most common case (session exists and is valid). galaxy_session_requires_flush = False if secure_id: # Decode the cookie value to get the session_key try: session_key = self.security.decode_guid(secure_id) if session_key: galaxy_session = self.session_manager.get_session_from_session_key(session_key=session_key) except Exception: # We'll end up creating a new galaxy_session session_key = None # If remote user is in use it can invalidate the session and in some # cases won't have a cookie set above, so we need to to check some # things now. if self.app.config.use_remote_user: remote_user_email = self.environ.get(self.app.config.remote_user_header, None) if galaxy_session: if remote_user_email and galaxy_session.user is None: # No user, associate galaxy_session.user = self.get_or_create_remote_user(remote_user_email) galaxy_session_requires_flush = True elif (remote_user_email and (galaxy_session.user.email != remote_user_email) and ((not self.app.config.allow_user_impersonation) or (remote_user_email not in self.app.config.admin_users_list))): # Session exists but is not associated with the correct # remote user, and the currently set remote_user is not a # potentially impersonating admin. invalidate_existing_session = True user_for_new_session = self.get_or_create_remote_user(remote_user_email) log.warning("User logged in as '%s' externally, but has a cookie as '%s' invalidating session", remote_user_email, galaxy_session.user.email) elif remote_user_email: # No session exists, get/create user for new session user_for_new_session = self.get_or_create_remote_user(remote_user_email) if ((galaxy_session and galaxy_session.user is None) and user_for_new_session is None): raise Exception("Remote Authentication Failure - user is unknown and/or not supplied.") else: if galaxy_session is not None and galaxy_session.user and galaxy_session.user.external: # Remote user support is not enabled, but there is an existing # session with an external user, invalidate invalidate_existing_session = True log.warning("User '%s' is an external user with an existing session, invalidating session since external auth is disabled", galaxy_session.user.email) elif galaxy_session is not None and galaxy_session.user is not None and galaxy_session.user.deleted: invalidate_existing_session = True log.warning("User '%s' is marked deleted, invalidating session" % galaxy_session.user.email) # Do we need to invalidate the session for some reason? if invalidate_existing_session: prev_galaxy_session = galaxy_session prev_galaxy_session.is_valid = False galaxy_session = None # No relevant cookies, or couldn't find, or invalid, so create a new session if galaxy_session is None: galaxy_session = self.__create_new_session(prev_galaxy_session, user_for_new_session) galaxy_session_requires_flush = True self.galaxy_session = galaxy_session self.__update_session_cookie(name=session_cookie) else: self.galaxy_session = galaxy_session # Do we need to flush the session? if galaxy_session_requires_flush: self.sa_session.add(galaxy_session) # FIXME: If prev_session is a proper relation this would not # be needed. if prev_galaxy_session: self.sa_session.add(prev_galaxy_session) self.sa_session.flush() # If the old session was invalid, get a new (or existing default, # unused) history with our new session if invalidate_existing_session: self.get_or_create_default_history() 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(OSError, 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 authnz_controller_base = url_for(controller='authnz', action='index') if self.request.path.startswith(authnz_controller_base): # All authnz requests pass through return # 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 __create_new_session(self, prev_galaxy_session=None, user_for_new_session=None): """ Create a new GalaxySession for this request, possibly with a connection to a previous session (in `prev_galaxy_session`) and an existing user (in `user_for_new_session`). Caller is responsible for flushing the returned session. """ session_key = self.security.get_new_guid() galaxy_session = self.app.model.GalaxySession( session_key=session_key, is_valid=True, remote_host=self.request.remote_host, remote_addr=self.request.remote_addr, referer=self.request.headers.get('Referer', None)) if prev_galaxy_session: # Invalidated an existing session for some reason, keep track galaxy_session.prev_session_id = prev_galaxy_session.id if user_for_new_session: # The new session should be associated with the user galaxy_session.user = user_for_new_session return galaxy_session def get_or_create_remote_user(self, remote_user_email): """ Create a remote user with the email remote_user_email and return it """ if not self.app.config.use_remote_user: return None if getattr(self.app.config, "normalize_remote_user_email", False): remote_user_email = remote_user_email.lower() user = self.sa_session.query(self.app.model.User).filter(self.app.model.User.table.c.email == remote_user_email).first() if user: # GVK: June 29, 2009 - This is to correct the behavior of a previous bug where a private # role and default user / history permissions were not set for remote users. When a # 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 'webapp' not in self.environ or self.environ['webapp'] != 'tool_shed': 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() user = self.app.model.User(email=remote_user_email) user.set_random_password(length=12) user.external = True # Replace invalid characters in the username for char in [x for x in username if x not in string.ascii_lowercase + string.digits + '-' + '.']: username = username.replace(char, '-') # Find a unique username - user can change it later if self.sa_session.query(self.app.model.User).filter_by(username=username).first(): i = 1 while self.sa_session.query(self.app.model.User).filter_by(username=(username + '-' + str(i))).first(): i += 1 username += '-' + str(i) user.username = username self.sa_session.add(user) 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 if 'webapp' not in self.environ or self.environ['webapp'] != 'tool_shed': self.app.security_agent.user_set_default_permissions(user) # self.log_event( "Automatically created account '%s'", user.email ) return user @property def cookie_path(self): return self.app.config.cookie_path or url_for('/') def __update_session_cookie(self, name='galaxysession'): """ Update the session cookie to match the current session. """ self.set_cookie(self.security.encode_guid(self.galaxy_session.session_key), name=name, path=self.cookie_path) def check_user_library_import_dir(self, user): if getattr(self.app.config, "user_library_import_dir_auto_creation", False): # try to create a user library import directory try: safe_makedirs(os.path.join(self.app.config.user_library_import_dir, user.email)) except ConfigurationError as e: self.log_event(unicodify(e)) def user_checks(self, user): """ This could contain more checks around a user upon login """ self.check_user_library_import_dir(user) def _associate_user_history(self, user, prev_galaxy_session=None): """ Associate the user's last accessed history (if exists) with their new session """ history = None set_permissions = False try: users_last_session = user.galaxy_sessions[0] except Exception: users_last_session = None if (prev_galaxy_session and prev_galaxy_session.current_history and not prev_galaxy_session.current_history.deleted and prev_galaxy_session.current_history.datasets and (prev_galaxy_session.current_history.user is None or prev_galaxy_session.current_history.user == user)): # If the previous galaxy session had a history, associate it with the new session, but only if it didn't # belong to a different user. history = prev_galaxy_session.current_history if prev_galaxy_session.user is None: # Increase the user's disk usage by the amount of the previous history's datasets if they didn't already # own it. for hda in history.datasets: user.adjust_total_disk_usage(hda.quota_amount(user)) # Only set default history permissions if the history is from the previous session and anonymous set_permissions = True elif self.galaxy_session.current_history: history = self.galaxy_session.current_history if (not history and users_last_session and users_last_session.current_history and not users_last_session.current_history.deleted): history = users_last_session.current_history elif not history: history = self.get_history(create=True, most_recent=True) if history not in self.galaxy_session.histories: self.galaxy_session.add_history(history) if history.user is None: history.user = user self.galaxy_session.current_history = history if set_permissions: self.app.security_agent.history_set_default_permissions(history, dataset=True, bypass_manage_permission=True) self.sa_session.add_all((prev_galaxy_session, self.galaxy_session, history)) def handle_user_login(self, user): """ Login a new user (possibly newly created) - do some 'system' checks (if any) for this user - create a new session - associate new session with user - if old session had a history and it was not associated with a user, associate it with the new session, otherwise associate the current session's history with the user - add the disk usage of the current session to the user's total disk usage """ self.user_checks(user) self.app.security_agent.create_user_role(user, self.app) # Set the previous session prev_galaxy_session = self.galaxy_session prev_galaxy_session.is_valid = False # Define a new current_session self.galaxy_session = self.__create_new_session(prev_galaxy_session, user) if self.webapp.name == 'galaxy': cookie_name = 'galaxysession' self._associate_user_history(user, prev_galaxy_session) else: cookie_name = 'galaxycommunitysession' self.sa_session.add_all((prev_galaxy_session, self.galaxy_session)) self.sa_session.flush() # This method is not called from the Galaxy reports, so the cookie will always be galaxysession self.__update_session_cookie(name=cookie_name) def handle_user_logout(self, logout_all=False): """ Logout the current user: - invalidate the current session - create a new session with no user associated """ prev_galaxy_session = self.galaxy_session prev_galaxy_session.is_valid = False self.galaxy_session = self.__create_new_session(prev_galaxy_session) self.sa_session.add_all((prev_galaxy_session, self.galaxy_session)) galaxy_user_id = prev_galaxy_session.user_id if logout_all and galaxy_user_id is not None: for other_galaxy_session in (self.sa_session.query(self.app.model.GalaxySession) .filter(and_(self.app.model.GalaxySession.table.c.user_id == galaxy_user_id, self.app.model.GalaxySession.table.c.is_valid == true(), self.app.model.GalaxySession.table.c.id != prev_galaxy_session.id))): other_galaxy_session.is_valid = False self.sa_session.add(other_galaxy_session) self.sa_session.flush() if self.webapp.name == 'galaxy': # This method is not called from the Galaxy reports, so the cookie will always be galaxysession self.__update_session_cookie(name='galaxysession') elif self.webapp.name == 'tool_shed': self.__update_session_cookie(name='galaxycommunitysession') def get_galaxy_session(self): """ Return the current galaxy session """ return self.galaxy_session def get_history(self, create=False, most_recent=False): """ Load the current history. - If that isn't available, we find the most recently updated history. - If *that* isn't available, we get or create the default history. Transactions will not always have an active history (API requests), so None is a valid response. """ history = None if self.galaxy_session: if hasattr(self.galaxy_session, 'current_history'): history = self.galaxy_session.current_history if not history and most_recent: history = self.get_most_recent_history() if not history and util.string_as_bool(create): history = self.get_or_create_default_history() return history def set_history(self, history): if history and not history.deleted: self.galaxy_session.current_history = history self.sa_session.add(self.galaxy_session) self.sa_session.flush() history = property(get_history, set_history) def get_or_create_default_history(self): """ Gets or creates a default history and associates it with the current session. """ # There must be a user to fetch a default history. if not self.galaxy_session.user: return self.new_history() # Look for default history that (a) has default name + is not deleted and # (b) has no datasets. If suitable history found, use it; otherwise, create # new history. unnamed_histories = self.sa_session.query(self.app.model.History).filter_by( user=self.galaxy_session.user, name=self.app.model.History.default_name, deleted=False) default_history = None for history in unnamed_histories: if len(history.datasets) == 0: # Found suitable default history. default_history = history break # Set or create history. if default_history: history = default_history self.set_history(history) else: history = self.new_history() return history def get_most_recent_history(self): """ Gets the most recently updated history. """ # There must be a user to fetch histories, and without a user we have # no recent history. if not self.galaxy_session.user: return None try: recent_history = self.sa_session.query(self.app.model.History).filter_by( user=self.galaxy_session.user, deleted=False).order_by(self.app.model.History.update_time.desc()).first() except NoResultFound: return None self.set_history(recent_history) return recent_history def new_history(self, name=None): """ Create a new history and associate it with the current session and its associated user (if set). """ # Create new history history = self.app.model.History() if name: history.name = name # Associate with session history.add_galaxy_session(self.galaxy_session) # Make it the session's current history self.galaxy_session.current_history = history # Associate with user if self.galaxy_session.user: history.user = self.galaxy_session.user # Track genome_build with history history.genome_build = self.app.genome_builds.default_value # Set the user's default history permissions self.app.security_agent.history_set_default_permissions(history) # Save self.sa_session.add_all((self.galaxy_session, history)) self.sa_session.flush() return history @base.lazy_property def template_context(self): return dict() def set_message(self, message, type=None): """ Convenience method for setting the 'message' and 'message_type' element of the template context. """ self.template_context['message'] = message if type: self.template_context['status'] = type def get_message(self): """ Convenience method for getting the 'message' element of the template context. """ return self.template_context['message'] def show_message(self, message, type='info', refresh_frames=None, cont=None, use_panels=False, active_view=""): """ Convenience method for displaying a simple page with a single message. `type`: one of "error", "warning", "info", or "done"; determines the type of dialog box and icon displayed with the message `refresh_frames`: names of frames in the interface that should be refreshed when the message is displayed """ refresh_frames = refresh_frames or [] return self.fill_template("message.mako", status=type, message=message, refresh_frames=refresh_frames, cont=cont, use_panels=use_panels, active_view=active_view) def show_error_message(self, message, refresh_frames=None, use_panels=False, active_view=""): """ Convenience method for displaying an error message. See `show_message`. """ refresh_frames = refresh_frames or [] return self.show_message(message, 'error', refresh_frames, use_panels=use_panels, active_view=active_view) def show_ok_message(self, message, refresh_frames=None, use_panels=False, active_view=""): """ Convenience method for displaying an ok message. See `show_message`. """ refresh_frames = refresh_frames or [] return self.show_message(message, 'done', refresh_frames, use_panels=use_panels, active_view=active_view) def show_warn_message(self, message, refresh_frames=None, use_panels=False, active_view=""): """ Convenience method for displaying an warn message. See `show_message`. """ refresh_frames = refresh_frames or [] return self.show_message(message, 'warning', refresh_frames, use_panels=use_panels, active_view=active_view) @property def session_csrf_token(self): token = '' if self.galaxy_session: token = self.security.encode_id( self.galaxy_session.id, kind="csrf" ) return token def check_csrf_token(self, payload): session_csrf_token = payload.get("session_csrf_token") if not session_csrf_token: return "No session token set, denying request." elif session_csrf_token != self.session_csrf_token: return "Wrong session token found, denying request." def fill_template(self, filename, **kwargs): """ Fill in a template, putting any keyword arguments on the context. """ # call get_user so we can invalidate sessions from external users, # if external auth has been disabled. self.get_user() if filename.endswith(".mako"): return self.fill_template_mako(filename, **kwargs) else: template = Template(file=os.path.join(self.app.config.template_path, filename), searchList=[kwargs, self.template_context, dict(caller=self, t=self, h=helpers, util=util, request=self.request, response=self.response, app=self.app)]) return str(template) def fill_template_mako(self, filename, template_lookup=None, **kwargs): template_lookup = template_lookup or self.webapp.mako_template_lookup template = template_lookup.get_template(filename) data = dict(caller=self, t=self, trans=self, h=helpers, util=util, request=self.request, response=self.response, app=self.app) data.update(self.template_context) data.update(kwargs) return template.render(**data) def stream_template_mako(self, filename, **kwargs): template = self.webapp.mako_template_lookup.get_template(filename) data = dict(caller=self, t=self, trans=self, h=helpers, util=util, request=self.request, response=self.response, app=self.app) data.update(self.template_context) data.update(kwargs) def render(environ, start_response): response_write = start_response(self.response.wsgi_status(), self.response.wsgi_headeritems()) class StreamBuffer: def write(self, d): response_write(d.encode('utf-8')) buffer = StreamBuffer() context = mako.runtime.Context(buffer, **data) template.render_context(context) return [] return render def fill_template_string(self, template_string, context=None, **kwargs): """ Fill in a template, putting any keyword arguments on the context. """ template = Template(source=template_string, searchList=[context or kwargs, dict(caller=self)]) return str(template)
def get_api_user(user_manager: UserManager = Depends(get_user_manager), key: Optional[str] = Query(None), x_api_key: Optional[str] = Header(None)) -> Optional[User]: api_key = key or x_api_key if not api_key: return None return user_manager.by_api_key(api_key=api_key)