Exemple #1
0
 def test_bad_origin_csrf_trusted_origin_bad_protocol(self):
     """
     A request with an origin with the wrong protocol compared to
     CSRF_TRUSTED_ORIGINS is rejected.
     """
     req = self._get_POST_request_with_token()
     req._is_secure_override = True
     req.META['HTTP_HOST'] = 'www.example.com'
     req.META['HTTP_ORIGIN'] = 'http://foo.example.com'
     mw = CsrfViewMiddleware(post_form_view)
     self._check_referer_rejects(mw, req)
     self.assertIs(mw._origin_verified(req), False)
     with self.assertLogs('django.security.csrf', 'WARNING') as cm:
         response = mw.process_view(req, post_form_view, (), {})
     self.assertEqual(response.status_code, 403)
     msg = REASON_BAD_ORIGIN % req.META['HTTP_ORIGIN']
     self.assertEqual(cm.records[0].getMessage(), 'Forbidden (%s): ' % msg)
     self.assertEqual(mw.allowed_origins_exact, {'http://no-match.com'})
     self.assertEqual(
         mw.allowed_origin_subdomains, {
             'https': ['.example.com'],
             'http': ['.no-match.com', '.no-match-2.com'],
         })
Exemple #2
0
def _redirect(request, provider):
    p = settings.SANCTION_PROVIDERS[provider]
    c = SanctionClient(auth_endpoint=p['auth_endpoint'],
                       client_id=p['client_id'],
                       token_endpoint=p['token_endpoint'],
                       client_secret=p['client_secret'],
                       resource_endpoint=p['resource_endpoint'])

    kwargs = p.get('auth_params', {})
    response = redirect(
        c.auth_uri(redirect_uri=p['redirect_uri'],
                   scope=p['scope'] if 'scope' in p else None,
                   **kwargs))

    # inject the state query param
    if getattr(settings, 'SANCTION_USE_CSRF', True):
        CsrfViewMiddleware().process_view(request, response, [], {})
        url = list(urlparse(response['location']))
        urlp = dict(parse_qsl(url[4]))
        urlp.update({'state': csrf.get_token(request)})
        url[4] = urlencode(urlp)
        response['location'] = urlunparse(url)

    return response
Exemple #3
0
def test_sending_a_patch_to_an_update_or_delete_view_that_has_not_implemented_patch_raises_not_implemented(
        patch_request):

    with pytest.raises(NotImplementedError):
        patch_response = CsrfViewMiddleware(
            UpdateOrDeleteResourceView().patch)(patch_request)
Exemple #4
0
 def _process_enforce_csrf(self, request):
     CsrfViewMiddleware().process_request(request)
     return super(SessionAuthenticationCrossDomainCsrf, self).enforce_csrf(request)  # lint-amnesty, pylint: disable=super-with-arguments
Exemple #5
0
    def list(self, request, *args, **kwargs):
        """
        We support multiple arguments for listing semantic fields.

        Exact fields
        ============

        You can use one of:

        * ``paths`` with a semi-colon separated list of paths to retrieve.

        * ``ids`` with a semi-colon separated list of ids to retreive.

        Searching
        =========

        Searching is mutually exclusive with returning exact
        fields. You must use ``search``, ``aspect``, ``scope``, ``root``:

        * ``search`` is the search text

        * ``aspect`` is where to search:

          + ``sf`` the semantic field headings

          + ``lexemes`` the lexemes

        * ``scope`` is the scope of the search:

          + ``all`: all semantic fields

          + ``hte`: only the fields from the HTE

          + ``btw``: only the fields created for BTW

        * ``root`` is the root of the search:

          + ``all``: all semantic fields

          + ``01``, ``02``, ``03``: all fields that have a path
          starting with this number.

        Pagination
        ==========

        When using ``search``, pagination is turned on. You can set
        pagination parameters with ``limit`` and ``offset``. ``limit``
        indicates how many records to return, ``offset`` indicates
        where to start in the set of results.  When paging is turned
        on, the results are returned as a dictionary containing:

        * ``count``: the number of matching results,

        * ``next`` and ``previous``: URLs to the next and previous set
          of results,

        * ``results`` an array of results.

        * ``unfiltered_count``: the total count of records that exist,
          ignoring filtering.

        When paging is off (not searching), the results are just an
        array of matching records.

        Selecting Fields
        ================

        You can reduce or expand the set of returned fields by using
        the ``fields`` parameter, which is a comma separated list of
        field names or field sets. The field sets exist:

        * The default: ``url``, ``path``, ``heading``, ``is_subcat``,
          ``verbose_pos``

        * The ``@search`` field set: ``parent``, ``related_by_pos``

        * The ``@details`` field set: ``parent``, ``related_by_pos``,
          ``lexemes``, ``children``

        See
        `:class:semantic_fields.serializers.SemanticFieldSerializer`
        for the full syntax.

        Depths of Relations
        ===================

        Using ``depths.<fieldname>`` allows to set a depth of
        expansion when following relationships. For instance without
        any specified ``depth``, the ``parent`` relation would be
        serialized as a URL to the parent. With ``depths.parent=1`` it
        would be realized as a serialization of the parent and the
        parent would itself contain a URL to its own
        parent. ``depths.parent=-1`` makes the depth infinite.

        ..warning:: Be careful when setting an infinite depth, as it
                    could cause an enormous amount of queries.
        """
        saved_method = request.method
        request.method = "POST"
        request.csrf_processing_done = False
        reason = CsrfViewMiddleware().process_view(request, None, (), {})
        request.method = saved_method

        if reason:
            return reason

        # If not specified, we use the JSON renderer.
        if request.META.get("HTTP_ACCEPT", None) is None:
            request.accepted_renderer = renderers.JSONRenderer()

        # And we can return only JSON.
        if request.accepted_renderer.media_type != "application/json":
            raise NotAcceptable

        # We have to check that these are set *here* because there's
        # nowhere else to check for them. The filter cannot do it.
        paths = request.GET.get('paths', None)
        ids = request.GET.get('ids', None)
        search = request.GET.get('search', None)

        if paths is None and ids is None and search is None:
            return HttpResponseBadRequest(
                "paths or ids or search must be specified")

        complex_paths = set()
        if paths is not None:
            # This interface accepts queries on semantic field
            # *expressions*. To perform such search, we split any
            # expression in its constituent parts and pass that to the
            # search. We then build "fake" semantic fields that we
            # return.
            paths = set(paths.split(";"))
            cleaned = set()
            for path in paths:
                try:
                    refs = parse_local_references(path)
                except FailedParse:
                    continue

                cleaned |= set(str(ref) for ref in refs)
                if len(refs) > 1:
                    complex_paths.add(path)

            if len(complex_paths) > 0:
                request.GET = request.GET.copy()  # Make it mutable.
                request.GET["paths"] = ";".join(cleaned)

        ret = super(SemanticFieldViewSet, self).list(request, *args, **kwargs)

        if len(complex_paths) > 0:
            # The return value is a response to the modified `paths`
            # we created. We need to modify it:
            #
            # a) to remove those semantic fields that are *only* the
            # result of breaking down a complex expression, and
            #
            # b) to add the result of complex expressions.

            # First, we add.
            sf_by_path = {sf["path"]: sf for sf in ret.data}
            for path in complex_paths:
                try:
                    refs = parse_local_references(path)
                except FailedParse:
                    continue
                combined = self.get_serializer(
                    make_specified_sf([sf_by_path[str(ref)] for ref in refs]))
                sf_by_path[path] = combined.data

            # This filters out what we need to remove.
            ret.data = [sf for path, sf in sf_by_path.items() if path in paths]

        return ret
