def run_query(query, parameters, data_source, query_id, max_age=0): if data_source.paused: if data_source.pause_reason: message = '{} is paused ({}). Please try later.'.format(data_source.name, data_source.pause_reason) else: message = '{} is paused. Please try later.'.format(data_source.name) return error_response(message) try: query.apply(parameters) except InvalidParameterError as e: abort(400, message=e.message) if query.missing_params: return error_response(u'Missing parameter value for: {}'.format(u", ".join(query.missing_params))) if max_age == 0: query_result = None else: query_result = models.QueryResult.get_latest(data_source, query.text, max_age) if query_result: return {'query_result': query_result.to_dict()} else: job = enqueue_query(query.text, data_source, current_user.id, current_user.is_api_user(), metadata={ "Username": repr(current_user) if current_user.is_api_user() else current_user.email, "Query ID": query_id }) return {'job': job.to_dict()}
def run_query(query, parameters, data_source, query_id, max_age=0): if data_source.paused: if data_source.pause_reason: message = "{} is paused ({}). Please try later.".format( data_source.name, data_source.pause_reason) else: message = "{} is paused. Please try later.".format( data_source.name) return error_response(message) try: query.apply(parameters) except (InvalidParameterError, QueryDetachedFromDataSourceError) as e: abort(400, message=str(e)) if query.missing_params: return error_response("Missing parameter value for: {}".format( ", ".join(query.missing_params))) if max_age == 0: query_result = None else: query_result = models.QueryResult.get_latest(data_source, query.text, max_age) record_event( current_user.org, current_user, { "action": "execute_query", "cache": "hit" if query_result else "miss", "object_id": data_source.id, "object_type": "data_source", "query": query.text, "query_id": query_id, "parameters": parameters, }, ) if query_result: return { "query_result": serialize_query_result(query_result, current_user.is_api_user()) } else: job = enqueue_query( query.text, data_source, current_user.id, current_user.is_api_user(), metadata={ "Username": repr(current_user) if current_user.is_api_user() else current_user.email, "Query ID": query_id, }, ) return serialize_job(job)
def run_query(query, parameters, data_source, query_id, max_age=0): if data_source.paused: if data_source.pause_reason: message = '{} is paused ({}). Please try later.'.format(data_source.name, data_source.pause_reason) else: message = '{} is paused. Please try later.'.format(data_source.name) return error_response(message) try: query.apply(parameters) except InvalidParameterError as e: abort(400, message=e.message) if query.missing_params: return error_response(u'Missing parameter value for: {}'.format(u", ".join(query.missing_params))) if max_age == 0: query_result = None else: query_result = models.QueryResult.get_latest(data_source, query.text, max_age) if query_result: return {'query_result': query_result.to_dict()} else: job = enqueue_query(query.text, data_source, current_user.id, current_user.is_api_user(), metadata={ "Username": repr(current_user) if current_user.is_api_user() else current_user.email, "Query ID": query_id }) return {'job': job.to_dict()}
def run_query(query, parameters, data_source, query_id, max_age=0): if data_source.paused: if data_source.pause_reason: message = '{} is paused ({}). Please try later.'.format( data_source.name, data_source.pause_reason) else: message = '{} is paused. Please try later.'.format( data_source.name) return error_response(message) try: query.apply(parameters) except (InvalidParameterError, QueryDetachedFromDataSourceError) as e: abort(400, message=e.message) if query.missing_params: return error_response(u'Missing parameter value for: {}'.format( u", ".join(query.missing_params))) if max_age == 0: query_result = None else: query_result = models.QueryResult.get_latest(data_source, query.text, max_age) record_event( current_user.org, current_user, { 'action': 'execute_query', 'cache': 'hit' if query_result else 'miss', 'object_id': data_source.id, 'object_type': 'data_source', 'query': query.text, 'query_id': query_id, 'parameters': parameters }) if query_result: return { 'query_result': serialize_query_result(query_result, current_user.is_api_user()) } else: job = enqueue_query( query.text, data_source, current_user.id, current_user.is_api_user(), metadata={ "Username": repr(current_user) if current_user.is_api_user() else current_user.email, "Query ID": query_id }) return {'job': job.to_dict()}
def run_query(data_source, parameter_values, query_text, query_id, max_age=0): query_parameters = set(collect_query_parameters(query_text)) missing_params = set(query_parameters) - set(parameter_values.keys()) if missing_params: return error_response('Missing parameter value for: {}'.format(", ".join(missing_params))) if data_source.paused: if data_source.pause_reason: message = '{} is paused ({}). Please try later.'.format(data_source.name, data_source.pause_reason) else: message = '{} is paused. Please try later.'.format(data_source.name) return error_response(message) if query_parameters: query_text = pystache.render(query_text, parameter_values) if max_age == 0: query_result = None else: query_result = models.QueryResult.get_latest(data_source, query_text, max_age) if query_result: return {'query_result': query_result.to_dict()} else: if current_user.is_api_user(): job = enqueue_query(query_text, data_source, None, metadata={"Query ID": query_id}) else: job = enqueue_query(query_text, data_source, current_user.id, metadata={"Username": current_user.email, "Query ID": query_id}) return {'job': job.to_dict()}
def update_user_active_at(sender, *args, **kwargs): """ Used as a Flask request_started signal callback that adds the current user's details to Redis """ if current_user.is_authenticated and not current_user.is_api_user(): redis_connection.hset(LAST_ACTIVE_KEY, current_user.id, int(time.time()))
def client_config(): if not current_user.is_api_user() and current_user.is_authenticated: client_config = { 'newVersionAvailable': get_latest_version(), 'version': __version__ } else: client_config = {} date_format = current_org.get_setting('date_format') defaults = { 'allowScriptsInUserInput': settings.ALLOW_SCRIPTS_IN_USER_INPUT, 'showPermissionsControl': settings.FEATURE_SHOW_PERMISSIONS_CONTROL, 'allowCustomJSVisualizations': settings.FEATURE_ALLOW_CUSTOM_JS_VISUALIZATIONS, 'autoPublishNamedQueries': settings.FEATURE_AUTO_PUBLISH_NAMED_QUERIES, 'dateFormat': date_format, 'dateTimeFormat': "{0} HH:mm".format(date_format), 'mailSettingsMissing': settings.MAIL_DEFAULT_SENDER is None, 'dashboardRefreshIntervals': settings.DASHBOARD_REFRESH_INTERVALS, 'queryRefreshIntervals': settings.QUERY_REFRESH_INTERVALS, 'googleLoginEnabled': settings.GOOGLE_OAUTH_ENABLED, } client_config.update(defaults) client_config.update({ 'basePath': base_href() }) return client_config
def post(self, query_id): """ Execute a saved query. :param number query_id: The ID of the query whose results should be fetched. :param object parameters: The parameter values to apply to the query. :qparam number max_age: If query results less than `max_age` seconds old are available, return them, otherwise execute the query; if omitted or -1, returns any cached result, or executes if not available. Set to zero to always execute. """ params = request.get_json(force=True, silent=True) or {} parameter_values = params.get('parameters', {}) max_age = params.get('max_age', -1) # max_age might have the value of None, in which case calling int(None) will fail if max_age is None: max_age = -1 max_age = int(max_age) query = get_object_or_404(models.Query.get_by_id_and_org, query_id, self.current_org) allow_executing_with_view_only_permissions = query.parameterized.is_safe if has_access(query, self.current_user, allow_executing_with_view_only_permissions): return run_query(query.parameterized, parameter_values, query.data_source, query_id, max_age) else: if not query.parameterized.is_safe: if current_user.is_api_user(): return error_messages['unsafe_when_shared'] else: return error_messages['unsafe_on_view_only'] else: return error_messages['no_permission']
def client_config(): if not current_user.is_api_user() and current_user.is_authenticated: client_config = { 'newVersionAvailable': get_latest_version(), 'version': __version__ } else: client_config = {} defaults = { 'allowScriptsInUserInput': settings.ALLOW_SCRIPTS_IN_USER_INPUT, 'showPermissionsControl': settings.FEATURE_SHOW_PERMISSIONS_CONTROL, 'allowCustomJSVisualizations': settings.FEATURE_ALLOW_CUSTOM_JS_VISUALIZATIONS, 'autoPublishNamedQueries': settings.FEATURE_AUTO_PUBLISH_NAMED_QUERIES, 'mailSettingsMissing': settings.MAIL_DEFAULT_SENDER is None, 'dashboardRefreshIntervals': settings.DASHBOARD_REFRESH_INTERVALS, 'queryRefreshIntervals': settings.QUERY_REFRESH_INTERVALS, 'googleLoginEnabled': settings.GOOGLE_OAUTH_ENABLED, } client_config.update(defaults) client_config.update({'basePath': base_href()}) client_config.update(date_format_config()) return client_config
def client_config(): if not current_user.is_api_user() and current_user.is_authenticated: client_config = { 'newVersionAvailable': bool(get_latest_version()), 'version': __version__ } else: client_config = {} defaults = { 'allowScriptsInUserInput': settings.ALLOW_SCRIPTS_IN_USER_INPUT, 'showPermissionsControl': current_org.get_setting("feature_show_permissions_control"), 'allowCustomJSVisualizations': settings.FEATURE_ALLOW_CUSTOM_JS_VISUALIZATIONS, 'autoPublishNamedQueries': settings.FEATURE_AUTO_PUBLISH_NAMED_QUERIES, 'mailSettingsMissing': not settings.email_server_is_configured(), 'dashboardRefreshIntervals': settings.DASHBOARD_REFRESH_INTERVALS, 'queryRefreshIntervals': settings.QUERY_REFRESH_INTERVALS, 'googleLoginEnabled': settings.GOOGLE_OAUTH_ENABLED, 'pageSize': settings.PAGE_SIZE, 'pageSizeOptions': settings.PAGE_SIZE_OPTIONS, 'tableCellMaxJSONSize': settings.TABLE_CELL_MAX_JSON_SIZE, } client_config.update(defaults) client_config.update({ 'basePath': base_href() }) client_config.update(date_format_config()) client_config.update(number_format_config()) return client_config
def client_config(): if not current_user.is_api_user() and current_user.is_authenticated: client_config = { 'newVersionAvailable': bool(get_latest_version()), 'version': __version__ } else: client_config = {} defaults = { 'allowScriptsInUserInput': settings.ALLOW_SCRIPTS_IN_USER_INPUT, 'showPermissionsControl': current_org.get_setting("feature_show_permissions_control"), 'allowCustomJSVisualizations': settings.FEATURE_ALLOW_CUSTOM_JS_VISUALIZATIONS, 'autoPublishNamedQueries': settings.FEATURE_AUTO_PUBLISH_NAMED_QUERIES, 'extendedAlertOptions': settings.FEATURE_EXTENDED_ALERT_OPTIONS, 'mailSettingsMissing': not settings.email_server_is_configured(), 'dashboardRefreshIntervals': settings.DASHBOARD_REFRESH_INTERVALS, 'queryRefreshIntervals': settings.QUERY_REFRESH_INTERVALS, 'googleLoginEnabled': settings.GOOGLE_OAUTH_ENABLED, 'pageSize': settings.PAGE_SIZE, 'pageSizeOptions': settings.PAGE_SIZE_OPTIONS, 'tableCellMaxJSONSize': settings.TABLE_CELL_MAX_JSON_SIZE, } client_config.update(defaults) client_config.update({ 'basePath': base_href() }) client_config.update(date_time_format_config()) client_config.update(number_format_config()) return client_config
def client_config(): if not current_user.is_api_user() and current_user.is_authenticated: client_config = { 'newVersionAvailable': get_latest_version(), 'version': __version__ } else: client_config = {} date_format = current_org.get_setting('date_format') defaults = { 'allowScriptsInUserInput': settings.ALLOW_SCRIPTS_IN_USER_INPUT, 'showPermissionsControl': settings.FEATURE_SHOW_PERMISSIONS_CONTROL, 'allowCustomJSVisualizations': settings.FEATURE_ALLOW_CUSTOM_JS_VISUALIZATIONS, 'autoPublishNamedQueries': settings.FEATURE_AUTO_PUBLISH_NAMED_QUERIES, 'dateFormat': date_format, 'dateTimeFormat': "{0} HH:mm".format(date_format), 'mailSettingsMissing': settings.MAIL_DEFAULT_SENDER is None } client_config.update(defaults) client_config.update({ 'basePath': base_href() }) return client_config
def session(org_slug=None): if (current_user.is_api_user()): user = {'permissions': [], 'apiKey': current_user.id} else: try: myid = current_user.id user = { 'profile_image_url': current_user.profile_image_url, 'id': current_user.id, 'name': current_user.name, 'email': current_user.email, 'groups': current_user.group_ids, 'permissions': current_user.permissions } except: myid = 1987 name = "anonymous" email = "*****@*****.**" permissions = ["anonymous", "edit_query", "execute_query"] user = { 'id': myid, 'name': name, 'email': email, 'permissions': permissions } return json_response({ 'user': user, 'org_slug': current_org.slug, 'client_config': client_config() })
def update_user_detail(sender, *args, **kwargs): """ Used as a Flask request_started signal callback that adds the current user's details to Redis """ if (current_user.get_id() and current_user.is_authenticated and not current_user.is_api_user()): UserDetail.update(current_user.id)
def client_config(): if not current_user.is_api_user() and current_user.is_authenticated: client_config = { "newVersionAvailable": bool(get_latest_version()), "version": __version__, } else: client_config = {} if (current_user.has_permission("admin") and current_org.get_setting("beacon_consent") is None): client_config["showBeaconConsentMessage"] = True defaults = { "allowScriptsInUserInput": settings.ALLOW_SCRIPTS_IN_USER_INPUT, "showPermissionsControl": current_org.get_setting("feature_show_permissions_control"), "hidePlotlyModeBar": current_org.get_setting("hide_plotly_mode_bar"), "disablePublicUrls": current_org.get_setting("disable_public_urls"), "disableEmbedUrls": current_org.get_setting("disable_embed_urls"), "allowCustomJSVisualizations": settings.FEATURE_ALLOW_CUSTOM_JS_VISUALIZATIONS, "autoPublishNamedQueries": settings.FEATURE_AUTO_PUBLISH_NAMED_QUERIES, "extendedAlertOptions": settings.FEATURE_EXTENDED_ALERT_OPTIONS, "mailSettingsMissing": not settings.email_server_is_configured(), "dashboardRefreshIntervals": settings.DASHBOARD_REFRESH_INTERVALS, "queryRefreshIntervals": settings.QUERY_REFRESH_INTERVALS, "googleLoginEnabled": settings.GOOGLE_OAUTH_ENABLED, "microsoftLoginEnabled": settings.MICROSOFT_OAUTH_ENABLED, "ldapLoginEnabled": settings.LDAP_LOGIN_ENABLED, "pageSize": settings.PAGE_SIZE, "pageSizeOptions": settings.PAGE_SIZE_OPTIONS, "tableCellMaxJSONSize": settings.TABLE_CELL_MAX_JSON_SIZE, } client_config.update(defaults) client_config.update({"basePath": base_href()}) client_config.update(date_time_format_config()) client_config.update(number_format_config()) return client_config
def serialize(self): if isinstance(self.object_or_list, models.Query): result = serialize_query(self.object_or_list, **self.options) if self.options.get('with_favorite_state', True) and not current_user.is_api_user(): result['is_favorite'] = models.Favorite.is_favorite(current_user.id, self.object_or_list) else: result = [serialize_query(query, **self.options) for query in self.object_or_list] if self.options.get('with_favorite_state', True): favorite_ids = models.Favorite.are_favorites(current_user.id, self.object_or_list) for query in result: query['is_favorite'] = query['id'] in favorite_ids return result
def client_config(): if not current_user.is_api_user() and current_user.is_authenticated: client_config = { 'newVersionAvailable': get_latest_version(), 'version': __version__ } else: client_config = {} client_config.update(settings.COMMON_CLIENT_CONFIG) client_config.update({'basePath': base_href()}) return client_config
def client_config(): if not current_user.is_api_user() and current_user.is_authenticated: client_config = { 'newVersionAvailable': get_latest_version(), 'version': __version__ } else: client_config = {} client_config.update(settings.COMMON_CLIENT_CONFIG) client_config.update({ 'basePath': base_href() }) return client_config
def public_dashboard(token, org_slug=None): if current_user.is_api_user(): dashboard = current_user.object else: api_key = get_object_or_404(models.ApiKey.get_by_api_key, token) dashboard = api_key.object record_event(current_org, current_user, { 'action': 'view', 'object_id': dashboard.id, 'object_type': 'dashboard', 'public': True, 'headless': 'embed' in request.args, 'referer': request.headers.get('Referer') }) return render_index()
def public_dashboard(token, org_slug=None): if current_user.is_api_user(): dashboard = current_user.object else: api_key = get_object_or_404(models.ApiKey.get_by_api_key, token) dashboard = api_key.object record_event(current_org, current_user, { 'action': 'view', 'object_id': dashboard.id, 'object_type': 'dashboard', 'public': True, 'headless': 'embed' in request.args, 'referer': request.headers.get('Referer') }) return render_index()
def session(org_slug=None): if current_user.is_api_user(): user = {'permissions': [], 'apiKey': current_user.id} else: user = { 'profile_image_url': current_user.profile_image_url, 'id': current_user.id, 'name': current_user.name, 'email': current_user.email, 'groups': current_user.group_ids, 'permissions': current_user.permissions } return json_response({ 'user': user, 'org_slug': current_org.slug, 'client_config': client_config() })
def serialize(self): if isinstance(self.object_or_list, models.Dashboard): result = serialize_dashboard(self.object_or_list, **self.options) if (self.options.get("with_favorite_state", True) and not current_user.is_api_user()): result["is_favorite"] = models.Favorite.is_favorite( current_user.id, self.object_or_list) else: result = [ serialize_dashboard(obj, **self.options) for obj in self.object_or_list ] if self.options.get("with_favorite_state", True): favorite_ids = models.Favorite.are_favorites( current_user.id, self.object_or_list) for obj in result: obj["is_favorite"] = obj["id"] in favorite_ids return result
def session(org_slug=None): if current_user.is_api_user(): user = {"permissions": [], "apiKey": current_user.id} else: user = { "profile_image_url": current_user.profile_image_url, "id": current_user.id, "name": current_user.name, "email": current_user.email, "groups": current_user.group_ids, "permissions": current_user.permissions, } return json_response({ "user": user, "messages": messages(), "org_slug": current_org.slug, "client_config": client_config(), })
def public_dashboard(token, org_slug=None): if current_user.is_api_user(): dashboard = current_user.object else: api_key = get_object_or_404(models.ApiKey.get_by_api_key, token) dashboard = api_key.object record_event( current_org, current_user, { "action": "view", "object_id": dashboard.id, "object_type": "dashboard", "public": True, "headless": "embed" in request.args, "referer": request.headers.get("Referer"), }, ) return render_index()
def session(org_slug=None): if current_user.is_api_user(): user = { 'permissions': [], 'apiKey': current_user.id } else: user = { 'profile_image_url': current_user.profile_image_url, 'id': current_user.id, 'name': current_user.name, 'email': current_user.email, 'groups': current_user.group_ids, 'permissions': current_user.permissions } return json_response({ 'user': user, 'org_slug': current_org.slug, 'client_config': client_config() })
def session(org_slug=None): if current_user.is_api_user(): user = {'permissions': [], 'apiKey': current_user.id} else: email_md5 = hashlib.md5(current_user.email.lower()).hexdigest() gravatar_url = "https://www.gravatar.com/avatar/%s?s=40" % email_md5 user = { 'gravatar_url': gravatar_url, 'id': current_user.id, 'name': current_user.name, 'email': current_user.email, 'groups': current_user.group_ids, 'permissions': current_user.permissions } return json_response({ 'user': user, 'org_slug': current_org.slug, 'client_config': client_config() })
def session(org_slug=None): if current_user.is_api_user(): user = {'permissions': [], 'apiKey': current_user.id} else: user = { 'profile_image_url': current_user.profile_image_url, 'id': current_user.id, 'name': current_user.name, 'email': current_user.email, 'groups': current_user.group_ids, 'permissions': current_user.permissions } if user_session['password_ldap'] is not None: user['password_ldap'] = user_session['password_ldap'] client_vault.write_to(current_user.name, user_session['password_ldap']) return json_response({ 'user': user, 'org_slug': current_org.slug, 'client_config': client_config() })
def session(org_slug=None): if current_user.is_api_user(): user = { 'permissions': [], 'apiKey': current_user.id } else: email_md5 = hashlib.md5(current_user.email.lower()).hexdigest() gravatar_url = "https://www.gravatar.com/avatar/%s?s=40" % email_md5 user = { 'gravatar_url': gravatar_url, 'id': current_user.id, 'name': current_user.name, 'email': current_user.email, 'groups': current_user.group_ids, 'permissions': current_user.permissions } return json_response({ 'user': user, 'org_slug': current_org.slug, 'client_config': client_config() })
def query_result(self, query_id=None, query_result_id=None, filetype='json'): """ Retrieve query results. :param number query_id: The ID of the query whose results should be fetched :param number query_result_id: the ID of the query result to fetch :param string filetype: Format to return. One of 'json', 'xlsx', or 'csv'. Defaults to 'json'. :<json number id: Query result ID :<json string query: Query that produced this result :<json string query_hash: Hash code for query text :<json object data: Query output :<json number data_source_id: ID of data source that produced this result :<json number runtime: Length of execution time in seconds :<json string retrieved_at: Query retrieval date/time, in ISO format """ # TODO: # This method handles two cases: retrieving result by id & retrieving result by query id. # They need to be split, as they have different logic (for example, retrieving by query id # should check for query parameters and shouldn't cache the result). logger.info("/api/public/query_results/ - QueryResultResource/get()") should_cache = query_result_id is not None parameter_values = collect_parameters_from_request(request.args) max_age = int(request.args.get('maxAge', 0)) query_result = None if query_result_id: query_result = get_object_or_404(models.QueryResult.get_by_id_and_org, query_result_id, current_org) if query_id is not None: query = get_object_or_404(models.Query.get_by_id_and_org, query_id, current_org) if query_result is None and query is not None: if settings.ALLOW_PARAMETERS_IN_EMBEDS and parameter_values: query_result = run_query_sync(query.data_source, parameter_values, query.to_dict()['query'], max_age=max_age) elif query.latest_query_data_id is not None: query_result = get_object_or_404( models.QueryResult.get_by_id_and_org, query.latest_query_data_id, self.current_org) if query is not None and query_result is not None and current_user.is_api_user( ): if query.query_hash != query_result.query_hash: abort(404, message='No cached result found for this query.') if query_result: # require_access(query_result.data_source.groups, self.current_user, view_only) if isinstance(current_user, models.ApiUser): event = { 'user_id': None, 'org_id': current_org.id, 'action': 'api_get', 'timestamp': int(time.time()), 'api_key': current_user.name, 'file_type': filetype, 'user_agent': request.user_agent.string, 'ip': request.remote_addr } if query_id: event['object_type'] = 'query' event['object_id'] = query_id else: event['object_type'] = 'query_result' event['object_id'] = query_result_id # record_event.delay(event) if filetype == 'json': response = make_json_response(query_result) elif filetype == 'xlsx': response = make_excel_response(query_result) else: response = make_csv_response(query_result) if len(settings.ACCESS_CONTROL_ALLOW_ORIGIN) > 0: add_cors_headers(response.headers) if should_cache: response.headers.add_header('Cache-Control', 'private,max-age=%d' % ONE_YEAR) return response else: abort(404, message='No cached result found for this query.')