Esempio n. 1
0
def login(request):
    """
    Render and process a most basic login form. Takes an URL as GET
    parameter "next" for redirection after successful login
    """
    ctx = {}
    if request.user.is_authenticated:
        return redirect(request.GET.get("next", 'control:index'))
    if request.method == 'POST':
        form = LoginForm(data=request.POST)
        if form.is_valid() and form.user_cache:
            request.session['pretix_auth_long_session'] = (
                settings.PRETIX_LONG_SESSIONS and form.cleaned_data.get('keep_logged_in', False)
            )
            if form.user_cache.require_2fa:
                request.session['pretix_auth_2fa_user'] = form.user_cache.pk
                request.session['pretix_auth_2fa_time'] = str(int(time.time()))
                twofa_url = reverse('control:auth.login.2fa')
                if "next" in request.GET and is_safe_url(request.GET.get("next"), allowed_hosts=None):
                    twofa_url += '?next=' + quote(request.GET.get('next'))
                return redirect(twofa_url)
            else:
                auth_login(request, form.user_cache)
                request.session['pretix_auth_login_time'] = int(time.time())
                if "next" in request.GET and is_safe_url(request.GET.get("next"), allowed_hosts=None):
                    return redirect(request.GET.get("next"))
                return redirect(reverse('control:index'))
    else:
        form = LoginForm()
    ctx['form'] = form
    ctx['can_register'] = settings.PRETIX_REGISTRATION
    ctx['can_reset'] = settings.PRETIX_PASSWORD_RESET
    return render(request, 'pretixcontrol/auth/login.html', ctx)
Esempio n. 2
0
def set_language_ex(request):
    next = request.POST.get('next', request.GET.get('next'))
    if not is_safe_url(url=next, host=request.get_host()):
        next = request.META.get('HTTP_REFERER')
        if not is_safe_url(url=next, host=request.get_host()):
            next = '/'

    # remove lang from query
    scheme, netloc, path, query, fragment = urlparse.urlsplit(next)
    parsed_query = urlparse.parse_qsl(query)
    altered = False
    for k, v in parsed_query[:]:
        if LANG_GET_KEY == k:
            parsed_query.remove((k, v))
            altered = True
    if altered:
        query = urllib.urlencode(parsed_query)
        next = urlparse.urlunsplit((scheme, netloc, path, query, fragment))

    response = http.HttpResponseRedirect(next)
    if request.method == 'POST':
        lang_code = request.POST.get('language', None)
        if lang_code and check_for_language(lang_code):
            if hasattr(request, 'session'):
                request.session[LANGUAGE_SESSION_KEY] = lang_code
            else:
                response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang_code,
                                    max_age=settings.LANGUAGE_COOKIE_AGE,
                                    path=settings.LANGUAGE_COOKIE_PATH,
                                    domain=settings.LANGUAGE_COOKIE_DOMAIN)
    return response
Esempio n. 3
0
def set_country(request):

    next = request.POST.get('next', request.GET.get('next'))
    if ((next or not request.is_ajax()) and
            not is_safe_url(next, request.get_host())):
        next = request.META.get('HTTP_REFERER')
        if next:
            next = unquote(next)  # HTTP_REFERER may be encoded.
        if not is_safe_url(next, request.get_host()):
            next = '/'
        if request.POST.get('country'):
            path = request.META.get('HTTP_REFERER').replace(request.scheme+'://' + request.get_host(), '')

            country_code = get_country_code_from_path(path)
            if country_code:
                path = request.META.get('HTTP_REFERER').replace(request.scheme+'://' + request.get_host(), '').replace('/'+country_code, '')
            if request.POST.get('country') == settings.COUNTRY_CODE:
                next = path
            else:
                next = '/' + request.POST.get('country') + path
    response = HttpResponseRedirect(next) if next else HttpResponse(status=204)
    if request.method == 'POST':
        country_code = request.POST.get('country')
        if country_code:
            request.session['country'] = country_code
            if hasattr(request, 'session'):
                request.session['_country'] = country_code
            else:
                response.set_cookie(
                    settings.COUNTRY_COOKIE_NAME, country_code,
                    max_age=settings.COUNTRY_COOKIE_AGE,
                    path=settings.COUNTRY_COOKIE_PATH,
                    domain=settings.COUNTRY_COOKIE_DOMAIN,
                )
    return response
Esempio n. 4
0
    def get_next_url(self):
        request = self.request
        redirect_to = request.POST.get(self.redirect_field_name,
                                       request.GET.get(self.redirect_field_name, ''))
        if not redirect_to:
            return

        host = self.request.get_host()

        try:
            # django >= 1.11 changed host arg to allowed_hosts list arg
            allowed_hosts = [host]

            try:
                allowed_hosts += self.get_success_url_allowed_hosts()
            except AttributeError:
                pass

            url_is_safe = is_safe_url(
                redirect_to,
                allowed_hosts=allowed_hosts,
                require_https=self.request.is_secure()
            )

        except TypeError:
            # django < 1.11
            url_is_safe = is_safe_url(redirect_to, host=host)

        if url_is_safe:
            return redirect_to
Esempio n. 5
0
def set_language_and_region(request, region_code="GL", language_code="en"):
    """
    Adapted from the Django's set_language

    Redirect to a given url while setting the chosen language in the
    session or cookie. The url and the language code need to be
    specified in the request parameters, or will be taken from HTTP_REFERER
    """
    next_url = request.POST.get('next', request.GET.get('next'))
    if not is_safe_url(url=next_url, host=request.get_host()):
        next_url = request.META.get('HTTP_REFERER')
        if not is_safe_url(url=next_url, host=request.get_host()):
            next_url = '/GL/en/'  # Default global region with English language.
    # In case of bogus information fall back to default region or language for that region if exists.
    region, new_language_code = get_region(region_code, language_code)
    if new_language_code != language_code:
        language_code = new_language_code

    old_path = URL(next_url).path
    if old_path == "/":
        new_path = "/%s/" % "/".join([region.code, language_code])
    else:
        new_path = "/" + "/".join([region.code, language_code] + old_path.split("/")[3:])
    next_url = URL(next_url).replace(path=new_path)
    response = http.HttpResponseRedirect(next_url)

    if hasattr(request, 'session'):
        request.session[LANGUAGE_SESSION_KEY] = language_code
    else:
        response.set_cookie(settings.LANGUAGE_COOKIE_NAME, language_code,
                            max_age=settings.LANGUAGE_COOKIE_AGE,
                            path=settings.LANGUAGE_COOKIE_PATH,
                            domain=settings.LANGUAGE_COOKIE_DOMAIN)
    return response
Esempio n. 6
0
    def get(self, *args, **kwargs):
        lang = kwargs.pop('lang')
        next_url = self.request.GET.get('next')
        if (next_url or not self.request.is_ajax()) and not is_safe_url(url=next_url, host=self.request.get_host()):
            next_url = self.request.META.get('HTTP_REFERER')
            if next_url:
                next_url = urlunquote(next_url)  # HTTP_REFERER may be encoded.
            if not is_safe_url(url=next_url, host=self.request.get_host()):
                next_url = '/'
        response = HttpResponseRedirect(next_url) if next_url else HttpResponse(status=204)

        if lang and check_for_language(lang):
            if next_url:
                if lang == 'ru':
                    next_trans = re.sub("/en/", "/", next_url)
                else:
                    next_trans = translate_url(next_url, lang)
                if next_trans != next_url:
                    response = HttpResponseRedirect(next_trans)
            translation.activate(lang)
            if hasattr(self.request, 'session'):
                self.request.session[translation.LANGUAGE_SESSION_KEY] = lang
            else:
                response.set_cookie(
                    settings.LANGUAGE_COOKIE_NAME, lang,
                    max_age=settings.LANGUAGE_COOKIE_AGE,
                    path=settings.LANGUAGE_COOKIE_PATH,
                    domain=settings.LANGUAGE_COOKIE_DOMAIN,
                )
        return response
Esempio n. 7
0
def set_language(request):
    """
    Redirect to a given url while setting the chosen language in the
    session or cookie. The url and the language code need to be
    specified in the request parameters.

    Since this view changes how the user will see the rest of the site, it must
    only be accessed as a POST request. If called as a GET request, it will
    redirect to the page in the request (the 'next' parameter) without changing
    any state.
    """
    next = request.POST.get("next", request.GET.get("next"))
    if not is_safe_url(url=next, host=request.get_host()):
        next = request.META.get("HTTP_REFERER")
        if not is_safe_url(url=next, host=request.get_host()):
            next = "/"
    response = http.HttpResponseRedirect(next)
    if request.method == "POST":
        lang_code = request.POST.get("language", None)
        if lang_code and check_for_language(lang_code):
            if hasattr(request, "session"):
                request.session[LANGUAGE_SESSION_KEY] = lang_code
            else:
                response.set_cookie(
                    settings.LANGUAGE_COOKIE_NAME,
                    lang_code,
                    max_age=settings.LANGUAGE_COOKIE_AGE,
                    path=settings.LANGUAGE_COOKIE_PATH,
                    domain=settings.LANGUAGE_COOKIE_DOMAIN,
                )
    return response