Exemple #6
0
def csrf_check(request, raise_exception=True):
    problem = CsrfViewMiddleware().process_view(request, None, (), {})
    if problem and raise_exception:
        raise SuspiciousOperation
    else:
        return not problem
Exemple #7
0
# -*- coding: utf-8 -*-

from django.middleware.csrf import CsrfViewMiddleware
from rek.mango.auth import User
from rek.rekvizitka.account_statuses import CompanyAccountStatus
from rek.rekvizitka.models import CompanyEmployee, Company
from rek.tornado_srv.utils import get_authenticated_user
csrf_checker = CsrfViewMiddleware()


class DjangoFakeRequest(object):
    def __init__(self, tornado_request, csrf_token):
        self.COOKIES = {}
        for cookie in tornado_request.cookies:
            self.COOKIES[cookie] = tornado_request.cookies[cookie].value
        self.META = {}
        self.method = tornado_request.method
        self.path = tornado_request.path
        self.POST = {'csrfmiddlewaretoken': csrf_token}

    def is_secure(self):
        return False  # mustdo: get protocol


def get_authorized_parameters(csrf_key, session_key, request):
    company = None

    django_request = DjangoFakeRequest(request, csrf_key)
    if csrf_checker.process_view(django_request, {}, None, None):
        return None, None, None
Exemple #8
0
def check_csrf(request):
    request.csrf_processing_done = False
    reason = CsrfViewMiddleware().process_view(request, None, (), {})

    if reason is not None:
        raise PermissionDenied
Exemple #9
0
def facebook_csrf_check(request):
    return CsrfViewMiddleware().process_view(request, facebook_csrf_check,
                                             None, None) == None
Exemple #10
0
def newmessage(request):
    from django.middleware.csrf import CsrfViewMiddleware
    csrf_middleware = CsrfViewMiddleware()
    response_data = {}
    if request.method == 'GET':
        # Get form definition
        form = BroadcastForm()
    elif request.method == 'POST':
        request.POST = json.loads(request.body)
        # Process request for CSRF
        csrf_middleware.process_view(request, None, None, None)
        form_data = request.POST.get('data', {})
        form = BroadcastForm(form_data)
        if form.is_valid():
            message = form.cleaned_data["message"]

            #Send Member
            if form.cleaned_data["member"]:
                queryset = _get_queryset(form)
                if queryset:
                    persons = Person.objects.filter(queryset)
                else:
                    persons = Person.objects.all()

                _send_sms(persons, message)
                _write_log(persons, message)

            #Send External Receiver
            if form.cleaned_data["external"]:
                if form.cleaned_data["extra_phones"]:
                    phones = form.cleaned_data["extra_phones"].split(',')
                    for phone in phones:
                        _send_single_sms(phone, message)
                        _write_single_log(message)

            #Send Non Member Receiver
            if form.cleaned_data["nonmembers"]:
                if form.cleaned_data["non_member"]:
                    phones = form.cleaned_data["non_member"]
                    for phone in phones:
                        person = nonmember.objects.get(id=int(phone.id))
                        _send_single_sms(phone, message)
                        _write_single_log(message, None, person)

            #Send Member Ulang Tahun
            if form.cleaned_data["ultah"]:
                if form.cleaned_data["ultah_today"]:
                    phones = form.cleaned_data["ultah_today"]
                    for phone in phones:
                        person = Person.objects.get(id=phone.id)
                        _send_single_sms(phone, message)
                        _write_single_log(message, None, person)

    remote_form = RemoteForm(form)
    # Errors in response_data['non_field_errors'] and response_data['errors']
    response_data.update(remote_form.as_dict())

    response = HttpResponse(json.dumps(response_data, cls=DjangoJSONEncoder),
                            content_type="application/json")

    # Process response for CSRF
    csrf_middleware.process_response(request, response)
    return response
Exemple #11
0
def cam53process(request):
    if request.method != "POST":
        return HttpResponse("Unknown FAIL", status=400, content_type="text/plain")

    reason = CsrfViewMiddleware().process_view(request, None, (), {})
    if reason:
        return HttpResponse("CSRF FAIL", status=400, content_type="text/plain")

    ok = []
    failed = []
    skipped = []
    vals = request.POST.dict()
    for i in range(int(vals["vals"])):
        try:
            if vals.get("ok_%d" % i, "off") == "on":
                user = User.objects.get(id=vals["user_%d" % i])
                amount = Money(vals["amount_%d" % i], EUR)
                tx = PettycashTransaction(
                    src=User.objects.get(id=settings.POT_ID), dst=user, amount=amount
                )
                tx.description = vals["description_%d" % i]
                tx._change_reason = vals["change_reason_%d" % i][:100]
                tx.save()
                alertOwnersToChange(
                    tx,
                    request.user,
                    [tx.src.email, tx.dst.email],
                    "Banking transaction processed; %s deposited" % tx.amount,
                    "deposit_tx.txt",
                )
                ok.append(tx)
            else:
                skipped.append(
                    "%s: %s"
                    % (
                        vals.get("description_%d" % i, "??"),
                        vals.get("amount_%d" % i, "??"),
                    )
                )
        except Exception as e:
            failed.append(
                "%d: %s %s: %s<br>%s"
                % (
                    i,
                    vals.get("change_reason_%d" % i, "??"),
                    vals.get("description_%d" % i, "??"),
                    vals.get("amount_%d" % i, "??"),
                    e,
                )
            )
    if ok:
        try:
            record = PettycashImportRecord.objects.create(by=request.user)
            record.save()
        except Exception as e:
            logger.error("Had issues recording transaction import")

    context = {
        "title": "Import Results",
        "settings": settings,
        "ok": ok,
        "failed": failed,
        "skipped": skipped,
        "has_permission": request.user.is_authenticated,
    }
    return render(request, "pettycash/importlog-results.html", context)
