def send_add_board_editor_notification(board_id, uid, read, write, session=None): inviting_user = user_logic.get_user_by_id(current_user.id, session=session) invited_user = user_logic.get_user_by_id(uid, session=session) board = Board.get(id=board_id, session=session) environment = board.environment permission_type = "edit" if write else "view" board_url = f"{QuerybookSettings.PUBLIC_URL}/{environment.name}/list/{board_id}/" notify_user( user=invited_user, template_name="board_invitation", template_params=dict( inviting_username=inviting_user.get_name(), read_or_write=permission_type, board_url=board_url, board_name=board.name, ), session=session, )
def get_user_info(uid): user = logic.get_user_by_id(uid) if user is None: abort(RESOURCE_NOT_FOUND_STATUS_CODE) return user
def get_my_user_info(): with DBSession() as session: uid = current_user.id return { "uid": uid, "info": logic.get_user_by_id(uid, session=session).to_dict(with_roles=True), }
def decorated_function(*args, **kwargs): user = None if current_app.config['LOGIN_DISABLED']: return f(user, *args, **kwargs) auth_header = request.headers.get('Authorization') if auth_header: if len(auth_header.split(' ')) != 2: return jsonify({ 'success': False, 'message': 'authorization header malformed' }), 422 auth_token = auth_header.split(' ')[1] user_id = User.decode_auth_token(auth_token) # decode_auth_token returns a string if there was an exception decoding the auth_token if isinstance(user_id, str): return jsonify({'success': False, 'message': user_id}), 401 user = get_user_by_id(user_id) return f(user, *args, **kwargs) else: return jsonify({ 'success': False, 'message': 'no authorization header' }), 401
def create_demo_lineage(metastore_id, uid, session=None): query_text = """CREATE TABLE world_happiness_ranking_2015_to_2019 AS SELECT w5.Country, w5.Region, w5.HappinessRank AS [Rank2015], w6.HappinessRank AS [Rank2016], w7.HappinessRank AS [Rank2017], w8.Rank AS [Rank2018], w9.Rank AS [Rank2019] FROM world_happiness_2019 w9 INNER JOIN world_happiness_2018 w8 ON w9.Country = w8.Country INNER JOIN world_happiness_2017 w7 ON w9.Country = w7.Country INNER JOIN world_happiness_2016 w6 ON w9.Country = w6.Country INNER JOIN world_happiness_2015 w5 ON w9.Country = w5.Country; """ user = user_logic.get_user_by_id(uid, session=session) data_job_metadata = m_logic.create_job_metadata_row( job_name="Untitled", metastore_id=metastore_id, job_info={"source": "demo lineage"}, job_owner=user.username, query_text=query_text, is_adhoc=True, session=session, ) lineage_logic.create_table_lineage_from_metadata( data_job_metadata.id, "sqlite", session=session )
def send_board_transfer_notification(board_id, next_owner_id, session=None): inviting_user = user_logic.get_user_by_id(current_user.id, session=session) invited_user = user_logic.get_user_by_id(next_owner_id, session=session) board = Board.get(id=board_id, session=session) environment = board.environment board_url = f"{QuerybookSettings.PUBLIC_URL}/{environment.name}/board/{board_id}/" notify_user( user=invited_user, template_name="board_ownership_transfer", template_params=dict( inviting_username=inviting_user.get_name(), board_url=board_url, board_name=board.name, ), session=session, )
def send_query_execution_invitation_notification(execution_id, uid, session=None): inviting_user = user_logic.get_user_by_id(current_user.id, session=session) invited_user = user_logic.get_user_by_id(uid, session=session) environment = get_default_user_environment_by_execution_id( execution_id=execution_id, uid=uid, session=session ) execution_url = f"{QuerybookSettings.PUBLIC_URL}/{environment.name}/query_execution/{execution_id}/" notify_user( user=invited_user, template_name="query_execution_invitation", template_params=dict( inviting_username=inviting_user.get_name(), execution_id=execution_id, execution_url=execution_url, ), session=session, )
def send_query_execution_access_request_notification(execution_id, uid, session=None): requestor = user_logic.get_user_by_id(uid, session=session) query_execution = logic.get_query_execution_by_id(execution_id, session=session) environment = get_default_user_environment_by_execution_id( execution_id=execution_id, uid=uid, session=session ) execution_url = f"{QuerybookSettings.PUBLIC_URL}/{environment.name}/query_execution/{execution_id}/" owner = user_logic.get_user_by_id(query_execution.uid, session=session) requestor_username = requestor.get_name() notify_user( user=owner, template_name="query_execution_access_request", template_params=dict( username=requestor_username, execution_id=execution_id, execution_url=execution_url, ), )
def load_user(uid, session=None): if not uid or uid == "None": return None user = get_user_by_id(uid, session=session) if user is None: # Invalid user, clear session flask_session.clear() flask.abort(401, description="Invalid cookie") return AuthUser(user)
def send_datadoc_transfer_notification(doc_id, next_owner_id, session=None): inviting_user = user_logic.get_user_by_id(current_user.id, session=session) invited_user = user_logic.get_user_by_id(next_owner_id, session=session) data_doc = logic.get_data_doc_by_id(doc_id, session=session) environment = data_doc.environment data_doc_title = data_doc.title or "Untitled" doc_url = f"{QuerybookSettings.PUBLIC_URL}/{environment.name}/datadoc/{doc_id}/" notify_user( user=invited_user, template_name="datadoc_ownership_transfer", template_params=dict( inviting_username=inviting_user.get_name(), doc_url=doc_url, data_doc_title=data_doc_title, ), session=session, )
def add_user_to_environment(uid, environment_id, commit=True, session=None): user = get_user_by_id(uid, session=session) env = get_environment_by_id(environment_id, session=session) if user and env: env.users.append(user) if commit: session.commit() else: session.flush()
def remove_user_to_environment(uid, environment_id, commit=True, session=None): user = get_user_by_id(uid, session=session) env = get_environment_by_id(environment_id, session=session) if user and env: session.query(UserEnvironment).filter_by(environment_id=environment_id, user_id=uid).delete() if commit: session.commit() else: session.flush()
def send_add_datadoc_editor_email(doc_id, uid, read, write, session=None): inviting_user = user_logic.get_user_by_id(current_user.id, session=session) invited_user = user_logic.get_user_by_id(uid, session=session) data_doc = logic.get_data_doc_by_id(doc_id, session=session) environment = data_doc.environment read_or_write = "edit" if write else "view" data_doc_title = data_doc.title or "Untitled" doc_url = f"{QuerybookSettings.PUBLIC_URL}/{environment.name}/datadoc/{doc_id}/" notify_user( user=invited_user, template_name="datadoc_invitation", template_params=dict( inviting_username=inviting_user.get_name(), read_or_write=read_or_write, doc_url=doc_url, data_doc_title=data_doc_title, ), session=session, )
def notifiy_on_execution_completion(query_execution_id, session=None): query_execution = qe_logic.get_query_execution_by_id(query_execution_id, session=session) notifications = query_execution.notifications if len(notifications): data_cell = next(iter(query_execution.cells), None) # TODO: this should be determined by the notification.user? # Come up with a more efficient way to determine env per user env_name = getattr( qe_perm_logic.get_default_user_environment_by_execution_id( execution_id=query_execution_id, uid=query_execution.uid, session=session, ), "name", None, ) # If the query execution is not associated with any environment # then no notification can be done if not env_name: return for notification in notifications: uid = notification.user user = user_logic.get_user_by_id(uid, session=session) doc_id = None cell_id = None query_title = "Untitled" if data_cell is not None: cell_id = data_cell.id doc_id = data_cell.doc.id query_title = data_cell.meta.get("title", query_title) notify_user( user=user, template_name="query_completion_notification", template_params=dict( query_execution=query_execution, doc_id=doc_id, cell_id=cell_id, query_title=query_title, public_url=QuerybookSettings.PUBLIC_URL, env_name=env_name, ), session=session, )
def send_datadoc_access_request_notification(doc_id, uid, session=None): requestor = user_logic.get_user_by_id(uid, session=session) data_doc = logic.get_data_doc_by_id(doc_id, session=session) environment = data_doc.environment data_doc_title = data_doc.title or "Untitled" doc_url = f"{QuerybookSettings.PUBLIC_URL}/{environment.name}/datadoc/{doc_id}/" owner = user_logic.get_user_by_id(data_doc.owner_uid, session=session) doc_editors = [owner] writer_uids = [ writer.uid for writer in logic.get_data_doc_writers_by_doc_id(doc_id) ] doc_editors.extend(user_logic.get_users_by_ids(writer_uids)) requestor_username = requestor.get_name() for user in doc_editors: notify_user( user=user, template_name="datadoc_access_request", template_params=dict( username=requestor_username, data_doc_title=data_doc_title, doc_url=doc_url, ), )
def send_board_access_request_notification(board_id, uid, session=None): requestor = user_logic.get_user_by_id(uid, session=session) board = Board.get(id=board_id, session=session) environment = board.environment board_url = f"{QuerybookSettings.PUBLIC_URL}/{environment.name}/list/{board_id}/" owner = user_logic.get_user_by_id(board.owner_uid, session=session) doc_editors = [owner] writer_uids = [ writer.uid for writer in logic.get_board_editors_by_board_id(board_id) ] doc_editors.extend(user_logic.get_users_by_ids(writer_uids)) requestor_username = requestor.get_name() for user in doc_editors: notify_user( user=user, template_name="board_access_request", template_params=dict( username=requestor_username, board_name=board.name, board_url=board_url, ), )
def load_user_with_api_access_token(request): token_string = request.headers.get("api-access-token") if token_string: with DBSession() as session: token_validation = get_api_access_token(token_string) if token_validation: if token_validation.enabled: user = get_user_by_id(token_validation.creator_uid, session=session) return AuthUser(user) else: flask.abort(401, description="Token is disabled.") else: flask.abort(401, description="Token is invalid.") return None
def get_client_setting_from_engine(engine, uid=None, session=None) -> Dict: """Compute the settings passed to the query engine. Both engine and user must be attached to a sqlalchemy session. Args: engine (QueryEngine): Corresponds to the DB QueryEngine uid (int, optional): Optional User id executed the query. Defaults to None. Returns: Dict: Dictionary of Kwargs send to the query engine client """ executor_params = {**engine.get_engine_params()} if uid is not None: user = user_logic.get_user_by_id(uid, session=session) proxy_user = user.username if executor_params.get("proxy_user_id", "") != "": proxy_user = user.to_dict()[executor_params["proxy_user_id"]] executor_params["proxy_user"] = proxy_user return executor_params
def get_credentials(self, uid): user = get_user_by_id(uid) if not (user and "gspread_token" in user.properties): raise UserTokenNotFound() token = user.properties["gspread_token"] client_config = _google_flow.client_config credentials = Credentials( token["access_token"], refresh_token=token.get("refresh_token"), id_token=token.get("id_token"), token_uri=client_config.get("token_uri"), client_id=client_config.get("client_id"), client_secret=client_config.get("client_secret"), scopes=SCOPES, ) credentials.expiry = datetime.datetime.utcfromtimestamp(token["expires_at"]) return credentials
def __call__( self, query: str, engine_id: int, uid: int = None, session=None, ): """Start the query execution progress. If async then it just sets up the necessary variables, if sync then actually execute the query Args: query (str): Query getting executed engine_id (int): The id of the engine uid (int, optional): User id for proxy user. Defaults to None. session (SqlAlchemySession, optional): for querying database Returns: Any[][]: Returns the result if sync, otherwise None """ engine = get_query_engine_by_id(engine_id, session=session) client_settings = { **engine.get_engine_params(), } if uid: user = get_user_by_id(uid, session=session) client_settings["proxy_user"] = user.username executor = get_executor_class(engine.language, engine.executor) if executor.SINGLE_QUERY_QUERY_ENGINE(): statements = [query] else: statements = get_statements(query) if len(statements) == 0: return None # Empty statement, return None cursor = executor._get_client(client_settings).cursor() if self._async: self._async_run(cursor, statements) return None else: return self._sync_run(cursor, statements)
def _get_executor_params_and_engine(query_execution_id, celery_task, session=None): query, statement_ranges, uid, engine_id = _get_query_execution_info( query_execution_id, session=session) user = user_logic.get_user_by_id(uid, session=session) engine = admin_logic.get_query_engine_by_id(engine_id, session=session) if engine.deleted_at is not None: raise ArchivedQueryEngine("This query engine is disabled.") return ( { "query_execution_id": query_execution_id, "celery_task": celery_task, "query": query, "statement_ranges": statement_ranges, "client_setting": { **engine.get_engine_params(), "proxy_user": user.email, }, }, engine, )
def test_get_user_by_id(self): user = User('testname', 'P@ssw0rd') db.session.add(user) db.session.commit() self.assertEqual(user, get_user_by_id(1))