Esempio n. 8
0
def login(request):
    redirect_to = request.POST.get('next', request.GET.get('next', '/dashboard'))
    if not request.user.is_anonymous():
        if not is_safe_url(url=redirect_to, host=request.get_host()):
            redirect_to = resolve_url(settings.LOGIN_REDIRECT_URL)
        return HttpResponseRedirect(redirect_to)
    if request.method == "POST":
        form = LoginForm(request, redirect_to=redirect_to, data=request.POST)
        if form.is_valid():

            # Ensure the user-originating redirection url is safe.
            if not is_safe_url(url=redirect_to, host=request.get_host()):
                redirect_to = resolve_url(settings.LOGIN_REDIRECT_URL)

            # Okay, security check complete. Log the user in.
            auth_login(request, form.get_user())

            return HttpResponseRedirect(redirect_to)
    else:
        form = LoginForm(request, redirect_to=redirect_to)

    current_site = get_current_site(request)

    context = {
        'form': form,
        'next': redirect_to,
        'site': current_site,
        'site_name': current_site.name,
    }

    return TemplateResponse(request, 'login.html', context)
Esempio n. 9
0
 def test_is_safe_url(self):
     for bad_url in ('http://example.com',
                     'http:///example.com',
                     'https://example.com',
                     'ftp://example.com',
                     r'\\example.com',
                     r'\\\example.com',
                     r'/\\/example.com',
                     r'\\\example.com',
                     r'\\example.com',
                     r'\\//example.com',
                     r'/\/example.com',
                     r'\/example.com',
                     r'/\example.com',
                     'http:///example.com',
                     'http:/\//example.com',
                     'http:\/example.com',
                     'http:/\example.com',
                     'javascript:alert("XSS")',
                     '\njavascript:alert(x)',
                     '\x08//example.com',
                     '\n'):
         self.assertFalse(http.is_safe_url(bad_url, host='testserver'), "%s should be blocked" % bad_url)
     for good_url in ('/view/?param=http://example.com',
                  '/view/?param=https://example.com',
                  '/view?param=ftp://example.com',
                  'view/?param=//example.com',
                  'https://testserver/',
                  'HTTPS://testserver/',
                  '//testserver/',
                  '/url%20with%20spaces/'):
         self.assertTrue(http.is_safe_url(good_url, host='testserver'), "%s should be allowed" % good_url)
Esempio n. 10
0
def set_language(request):
    """
    Redirect to a given URL while setting the chosen language in the session
    (if enabled) and in a cookie. The URL and the language code need to be
    specified in the request parameters.

    Since this view changes how the user will see the rest of the site, it must
    only be accessed as a POST request. If called as a GET request, it will
    redirect to the page in the request (the 'next' parameter) without changing
    any state.
    """
    next = request.POST.get('next', request.GET.get('next'))
    if ((next or not request.is_ajax()) and
            not is_safe_url(url=next, allowed_hosts={request.get_host()}, require_https=request.is_secure())):
        next = request.META.get('HTTP_REFERER')
        next = next and unquote(next)  # HTTP_REFERER may be encoded.
        if not is_safe_url(url=next, allowed_hosts={request.get_host()}, require_https=request.is_secure()):
            next = '/'
    response = HttpResponseRedirect(next) if next else HttpResponse(status=204)
    if request.method == 'POST':
        lang_code = request.POST.get(LANGUAGE_QUERY_PARAMETER)
        if lang_code and check_for_language(lang_code):
            if next:
                next_trans = translate_url(next, lang_code)
                if next_trans != next:
                    response = HttpResponseRedirect(next_trans)
            if hasattr(request, 'session'):
                request.session[LANGUAGE_SESSION_KEY] = lang_code
            response.set_cookie(
                settings.LANGUAGE_COOKIE_NAME, lang_code,
                max_age=settings.LANGUAGE_COOKIE_AGE,
                path=settings.LANGUAGE_COOKIE_PATH,
                domain=settings.LANGUAGE_COOKIE_DOMAIN,
            )
    return response
Esempio n. 11
0
def get_go_back_url(request, redirect_fieldname=REDIRECT_FIELD_NAME, default='/'):
    redirect_to = request.REQUEST.get(redirect_fieldname)
    if redirect_to == reverse('logout') or not is_safe_url(url=redirect_to, host=request.get_host()):
        redirect_to = request.META.get('HTTP_REFERER')
        if redirect_to == reverse('logout') or not is_safe_url(url=redirect_to, host=request.get_host()):
            redirect_to = resolve_url(default) if default else None
    return redirect_to
Esempio n. 12
0
    def process_response(self, request, response):
        if request.method == 'POST':
            language = request.POST.get('language')
            action = request.POST.get('action')
            if action == 'set_language' and check_for_language(language):
                host = request.get_host()
                next_url = request.GET.get('next', None)
                referer = request.META.get('HTTP_REFERER', None)

                if next_url:
                    if is_safe_url(url = next_url, host = host):
                        response = HttpResponseRedirect(next_url)
                elif referer:
                    if is_safe_url(url = referer, host = host):
                        referer_url = urlparse(referer)[2]
                        try:
                            # http://wenda.soso.io/questions/275666/django-templates-get-current-url-in-another-language
                            view = resolve(referer_url)
                            with translation.override(language):
                                next_url = reverse(view.view_name, args = view.args, kwargs = view.kwargs)
                                response = HttpResponseRedirect(next_url)
                        except (Resolver404, NoReverseMatch):
                            pass

                if hasattr(request, 'session'):
                    request.session[translation.LANGUAGE_SESSION_KEY] = language
                else:
                    response.set_cookie(settings.LANGUAGE_COOKIE_NAME, language, max_age = settings.LANGUAGE_COOKIE_AGE, path = settings.LANGUAGE_COOKIE_PATH, domain = settings.LANGUAGE_COOKIE_DOMAIN)

        return response
Esempio n. 13
0
def set_language(request):
    """
    Redirect to a given url while setting the chosen language in the
    session or cookie. The url and the language code need to be
    specified in the request parameters.
    Since this view changes how the user will see the rest of the site, it must
    only be accessed as a POST request. If called as a GET request, it will
    redirect to the page in the request (the 'next' parameter) without changing
    any state.
    """
    next = request.POST.get('next', request.GET.get('next'))
    if not is_safe_url(url=next, host=request.get_host()):
        next = request.META.get('HTTP_REFERER')
        if not is_safe_url(url=next, host=request.get_host()):
            next = '/'
    response = http.HttpResponseRedirect(next)
    if request.method == 'POST':
        lang_code = request.POST.get(LANGUAGE_QUERY_PARAMETER)
        if lang_code and check_for_language(lang_code):
            next_trans = translate_url(next, lang_code)
            if next_trans != next:
                response = http.HttpResponseRedirect(next_trans)
            if hasattr(request, 'session'):
                request.session[LANGUAGE_SESSION_KEY] = lang_code
            # Always set cookie
            response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang_code,
                                max_age=settings.LANGUAGE_COOKIE_AGE,
                                path=settings.LANGUAGE_COOKIE_PATH,
                                domain=settings.LANGUAGE_COOKIE_DOMAIN)
    return response
Esempio n. 14
0
def set_theme(request):
    """
    Redirect to a given url while setting the chosen theme in the session or cookie. The url and the theme identifier
    need to be specified in the request parameters.

    Since this view changes how the user will see the rest of the site, it must only be accessed as a POST request. If
    called as a GET request, it will redirect to the page in the request (the 'next' parameter) without changing any
    state.
    """
    next = request.POST.get('next', request.GET.get('next'))

    if not is_safe_url(url=next, host=request.get_host()):
        next = request.META.get('HTTP_REFERER')

        if not is_safe_url(url=next, host=request.get_host()):
            next = '/'

    response = http.HttpResponseRedirect(next)

    if request.method == 'POST':
        theme = request.POST.get('theme', None)

        if theme:
            if hasattr(request, 'session'):
                request.session['DJANGO_BOOTSTRAP_UI_THEME'] = theme
            else:
                response.set_cookie('DJANGO_BOOTSTRAP_UI_THEME', theme)

    return response