Exemple #12
0
    def dispatch(self, request, *args, **kwargs):
        """
        Call handler's method according to request HTTP verb.
        """

        ##################################
        #         Request Details        #
        ##################################

        requested_at = datetime.datetime.now()
        method = request.method
        endpoint = request.path
        source_ip = request.META['REMOTE_ADDR']
        user_agent = request.META['HTTP_USER_AGENT']

        ##################################
        #           HTTP Method          #
        ##################################

        # Check if verb is allowed.
        try:
            self.allowed_methods.index(method.upper())
        except ValueError:
            return HttpResponseNotAllowed(self.allowed_methods)
        # Variable containing allowed verbs does not exist, no verbs allowed then.
        except AttributeError:
            return HttpResponseNotAllowed([])

        # If verb is available, respective method must exist.
        meth = getattr(self, method.lower(), None)
        if not meth:
            return HttpResponse(
                status=HTTPStatus.SERVER_ERROR_501_NOT_IMPLEMENTED)

        ##################################
        #         Authentication         #
        ##################################

        #
        # 1) Check for authentication requirements.
        #

        # Flags if the handler requires authentication (defaults to Yes, changed otherwise).
        authentication_required = True

        ####
        # a) Handler-wide authentication (i.e. ALL methods require auth) ------>
        try:
            # If authentication is required, then the handler has the following attribute
            # consisting of an array of the available authentication types.
            authentication_classes = self.authentication
        # <------ No handler-wide authentication required.
        except AttributeError:

            ####
            # b) Check for method-specific authentication requirements. ------>
            try:
                # If authentication is required, the respective method decorator adds the array of
                # available authentication types to the following method var.
                authentication_classes = meth.authentication
            # <------ No method-specific authentication required.
            except AttributeError:

                ####
                # c) If this place is reached, then NO auth is required. Period. ------>
                authentication_classes = None
                # <------

        #
        # 2) Authentication is required! Check for any valid auth credentials, according to available auth types.
        #
        if authentication_classes:

            authentication = None

            # Check for valid credentials for each of the available authentication types.
            for ac in authentication_classes:
                try:
                    authentication = ac().authenticate(request)
                    # Break the loop as soon as the first authentication class successfully validates respective credentials.
                    if authentication:
                        break
                except NotImplementedError:
                    pass

            # If this place is reached without any of the authentication classes having returned success,
            # then authentication has failed and since we are here because this resource requires authentication,
            # the request is forbidden.
            if not authentication:
                return HttpResponse(
                    status=HTTPStatus.CLIENT_ERROR_401_UNAUTHORIZED)

        #
        # 3) No authentication is required.
        #
        else:
            authentication_required = False

            # Even though authentication is not required, check if request was made by an
            # authenticated user, for logging purposes.
            authentication = AnyAuthentication().authenticate(request)

        # Put the result of the authentication in the request object, as it may be used in executing the API call
        # (e.g. figuring out how to serialize objects, given the user permissions)
        request.auth = authentication

        ##################################
        #        CSRF Validation         #
        ##################################

        # Check for possible configuration.
        try:
            csrf_enabled = settings.YAPI['CSRFValidation']
        # By default, CSRF validation is enabled.
        except (AttributeError, KeyError):
            csrf_enabled = True

        # When request is anonymous or authenticated via Django session, explicitly perform CSRF validation.
        if csrf_enabled == True and authentication_required == True and (
                not request.auth
                or request.auth['class'] == 'SessionAuthentication'):
            reason = CsrfViewMiddleware().process_view(request, None, (), {})
            # CSRF Failed.
            if reason:
                return HttpResponse(
                    content=json.dumps({
                        'message':
                        'CSRF verification failed. Request aborted.'
                    }),
                    status=HTTPStatus.CLIENT_ERROR_403_FORBIDDEN,
                    mimetype='application/json')

        ##################################
        #          Authorization         #
        ##################################

        #
        # 1) Check for permission requirements.
        #

        ####
        # a) Handler-wide permissions (i.e. ALL methods same permissions) ------>
        try:
            # If specific permissions are required, then the handler has the following attribute
            # consisting of an array of the required permissions.
            permission_classes = self.permissions
        # <------ No handler-wide permissions required.
        except AttributeError:

            ####
            # b) Check for method-specific permission requirements. ------>
            try:
                # If permission is required, the respective method decorator adds the array of
                # required permission types to the following method var.
                permission_classes = meth.permission
            # <------ No method-specific permissions required.
            except AttributeError:

                ####
                # c) If this place is reached, then are NOT permission requirements. Period. ------>
                permission_classes = None
                # <------

        #
        # 2) Validate permissions.
        #
        if permission_classes:

            # If there are permission restrictions, then the request must be authenticated.
            if not authentication:
                return HttpResponseForbidden()

            # For the request to be authorized, ***ALL** the permission classes must return True.
            else:
                for p in permission_classes:
                    try:
                        if not p().has_permission(request,
                                                  authentication['user']):
                            return HttpResponseForbidden()
                    # The permission class doesn't have the necessary method implemented, we consider the permission check as failed,
                    # thus, the user isn't authorized to access the resource.
                    except NotImplementedError:
                        return HttpResponseForbidden()

        # There aren't any permission restrictions.
        else:
            pass

        ##################################
        #          Request Body          #
        ##################################

        # Some requests require for a body.
        try:
            ['POST', 'PUT'].index(method.upper())

            # If this place is reached, then the HTTP request should have a body.
            try:

                # Don't process body if request haz files, because it messes up stream and stuff and basically
                # everything blows up.
                # TODO: Got to figure this out better.
                if request.FILES:
                    request.data = request.FILES

                # Business as usual...
                else:
                    # For now, the only parser suported is JSON.
                    data = json.loads(request.body)

                    # If this place is reached, then body was successfully parsed. Add it to the request object.
                    request.data = data

            # Error parsing request body to JSON.
            except ValueError:
                return HttpResponse(
                    content=json.dumps({'message': 'Missing arguments'}),
                    status=HTTPStatus.CLIENT_ERROR_400_BAD_REQUEST,
                    mimetype='application/json')
        except ValueError:
            pass
        except:
            logger.error('Unable to process request body!', exc_info=1)
            return Response(
                request=request,
                data={'message': 'Resource #1'},
                serializer=None,
                status=HTTPStatus.SERVER_ERROR_500_INTERNAL_SERVER_ERROR)

        ##################################
        #          Execute Call          #
        ##################################

        # Invoke method, logging execution time start and end.
        exec_start = datetime.datetime.now()
        try:
            result = meth(request, *args, **kwargs)
        except:
            logger.error('Error executing API call', exc_info=1)
            result = HttpResponse(
                status=HTTPStatus.SERVER_ERROR_500_INTERNAL_SERVER_ERROR)
        exec_end = datetime.datetime.now()

        ##################################
        #               Log              #
        ##################################

        try:
            request_data = None
            response_data = None

            # If bad request, log request data (POST and PUT) and response body.
            if result.status_code >= 400 and result.status_code <= 599:
                if method == 'POST' or method == 'PUT':
                    request_data = request.data
                response_data = result.content

            # Log.
            ApiCall.new(date=requested_at,
                        method=method,
                        endpoint=endpoint,
                        source_ip=source_ip,
                        execution_start=exec_start,
                        execution_end=exec_end,
                        status=result.status_code,
                        user_agent=user_agent,
                        authentication=authentication,
                        request_get_params=dict(request.GET.iterlists()),
                        request_data=request_data,
                        response_data=response_data)

        # If error occurs, JUST log. If this place is reached, then the request was successfully
        # executed and result should be returned.
        except:
            logger.error('Unable to log API call!', exc_info=1)

        ##################################
        #             Return             #
        ##################################

        return result
