contentdb/app/utils/flask.py

108 lines
2.9 KiB
Python
Raw Normal View History

2021-01-30 19:25:00 +01:00
# ContentDB
# Copyright (C) 2018-21 rubenwardy
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
2022-01-21 15:23:27 +01:00
from urllib.parse import urljoin, urlparse, urlunparse
2021-01-30 19:25:00 +01:00
import user_agents
from flask import request, abort
from werkzeug.datastructures import MultiDict
from app.models import *
def is_safe_url(target):
ref_url = urlparse(request.host_url)
test_url = urlparse(urljoin(request.host_url, target))
return test_url.scheme in ('http', 'https') and \
ref_url.netloc == test_url.netloc
# These are given to Jinja in template_filters.py
def abs_url_for(endpoint: str, **kwargs):
2021-01-30 19:25:00 +01:00
scheme = "https" if app.config["BASE_URL"][:5] == "https" else "http"
return url_for(endpoint, _external=True, _scheme=scheme, **kwargs)
2021-01-30 19:25:00 +01:00
def abs_url(path):
return urljoin(app.config["BASE_URL"], path)
2022-01-21 15:23:27 +01:00
def abs_url_samesite(path):
base = urlparse(app.config["BASE_URL"])
return urlunparse(base._replace(path=path))
2022-01-21 00:30:56 +01:00
def url_current(abs=False):
2022-01-23 18:14:03 +01:00
if request.args is None or request.view_args is None:
return None
2022-01-21 00:30:56 +01:00
args = MultiDict(request.args)
dargs = dict(args.lists())
dargs.update(request.view_args)
if abs:
return abs_url_for(request.endpoint, **dargs)
else:
return url_for(request.endpoint, **dargs)
2021-08-18 23:09:41 +02:00
def url_set_anchor(anchor):
args = MultiDict(request.args)
dargs = dict(args.lists())
dargs.update(request.view_args)
return url_for(request.endpoint, **dargs) + "#" + anchor
2021-01-30 19:25:00 +01:00
def url_set_query(**kwargs):
if request.endpoint is None:
return None
2021-01-30 19:25:00 +01:00
args = MultiDict(request.args)
for key, value in kwargs.items():
if key == "_add":
for key2, value_to_add in value.items():
values = set(args.getlist(key2))
values.add(value_to_add)
args.setlist(key2, list(values))
elif key == "_remove":
for key2, value_to_remove in value.items():
values = set(args.getlist(key2))
values.discard(value_to_remove)
args.setlist(key2, list(values))
else:
args.setlist(key, [ value ])
dargs = dict(args.lists())
2022-01-11 18:06:24 +01:00
if request.view_args:
dargs.update(request.view_args)
2021-01-30 19:25:00 +01:00
return url_for(request.endpoint, **dargs)
def get_int_or_abort(v, default=None):
if v is None:
return default
try:
return int(v or default)
except ValueError:
abort(400)
def is_user_bot():
user_agent = request.headers.get('User-Agent')
if user_agent is None:
return True
user_agent = user_agents.parse(user_agent)
return user_agent.is_bot