Esempio n. 15
0
 def test_is_safe_url(self):
     for bad_url in (
         "http://example.com",
         "http:///example.com",
         "https://example.com",
         "ftp://exampel.com",
         r"\\example.com",
         r"\\\example.com",
         r"/\\/example.com",
         r"\\\example.com",
         r"\\example.com",
         r"\\//example.com",
         r"/\/example.com",
         r"\/example.com",
         r"/\example.com",
         "http:///example.com",
         "http:/\//example.com",
         "http:\/example.com",
         "http:/\example.com",
         'javascript:alert("XSS")',
         "\njavascript:alert(x)",
     ):
         self.assertFalse(http.is_safe_url(bad_url, host="testserver"), "%s should be blocked" % bad_url)
     for good_url in (
         "/view/?param=http://example.com",
         "/view/?param=https://example.com",
         "/view?param=ftp://exampel.com",
         "view/?param=//example.com",
         "https://testserver/",
         "HTTPS://testserver/",
         "//testserver/",
         "/url%20with%20spaces/",
     ):
         self.assertTrue(http.is_safe_url(good_url, host="testserver"), "%s should be allowed" % good_url)
Esempio n. 16
0
def set_language(request):
    """
Redirect to a given url while setting the chosen language in the
session or cookie. The url and the language code need to be
specified in the request parameters.

Since this view changes how the user will see the rest of the site, it must
only be accessed as a POST request. If called as a GET request, it will
redirect to the page in the request (the 'next' parameter) without changing
any state.
"""
    next = request.POST.get('next', request.GET.get('next'))
    if not is_safe_url(url=next, host=request.get_host()):
        next = request.META.get('HTTP_REFERER')
        if not is_safe_url(url=next, host=request.get_host()):
            next = '/'
    response = http.HttpResponseRedirect(next)
    if request.method == 'POST':
        lang_code = request.POST.get('language', None)
        if lang_code and check_for_language(lang_code):
            if hasattr(request, 'session'):
                request.session['_language'] = lang_code
            else:
                response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang_code)
    return response
Esempio n. 17
0
def cleanup_next(strategy, **kwargs):
    # This is mostly fix for lack of next validation in Python Social Auth
    # see https://github.com/python-social-auth/social-core/issues/62
    url = strategy.session_get('next')
    if url and not is_safe_url(url, allowed_hosts=None):
        strategy.session_set('next', None)
    if is_safe_url(kwargs.get('next', ''), allowed_hosts=None):
        return None
    return {'next': None}
Esempio n. 18
0
def cookies_agreement_view(request):
    next = request.POST.get('next', request.GET.get('next'))
    if not is_safe_url(url=next, host=request.get_host()):
        next = request.META.get('HTTP_REFERER')
        if not is_safe_url(url=next, host=request.get_host()):
            next = '/'
    if request.method == 'POST':
        request.session['COOKIES_AGREEMENT'] = 'accepted'
    return http.HttpResponseRedirect(next)
Esempio n. 19
0
def language(request, code):
    next = request.POST.get('next', request.GET.get('next'))
    if not is_safe_url(url=next, host=request.get_host()):
        next = request.META.get('HTTP_REFERER')
        if not is_safe_url(url=next, host=request.get_host()):
            next = '/'
    response = http.HttpResponseRedirect(next)
    l = ViewPage(request)
    l.set_language(code, response=response)
    return response
Esempio n. 20
0
 def is_safe_url(self, url):
     if settings.DEBUG:
         return True
     if url is None:
         return False
     current_domain = Site.objects.get_current().domain
     url_domain = urlparse(url).netloc
     # Check if the url domain is (a subdomain of) the current domain
     if url_domain == current_domain or url_domain.endswith("."+current_domain):
         return is_safe_url(url=url, host=url_domain)
     return is_safe_url(url=url)
Esempio n. 21
0
 def get_next_url(self):
     """
     copied from django.views.i18n.set_language.  Grabs the next URL in a
     safe way.
     """
     next = self.request.REQUEST.get('next')
     if not is_safe_url(url=next, host=self.request.get_host()):
         next = self.request.META.get('HTTP_REFERER')
         if not is_safe_url(url=next, host=self.request.get_host()):
             next = self.url
     return next
Esempio n. 22
0
def login(request, template_name='accounts/login.html',
          redirect_field_name=REDIRECT_FIELD_NAME,
          authentication_form=AuthenticationForm,
          current_app=None, extra_context=None):
    """
    Displays the login form and handles the login action.
    Borrowed from ``django.contrib.auth.views.login`` but customized for the following reasons:
        * Don't show the login form to users who are logged in already
        * We had some bugs which didn't capture data that we should have captured.
          For these users we manually logged them out so that the next time they login, we can
          redirect them to their profile page with an appropriate message.
    """
    redirect_to = request.POST.get(redirect_field_name,
                                   request.GET.get(redirect_field_name, ''))
    # This is a customization, not sure why Django doesn't do this already
    # but if the user is already logged in, why would we show them the login form?
    if request.user.is_authenticated():
        if redirect_to and is_safe_url(url=redirect_to, host=request.get_host()):
            return redirect(redirect_to)
        else:
            return redirect('dashboard')

    if request.method == "POST":
        form = authentication_form(request, data=request.POST)
        if form.is_valid():
            # Ensure the user-originating redirection url is safe.
            if redirect_to and not is_safe_url(url=redirect_to,
                                               host=request.get_host()):

                redirect_to = resolve_url(settings.LOGIN_REDIRECT_URL)

            # Okay, security check complete. Log the user in.
            auth_login(request, form.get_user())
            if not redirect_to:
                redirect_to = reverse('dashboard')

            return redirect(redirect_to)
        else:
            messages.error(request, "Please correct the errors below.")
    else:
        form = authentication_form(request)

    current_site = get_current_site(request)

    context = {
        'form': form,
        redirect_field_name: redirect_to,
        'site': current_site,
        'site_name': current_site.name,
    }
    if extra_context is not None:
        context.update(extra_context)
    return render(request, template_name, context)
Esempio n. 23
0
def change_calendar(request):
    nxt = request.POST.get('next', request.GET.get('next'))
    if not is_safe_url(url=nxt, host=request.get_host()):
        nxt = request.META.get('HTTP_REFERER')
        if not is_safe_url(url=nxt, host=request.get_host()):
            nxt = '/'
    response = http.HttpResponseRedirect(nxt)
    if request.method == 'POST':
        cal_code = request.POST.get('calendar')
        if cal_code and hasattr(request, 'session'):
            request.session['sess_cal'] = cal_code
    return response
def set_language(request):
    next = request.GET.get('next')
    if not is_safe_url(url=next, host=request.get_host()):
        next = request.META.get('HTTP_REFERER')
        if not is_safe_url(url=next, host=request.get_host()):
            next = '/'
    response = http.HttpResponseRedirect(next)

    lang_code = request.GET.get('lang')
    if lang_code and check_for_language(lang_code):
        response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang_code)

    return response
Esempio n. 25
0
    def test_is_safe_url(self):
        for bad_url in ('http://example.com',
                        'http:///example.com',
                        'https://example.com',
                        'ftp://example.com',
                        r'\\example.com',
                        r'\\\example.com',
                        r'/\\/example.com',
                        r'\\\example.com',
                        r'\\example.com',
                        r'\\//example.com',
                        r'/\/example.com',
                        r'\/example.com',
                        r'/\example.com',
                        'http:///example.com',
                        'http:/\//example.com',
                        'http:\/example.com',
                        'http:/\example.com',
                        'javascript:alert("XSS")',
                        '\njavascript:alert(x)',
                        '\x08//example.com',
                        r'http://otherserver\@example.com',
                        r'http:\\testserver\@example.com',
                        r'http://testserver\me:[email protected]',
                        r'http://testserver\@example.com',
                        r'http:\\testserver\confirm\[email protected]',
                        '\n'):
            self.assertFalse(http.is_safe_url(bad_url, host='testserver'), "%s should be blocked" % bad_url)
        for good_url in ('/view/?param=http://example.com',
                     '/view/?param=https://example.com',
                     '/view?param=ftp://example.com',
                     'view/?param=//example.com',
                     'https://testserver/',
                     'HTTPS://testserver/',
                     '//testserver/',
                     'http://testserver/[email protected]',
                     '/url%20with%20spaces/'):
            self.assertTrue(http.is_safe_url(good_url, host='testserver'), "%s should be allowed" % good_url)

        if six.PY2:
            # Check binary URLs, regression tests for #26308
            self.assertTrue(
                http.is_safe_url(b'https://testserver/', host='testserver'),
                "binary URLs should be allowed on Python 2"
            )
            self.assertFalse(http.is_safe_url(b'\x08//example.com', host='testserver'))
            self.assertTrue(http.is_safe_url('àview/'.encode('utf-8'), host='testserver'))
            self.assertFalse(http.is_safe_url('àview'.encode('latin-1'), host='testserver'))

        # Valid basic auth credentials are allowed.
        self.assertTrue(http.is_safe_url(r'http://*****:*****@testserver/', host='user:pass@testserver'))
        # A path without host is allowed.
        self.assertTrue(http.is_safe_url('/confirm/[email protected]'))
        # Basic auth without host is not allowed.
        self.assertFalse(http.is_safe_url(r'http://testserver\@example.com'))