Exemple #13
0
def user_predictions_post_handle(request):
    user_id = request.user
    error_text = ''
    state = ''
    goals_home = 0
    goals_guest = 0
    has_error = False
    show_back_button = True
    tie_statuses = ['tie', 'penalties_home', 'penalties_guest']
    # check if there is form POST
    if request.method != 'POST':
        error_text = 'Невалидна форма! Върни се в началото!'
        show_back_button = False
        content_dict = {
            'error_text': error_text,
            'show_back_button': False,
        }
        return render(request, 'matches/prediction-error.html', content_dict)
    # check if user have predictions for that day already
    date_check = datetime.datetime.now().date()
    check_queryset = UserPredictions.objects.filter(
        match__match_date=date_check, user_id=user_id).count()
    if check_queryset != 0:
        error_text = 'Вече има прогнози за този ден от теб!'
        show_back_button = False
        content_dict = {
            'error_text': error_text,
            'show_back_button': False,
        }
        return render(request, 'matches/prediction-error.html', content_dict)
    # CSRF TOKEN manual check
    reason = CsrfViewMiddleware().process_view(request, None, (), {})
    if reason:
        raise PermissionError()
    # handle POST data and check for errors
    post_data = dict(request.POST)
    post_data = {
        key: value
        for key, value in post_data.items() if key != 'csrfmiddlewaretoken'
    }
    predict_match_data = {}
    # check if data input is okay
    for key in post_data:
        split_key = key.split('_')
        match_number = int(split_key[0])
        if split_key[1] == 'match':
            state = post_data[key][0]
        elif split_key[2] == 'home':
            try:
                goals_home = int(post_data[key][0])
            except ValueError:
                error_text = "Моля, въведете цели положителни числа в полетата за гол! Като бройка голове - един, два, три... Опитай пак!"
                has_error = True
                break
        elif split_key[2] == 'guest':
            try:
                goals_guest = int(post_data[key][0])
            except ValueError:
                error_text = 'Моля, въведете цели положителни числа в полетата за гол! Като бройка голове - един, два, три... Опитай пак!'
                has_error = True
                break
        if goals_guest < 0 or goals_home < 0:
            error_text = 'Моля, въведете цели положителни числа в полетата за гол! Като бройка голове - един, два, три... Опитай пак!'
            has_error = True
            break
        temp_arr = [state, goals_home, goals_guest]
        predict_match_data[match_number] = temp_arr

    # check if data is logically correct
    if not has_error:
        for key in predict_match_data:
            state = predict_match_data[key][0]
            goals_home = predict_match_data[key][1]
            goals_guest = predict_match_data[key][2]
            if state == 'home' and goals_home <= goals_guest:
                error_text = f'Головете за мач {key} не съотвестват на въведения изход от двубоя. Въведена е победа за домакин, ' \
                             'но головете на домакина по-малко от тези на госта!'
                has_error = True
            elif state == 'guest' and goals_guest <= goals_home:

                error_text = f'Головете за мач {key} не съотвестват на въведения изход от двубоя. Въведена е победа за гост, ' \
                             'но головете на госта по-малко от тези на домакина!'
                has_error = True
            elif state in tie_statuses and goals_home != goals_guest:
                error_text = f'Головете мач {key} на домакина и на госта не са равни!'
                has_error = True

    # write to database
    for key in predict_match_data:
        if has_error:
            break
        match_state = predict_match_data[key][0]
        goals_home = predict_match_data[key][1]
        goals_guest = predict_match_data[key][2]
        match = Matches.objects.get(match_number=key)
        # check if match has started!
        current_time = datetime.datetime.utcnow()
        if current_time > match.match_start_time_utc:
            print(
                f'NOTE: {request.user} tried to give prediction for {match} at UTC: {current_time}'
            )
            has_error = True
            error_text = error_text + f'|||Твоята прогноза за {match} не беше зачетена, тъй като мача е вече започнал.|||'
            show_back_button = False
            continue
        user_prediction = UserPredictions(
            user_id=user_id,
            match=match,
            prediction_match_state=match_state,
            prediction_goals_home=goals_home,
            prediction_goals_guest=goals_guest,
            gave_prediction=True,
            creation_time=datetime.datetime.utcnow(),
            last_edit=datetime.datetime.utcnow())
        user_prediction.save()

    if has_error:
        content_dict = {
            'error_text': error_text,
            'show_back_button': show_back_button,
        }
        return render(request, 'matches/prediction-error.html', content_dict)
    else:
        content_dict = {}
        return render(request, 'matches/prediction-success.html', content_dict)
