def before_cursor_execute(conn, cursor, statement, parameters, context, executemany): if not g.get('req_start_sent'): g.req_start_sent = True logger.debug('Request started', extra={'sql_log_type': 'start_request', 'req_verb': request.method if has_request_context() else None, 'req_path': request.path if has_request_context() else None, 'req_url': request.url if has_request_context() else None}) context._query_start_time = time.time() source_line = _get_sql_line() if source_line: log_msg = 'Start Query:\n {0[file]}:{0[line]} {0[function]}\n\n{1}\n{2}'.format( source_line, _prettify_sql(statement), _prettify_params(parameters) if parameters else '' ).rstrip() else: # UPDATEs can't be traced back to their source since they are executed only on flush log_msg = 'Start Query:\n{0}\n{1}'.format( _prettify_sql(statement), _prettify_params(parameters) if parameters else '' ).rstrip() # psycopg2._psycopg.Binary objects are extremely weird and don't work in isinstance checks if hasattr(parameters, 'iteritems'): parameters = {k: _fix_param(v) for k, v in parameters.iteritems()} else: parameters = tuple(_fix_param(v) for v in parameters) logger.debug(log_msg, extra={'sql_log_type': 'start', 'req_path': request.path if has_request_context() else None, 'sql_source': source_line['items'] if source_line else None, 'sql_statement': statement, 'sql_verb': statement.split()[0], 'sql_params': parameters})
def share_on_facebook(): from .twitter import collect_images if request.method == "GET": post = Post.load_by_id(request.args.get("id")) message, link, name, picture = guess_content(post) imgs = [urljoin(get_settings().site_url, img) for img in collect_images(post)] albums = [] if imgs: current_app.logger.debug("fetching user albums") resp = requests.get( "https://graph.facebook.com/v2.2/me/albums", params={"access_token": get_settings().facebook_access_token}, ) resp.raise_for_status() current_app.logger.debug("user albums response %s: %s", resp, resp.text) albums = resp.json().get("data", []) return render_template( "admin/share_on_facebook.jinja2", post=post, preview=message, link=link, name=name, picture=picture, imgs=imgs, albums=albums, ) try: post_id = request.form.get("post_id") preview = request.form.get("preview") img_url = request.form.get("img") is_photo = request.form.get("post_type") == "photo" album_id = request.form.get("album") link = request.form.get("link") if album_id == "new": album_id = create_album(request.form.get("new_album_name"), request.form.get("new_album_message")) post = Post.load_by_id(post_id) facebook_url = handle_new_or_edit( post, message=preview, link=link, name=None, picture=img_url, is_photo=is_photo, album_id=album_id ) db.session.commit() if has_request_context(): flash( 'Shared on Facebook: <a href="{}">Original</a>, ' '<a href="{}">On Facebook</a><br/>'.format(post.permalink, facebook_url) ) return redirect(post.permalink) except Exception as e: if has_request_context(): current_app.logger.exception("posting to facebook") flash("Share on Facebook Failed! Exception: {}".format(e)) return redirect(url_for("views.index"))
def decorator(*args, **kwargs): from pony.orm import db_session from pony.orm.core import local from flask import after_this_request, current_app, has_app_context, \ has_request_context from flask.signals import appcontext_popped register = local.db_context_counter == 0 if register and (has_app_context() or has_request_context()): db_session.__enter__() result = f(*args, **kwargs) if register: if has_request_context(): @after_this_request def pop(request): db_session.__exit__() return request elif has_app_context(): @appcontext_popped.connect_via( current_app._get_current_object() ) def pop(sender, *args, **kwargs): while local.db_context_counter: db_session.__exit__() else: raise RuntimeError('Needs app or request context') return result
def configure_app(app): log_msg_format = app.config['API_LOG_MSG_FORMAT'] log_date_format = app.config['API_LOG_DATE_FORMAT'] sqla_logger = logging.getLogger('sqlalchemy') pool_logger = logging.getLogger('sqlalchemy.pool') # Set the message formatter for the default log handler current_handlers = app.logger.handlers default_handler = current_handlers[0] if current_handlers else None if default_handler: # A newline is included before the log message to visually separate them better default_handler.setFormatter(logging.Formatter("\n" + log_msg_format, datefmt=log_date_format)) pool_logger.addHandler(default_handler) # Setup the log handlers if not testing if not app.testing: # Rotating file handler file_handler = handlers.RotatingFileHandler( app.config['API_LOG_FILE_PATH'], mode='a', maxBytes=1 * 1024 * 1024, backupCount=10) file_handler.setLevel(logging.INFO) file_handler.setFormatter(logging.Formatter(log_msg_format, datefmt=log_date_format)) # Add handlers to loggers loggers = [app.logger, sqla_logger] for logger in loggers: logger.addHandler(file_handler) # Set the log level if 'LOG_LEVEL' in app.config: # Log at the level specified in the app config app.logger.setLevel(app.config['LOG_LEVEL']) else: # Log at the DEBUG level when testing/debugging, otherwise log INFO and above if app.debug or app.testing: app.logger.setLevel(logging.DEBUG) else: app.logger.setLevel(logging.INFO) # Configure connection pool debug logging if app.config.get('POOL_DEBUG_LOGGING'): pool_logger.setLevel(logging.DEBUG) # Include this extra information in all log messages (lambda functions get executed at log time) if app.config.get('API_LOG_VERBOSE_DEV_MESSAGES', False): extra_info = lu.ExtraInfo() extra_info['ip'] = lambda: has_request_context() and ah.get_remote_addr() or None extra_info['uid'] = lambda: str(g.user.id).upper() if hasattr(g, 'user') and g.user.id else None extra_info['ua'] = lambda: has_request_context() and ah.get_user_agent_summary() or None extra_info['url'] = lambda: has_request_context() and request.url or None app._logger = lu.ExtraInfoLogger(app.logger, extra_info) # Connect the exception logging functions to the `got_request_exception` signal got_request_exception.connect(lu.log_api_exception, app) got_request_exception.connect(lu.log_api_exception_to_browser_console, app)
def test_context_test(app): assert not flask.request assert not flask.has_request_context() ctx = app.test_request_context() ctx.push() try: assert flask.request assert flask.has_request_context() finally: ctx.pop()
def share_on_facebook(): from .twitter import collect_images if request.method == 'GET': post = Post.load_by_id(request.args.get('id')) message, link, name, picture = guess_content(post) imgs = [urllib.parse.urljoin(get_settings().site_url, img) for img in collect_images(post)] albums = [] if imgs: current_app.logger.debug('fetching user albums') resp = requests.get( 'https://graph.facebook.com/v2.2/me/albums', params={'access_token': get_settings().facebook_access_token}) resp.raise_for_status() current_app.logger.debug( 'user albums response %s: %s', resp, resp.text) albums = resp.json().get('data', []) return render_template('admin/share_on_facebook.jinja2', post=post, preview=message, link=link, name=name, picture=picture, imgs=imgs, albums=albums) try: post_id = request.form.get('post_id') preview = request.form.get('preview') img_url = request.form.get('img') is_photo = request.form.get('post_type') == 'photo' album_id = request.form.get('album') link = request.form.get('link') if album_id == 'new': album_id = create_album( request.form.get('new_album_name'), request.form.get('new_album_message')) post = Post.load_by_id(post_id) facebook_url = handle_new_or_edit( post, message=preview, link=link, name=None, picture=img_url, is_photo=is_photo, album_id=album_id) db.session.commit() if has_request_context(): flash('Shared on Facebook: <a href="{}">Original</a>, ' '<a href="{}">On Facebook</a><br/>' .format(post.permalink, facebook_url)) return redirect(post.permalink) except Exception as e: if has_request_context(): current_app.logger.exception('posting to facebook') flash('Share on Facebook Failed! Exception: {}'.format(e)) return redirect(url_for('views.index'))
def on_request_tearing_down(sender, **kwargs): query_count = g.get('sql_query_count', 0) if not query_count: return duration = (time.time() - g.req_start_ts) if 'req_start_ts' in g else 0 logger.debug('Request finished', extra={'sql_log_type': 'end_request', 'sql_query_count': query_count, 'req_verb': request.method if has_request_context() else None, 'req_url': request.url if has_request_context() else None, 'req_path': request.path if has_request_context() else None, 'req_duration': duration})
def test_context_test(): app = flask.Flask(__name__) assert not flask.request assert not flask.has_request_context() ctx = app.test_request_context() ctx.push() try: assert flask.request assert flask.has_request_context() finally: ctx.pop()
def test_context_test(self): app = flask.Flask(__name__) self.assert_(not flask.request) self.assert_(not flask.has_request_context()) ctx = app.test_request_context() ctx.push() try: self.assert_(flask.request) self.assert_(flask.has_request_context()) finally: ctx.pop()
def share_on_facebook(): from .twitter import collect_images if request.method == 'GET': post = Post.load_by_id(request.args.get('id')) preview = post.title + '\n\n' if post.title else '' preview += format_markdown_as_facebook(post.content) imgs = [urllib.parse.urljoin(get_settings().site_url, img) for img in collect_images(post)] albums = [] if imgs: app.logger.debug('fetching user albums') resp = requests.get( 'https://graph.facebook.com/v2.0/me/albums', params={'access_token': get_settings().facebook_access_token}) resp.raise_for_status() app.logger.debug('user albums response %s: %s', resp, resp.text) albums = resp.json().get('data', []) return render_template('share_on_facebook.html', post=post, preview=preview, imgs=imgs, albums=albums) try: post_id = request.form.get('post_id') preview = request.form.get('preview') img_url = request.form.get('img') post_type = request.form.get('post_type') album_id = request.form.get('album') if album_id == 'new': album_id = create_album( request.form.get('new_album_name'), request.form.get('new_album_message')) post = Post.load_by_id(post_id) facebook_url = handle_new_or_edit(post, preview, img_url, post_type, album_id) db.session.commit() if has_request_context(): flash('Shared on Facebook: <a href="{}">Original</a>, ' '<a href="{}">On Facebook</a><br/>' .format(post.permalink, facebook_url)) return redirect(post.permalink) except Exception as e: if has_request_context(): app.logger.exception('posting to facebook') flash('Share on Facebook Failed! Exception: {}'.format(e)) return redirect(url_for('index'))
def on_tearing_down(sender, **kwargs): if g.get('req_end_sent'): return g.req_end_sent = True stats = get_request_stats() if not stats['query_count']: return logger.debug('Request finished', extra={'sql_log_type': 'end_request', 'sql_query_count': stats['query_count'], 'repl': app.config.get('REPL'), 'req_verb': request.method if has_request_context() else None, 'req_url': request.url if has_request_context() else None, 'req_path': request.path if has_request_context() else None, 'req_duration': stats['req_duration'], 'req_query_duration': stats['query_duration']})
def get_allowed_sender_emails(self, include_current_user=True, include_creator=True, include_managers=True, include_support=True, include_chairs=True, extra=None): """ Return the emails of people who can be used as senders (or rather Reply-to contacts) in emails sent from within an event. :param include_current_user: Whether to include the email of the currently logged-in user :param include_creator: Whether to include the email of the event creator :param include_managers: Whether to include the email of all event managers :param include_support: Whether to include the "event support" email :param include_chairs: Whether to include the emails of event chairpersons (or lecture speakers) :param extra: An email address that is always included, even if it is not in any of the included lists. :return: An OrderedDict mapping emails to pretty names """ emails = {} # Support if include_support: support = self.as_legacy.getSupportInfo() emails[support.getEmail()] = support.getCaption() or support.getEmail() # Current user if include_current_user and has_request_context() and session.user: emails[session.user.email] = session.user.full_name # Creator if include_creator: emails[self.creator.email] = self.creator.full_name # Managers if include_managers: emails.update((p.principal.email, p.principal.full_name) for p in self.acl_entries if p.type == PrincipalType.user and p.full_access) # Chairs if include_chairs: emails.update((pl.email, pl.full_name) for pl in self.person_links if pl.email) # Extra email (e.g. the current value in an object from the DB) if extra: emails.setdefault(extra, extra) # Sanitize and format emails emails = {to_unicode(email.strip().lower()): '{} <{}>'.format(to_unicode(name), to_unicode(email)) for email, name in emails.iteritems() if email and email.strip()} own_email = session.user.email if has_request_context() and session.user else None return OrderedDict(sorted(emails.items(), key=lambda x: (x[0] != own_email, x[1].lower())))
def translator(data): # Replace refs when we are in request context. context = dict(replace_refs=has_request_context()) # DOI validation context if request and request.view_args.get('pid_value'): managed_prefix = current_app.config['PIDSTORE_DATACITE_DOI_PREFIX'] _, record = request.view_args.get('pid_value').data context['recid'] = record['recid'] if record.has_minted_doi() or record.get('conceptdoi'): context['required_doi'] = record['doi'] elif not record.is_published(): context['allowed_dois'] = [doi_generator(record['recid'])] else: # Ensure we cannot change to e.g. empty string. context['doi_required'] = True context['managed_prefixes'] = [managed_prefix] context['banned_prefixes'] = \ ['10.5072'] if managed_prefix != '10.5072' else [] # Extra context context.update(kwargs) # Load data result = schema_class(context=context).load(data) if result.errors: raise MarshmallowErrors(result.errors) return result.data
def get_request_info(hide_passwords=True): """Gets various information about the current HTTP request. This is especially useful for logging purposes where you want as many information as possible. :param hide_passwords: Hides the actual value of POST fields if their name contains ``password``. :return: a dictionary containing request information, or ``None`` when called outside a request context """ if not has_request_context(): return None return { "id": request.id, "url": request.url, "endpoint": request.url_rule.endpoint if request.url_rule else None, "method": request.method, "rh": g.rh.__class__.__name__ if "rh" in g else None, "user": repr(session.user), "ip": request.remote_addr, "user_agent": unicode(request.user_agent), "referrer": request.referrer, "data": { "url": _format_request_data(request.view_args, False), "get": _format_request_data(request.args, False), "post": _format_request_data(request.form, hide_passwords), "json": request.get_json(silent=True), "headers": _format_request_data(request.headers, False), }, }
def _transaction_ended(session, transaction): # The zope transaction system closes the session (and thus the # transaction) e.g. when calling `transaction.abort()`. # in this case we need to clear the memoization cache to avoid # accessing memoized objects (which are now session-less) if transaction._parent is not None: # we don't care about sub-transactions return if has_app_context(): if 'memoize_cache' in g: del g.memoize_cache if 'settings_cache' in g: del g.settings_cache if 'global_settings_cache' in g: del g.global_settings_cache if 'event_notes' in g: del g.event_notes if 'event_attachments' in g: del g.event_attachments if 'relationship_cache' in g: del g.relationship_cache if has_request_context() and hasattr(flask_session, '_user'): delattr(flask_session, '_user')
def validate_doi(self, value): """Validate if doi exists.""" if value and has_request_context(): required_doi = self.context.get('required_doi') if value == required_doi: return err = ValidationError(_('DOI already exists in Zenodo.'), field_names=['doi']) try: doi_pid = PersistentIdentifier.get('doi', value) except PIDDoesNotExistError: return # If the DOI exists, check if it's been assigned to this record # by fetching the recid and comparing both PIDs record UUID try: recid_pid = PersistentIdentifier.get( 'recid', self.context['recid']) except PIDDoesNotExistError: # There's no way to verify if this DOI belongs to this record raise err doi_uuid = doi_pid.get_assigned_object() recid_uuid = recid_pid.get_assigned_object() if doi_uuid and doi_uuid == recid_uuid: return else: # DOI exists and belongs to a different record raise err
def set_best_lang(check_session=True): """ Get the best language/locale for the current user. This means that first the session will be checked, and then in the absence of an explicitly-set language, we will try to guess it from the browser settings and only after that fall back to the server's default. """ from indico.core.config import Config if not has_request_context(): return 'en_GB' if current_app.config['TESTING'] else Config.getInstance().getDefaultLocale() elif 'lang' in g: return g.lang elif check_session and session.lang is not None: return session.lang # try to use browser language preferred = [x.replace('-', '_') for x in request.accept_languages.values()] resolved_lang = negotiate_locale(preferred, list(get_all_locales()), aliases=LOCALE_ALIASES) if not resolved_lang: if current_app.config['TESTING']: return 'en_GB' # fall back to server default resolved_lang = Config.getInstance().getDefaultLocale() # As soon as we looked up a language, cache it during the request. # This will be returned when accessing `session.lang` since there's code # which reads the language from there and might fail (e.g. by returning # lazy strings) if it's not set. g.lang = resolved_lang return resolved_lang
def __init__(self, cls=None): # check for the presence of a request context if not has_request_context(): return self._data = [] # If we're loading a view and have not yet loaded its static dependencies, asynchronously load them if cls.__class__.__name__.find('View') != -1: folder = cls.__class__.__name__.replace('View', '').lower() # if its not in loaded, it hasn't been loaded if folder not in session['sajax']['loaded_dep']: # css first, /static/css/obt_folder.css filepath = self.root+'/static/css/%s%s%s.css' % (self.inc_file_prefix, folder, self.inc_file_suffix) if os.path.isfile(filepath): self._data.append({'action': 'load', 'data': url_for('static', filename='css/%s.css' % folder)}) # first the js file at /static/js/folder/folder.js if it exists if os.path.isfile(self.root+'/static/js/%s/%s.js' % (folder, folder)): self._data.append({'action': 'load', 'data': url_for('static', filename='js/%s/%s.js' % (folder, folder))}) # then all the rest of the js files in /static/js/folder/ if os.path.isdir(self.root+'/static/js/'+folder): for file in os.listdir(self.root+'/static/js/'+folder): if (file != folder+'.js'): self._data.append({'action': 'load', 'data': url_for('static', filename='js/%s/%s' % (folder, file))}) # this folder's js files might have defined an object self._data.append({'action': 'js', 'data': "if (typeof %s != 'undefined') window.%s = new %s()" % (folder, folder, folder)}) # The files will be loaded, mark them as such session['sajax']['loaded_dep'].append(folder)
def get_request_info(hide_passwords=True): """Gets various information about the current HTTP request. This is especially useful for logging purposes where you want as many information as possible. :param hide_passwords: Hides the actual value of POST fields if their name contains ``password``. :return: a dictionary containing request information, or ``None`` when called outside a request context """ if not has_request_context(): return None return { 'id': request.id, 'url': request.url, 'endpoint': request.url_rule.endpoint if request.url_rule else None, 'method': request.method, 'rh': g.rh.__class__.__name__ if 'rh' in g else None, 'user': repr(session.user), 'ip': request.remote_addr, 'user_agent': unicode(request.user_agent), 'referrer': request.referrer, 'data': { 'url': _format_request_data(request.view_args, False), 'get': _format_request_data(request.args, False), 'post': _format_request_data(request.form, hide_passwords), 'json': request.get_json(silent=True), 'headers': _format_request_data(request.headers, False), } }
def _can_access(cls, obj, user, authorized, **kwargs): # Grant full access to attachments/folders to certain networks if not has_request_context() or not request.remote_addr or authorized is not None: return ip = unicode(request.remote_addr) if any(net.contains_ip(ip) for net in IPNetworkGroup.query.filter_by(attachment_access_override=True)): return True
def filter(self, record): if not record.exc_info or not has_request_context(): return True ex = record.exc_info[1] if not isinstance(ex, HTTPException): return True return ex.code in self.include_codes
def before_request(self, *args, **kwargs): super(IndicoSentry, self).before_request() if not has_request_context(): return self.client.extra_context({'Endpoint': str(request.url_rule.endpoint) if request.url_rule else None, 'Request ID': request.id}) self.client.tags_context({'locale': set_best_lang()})
def get_locale(self): if has_request_context(): locale = session.get('locale') if locale: return locale session['locale'] = self.babel_default_locale return session['locale']
def _get_current_auth(): # 1. Do we have a request? if has_request_context(): # 2. Does this request already have current_auth? If so, return it if hasattr(_request_ctx_stack.top, 'current_auth'): return _request_ctx_stack.top.current_auth # 3. If not, does it have a known user (Flask-Login protocol)? If so, construct current_auth if hasattr(_request_ctx_stack.top, 'user'): _request_ctx_stack.top.current_auth = CurrentAuth(_request_ctx_stack.top.user) # 4. If none of these, construct a blank one and probe for content else: ca = CurrentAuth(None) # If the login manager below calls :func:`add_auth_attribute`, # we'll have a recursive entry into :func:`_get_current_auth`, so make sure # the stack has an empty :class:`CurrentAuth` on it _request_ctx_stack.top.current_auth = ca # 4.1. Now check for a login manager and call it # Flask-Login, Flask-Lastuser or equivalent must add a login_manager if hasattr(current_app, 'login_manager') and hasattr(current_app.login_manager, '_load_user'): current_app.login_manager._load_user() # 4.2. In case the login manager did not call :func:`add_auth_attribute`, we'll # need to copy the user symbol manually if ca.user is None: object.__setattr__(ca, 'user', getattr(_request_ctx_stack.top, 'user', None)) # Return the newly constructed current_auth return _request_ctx_stack.top.current_auth # Fallback if there is no request context. Return a blank current_auth # so that ``current_auth.is_authenticated`` remains valid for checking status return CurrentAuth(None) # Make this work even when there's no request
def _add_permissions_filter(self, query, model_class): """Filter by the users present in either the `viewers` or `owners` lists """ # not used from a request handler - no relevant user if not has_request_context(): return query # Queries of elements that aren't resources (tenants, users, etc.), # shouldn't be filtered if not model_class.is_resource: return query # For users that are allowed to see all resources, regardless of tenant is_admin = is_administrator(self.current_tenant) if is_admin: return query # Only get resources that are public - not private (note that ~ stands # for NOT, in SQLA), *or* those where the current user is the creator user_filter = sql_or( model_class.visibility != VisibilityState.PRIVATE, model_class.creator == current_user ) return query.filter(user_filter)
def set_best_lang(): """ Get the best language/locale for the current user. This means that first the session will be checked, and then in the absence of an explicitly-set language, we will try to guess it from the browser settings and only after that fall back to the server's default. """ if not has_request_context(): return 'en_GB' if current_app.config['TESTING'] else HelperMaKaCInfo.getMaKaCInfoInstance().getLang() elif session.lang is not None: return session.lang # try to use browser language preferred = [x.replace('-', '_') for x in request.accept_languages.values()] resolved_lang = negotiate_locale(preferred, list(get_all_locales()), aliases=LOCALE_ALIASES) if not resolved_lang: if current_app.config['TESTING']: return 'en_GB' with DBMgr.getInstance().global_connection(): # fall back to server default minfo = HelperMaKaCInfo.getMaKaCInfoInstance() resolved_lang = minfo.getLang() session.lang = resolved_lang return resolved_lang
def after_execute(conn, elt, multiparams, params, result): duration = 1000 * (time.time() - conn.info['query_start_time'].pop(-1)) action = elt.__class__.__name__ if action == 'Select': name = 'unknown' try: name = _table_name_from_select_element(elt) except Exception: logging.exception('Failed finding table name.') elif action in ['Update', 'Insert', 'Delete']: name = elt.table.name else: # create/drop tables, sqlalchemy internal schema queries, etc return action = action.lower() statsd_client.timing('db.{}.{}'.format(name, action), duration) metrics_logger.debug("table=%s query=%s duration=%.2f", name, action, duration) if has_request_context(): g.setdefault('queries_count', 0) g.setdefault('queries_duration', 0) g.queries_count += 1 g.queries_duration += duration return result
def get_info_from_file_number(file_number, privileged=False, filename=None): if current_user and current_user.is_authenticated and current_user.has_role('admin', 'developer', 'advocate', 'trainer'): privileged = True else: if has_request_context() and 'uid' in session: uid = session['uid'] else: uid = docassemble.base.functions.get_uid() #logmessage("get_info_from_file_number: privileged is " + str(privileged) + " and uid is " + str(uid)) result = dict() if privileged: upload = Uploads.query.filter_by(indexno=file_number).first() else: upload = Uploads.query.filter(and_(Uploads.indexno == file_number, or_(Uploads.key == uid, Uploads.private == False))).first() if upload: if filename is None: result['filename'] = upload.filename else: result['filename'] = filename result['extension'], result['mimetype'] = get_ext_and_mimetype(result['filename']) sf = SavedFile(file_number, extension=result['extension'], fix=True) result['path'] = sf.path result['fullpath'] = result['path'] + '.' + result['extension'] result['private'] = upload.private result['persistent'] = upload.persistent #logmessage("fullpath is " + str(result['fullpath'])) if 'path' not in result: logmessage("get_info_from_file_number: path is not in result for " + str(file_number)) return result final_filename = result['path'] + '.' + result['extension'] if os.path.isfile(final_filename): add_info_about_file(final_filename, result) # else: # logmessage("Filename " + final_filename + "did not exist.") return(result)
def get_request_information(): """ Returns a dictionary of contextual information about the user at the time of logging. Returns: The dictionary. """ information = {} if has_request_context(): information["request"] = { "api_endpoint_method": request.method, "api_endpoint": request.path, "ip": request.remote_addr, "platform": request.user_agent.platform, "browser": request.user_agent.browser, "browser_version": request.user_agent.version, "user_agent":request.user_agent.string } if api.auth.is_logged_in(): user = api.user.get_user() team = api.user.get_team() groups = api.team.get_groups() information["user"] = { "username": user["username"], "email": user["email"], "team_name": team["team_name"], "groups": [group["name"] for group in groups] } return information
def logout_user(): """Remove the user from the session.""" #TODO: invalidate token with api if has_request_context(): session.pop('user_id', None) g.current_user = AnonymousUser()
def get_acc_key(self): """Generate key for caching authorizations.""" remote_ip = str(request.remote_addr) if has_request_context() else '0' return 'current_user::' + str(self.uid) + '::' + remote_ip
def _get_request_id(self): empty_guid = '00000000-0000-0000-0000-000000000000' if flask.has_request_context() and hasattr(request, 'environ'): return request.environ.get('REQUEST_ID', empty_guid) else: return empty_guid
def _clear_cache(): if has_request_context(): g.pop('global_settings_cache', None)
'ModelView', # View base classes 'route', 'viewdata', 'url_change_check', 'requires_roles', # View decorators 'UrlChangeCheck', 'UrlForView', 'InstanceLoader', # Mixin classes ] #: A proxy object that holds the currently executing :class:`ClassView` instance, #: for use in templates as context. Exposed to templates by #: :func:`coaster.app.init_app`. Note that the current view handler method within the #: class is named :attr:`~current_view.current_handler`, so to examine it, use #: :attr:`current_view.current_handler`. current_view = LocalProxy(lambda: has_request_context() and getattr( _request_ctx_stack.top, 'current_view', None)) # :func:`route` wraps :class:`ViewHandler` so that it can have an independent __doc__ def route(rule, **options): """ Decorator for defining routes on a :class:`ClassView` and its methods. Accepts the same parameters that Flask's ``app.``:meth:`~flask.Flask.route` accepts. See :class:`ClassView` for usage notes. """ return ViewHandler(rule, rule_options=options) def viewdata(**kwargs): """
def get_form_data( # pylint: disable=too-many-locals slice_id: Optional[int] = None, use_slice_data: bool = False ) -> Tuple[Dict[str, Any], Optional[Slice]]: form_data: Dict[str, Any] = {} if has_request_context(): # type: ignore # chart data API requests are JSON request_json_data = ( request.json["queries"][0] if request.is_json and "queries" in request.json else None ) add_sqllab_custom_filters(form_data) request_form_data = request.form.get("form_data") request_args_data = request.args.get("form_data") if request_json_data: form_data.update(request_json_data) if request_form_data: parsed_form_data = loads_request_json(request_form_data) # some chart data api requests are form_data queries = parsed_form_data.get("queries") if isinstance(queries, list): form_data.update(queries[0]) else: form_data.update(parsed_form_data) # request params can overwrite the body if request_args_data: form_data.update(loads_request_json(request_args_data)) # Fallback to using the Flask globals (used for cache warmup and async queries) if not form_data and hasattr(g, "form_data"): form_data = getattr(g, "form_data") # chart data API requests are JSON json_data = form_data["queries"][0] if "queries" in form_data else {} form_data.update(json_data) if has_request_context(): # type: ignore url_id = request.args.get("r") if url_id: saved_url = db.session.query(models.Url).filter_by(id=url_id).first() if saved_url: url_str = parse.unquote_plus( saved_url.url.split("?")[1][10:], encoding="utf-8" ) url_form_data = loads_request_json(url_str) # allow form_date in request override saved url url_form_data.update(form_data) form_data = url_form_data form_data = {k: v for k, v in form_data.items() if k not in REJECTED_FORM_DATA_KEYS} # When a slice_id is present, load from DB and override # the form_data from the DB with the other form_data provided slice_id = form_data.get("slice_id") or slice_id slc = None # Check if form data only contains slice_id, additional filters and viz type valid_keys = ["slice_id", "extra_filters", "adhoc_filters", "viz_type"] valid_slice_id = all(key in valid_keys for key in form_data) # Include the slice_form_data if request from explore or slice calls # or if form_data only contains slice_id and additional filters if slice_id and (use_slice_data or valid_slice_id): slc = db.session.query(Slice).filter_by(id=slice_id).one_or_none() if slc: slice_form_data = slc.form_data.copy() slice_form_data.update(form_data) form_data = slice_form_data update_time_range(form_data) if app.config["SIP_15_ENABLED"]: form_data["time_range_endpoints"] = get_time_range_endpoints( form_data, slc, slice_id ) return form_data, slc
def _get_user(): if has_request_context() and not hasattr(_request_ctx_stack.top, _get_endpoint()): current_app.login_manager._load_user() return getattr(_request_ctx_stack.top, _get_endpoint(), None)
def save(self, commit=True): if has_request_context(): self._set_user(getattr(request, 'user', None)) db.session.add(self) if commit: db.session.commit()
def _get_user(): if has_request_context() and session.avatar: return session.avatar else: return AvatarHolder().getById(Config.getInstance().getJanitorUserId())
def trace_id_header_dict() -> Dict[str, str]: if has_request_context(): trace_id = trace_id_header() return {Auditor.TRACE_ID_HEADER: str(trace_id)} return {}
def display_full_name(self): """Return the full name using the user's preferred name format.""" if has_request_context(): return format_display_full_name(session.user, self) else: return format_display_full_name(None, self)
def _event_deleted(event, **kwargs): user = session.user if has_request_context( ) and session.user else User.get(Config.getInstance().getJanitorUserId()) for event_vc_room in VCRoomEventAssociation.find_for_event( event, include_hidden=True, include_deleted=True): event_vc_room.delete(user)
def get_current_flask_request_id_or_none(): if flask.has_request_context(): return flask.request.correlation_id
def __init__(self, event, management=False, user=None): self.management = management self.user = user if user is not None or not has_request_context() else session.user self.event = event self.can_manage_event = self.event.can_manage(self.user)
def to_python(self, value): assert has_request_context() return value
def layout_fn(*args, **kwargs): if flask.has_app_context() and flask.has_request_context(): dash_app._cached_layout = None # pylint: disable=protected-access return layout(dashboards, DASHBOARD_PREFIX)
def _wrap(*args, **kwargs): if not _flask.has_request_context(): raise RuntimeError('`{0}` method needs a flask/dash request' ' context to run. Make sure to run ' '`{0}` from a callback.'.format(func.__name__)) return func(*args, **kwargs)
def serve_layout(): if flask.has_request_context(): return layout_for_page['url_bar_and_content_div'] return html.Div(list(layout_for_page.values()))
def emit(self, event, *args, **kwargs): """Emit a server generated SocketIO event. This function emits a SocketIO event to one or more connected clients. A JSON blob can be attached to the event as payload. This function can be used outside of a SocketIO event context, so it is appropriate to use when the server is the originator of an event, outside of any client context, such as in a regular HTTP request handler or a background task. Example:: @app.route('/ping') def ping(): socketio.emit('ping event', {'data': 42}, namespace='/chat') :param event: The name of the user event to emit. :param args: A dictionary with the JSON data to send as payload. :param namespace: The namespace under which the message is to be sent. Defaults to the global namespace. :param to: Send the message to all the users in the given room. If this parameter is not included, the event is sent to all connected users. :param include_self: ``True`` to include the sender when broadcasting or addressing a room, or ``False`` to send to everyone but the sender. :param skip_sid: The session id of a client to ignore when broadcasting or addressing a room. This is typically set to the originator of the message, so that everyone except that client receive the message. To skip multiple sids pass a list. :param callback: If given, this function will be called to acknowledge that the client has received the message. The arguments that will be passed to the function are those provided by the client. Callback functions can only be used when addressing an individual client. """ namespace = kwargs.pop('namespace', '/') to = kwargs.pop('to', kwargs.pop('room', None)) include_self = kwargs.pop('include_self', True) skip_sid = kwargs.pop('skip_sid', None) if not include_self and not skip_sid: skip_sid = flask.request.sid callback = kwargs.pop('callback', None) if callback: # wrap the callback so that it sets app app and request contexts sid = None if has_request_context(): sid = getattr(flask.request, 'sid', None) original_callback = callback def _callback_wrapper(*args): return self._handle_event(original_callback, None, namespace, sid, *args) if sid: # the callback wrapper above will install a request context # before invoking the original callback # we only use it if the emit was issued from a Socket.IO # populated request context (i.e. request.sid is defined) callback = _callback_wrapper self.server.emit(event, *args, namespace=namespace, to=to, skip_sid=skip_sid, callback=callback, **kwargs)
def patron_owner_permission(record): """Return permission to allow owner and librarian to access the record.""" if not has_request_context(): # allows performing the actions out of the request context f.e. CLI return allow_all() return PatronOwnerPermission(record)
def filter(self, record): # Ensure the proxied request is our locked request # And the record is created in a request context to begin with if not f.has_request_context(): return False return f.request == self._request
def filter(self, record): if not logging.Filter.filter(self, record): return False # Add request ID if available record.request_id = request.id if has_request_context() else '0' * 12 return True
def request_ip_address(): assert has_request_context() return request.remote_addr
def filter(self, record) -> bool: record.request_id = request_id() if flask.has_request_context() else "-" return True
def _get_api_name(self): default = '' if flask.has_request_context() and getattr(flask.g, 'apiName', None): return flask.g.apiName else: return default
def get_user(): if has_request_context() and not hasattr(_request_ctx_stack.top, 'user'): current_identity.get_current_user() return getattr(_request_ctx_stack.top, 'user', None)
def _add_request_id_header(headers): if not has_request_context(): return headers headers['X-B3-TraceId'] = request.request_id headers['X-B3-SpanId'] = request.span_id return headers
def format(self, record: logging.LogRecord) -> str: if has_request_context(): record.src_ip = request.remote_addr return super().format(record)
def circulation_transaction_user_validator(transaction_user_pid): """Validate that the given transaction user PID is valid.""" if has_request_context(): return transaction_user_pid == str(current_user.id) else: return True
def filter(self, record): # Add our request ID if available record.request_id = request.id if has_request_context() else '0' * 16 return True
def _add_request_id_header(headers): if not has_request_context(): return headers headers['NotifyRequestID'] = request.request_id return headers