Esempio n. 26
0
def set_language(request):
    next = request.REQUEST.get('next')
    if not is_safe_url(url=next, host=request.get_host()):
        next = request.META.get('HTTP_REFERER')
        if not is_safe_url(url=next, host=request.get_host()):
            next = '/'
    response = http.HttpResponseRedirect(next)
    lang_code = request.GET.get('language', None)
    if lang_code and check_for_language(lang_code):
        if hasattr(request, 'session'):
            request.session['django_language'] = lang_code
        else:
            response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang_code)
    return response
Esempio n. 27
0
def set_language(request, lang_code):
    """View to change site language."""
    next_url = request.GET.get('next')
    if not is_safe_url(url=next_url, host=request.get_host()):
        next_url = request.META.get('HTTP_REFERER')
        if not is_safe_url(url=next_url, host=request.get_host()):
            next_url = '/'
    response = HttpResponseRedirect(next_url)
    if lang_code and check_for_language(lang_code):
        if hasattr(request, 'session'):
            request.session['django_language'] = lang_code
        else:
            response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang_code)
    return response
Esempio n. 28
0
def set_language(request):
    """
    Redirect to a given url, reversed while setting the chosen language in the
    session or cookie. The url and the language code need to be
    specified in the request parameters.

    Since this view changes how the user will see the rest of the site, it must
    only be accessed as a POST request.
    """
    
    if request.method == 'POST':
        # get necessary values from request
        language = request.POST.get('language', None)
        next_path = request.REQUEST.get('next', '')
        # django safety checks... 
        if not is_safe_url(url=next_path, host=request.get_host()):
            referer = request.META.get('HTTP_REFERER', '')
            next_path = urlparse.urlparse(referer).path
            if not is_safe_url(url=next_path, host=request.get_host):
                next_path = '/'
        
        next_path = urllib.unquote(next_path).decode('utf8')

        # check if given url is found using current locale
        resolver = get_resolver(None)
        resolve_result = try_url_for_language(next_path, get_language(), resolver)
        if resolve_result is None:
            # we didn't succeed at resolving the url with current locale, so
            # we may as well redirect to given url, and it will just be a 404
            redirect_to = next_path
        else:
            # we did succeed, this means the route exists and we can get view's
            # name, expected args and kwargs
            url_name = resolve_result.url_name
            view_args = resolve_result[1]
            view_kwargs = resolve_result[2]
            with locale_context(language):
                redirect_to = reverse(url_name, args=view_args, kwargs=view_kwargs)
            
        # this is standard django stuff again...
        response = http.HttpResponseRedirect(redirect_to)
        if language and check_for_language(language):
            if hasattr(request, 'session'):
                request.session['django_language'] = language
            else:
                response.set_cookie(settings.LANGUAGE_COOKIE_NAME, language)
        return response
    else:
        return http.HttpResponseNotAllowed(['POST',])
Esempio n. 29
0
    def done(self, form_list, **kwargs):
        user = self.get_user()
        login(self.request, user)

        if not self.request.user.info.registration_finished:
            # If the user has not finished registration yet, redirect them there to finish it now.
            redirect_to = reverse('register')
        else:
            redirect_to = self.request.POST.get(
                self.redirect_field_name,
                self.request.GET.get(self.redirect_field_name, '')
            )
            if not is_safe_url(url=redirect_to, host=self.request.get_host()):
                redirect_to = resolve_url(settings.LOGIN_REDIRECT_URL)

        device = getattr(user, 'otp_device', None)

        if device:
            if isinstance(device, StaticDevice):
                # User logged in using a static backup code, refresh it with a new one.
                device.token_set.create(token=StaticToken.random_token())

            signals.user_verified.send(
                sender=__name__,
                request=self.request,
                user=user,
                device=device
            )

        # Track login type in Segment.
        analytics.track(user.id, 'user-login', {
            'login_type': 'Traditional',
        })

        return redirect(redirect_to)
Esempio n. 30
0
def logout(request, next_page=None,
           template_name='registration/logged_out.html',
           redirect_field_name=REDIRECT_FIELD_NAME,
           current_app=None, extra_context=None):
    """
    Logs out the user and displays 'You are logged out' message.
    """
    auth_logout(request)

    if redirect_field_name in request.REQUEST:
        next_page = request.REQUEST[redirect_field_name]
        # Security check -- don't allow redirection to a different host.
        if not is_safe_url(url=next_page, host=request.get_host()):
            next_page = request.path

    if next_page:
        # Redirect to this page until the session has been cleared.
        return HttpResponseRedirect(next_page)

    current_site = get_current_site(request)
    context = {
        'site': current_site,
        'site_name': current_site.name,
        'title': _('Logged out')
    }
    if extra_context is not None:
        context.update(extra_context)
    return TemplateResponse(request, template_name, context,
        current_app=current_app)
Esempio n. 31
0
def get_redirect_url(request, redirect_to, fallback):
    # Ensure the user-originating redirection url is safe.
    if not is_safe_url(url=redirect_to, allowed_hosts={request.get_host()}):
        redirect_to = resolve_url(fallback)
    return redirect_to
Esempio n. 32
0
def limited_login(request, template_name='registration/login.html',
          redirect_field_name=REDIRECT_FIELD_NAME,
          authentication_form=AuthenticationForm,
          current_app=None, extra_context=None):
    """
    Displays the login form and handles the login action.
    """
    redirect_to = request.REQUEST.get(redirect_field_name, '')
    request.session.set_test_cookie()

    if request.method == "POST":
        form = authentication_form(request, data=request.POST)
        username = request.POST.get('username')
        try:
            target_user = LinkUser.objects.get(email=username)
        except LinkUser.DoesNotExist:
            target_user = None
        if target_user and not target_user.is_confirmed:
            request.session['email'] = target_user.email
            return HttpResponseRedirect(reverse('user_management_not_active'))
        elif target_user and not target_user.is_active:
            return HttpResponseRedirect(reverse('user_management_account_is_deactivated'))
            
          
        if form.is_valid():
            
            host = request.get_host()

            if settings.DEBUG == False:
                host = settings.HOST

            # Ensure the user-originating redirection url is safe.
            if not is_safe_url(url=redirect_to, host=host):
                redirect_to = resolve_url(settings.LOGIN_REDIRECT_URL)

            # Okay, security check complete. Log the user in.
            auth_login(request, form.get_user())

            response = HttpResponseRedirect(redirect_to)

            # Set the user-info cookie for mirror servers.
            # This will be set by the main server, e.g. //direct.perma.cc,
            # but will be readable by any mirror serving //perma.cc.
            user_info = {
                'groups':[group.pk for group in request.user.groups.all()],
            }
            # The cookie should last as long as the login cookie, so cookie logic is copied from SessionMiddleware.
            if request.session.get_expire_at_browser_close():
                max_age = None
                expires = None
            else:
                max_age = request.session.get_expiry_age()
                expires_time = time.time() + max_age
                expires = cookie_date(expires_time)
            response.set_cookie(settings.MIRROR_COOKIE_NAME,
                                json.dumps(user_info),
                                max_age=max_age,
                                expires=expires,
                                domain=get_mirror_cookie_domain(request),
                                path=settings.SESSION_COOKIE_PATH,
                                secure=settings.SESSION_COOKIE_SECURE or None,
                                httponly=settings.SESSION_COOKIE_HTTPONLY or None)

            return response
    else:
        form = authentication_form(request)

    current_site = get_current_site(request)

    context = {
        'form': form,
        redirect_field_name: redirect_to,
        'site': current_site,
        'site_name': current_site.name,
    }
    if extra_context is not None:
        context.update(extra_context)
    return TemplateResponse(request, template_name, context,
                            current_app=current_app)