Exemple #14
0
def is_valid_csrf(request):
    reason = CsrfViewMiddleware().process_view(request, None, (), {})
    return False if reason else True
def test_sending_a_post_to_a_create_view_that_has_not_implemented_post_raises_not_implemented(
        post_request):

    with pytest.raises(NotImplementedError):
        post_response = CsrfViewMiddleware(
            CreateResourceView().post)(post_request)
Exemple #16
0
 def check_csrf(self, request):
     reason = CsrfViewMiddleware().process_view(request, None, (), {})
     if reason:
         # CSRF failed
         raise PermissionException()
Exemple #17
0
 def test_csrf(self, request):
     middleware = CsrfViewMiddleware()
     return middleware.process_view(request, self.dispatch, [request], {})
Exemple #18
0
def check_csrf(request: HttpRequest, callback: Callable):
    mware = CsrfViewMiddleware(lambda: None)
    request.csrf_processing_done = False
    return mware.process_view(request, callback, [], {})
Exemple #19
0
def check_csrf(request):
    return CsrfViewMiddleware().process_view(request, detail, None, None)
Exemple #20
0
class CsrfViewMiddlewareTestMixin:
    """
    Shared methods and tests for session-based and cookie-based tokens.
    """

    _csrf_id = _csrf_id_cookie = '1bcdefghij2bcdefghij3bcdefghij4bcdefghij5bcdefghij6bcdefghijABCD'
    mw = CsrfViewMiddleware()

    def _get_GET_no_csrf_cookie_request(self):
        return TestingHttpRequest()

    def _get_GET_csrf_cookie_request(self):
        raise NotImplementedError(
            'This method must be implemented by a subclass.')

    def _get_POST_csrf_cookie_request(self):
        req = self._get_GET_csrf_cookie_request()
        req.method = "POST"
        return req

    def _get_POST_no_csrf_cookie_request(self):
        req = self._get_GET_no_csrf_cookie_request()
        req.method = "POST"
        return req

    def _get_POST_request_with_token(self):
        req = self._get_POST_csrf_cookie_request()
        req.POST['csrfmiddlewaretoken'] = self._csrf_id
        return req

    def _check_token_present(self, response, csrf_id=None):
        text = str(response.content, response.charset)
        match = re.search("name='csrfmiddlewaretoken' value='(.*?)'", text)
        csrf_token = csrf_id or self._csrf_id
        self.assertTrue(
            match and equivalent_tokens(csrf_token, match.group(1)),
            "Could not find csrfmiddlewaretoken to match %s" % csrf_token)

    def test_process_response_get_token_not_used(self):
        """
        If get_token() is not called, the view middleware does not
        add a cookie.
        """
        # This is important to make pages cacheable.  Pages which do call
        # get_token(), assuming they use the token, are not cacheable because
        # the token is specific to the user
        req = self._get_GET_no_csrf_cookie_request()
        # non_token_view_using_request_processor does not call get_token(), but
        # does use the csrf request processor.  By using this, we are testing
        # that the view processor is properly lazy and doesn't call get_token()
        # until needed.
        self.mw.process_request(req)
        self.mw.process_view(req, non_token_view_using_request_processor, (),
                             {})
        resp = non_token_view_using_request_processor(req)
        resp2 = self.mw.process_response(req, resp)

        csrf_cookie = resp2.cookies.get(settings.CSRF_COOKIE_NAME, False)
        self.assertIs(csrf_cookie, False)

    # Check the request processing
    def test_process_request_no_csrf_cookie(self):
        """
        If no CSRF cookies is present, the middleware rejects the incoming
        request. This will stop login CSRF.
        """
        with patch_logger('django.security.csrf', 'warning') as logger_calls:
            req = self._get_POST_no_csrf_cookie_request()
            self.mw.process_request(req)
            req2 = self.mw.process_view(req, post_form_view, (), {})
            self.assertEqual(403, req2.status_code)
            self.assertEqual(logger_calls[0],
                             'Forbidden (%s): ' % REASON_NO_CSRF_COOKIE)

    def test_process_request_csrf_cookie_no_token(self):
        """
        If a CSRF cookie is present but no token, the middleware rejects
        the incoming request.
        """
        with patch_logger('django.security.csrf', 'warning') as logger_calls:
            req = self._get_POST_csrf_cookie_request()
            self.mw.process_request(req)
            req2 = self.mw.process_view(req, post_form_view, (), {})
            self.assertEqual(403, req2.status_code)
            self.assertEqual(logger_calls[0],
                             'Forbidden (%s): ' % REASON_BAD_TOKEN)

    def test_process_request_csrf_cookie_and_token(self):
        """
        If both a cookie and a token is present, the middleware lets it through.
        """
        req = self._get_POST_request_with_token()
        self.mw.process_request(req)
        req2 = self.mw.process_view(req, post_form_view, (), {})
        self.assertIsNone(req2)

    def test_process_request_csrf_cookie_no_token_exempt_view(self):
        """
        If a CSRF cookie is present and no token, but the csrf_exempt decorator
        has been applied to the view, the middleware lets it through
        """
        req = self._get_POST_csrf_cookie_request()
        self.mw.process_request(req)
        req2 = self.mw.process_view(req, csrf_exempt(post_form_view), (), {})
        self.assertIsNone(req2)

    def test_csrf_token_in_header(self):
        """
        The token may be passed in a header instead of in the form.
        """
        req = self._get_POST_csrf_cookie_request()
        req.META['HTTP_X_CSRFTOKEN'] = self._csrf_id
        self.mw.process_request(req)
        req2 = self.mw.process_view(req, post_form_view, (), {})
        self.assertIsNone(req2)

    @override_settings(CSRF_HEADER_NAME='HTTP_X_CSRFTOKEN_CUSTOMIZED')
    def test_csrf_token_in_header_with_customized_name(self):
        """
        settings.CSRF_HEADER_NAME can be used to customize the CSRF header name
        """
        req = self._get_POST_csrf_cookie_request()
        req.META['HTTP_X_CSRFTOKEN_CUSTOMIZED'] = self._csrf_id
        self.mw.process_request(req)
        req2 = self.mw.process_view(req, post_form_view, (), {})
        self.assertIsNone(req2)

    def test_put_and_delete_rejected(self):
        """
        HTTP PUT and DELETE methods have protection
        """
        req = TestingHttpRequest()
        req.method = 'PUT'
        with patch_logger('django.security.csrf', 'warning') as logger_calls:
            req2 = self.mw.process_view(req, post_form_view, (), {})
            self.assertEqual(403, req2.status_code)
            self.assertEqual(logger_calls[0],
                             'Forbidden (%s): ' % REASON_NO_CSRF_COOKIE)

        req = TestingHttpRequest()
        req.method = 'DELETE'
        with patch_logger('django.security.csrf', 'warning') as logger_calls:
            req2 = self.mw.process_view(req, post_form_view, (), {})
            self.assertEqual(403, req2.status_code)
            self.assertEqual(logger_calls[0],
                             'Forbidden (%s): ' % REASON_NO_CSRF_COOKIE)

    def test_put_and_delete_allowed(self):
        """
        HTTP PUT and DELETE can get through with X-CSRFToken and a cookie.
        """
        req = self._get_GET_csrf_cookie_request()
        req.method = 'PUT'
        req.META['HTTP_X_CSRFTOKEN'] = self._csrf_id
        self.mw.process_request(req)
        req2 = self.mw.process_view(req, post_form_view, (), {})
        self.assertIsNone(req2)

        req = self._get_GET_csrf_cookie_request()
        req.method = 'DELETE'
        req.META['HTTP_X_CSRFTOKEN'] = self._csrf_id
        self.mw.process_request(req)
        req2 = self.mw.process_view(req, post_form_view, (), {})
        self.assertIsNone(req2)

    # Tests for the template tag method
    def test_token_node_no_csrf_cookie(self):
        """
        CsrfTokenNode works when no CSRF cookie is set.
        """
        req = self._get_GET_no_csrf_cookie_request()
        resp = token_view(req)

        token = get_token(req)
        self.assertIsNotNone(token)
        self._check_token_present(resp, token)

    def test_token_node_empty_csrf_cookie(self):
        """
        A new token is sent if the csrf_cookie is the empty string.
        """
        req = self._get_GET_no_csrf_cookie_request()
        req.COOKIES[settings.CSRF_COOKIE_NAME] = ""
        self.mw.process_view(req, token_view, (), {})
        resp = token_view(req)

        token = get_token(req)
        self.assertIsNotNone(token)
        self._check_token_present(resp, token)

    def test_token_node_with_csrf_cookie(self):
        """
        CsrfTokenNode works when a CSRF cookie is set.
        """
        req = self._get_GET_csrf_cookie_request()
        self.mw.process_request(req)
        self.mw.process_view(req, token_view, (), {})
        resp = token_view(req)
        self._check_token_present(resp)

    def test_get_token_for_exempt_view(self):
        """
        get_token still works for a view decorated with 'csrf_exempt'.
        """
        req = self._get_GET_csrf_cookie_request()
        self.mw.process_request(req)
        self.mw.process_view(req, csrf_exempt(token_view), (), {})
        resp = token_view(req)
        self._check_token_present(resp)

    def test_get_token_for_requires_csrf_token_view(self):
        """
        get_token() works for a view decorated solely with requires_csrf_token.
        """
        req = self._get_GET_csrf_cookie_request()
        resp = requires_csrf_token(token_view)(req)
        self._check_token_present(resp)

    def test_token_node_with_new_csrf_cookie(self):
        """
        CsrfTokenNode works when a CSRF cookie is created by
        the middleware (when one was not already present)
        """
        req = self._get_GET_no_csrf_cookie_request()
        self.mw.process_view(req, token_view, (), {})
        resp = token_view(req)
        resp2 = self.mw.process_response(req, resp)
        csrf_cookie = resp2.cookies[settings.CSRF_COOKIE_NAME]
        self._check_token_present(resp, csrf_id=csrf_cookie.value)

    def test_cookie_not_reset_on_accepted_request(self):
        """
        The csrf token used in posts is changed on every request (although
        stays equivalent). The csrf cookie should not change on accepted
        requests. If it appears in the response, it should keep its value.
        """
        req = self._get_POST_request_with_token()
        self.mw.process_request(req)
        self.mw.process_view(req, token_view, (), {})
        resp = token_view(req)
        resp = self.mw.process_response(req, resp)
        csrf_cookie = resp.cookies.get(settings.CSRF_COOKIE_NAME, None)
        if csrf_cookie:
            self.assertEqual(csrf_cookie.value, self._csrf_id_cookie,
                             "CSRF cookie was changed on an accepted request")

    @override_settings(DEBUG=True, ALLOWED_HOSTS=['www.example.com'])
    def test_https_bad_referer(self):
        """
        A POST HTTPS request with a bad referer is rejected
        """
        req = self._get_POST_request_with_token()
        req._is_secure_override = True
        req.META['HTTP_HOST'] = 'www.example.com'
        req.META['HTTP_REFERER'] = 'https://www.evil.org/somepage'
        req.META['SERVER_PORT'] = '443'
        response = self.mw.process_view(req, post_form_view, (), {})
        self.assertContains(
            response,
            'Referer checking failed - https://www.evil.org/somepage does not '
            'match any trusted origins.',
            status_code=403,
        )

    def test_https_malformed_host(self):
        """
        CsrfViewMiddleware generates a 403 response if it receives an HTTPS
        request with a bad host.
        """
        req = self._get_GET_no_csrf_cookie_request()
        req._is_secure_override = True
        req.META['HTTP_HOST'] = '@malformed'
        req.META['HTTP_REFERER'] = 'https://www.evil.org/somepage'
        req.META['SERVER_PORT'] = '443'
        response = self.mw.process_view(req, token_view, (), {})
        self.assertEqual(response.status_code, 403)

    @override_settings(DEBUG=True)
    def test_https_malformed_referer(self):
        """
        A POST HTTPS request with a bad referer is rejected.
        """
        malformed_referer_msg = 'Referer checking failed - Referer is malformed.'
        req = self._get_POST_request_with_token()
        req._is_secure_override = True
        req.META['HTTP_REFERER'] = 'http://*****:*****@override_settings(ALLOWED_HOSTS=['www.example.com'])
    def test_https_good_referer(self):
        """
        A POST HTTPS request with a good referer is accepted.
        """
        req = self._get_POST_request_with_token()
        req._is_secure_override = True
        req.META['HTTP_HOST'] = 'www.example.com'
        req.META['HTTP_REFERER'] = 'https://www.example.com/somepage'
        self.mw.process_request(req)
        req2 = self.mw.process_view(req, post_form_view, (), {})
        self.assertIsNone(req2)

    @override_settings(ALLOWED_HOSTS=['www.example.com'])
    def test_https_good_referer_2(self):
        """
        A POST HTTPS request with a good referer is accepted where the referer
        contains no trailing slash.
        """
        # See ticket #15617
        req = self._get_POST_request_with_token()
        req._is_secure_override = True
        req.META['HTTP_HOST'] = 'www.example.com'
        req.META['HTTP_REFERER'] = 'https://www.example.com'
        self.mw.process_request(req)
        req2 = self.mw.process_view(req, post_form_view, (), {})
        self.assertIsNone(req2)

    def _test_https_good_referer_behind_proxy(self):
        req = self._get_POST_request_with_token()
        req._is_secure_override = True
        req.META.update({
            'HTTP_HOST': '10.0.0.2',
            'HTTP_REFERER': 'https://www.example.com/somepage',
            'SERVER_PORT': '8080',
            'HTTP_X_FORWARDED_HOST': 'www.example.com',
            'HTTP_X_FORWARDED_PORT': '443',
        })
        self.mw.process_request(req)
        req2 = self.mw.process_view(req, post_form_view, (), {})
        self.assertIsNone(req2)

    @override_settings(ALLOWED_HOSTS=['www.example.com'],
                       CSRF_TRUSTED_ORIGINS=['dashboard.example.com'])
    def test_https_csrf_trusted_origin_allowed(self):
        """
        A POST HTTPS request with a referer added to the CSRF_TRUSTED_ORIGINS
        setting is accepted.
        """
        req = self._get_POST_request_with_token()
        req._is_secure_override = True
        req.META['HTTP_HOST'] = 'www.example.com'
        req.META['HTTP_REFERER'] = 'https://dashboard.example.com'
        self.mw.process_request(req)
        req2 = self.mw.process_view(req, post_form_view, (), {})
        self.assertIsNone(req2)

    @override_settings(ALLOWED_HOSTS=['www.example.com'],
                       CSRF_TRUSTED_ORIGINS=['.example.com'])
    def test_https_csrf_wildcard_trusted_origin_allowed(self):
        """
        A POST HTTPS request with a referer that matches a CSRF_TRUSTED_ORIGINS
        wildcard is accepted.
        """
        req = self._get_POST_request_with_token()
        req._is_secure_override = True
        req.META['HTTP_HOST'] = 'www.example.com'
        req.META['HTTP_REFERER'] = 'https://dashboard.example.com'
        self.mw.process_request(req)
        response = self.mw.process_view(req, post_form_view, (), {})
        self.assertIsNone(response)

    def _test_https_good_referer_matches_cookie_domain(self):
        req = self._get_POST_request_with_token()
        req._is_secure_override = True
        req.META['HTTP_REFERER'] = 'https://foo.example.com/'
        req.META['SERVER_PORT'] = '443'
        self.mw.process_request(req)
        response = self.mw.process_view(req, post_form_view, (), {})
        self.assertIsNone(response)

    def _test_https_good_referer_matches_cookie_domain_with_different_port(
            self):
        req = self._get_POST_request_with_token()
        req._is_secure_override = True
        req.META['HTTP_HOST'] = 'www.example.com'
        req.META['HTTP_REFERER'] = 'https://foo.example.com:4443/'
        req.META['SERVER_PORT'] = '4443'
        self.mw.process_request(req)
        response = self.mw.process_view(req, post_form_view, (), {})
        self.assertIsNone(response)

    def test_ensures_csrf_cookie_no_logging(self):
        """
        ensure_csrf_cookie() doesn't log warnings (#19436).
        """
        class TestHandler(logging.Handler):
            def emit(self, record):
                raise Exception("This shouldn't have happened!")

        logger = logging.getLogger('django.request')
        test_handler = TestHandler()
        old_log_level = logger.level
        try:
            logger.addHandler(test_handler)
            logger.setLevel(logging.WARNING)

            req = self._get_GET_no_csrf_cookie_request()
            ensure_csrf_cookie_view(req)
        finally:
            logger.removeHandler(test_handler)
            logger.setLevel(old_log_level)

    def test_post_data_read_failure(self):
        """
        #20128 -- IOErrors during POST data reading should be caught and
        treated as if the POST data wasn't there.
        """
        class CsrfPostRequest(HttpRequest):
            """
            HttpRequest that can raise an IOError when accessing POST data
            """
            def __init__(self, token, raise_error):
                super().__init__()
                self.method = 'POST'

                self.raise_error = False
                self.COOKIES[settings.CSRF_COOKIE_NAME] = token

                # Handle both cases here to prevent duplicate code in the
                # session tests.
                self.session = {}
                self.session[CSRF_SESSION_KEY] = token

                self.POST['csrfmiddlewaretoken'] = token
                self.raise_error = raise_error

            def _load_post_and_files(self):
                raise IOError('error reading input data')

            def _get_post(self):
                if self.raise_error:
                    self._load_post_and_files()
                return self._post

            def _set_post(self, post):
                self._post = post

            POST = property(_get_post, _set_post)

        token = ('ABC' + self._csrf_id)[:CSRF_TOKEN_LENGTH]

        req = CsrfPostRequest(token, raise_error=False)
        self.mw.process_request(req)
        resp = self.mw.process_view(req, post_form_view, (), {})
        self.assertIsNone(resp)

        req = CsrfPostRequest(token, raise_error=True)
        with patch_logger('django.security.csrf', 'warning') as logger_calls:
            self.mw.process_request(req)
            resp = self.mw.process_view(req, post_form_view, (), {})
            self.assertEqual(resp.status_code, 403)
            self.assertEqual(logger_calls[0],
                             'Forbidden (%s): ' % REASON_BAD_TOKEN)
 def _process_enforce_csrf(self, request):
     CsrfViewMiddleware().process_request(request)
     return super().enforce_csrf(request)
 def _process_enforce_csrf(self, request):
     CsrfViewMiddleware().process_request(request)
     return super(SessionAuthenticationCrossDomainCsrf,
                  self).enforce_csrf(request)
