from django.http import HttpResponseRedirect, Http404, HttpResponse
from django.core.exceptions import PermissionDenied
from django.shortcuts import get_object_or_404
-from pgweb.util.decorators import login_required, script_sources, frame_sources, content_sources
+from pgweb.util.decorators import login_required, script_sources, frame_sources, content_sources, queryparams
from django.views.decorators.csrf import csrf_exempt
from django.utils.encoding import force_bytes
from django.utils.http import urlsafe_base64_encode
@script_sources('https://www.gstatic.com/recaptcha/')
@frame_sources('https://www.google.com/')
@transaction.atomic
+@queryparams('do_abort')
def signup_oauth(request):
if 'oauth_email' not in request.session \
or 'oauth_firstname' not in request.session \
####
# Community authentication endpoint
####
+@queryparams('d', 'su')
def communityauth(request, siteid):
# Get whatever site the user is trying to log in to.
site = get_object_or_404(CommunityAuthSite, pk=siteid)
@login_required
+@queryparams('next')
def communityauth_consent(request, siteid):
org = get_object_or_404(CommunityAuthSite, id=siteid).org
if request.method == 'POST':
)
+@queryparams('s', 'e', 'n', 'u')
def communityauth_search(request, siteid):
# Perform a search for users. The response will be encrypted with the site
# key to prevent abuse, therefor we need the site.
from django.views.decorators.csrf import csrf_exempt
from django.conf import settings
-from pgweb.util.decorators import cache
+from pgweb.util.decorators import cache, queryparams
import urllib.parse
import requests
@csrf_exempt
+@queryparams('a', 'd', 'l', 'ln', 'm', 'p', 'q', 's', 'u')
@cache(minutes=30)
def search(request):
# Perform a general web search
return _cache
+def queryparams(*args):
+ """
+ Allow specified query parameters when calling function.
+ NOTE! Must be the "outermost" decorator!!!
+ """
+ def _queryparams(fn):
+ fn.queryparams = args
+ return fn
+ return _queryparams
+
+
def allow_frames(fn):
def _allow_frames(request, *_args, **_kwargs):
resp = fn(request, *_args, **_kwargs)
from django.conf import settings
+from django.http import QueryDict
from pgweb.util.templateloader import initialize_template_collection, get_all_templates
response['X-XSS-Protection'] = "1; mode=block"
return response
+
+ def process_view(self, request, view_func, view_args, view_kwargs):
+ # Filter out any query parameters that are not explicitly allowed. We do the same thing in Varnish,
+ # and it's better to also do it in django if they show up here, so issues because of it are caught
+ # in local testing where there is no Varnish.
+ if not request.GET:
+ # If there are no parameters, just skip this whole process
+ return None
+
+ if request.path.startswith('/admin/'):
+ # django-admin uses it a lot and it's not for us to change
+ return None
+
+ allowed = getattr(view_func, 'queryparams', None)
+
+ if allowed:
+ # Filter the QueryDict for only the allowed parameters
+ result = request.GET.copy()
+ for k in request.GET.keys():
+ if k not in allowed:
+ del result[k]
+ result.mutable = False
+ request.GET = result
+ else:
+ request.GET = QueryDict()
+ return None