Esempio n. 33
0
def weblate_context(request):
    """Context processor to inject various useful variables into context."""
    if 'next' in request.GET and is_safe_url(request.GET['next']):
        login_redirect_url = request.GET['next']
    else:
        login_redirect_url = request.get_full_path()

    projects = Project.objects.all_acl(request.user)

    # Load user translations if user is authenticated
    subscribed_projects = None
    if request.user.is_authenticated:
        subscribed_projects = request.user.profile.subscriptions.all()

    if settings.OFFER_HOSTING:
        description = _(
            'Hosted Weblate, the place to translate your software project.'
        )
    else:
        description = _(
            'This site runs Weblate for translating various software projects.'
        )

    if (hasattr(settings, 'ROLLBAR') and
            'client_token' in settings.ROLLBAR and
            'environment' in settings.ROLLBAR):
        rollbar_token = settings.ROLLBAR['client_token']
        rollbar_environment = settings.ROLLBAR['environment']
    else:
        rollbar_token = None
        rollbar_environment = None

    return {
        'version': weblate.VERSION,
        'description': description,

        'weblate_url': URL_BASE % weblate.VERSION,
        'donate_url': URL_DONATE % weblate.VERSION,

        'site_title': settings.SITE_TITLE,
        'site_url': get_site_url(),

        'offer_hosting': settings.OFFER_HOSTING,
        'demo_server': settings.DEMO_SERVER,
        'enable_avatars': settings.ENABLE_AVATARS,
        'enable_sharing': settings.ENABLE_SHARING,

        'piwik_site_id': settings.PIWIK_SITE_ID,
        'piwik_url': settings.PIWIK_URL,
        'google_analytics_id': settings.GOOGLE_ANALYTICS_ID,

        'current_date': datetime.utcnow().strftime('%Y-%m-%d'),
        'current_year': datetime.utcnow().strftime('%Y'),
        'current_month': datetime.utcnow().strftime('%m'),

        'login_redirect_url': login_redirect_url,

        'hooks_enabled': settings.ENABLE_HOOKS,
        'has_ocr': weblate.screenshots.views.HAS_OCR,

        'registration_open': settings.REGISTRATION_OPEN,
        'acl_projects': projects,
        'subscribed_projects': subscribed_projects,

        'rollbar_token': rollbar_token,
        'rollbar_environment': rollbar_environment,
    }
Esempio n. 34
0
def adjudicator_view_application(request):
    """View which handles adjudicator viewing of applications"""

    application_id = request.GET.get("application_id", "")

    FSJ_user = get_FSJ_user(request.user.username)
    context = get_standard_context(FSJ_user)
    # Return_url specifies where the view is being accessed from
    return_url = request.GET.get("return", "")
    url_is_safe = is_safe_url(
        url=urllib.parse.unquote(return_url),
        allowed_hosts=settings.ALLOWED_HOSTS,
        require_https=request.is_secure(),
    )

    try:
        # Archived applications can only be viewed by coordinators and get redirected
        application = Application.objects.get(application_id=application_id)
        if application.is_archived or not application.is_reviewed:
            return redirect('/home/')
    except Application.DoesNotExist:
        messages.warning(request, _("This application does not exist"))

        if url_is_safe:
            return redirect(urllib.parse.unquote(return_url))

    # Adjudicators cannot post directly to the application
    if request.method == 'POST':
        raise PermissionDenied

    else:
        try:
            comment = Comment.objects.get(application=application,
                                          adjudicator=FSJ_user)
            form = CommentRestrictedForm(instance=comment, prefix="form")

            delete_url = "/awards/delete/?award_id=" + str(
                application.award.awardid) + "&application_id=" + str(
                    application.application_id)
            context["delete_url"] = delete_url

        except Comment.DoesNotExist:
            form = CommentRestrictedForm(prefix="form")

        try:
            ranking = Ranking.objects.get(application=application,
                                          adjudicator=FSJ_user)
            form2 = RankingRestrictedForm(FSJ_user,
                                          application.award,
                                          instance=ranking,
                                          prefix="form2")
            context["ranking"] = ranking

        except Ranking.DoesNotExist:
            form2 = RankingRestrictedForm(FSJ_user,
                                          application.award,
                                          prefix="form2")

        url = "/awards/edit/?award_id=" + str(
            application.award.awardid) + "&application_id=" + str(
                application.application_id)

        # form is the Comment form
        context["form"] = form
        # form2 is the Ranking form
        context["form2"] = form2
        context["adjudicator"] = FSJ_user

        context["student"] = application.student
        if application.application_file:
            context["document"] = settings.MEDIA_URL + str(
                application.application_file)
        context["award"] = application.award
        context["url"] = url
        if url_is_safe and return_url:
            context["return_url"] = str(return_url)

        context["archived"] = False
        context["FSJ_user"] = FSJ_user
        template = loader.get_template("FSJ/view_application.html")

        application.add_viewed(FSJ_user)
        return HttpResponse(template.render(context, request))
Esempio n. 35
0
 def get_success_url(self):
     if 'next' in self.request.GET and is_safe_url(
             self.request.GET['next']):
         return self.request.GET['next']
     else:
         return super(AddTOTPDeviceView, self).get_success_url()
Esempio n. 36
0
    def get_success_url(self):

        redirect_to = self.request.POST.get(self.redirect_field_name)
        if not is_safe_url(url=redirect_to, allowed_hosts=[self.request.get_host()]):
            redirect_to = self.success_url
        return redirect_to
Esempio n. 37
0
 def is_safe_url(self, url):
     from django.utils.http import is_safe_url
     return is_safe_url(url)
Esempio n. 38
0
 def get_success_url(self):
     redirect_to = self.request.GET.get(self.redirect_field_name)
     if not is_safe_url(url=redirect_to, host=self.request.get_host()):
         redirect_to = self.success_url
     return redirect_to
Esempio n. 39
0
 def redirect(self, request):
     next = request.GET.get(REDIRECT_FIELD_NAME, "")
     if not is_safe_url(next, host=request.get_host()):
         next = auth.get_login_url()
     return super().redirect(next)
Esempio n. 40
0
 def is_safe_url(self, url):
     return is_safe_url(url=url, host=self.request.get_host())
Esempio n. 41
0
 def clean_redirect_url(self):
     url = self.cleaned_data['redirect_url'].strip()
     if url and is_safe_url(url, self.host):
         return url
     return settings.LOGIN_REDIRECT_URL
Esempio n. 42
0
 def clean_redirect_url(self):
     url = self.cleaned_data['redirect_url'].strip()
     if url and is_safe_url(url, self.host):
         return url
Esempio n. 43
0
def login(
    request,
    template_name="accounts/login.html",
    redirect_field_name=REDIRECT_FIELD_NAME,
    authentication_form=AuthenticationForm,
    current_app=None,
    extra_context=None,
):
    """
    Displays the login form and handles the login action.
    """
    is_json = "application/json" in request.META.get("HTTP_ACCEPT", "")
    redirect_to = request.REQUEST.get(redirect_field_name, "")

    if request.method == "POST":
        form = authentication_form(request, data=request.POST)
        if form.is_valid():
            # Ensure the user-originating redirection url is safe.
            if not is_safe_url(url=redirect_to, host=request.get_host()):
                redirect_to = resolve_url(form.get_login_redirect_url())

            # Okay, security check complete. Log the user in.
            auth_login(request, form.get_user())

            statsd.incr("login.success")

            logger.info(
                "login succeeded",
                extra={
                    "IP": get_ip(request),
                    "USERNAME": request.POST.get("username"),
                    "HTTP_REFERER": request.META.get("HTTP_REFERER"),
                    "HTTP_USER_AGENT": request.META.get("HTTP_USER_AGENT"),
                },
            )

            if is_json:
                return HttpResponse(status=204)
            return HttpResponseRedirect(redirect_to)
        else:
            statsd.incr("login.failed")

            logger.info(
                "login failed",
                extra={
                    "IP": get_ip(request),
                    "USERNAME": request.POST.get("username"),
                    "HTTP_REFERER": request.META.get("HTTP_REFERER"),
                    "HTTP_USER_AGENT": request.META.get("HTTP_USER_AGENT"),
                },
            )

            if is_json:
                return HttpResponse(json.dumps(form.errors),
                                    status=400,
                                    content_type="application/json")
    else:
        form = authentication_form(request)

    current_site = get_current_site(request)

    context = {
        "form": form,
        redirect_field_name: redirect_to,
        "site": current_site,
        "site_name": current_site.name
    }
    if extra_context is not None:
        context.update(extra_context)

    return TemplateResponse(request,
                            template_name,
                            context,
                            current_app=current_app)