Exemple #23
0
def handle_instance_form(request, app_label, model_name, instance_id=None):
    if not request.user.is_authenticated():
        return HttpResponse('Unauthorized', status=401)

    csrf_middleware = CsrfViewMiddleware()

    response_data = {
        'meta': {
            'app_label': app_label,
            'model_name': model_name
        },
        'admin': {}
    }

    instance = None

    for model, model_admin in site._registry.items():
        if app_label != model._meta.app_label or model_name != model._meta.module_name:
            continue

        field_configuration = {
            'include': model_admin.fields or [],
            'exclude': model_admin.exclude or [],
            'ordering': model_admin.fields or [],
            'fieldsets': model_admin.fieldsets or {},
            'readonly': model_admin.readonly_fields or []
        }

        if instance_id is not None:
            response_data[instance_id] = instance_id
            try:
                instance = model.objects.get(pk=instance_id)
            except model.DoesNotExist:
                raise Http404('Invalid instance ID')

        current_model = model

        CurrentModelForm = ADMIN_FORM_OVERRIDES.get(model_name, None)

        if CurrentModelForm is None:

            class CurrentModelForm(ModelForm):
                class Meta:
                    model = current_model

        if request.method == 'GET':
            # Return instance form for given model name
            # Return initial values if instance ID is supplied, otherwise return empty form
            if instance is None:
                form = CurrentModelForm()
            else:
                form = CurrentModelForm(instance=instance)
                for field_name, initial_value in form.initial.items():
                    if initial_value is not None and field_name in form.fields:
                        form.fields[field_name].initial = initial_value

            response_data['csrfmiddlewaretoken'] = get_token(request)

            remote_form = RemoteForm(form, **field_configuration)
            response_data.update(remote_form.as_dict())
        elif request.raw_post_data:
            request.POST = json.loads(request.raw_post_data)
            csrf_middleware.process_view(request, None, None, None)
            if 'data' in request.POST:
                if instance_id is None:
                    form = CurrentModelForm(request.POST['data'])
                else:
                    form = CurrentModelForm(request.POST['data'],
                                            instance=instance)
                if form.is_valid():
                    if not request.POST['meta']['validate']:
                        form.save()

                remote_form = RemoteForm(form, **field_configuration)
                response_data.update(remote_form.as_dict())

    response = HttpResponse(json.dumps(response_data, cls=LazyEncoder),
                            mimetype="application/json")
    csrf_middleware.process_response(request, response)
    return response
