def get_db_query(self): if self.db_query is None: self.db_query = self._build_db_query() if not self.has['medscan']: minus_q = ~HasOnlySource('medscan') self.db_query &= minus_q if not self.ev_filter: self.ev_filter = minus_q.ev_filter() else: self.ev_filter &= minus_q.ev_filter() if self.strict: num_agents = (self.db_query.list_component_queries() .count(HasAgent.__name__)) self.db_query &= HasNumAgents((num_agents,)) # Note the query in the log, if one is running. if is_log_running(): note_in_log(query=self.db_query.to_json()) logger.info(f"Constructed query \"{self.db_query}\":\n" f"{json.dumps(self.db_query.to_json(), indent=2)}") # Prevent someone from breaking the database by querying too many # hashes, paper IDs, or MeshIds. query_set = set(self.db_query.list_component_queries()) if {'HasHash', 'FromPapers', 'FromMeshIds'} & query_set: for q in self.db_query.iter_component_queries(): if isinstance(q, HasHash): list_len = len(q.stmt_hashes) lbl = 'hashes' elif isinstance(q, FromPapers): list_len = len(q.paper_list) lbl = 'paper IDs' elif isinstance(q, FromMeshIds): list_len = len(q.mesh_ids) lbl = 'MeSH IDs' else: list_len = 0 lbl = None if list_len > MAX_LIST_LEN: logger.error(f"Length exceeded: {list_len} > " f"{MAX_LIST_LEN}") raise HttpUserError(f"Too many {lbl}! Only " f"{MAX_LIST_LEN} {lbl} allowed.") return self.db_query
def resolve_auth(query): """Get the roles for the current request, either by JWT or API key. If by API key, the key must be in the query. If by JWT, @jwt_optional or similar must wrap the calling function. Returns a tuple with the current user, if applicable, and a list of associated roles. """ api_key = query.pop('api_key', None) logger.info("Got api key %s" % api_key) if api_key: logger.info("Using API key role.") role = Role.get_by_api_key(api_key) set_role_in_log(role) return None, [role] user_identity = get_jwt_identity() logger.debug("Got user_identity: %s" % user_identity) if not user_identity: logger.info("No user identity, no role.") return None, [] try: current_user = User.get_by_identity(user_identity) logger.debug("Got user: %s" % current_user) except BadIdentity: logger.info("Identity malformed, no role.") return None, [] except Exception as e: logger.exception(e) logger.error("Unexpected error looking up user.") return None, [] if not current_user: logger.info("Identity not mapped to user, no role.") return None, [] logger.info("Identity mapped to the user, returning roles.") if is_log_running(): set_user_in_log(current_user) return current_user, list(current_user.roles)
def get_db_query(self): if self.db_query is None: self.db_query = self._build_db_query() if not self.has['medscan']: minus_q = ~HasOnlySource('medscan') self.db_query &= minus_q if not self.ev_filter: self.ev_filter = minus_q.ev_filter() else: self.ev_filter &= minus_q.ev_filter() if self.strict: num_agents = (self.db_query.list_component_queries() .count(HasAgent.__name__)) self.db_query &= HasNumAgents((num_agents,)) # Note the query in the log, if one is running. if is_log_running(): note_in_log(query=self.db_query.to_json()) logger.info(f"Constructed query \"{self.db_query}\":\n" f"{json.dumps(self.db_query.to_json(), indent=2)}") return self.db_query
def resolve_auth(query, failure_reason=None): """Get the roles for the current request, either by JWT or API key. If by API key, the key must be in the query. If by JWT, @jwt_optional or similar must wrap the calling function. If the reason for credentials failing is of interest, you can pass an empty dictionary to `failure_reason`. If there is an auth problem, it will be populated with 'auth_attempted' and 'reason', indicating the kind of auth (e.g. "API key" or "Identity") that was attempted, and the reason it was rejected (e.g. "Invalid"). Returns a tuple with the current user, if applicable, and a list of associated roles. """ api_key = query.pop('api_key', None) logger.info("Got api key %s" % api_key) if api_key: logger.info("Using API key role.") try: role = Role.get_by_api_key(api_key) except UserDatabaseError: if failure_reason is not None: failure_reason['auth_attempted'] = "API key" failure_reason['reason'] = "Invalid" return None, [] set_role_in_log(role) return None, [role] user_identity = get_jwt_identity() logger.debug("Got user_identity: %s" % user_identity) if not user_identity: logger.info("No user identity, no role.") if failure_reason is not None: failure_reason['auth_attempted'] = None failure_reason['reason'] = "No auth" return None, [] try: current_user = User.get_by_identity(user_identity) logger.debug("Got user: %s" % current_user) except BadIdentity: logger.info("Identity malformed, no role.") if failure_reason is not None: failure_reason['auth_attempted'] = "Identity" failure_reason['reason'] = "Invalid" return None, [] except Exception as e: logger.exception(e) logger.error("Unexpected error looking up user.") if failure_reason is not None: failure_reason['auth_attempted'] = "Identity" failure_reason['reason'] = 'Unexpected' return None, [] if not current_user: logger.info("Identity not mapped to user, no role.") if failure_reason is not None: failure_reason['auth_attempted'] = "Identity" failure_reason['reason'] = "No user" return None, [] logger.info("Identity mapped to the user, returning roles.") if is_log_running(): set_user_in_log(current_user) return current_user, list(current_user.roles)