Esempio n. 44
0
    def post(self, request, **kwargs):

        # Attempt to derive parent object if a parent class has been given
        if self.parent_cls:
            parent_obj = get_object_or_404(self.parent_cls, **kwargs)
        else:
            parent_obj = None

        # Determine URL to redirect users upon modification of objects
        posted_return_url = request.POST.get('return_url')
        if posted_return_url and is_safe_url(url=posted_return_url,
                                             host=request.get_host()):
            return_url = posted_return_url
        elif parent_obj:
            return_url = parent_obj.get_absolute_url()
        else:
            return_url = reverse(self.default_return_url)

        # Are we editing *all* objects in the queryset or just a selected subset?
        if request.POST.get('_all') and self.filter is not None:
            pk_list = [
                obj.pk for obj in self.filter(request.GET,
                                              self.cls.objects.only('pk')).qs
            ]
        else:
            pk_list = [int(pk) for pk in request.POST.getlist('pk')]

        if '_apply' in request.POST:
            form = self.form(self.cls, request.POST)
            if form.is_valid():

                custom_fields = form.custom_fields if hasattr(
                    form, 'custom_fields') else []
                standard_fields = [
                    field for field in form.fields
                    if field not in custom_fields and field != 'pk'
                ]
                nullified_fields = request.POST.getlist('_nullify')

                try:

                    with transaction.atomic():

                        updated_count = 0
                        for obj in self.cls.objects.filter(pk__in=pk_list):

                            # Update standard fields. If a field is listed in _nullify, delete its value.
                            for name in standard_fields:
                                if name in form.nullable_fields and name in nullified_fields:
                                    setattr(
                                        obj, name, '' if isinstance(
                                            form.fields[name], CharField) else
                                        None)
                                elif form.cleaned_data[name] not in (None, ''):
                                    setattr(obj, name, form.cleaned_data[name])
                            obj.full_clean()
                            obj.save()

                            # Update custom fields
                            obj_type = ContentType.objects.get_for_model(
                                self.cls)
                            for name in custom_fields:
                                field = form.fields[name].model
                                if name in form.nullable_fields and name in nullified_fields:
                                    CustomFieldValue.objects.filter(
                                        field=field,
                                        obj_type=obj_type,
                                        obj_id=obj.pk).delete()
                                elif form.cleaned_data[name] not in [None, '']:
                                    try:
                                        cfv = CustomFieldValue.objects.get(
                                            field=field,
                                            obj_type=obj_type,
                                            obj_id=obj.pk)
                                    except CustomFieldValue.DoesNotExist:
                                        cfv = CustomFieldValue(
                                            field=field,
                                            obj_type=obj_type,
                                            obj_id=obj.pk)
                                    cfv.value = form.cleaned_data[name]
                                    cfv.save()

                            updated_count += 1

                    if updated_count:
                        msg = 'Updated {} {}'.format(
                            updated_count, self.cls._meta.verbose_name_plural)
                        messages.success(self.request, msg)
                        UserAction.objects.log_bulk_edit(
                            request.user,
                            ContentType.objects.get_for_model(self.cls), msg)

                    return redirect(return_url)

                except ValidationError as e:
                    messages.error(self.request,
                                   "{} failed validation: {}".format(obj, e))

        else:
            initial_data = request.POST.copy()
            initial_data['pk'] = pk_list
            form = self.form(self.cls, initial=initial_data)

        # Retrieve objects being edited
        queryset = self.queryset or self.cls.objects.all()
        table = self.table(queryset.filter(pk__in=pk_list), orderable=False)
        if not table.rows:
            messages.warning(
                request, "No {} were selected.".format(
                    self.cls._meta.verbose_name_plural))
            return redirect(return_url)

        return render(
            request, self.template_name, {
                'form': form,
                'table': table,
                'obj_type_plural': self.cls._meta.verbose_name_plural,
                'return_url': return_url,
            })
Esempio n. 45
0
def step_4(request, step):
    gleaned_data = get_deserialized_gleaned_data(request)

    if gleaned_data is None:
        return redirect('data_capture:step_3')

    if request.method == 'GET' and not gleaned_data.valid_rows:
        return redirect('data_capture:step_3')

    session_pl = request.session[SESSION_KEY]
    step_1_form = get_step_form_from_session(1, request)
    step_2_form = get_step_form_from_session(2, request)

    pl_details = {
        'preferred_schedule': step_1_form.cleaned_data['schedule_class'],
        'contract_number': step_1_form.cleaned_data['contract_number'],
        'vendor_name': step_2_form.cleaned_data['vendor_name'],
        'is_small_business': step_2_form.cleaned_data['is_small_business'],
        'contractor_site': step_2_form.cleaned_data['contractor_site'],
        'contract_start': step_2_form.cleaned_data['contract_start'],
        'contract_end': step_2_form.cleaned_data['contract_end'],
        'escalation_rate': step_2_form.cleaned_data['escalation_rate'],
    }

    show_edit_form = (request.GET.get('show_edit_form') == 'on')

    if request.method == 'POST':
        if not gleaned_data.valid_rows:
            # Our UI never should've let the user issue a request
            # like this.
            return HttpResponseBadRequest()
        form = forms.Step4Form(request.POST)
    else:
        form = forms.Step4Form.from_post_data_subsets(
            session_pl['step_1_POST'], session_pl['step_2_POST'])

    prev_url = request.GET.get('prev')
    if not is_safe_url(prev_url):
        prev_url = None

    step_4_without_edit_url = build_url('data_capture:step_4', prev=prev_url)
    step_4_with_edit_url = build_url('data_capture:step_4',
                                     prev=prev_url,
                                     show_edit_form='on')

    if request.method == 'POST':
        if form.is_valid():
            if 'save-changes' in request.POST:
                # There's not a particularly easy way to separate one
                # step's fields from another, but fortunately that's OK
                # because Django's Form constructors take only the POST
                # data they need, and ignore the rest.
                session_pl['step_1_POST'] = request.POST
                session_pl['step_2_POST'] = request.POST

                # Changing the value of a subkey doesn't cause the session to
                # save, so do it manually.
                request.session.modified = True

                return redirect(step_4_without_edit_url)
            else:
                price_list = form.save(commit=False)

                price_list.submitter = request.user
                price_list.serialized_gleaned_data = json.dumps(
                    session_pl['gleaned_data'])

                # We always want to explicitly set the schedule to the
                # one that the gleaned data is part of, in case we gracefully
                # fell back to a schedule other than the one the user chose.
                price_list.schedule = registry.get_classname(gleaned_data)

                price_list.status = SubmittedPriceList.STATUS_UNREVIEWED
                price_list.status_changed_at = timezone.now()
                price_list.status_changed_by = request.user

                price_list.uploaded_filename = session_pl['filename']

                price_list.save()
                gleaned_data.add_to_price_list(price_list)

                del request.session[SESSION_KEY]

                return redirect('data_capture:step_5')
        else:
            add_generic_form_error(request, form)
            show_edit_form = True

    return step.render(
        request, {
            'show_edit_form':
            show_edit_form,
            'form':
            form,
            'step_4_with_edit_url':
            step_4_with_edit_url,
            'step_4_without_edit_url':
            step_4_without_edit_url,
            'prev_url':
            prev_url,
            'gleaned_data':
            gleaned_data,
            'price_list':
            pl_details,
            'is_preferred_schedule':
            isinstance(gleaned_data, pl_details['preferred_schedule']),
            'preferred_schedule_title':
            pl_details['preferred_schedule'].title,
        })
Esempio n. 46
0
def get_safe_redirect_to(url: str, redirect_host: str) -> str:
    is_url_safe = is_safe_url(url=url, allowed_hosts=set(redirect_host))
    if is_url_safe:
        return urllib.parse.urljoin(redirect_host, url)
    else:
        return redirect_host
Esempio n. 47
0
    def post(self, request):

        form = ImportForm(request.POST)
        if form.is_valid():

            # Initialize model form
            data = form.cleaned_data['data']
            model_form = self.model_form(data)

            # Assign default values for any fields which were not specified. We have to do this manually because passing
            # 'initial=' to the form on initialization merely sets default values for the widgets. Since widgets are not
            # used for YAML/JSON import, we first bind the imported data normally, then update the form's data with the
            # applicable field defaults as needed prior to form validation.
            for field_name, field in model_form.fields.items():
                if field_name not in data and hasattr(field, 'initial'):
                    model_form.data[field_name] = field.initial

            if model_form.is_valid():

                try:
                    with transaction.atomic():

                        # Save the primary object
                        obj = model_form.save()

                        # Iterate through the related object forms (if any), validating and saving each instance.
                        for field_name, related_object_form in self.related_object_forms.items(
                        ):

                            for i, rel_obj_data in enumerate(
                                    data.get(field_name, list())):

                                f = related_object_form(obj, rel_obj_data)

                                for subfield_name, field in f.fields.items():
                                    if subfield_name not in rel_obj_data and hasattr(
                                            field, 'initial'):
                                        f.data[subfield_name] = field.initial

                                if f.is_valid():
                                    f.save()
                                else:
                                    # Replicate errors on the related object form to the primary form for display
                                    for subfield_name, errors in f.errors.items(
                                    ):
                                        for err in errors:
                                            err_msg = "{}[{}] {}: {}".format(
                                                field_name, i, subfield_name,
                                                err)
                                            model_form.add_error(None, err_msg)
                                    raise AbortTransaction()

                except AbortTransaction:
                    pass

            if not model_form.errors:

                messages.success(
                    request,
                    mark_safe('Imported object: <a href="{}">{}</a>'.format(
                        obj.get_absolute_url(), obj)))

                if '_addanother' in request.POST:
                    return redirect(request.get_full_path())

                return_url = form.cleaned_data.get('return_url')
                if return_url is not None and is_safe_url(
                        url=return_url, allowed_hosts=request.get_host()):
                    return redirect(return_url)
                else:
                    return redirect(self.get_return_url(request, obj))

            else:

                # Replicate model form errors for display
                for field, errors in model_form.errors.items():
                    for err in errors:
                        if field == '__all__':
                            form.add_error(None, err)
                        else:
                            form.add_error(None, "{}: {}".format(field, err))

        return render(
            request, self.template_name, {
                'form': form,
                'obj_type': self.model._meta.verbose_name,
                'return_url': self.get_return_url(request),
            })