Exemple #24
0
    def process_response(self, request, response):

        # Caching is only applicable for text-based, non-streaming
        # responses. We also skip it for non-200 statuses during
        # development, so that stack traces are correctly rendered.
        is_text = response.get("content-type", "").startswith("text")
        valid_status = response.status_code == 200
        streaming = getattr(response, "streaming", False)
        if not is_text or streaming or (settings.DEBUG and not valid_status):
            return response

        # Cache the response if all the required conditions are met.
        # Response must be marked for updating by the
        # ``FetchFromCacheMiddleware`` having a cache get miss, the
        # user must not be authenticated, the HTTP status must be OK
        # and the response mustn't include an expiry age, indicating it
        # shouldn't be cached.
        marked_for_update = getattr(request, "_update_cache", False)
        anon = hasattr(request, "user") and not is_authenticated(request.user)
        timeout = get_max_age(response)
        if timeout is None:
            timeout = settings.CACHE_MIDDLEWARE_SECONDS
        if anon and valid_status and marked_for_update and timeout:
            cache_key = cache_key_prefix(request) + request.get_full_path()
            _cache_set = lambda r: cache_set(cache_key, r.content, timeout)
            if callable(getattr(response, "render", None)):
                response.add_post_render_callback(_cache_set)
            else:
                _cache_set(response)

        # Second phase rendering for non-cached template code and
        # content. Split on the delimiter the ``nevercache`` tag
        # wrapped its contents in, and render only the content
        # enclosed by it, to avoid possible template code injection.
        token = nevercache_token()
        try:
            token = token.encode('utf-8')
        except AttributeError:
            pass
        parts = response.content.split(token)
        # Restore csrf token from cookie - check the response
        # first as it may be being set for the first time.
        csrf_token = None
        try:
            csrf_token = response.cookies[settings.CSRF_COOKIE_NAME].value
        except KeyError:
            try:
                csrf_token = request.COOKIES[settings.CSRF_COOKIE_NAME]
            except KeyError:
                pass
        if csrf_token:
            request.META["CSRF_COOKIE"] = csrf_token
        context = RequestContext(request)
        for i, part in enumerate(parts):
            if i % 2:
                part = Template(part).render(context).encode("utf-8")
            parts[i] = part
        response.content = b"".join(parts)
        response["Content-Length"] = len(response.content)
        if hasattr(request, '_messages'):
            # Required to clear out user messages.
            request._messages.update(response)
        # Response needs to be run-through the CSRF middleware again so
        # that if there was a {% csrf_token %} inside of the nevercache
        # the cookie will be correctly set for the the response
        csrf_mw_name = "django.middleware.csrf.CsrfViewMiddleware"
        if csrf_mw_name in get_middleware_setting():
            response.csrf_processing_done = False
            csrf_mw = CsrfViewMiddleware()
            csrf_mw.process_response(request, response)
        return response
Exemple #25
0
def check_csrf(request: HttpRequest,
               callback: Callable) -> Optional[HttpResponseForbidden]:
    mware = CsrfViewMiddleware(lambda: None)  # type: ignore
    request.csrf_processing_done = False  # type: ignore
    mware.process_request(request)
    return mware.process_view(request, callback, (), {})