Esempio n. 48
0
def _get_login_redirect_url(request, redirect_to):
    """ Ensure the user-originating redirection URL is safe.
    """
    if not is_safe_url(url=redirect_to, host=request.get_host()):
        return resolve_url(settings.LOGIN_REDIRECT_URL)
    return redirect_to
Esempio n. 49
0
def proxy(request):
    PROXY_ALLOWED_HOSTS = getattr(settings, 'PROXY_ALLOWED_HOSTS', ())

    host = None

    if 'geonode.geoserver' in settings.INSTALLED_APPS:
        from geonode.geoserver.helpers import ogc_server_settings
        hostname = (
            ogc_server_settings.hostname, ) if ogc_server_settings else ()
        PROXY_ALLOWED_HOSTS += hostname
        host = ogc_server_settings.netloc

    if 'url' not in request.GET:
        return HttpResponse(
            "The proxy service requires a URL-encoded URL as a parameter.",
            status=400,
            content_type="text/plain")

    raw_url = request.GET['url']
    url = urlsplit(raw_url)
    locator = str(url.path)
    if url.query != "":
        locator += '?' + url.query
    if url.fragment != "":
        locator += '#' + url.fragment

    if not settings.DEBUG:
        if not validate_host(url.hostname, PROXY_ALLOWED_HOSTS):
            return HttpResponse(
                "DEBUG is set to False but the host of the path provided to the proxy service"
                " is not in the PROXY_ALLOWED_HOSTS setting.",
                status=403,
                content_type="text/plain")
    headers = {}

    if settings.SESSION_COOKIE_NAME in request.COOKIES and is_safe_url(
            url=raw_url, host=host):
        headers["Cookie"] = request.META["HTTP_COOKIE"]

    if request.method in ("POST", "PUT") and "CONTENT_TYPE" in request.META:
        headers["Content-Type"] = request.META["CONTENT_TYPE"]

    if url.scheme == 'https':
        conn = HTTPSConnection(url.hostname, url.port)
    else:
        conn = HTTPConnection(url.hostname, url.port)
    conn.request(request.method, locator, request.body, headers)

    result = conn.getresponse()

    # If we get a redirect, let's add a useful message.
    if result.status in (301, 302, 303, 307):
        response = HttpResponse(
            ('This proxy does not support redirects. The server in "%s" '
             'asked for a redirect to "%s"' %
             (url, result.getheader('Location'))),
            status=result.status,
            content_type=result.getheader("Content-Type", "text/plain"))

        response['Location'] = result.getheader('Location')
    else:
        response = HttpResponse(result.read(),
                                status=result.status,
                                content_type=result.getheader(
                                    "Content-Type", "text/plain"))

    return response
Esempio n. 50
0
 def clean_redirect_url(self):
     redirect_url = self.cleaned_data['redirect_url']
     if is_safe_url(redirect_url,
                    allowed_hosts=settings.ALLOWED_REDIRECT_HOSTS):
         return redirect_url
     return ''
Esempio n. 51
0
def get_valid_next_url_from_request(request):
    next_url = request.POST.get('next') or request.GET.get('next')
    if not next_url or not is_safe_url(url=next_url, host=request.get_host()):
        return ''
    return next_url
Esempio n. 52
0
def safe_redirect(url, action):
    if not is_safe_url(url):
        url = reverse('home')
    log.info(u'Redirecting after {} to: {}'.format(action, url))
    return HttpResponseRedirect(url)
Esempio n. 53
0
 def get_success_url(self):
     url = self.request.POST.get(REDIRECT_FIELD_NAME)
     if url and is_safe_url(url, self.request.get_host()):
         return url
     return settings.LOGIN_REDIRECT_URL
Esempio n. 54
0
def redirect_next(next_url, fallback):
    """Redirect to next URL from request after validating it."""
    if (next_url is None or not is_safe_url(next_url, allowed_hosts=None)
            or not next_url.startswith('/')):
        return redirect(fallback)
    return HttpResponseRedirect(next_url)
Esempio n. 55
0
    def post(self, request, **kwargs):

        # Attempt to derive parent object if a parent class has been given
        if self.parent_cls:
            parent_obj = get_object_or_404(self.parent_cls, **kwargs)
        else:
            parent_obj = None

        # Determine URL to redirect users upon modification of objects
        posted_return_url = request.POST.get('return_url')
        if posted_return_url and is_safe_url(url=posted_return_url, host=request.get_host()):
            return_url = posted_return_url
        elif parent_obj:
            return_url = parent_obj.get_absolute_url()
        else:
            return_url = reverse(self.default_return_url)

        # Are we editing *all* objects in the queryset or just a selected subset?
        if request.POST.get('_all') and self.filter is not None:
            pk_list = [obj.pk for obj in self.filter(request.GET, self.cls.objects.only('pk')).qs]
        else:
            pk_list = [int(pk) for pk in request.POST.getlist('pk')]

        if '_apply' in request.POST:
            form = self.form(self.cls, request.POST)
            if form.is_valid():

                custom_fields = form.custom_fields if hasattr(form, 'custom_fields') else []
                standard_fields = [field for field in form.fields if field not in custom_fields and field != 'pk']

                # Update standard fields. If a field is listed in _nullify, delete its value.
                nullified_fields = request.POST.getlist('_nullify')
                fields_to_update = {}
                for field in standard_fields:
                    if field in form.nullable_fields and field in nullified_fields:
                        if isinstance(form.fields[field], CharField):
                            fields_to_update[field] = ''
                        else:
                            fields_to_update[field] = None
                    elif form.cleaned_data[field] not in (None, ''):
                        fields_to_update[field] = form.cleaned_data[field]
                updated_count = self.cls.objects.filter(pk__in=pk_list).update(**fields_to_update)

                # Update custom fields for objects
                if custom_fields:
                    objs_updated = self.update_custom_fields(pk_list, form, custom_fields, nullified_fields)
                    if objs_updated and not updated_count:
                        updated_count = objs_updated

                if updated_count:
                    msg = 'Updated {} {}'.format(updated_count, self.cls._meta.verbose_name_plural)
                    messages.success(self.request, msg)
                    UserAction.objects.log_bulk_edit(request.user, ContentType.objects.get_for_model(self.cls), msg)
                return redirect(return_url)

        else:
            initial_data = request.POST.copy()
            initial_data['pk'] = pk_list
            form = self.form(self.cls, initial=initial_data)

        # Retrieve objects being edited
        queryset = self.queryset or self.cls.objects.all()
        table = self.table(queryset.filter(pk__in=pk_list), orderable=False)
        if not table.rows:
            messages.warning(request, "No {} were selected.".format(self.cls._meta.verbose_name_plural))
            return redirect(return_url)

        return render(request, self.template_name, {
            'form': form,
            'table': table,
            'obj_type_plural': self.cls._meta.verbose_name_plural,
            'return_url': return_url,
        })
Esempio n. 56
0
def login(request,
          template_name='registration/login.html',
          redirect_field_name=REDIRECT_FIELD_NAME,
          authentication_form=AuthenticationForm,
          current_app=None,
          extra_context=None):
    """
    Displays the login form and handles the login action.
    """
    redirect_to = request.REQUEST.get(redirect_field_name, '')

    if request.method == "POST":
        form = authentication_form(request, data=request.POST)
        if form.is_valid():

            # Ensure the user-originating redirection url is safe.
            if not is_safe_url(url=redirect_to, host=request.get_host()):
                redirect_to = resolve_url(settings.LOGIN_REDIRECT_URL)

            # Okay, security check complete. Log the user in.
            auth_login(request, form.get_user())

            rp = HttpResponseRedirect(redirect_to)

            from lighting.models import Remind, Unit

            for unit in Unit.objects.all():
                if Remind.objects.filter(unit=unit):
                    continue
                if unit.is_expiring or unit.is_expired:
                    if Unit.objects.filter(
                            name=unit.name).order_by("-validity")[0] == unit:
                        Remind(unit=unit).save()
            for remind in Remind.objects.all():
                if not (remind.unit.is_expiring or remind.unit.is_expired):
                    remind.delete()
                unit = remind.unit
                if Unit.objects.filter(
                        name=unit.name).order_by("-validity")[0] != unit:
                    remind.delete()

            if Remind.objects.filter(is_show=True, deleted=False):
                rp.set_cookie("remind", "true")
            else:
                rp.set_cookie("remind", "false")
            return rp
    else:
        form = authentication_form(request)

    current_site = get_current_site(request)

    context = {
        'form': form,
        redirect_field_name: redirect_to,
        'site': current_site,
        'site_name': current_site.name,
    }
    if extra_context is not None:
        context.update(extra_context)
    return TemplateResponse(request,
                            template_name,
                            context,
                            current_app=current_app)
Esempio n. 57
0
def switch_keystone_provider(request, keystone_provider=None,
                             redirect_field_name=auth.REDIRECT_FIELD_NAME):
    """Switches the user's keystone provider using K2K Federation

    If keystone_provider is given then we switch the user to
    the keystone provider using K2K federation. Otherwise if keystone_provider
    is None then we switch the user back to the Identity Provider Keystone
    which a non federated token auth will be used.
    """
    base_token = request.session.get('k2k_base_unscoped_token', None)
    k2k_auth_url = request.session.get('k2k_auth_url', None)
    keystone_providers = request.session.get('keystone_providers', None)
    recent_project = request.COOKIES.get('recent_project')

    if not base_token or not k2k_auth_url:
        msg = _('K2K Federation not setup for this session')
        raise exceptions.KeystoneAuthException(msg)

    redirect_to = request.GET.get(redirect_field_name, '')
    if not http.is_safe_url(url=redirect_to,
                            allowed_hosts=[request.get_host()]):
        redirect_to = settings.LOGIN_REDIRECT_URL

    unscoped_auth_ref = None
    keystone_idp_id = settings.KEYSTONE_PROVIDER_IDP_ID

    if keystone_provider == keystone_idp_id:
        current_plugin = plugin.TokenPlugin()
        unscoped_auth = current_plugin.get_plugin(auth_url=k2k_auth_url,
                                                  token=base_token)
    else:
        # Switch to service provider using K2K federation
        plugins = [plugin.TokenPlugin()]
        current_plugin = plugin.K2KAuthPlugin()

        unscoped_auth = current_plugin.get_plugin(
            auth_url=k2k_auth_url, service_provider=keystone_provider,
            plugins=plugins, token=base_token, recent_project=recent_project)

    try:
        # Switch to identity provider using token auth
        unscoped_auth_ref = current_plugin.get_access_info(unscoped_auth)
    except exceptions.KeystoneAuthException as exc:
        msg = 'Switching to Keystone Provider %s has failed. %s' \
              % (keystone_provider, exc)
        messages.error(request, msg)

    if unscoped_auth_ref:
        try:
            request.user = auth.authenticate(
                request, auth_url=unscoped_auth.auth_url,
                token=unscoped_auth_ref.auth_token)
        except exceptions.KeystoneAuthException as exc:
            msg = 'Keystone provider switch failed: %s' % exc
            res = django_http.HttpResponseRedirect(settings.LOGIN_URL)
            res.set_cookie('logout_reason', msg, max_age=10)
            return res
        auth.login(request, request.user)
        auth_user.set_session_from_user(request, request.user)
        request.session['keystone_provider_id'] = keystone_provider
        request.session['keystone_providers'] = keystone_providers
        request.session['k2k_base_unscoped_token'] = base_token
        request.session['k2k_auth_url'] = k2k_auth_url
        message = (
            _('Switch to Keystone Provider "%(keystone_provider)s" '
              'successful.') % {'keystone_provider': keystone_provider})
        messages.success(request, message)

    response = shortcuts.redirect(redirect_to)
    return response
Esempio n. 58
0
 def is_safe_url(self, url):
     from django.utils.http import is_safe_url
     return is_safe_url(url, allowed_hosts=None)
Esempio n. 59
0
    def post(self, request):

        # Are we editing *all* objects in the queryset or just a selected subset?
        if request.POST.get('_all') and self.filter is not None:
            pk_list = [
                obj.pk for obj in self.filter(request.GET,
                                              self.model.objects.only('pk')).qs
            ]
        else:
            pk_list = [int(pk) for pk in request.POST.getlist('pk')]

        # Determine URL to redirect users upon modification of objects
        posted_return_url = request.POST.get('return_url')
        if posted_return_url and is_safe_url(url=posted_return_url,
                                             host=request.get_host()):
            return_url = posted_return_url
        else:
            return_url = reverse(self.default_return_url)

        selected_objects = self.parent_model.objects.filter(pk__in=pk_list)
        if not selected_objects:
            messages.warning(
                request, "No {} were selected.".format(
                    self.parent_model._meta.verbose_name_plural))
            return redirect(return_url)
        table = self.table(selected_objects)

        if '_create' in request.POST:
            form = self.form(request.POST)
            if form.is_valid():

                new_components = []
                data = deepcopy(form.cleaned_data)
                for obj in data['pk']:

                    names = data['name_pattern']
                    for name in names:
                        component_data = {
                            self.parent_field: obj.pk,
                            'name': name,
                        }
                        component_data.update(data)
                        component_form = self.model_form(component_data)
                        if component_form.is_valid():
                            new_components.append(
                                component_form.save(commit=False))
                        else:
                            for field, errors in component_form.errors.as_data(
                            ).items():
                                for e in errors:
                                    form.add_error(
                                        field, '{} {}: {}'.format(
                                            obj, name, ', '.join(e)))

                if not form.errors:
                    self.model.objects.bulk_create(new_components)
                    messages.success(
                        request, "Added {} {} to {} {}.".format(
                            len(new_components),
                            self.model._meta.verbose_name_plural,
                            len(form.cleaned_data['pk']),
                            self.parent_model._meta.verbose_name_plural))
                    return redirect(return_url)

        else:
            form = self.form(initial={'pk': pk_list})

        return render(
            request, self.template_name, {
                'form': form,
                'component_name': self.model._meta.verbose_name_plural,
                'table': table,
                'return_url': reverse(self.default_return_url),
            })
Esempio n. 60
0
    def post(self, request, **kwargs):

        # Attempt to derive parent object if a parent class has been given
        if self.parent_cls:
            parent_obj = get_object_or_404(self.parent_cls, **kwargs)
        else:
            parent_obj = None

        # Determine URL to redirect users upon deletion of objects
        posted_return_url = request.POST.get('return_url')
        if posted_return_url and is_safe_url(url=posted_return_url,
                                             host=request.get_host()):
            return_url = posted_return_url
        elif parent_obj:
            return_url = parent_obj.get_absolute_url()
        else:
            return_url = reverse(self.default_return_url)

        # Are we deleting *all* objects in the queryset or just a selected subset?
        if request.POST.get('_all') and self.filter is not None:
            pk_list = [
                obj.pk for obj in self.filter(request.GET,
                                              self.cls.objects.only('pk')).qs
            ]
        else:
            pk_list = [int(pk) for pk in request.POST.getlist('pk')]

        form_cls = self.get_form()

        if '_confirm' in request.POST:
            form = form_cls(request.POST)
            if form.is_valid():

                # Delete objects
                queryset = self.cls.objects.filter(pk__in=pk_list)
                try:
                    deleted_count = queryset.delete()[1][self.cls._meta.label]
                except ProtectedError as e:
                    handle_protectederror(list(queryset), request, e)
                    return redirect(return_url)

                msg = 'Deleted {} {}'.format(
                    deleted_count, self.cls._meta.verbose_name_plural)
                messages.success(request, msg)
                UserAction.objects.log_bulk_delete(
                    request.user, ContentType.objects.get_for_model(self.cls),
                    msg)
                return redirect(return_url)

        else:
            form = form_cls(initial={'pk': pk_list, 'return_url': return_url})

        # Retrieve objects being deleted
        queryset = self.queryset or self.cls.objects.all()
        table = self.table(queryset.filter(pk__in=pk_list), orderable=False)
        if not table.rows:
            messages.warning(
                request, "No {} were selected for deletion.".format(
                    self.cls._meta.verbose_name_plural))
            return redirect(return_url)

        return render(
            request, self.template_name, {
                'form': form,
                'parent_obj': parent_obj,
                'obj_type_plural': self.cls._meta.verbose_name_plural,
                'table': table,
                'return_url': return_url,
            })