Beispiel #1
0
 def get_etags_and_matchers(self, request):
     etags = None
     if_none_match = request.META.get(prepare_header_name("if-none-match"))
     if_match = request.META.get(prepare_header_name("if-match"))
     if if_none_match or if_match:
         # There can be more than one ETag in the request, so we
         # consider the list of values.
         try:
             etags = parse_etags(if_none_match or if_match)
         except ValueError:
             # In case of invalid etag ignore all ETag headers.
             # Apparently Opera sends invalidly quoted headers at times
             # (we should be returning a 400 response, but that's a
             # little extreme) -- this is Django bug #10681.
             if_none_match = None
             if_match = None
     return etags, if_none_match, if_match
Beispiel #2
0
 def is_valid_bulk_operation(self):
     if extensions_api_settings.DEFAULT_BULK_OPERATION_HEADER_NAME:
         header_name = utils.prepare_header_name(extensions_api_settings.DEFAULT_BULK_OPERATION_HEADER_NAME)
         return bool(self.request.META.get(header_name, None)), {
             'detail': 'Header \'{0}\' should be provided for bulk operation.'.format(
                 extensions_api_settings.DEFAULT_BULK_OPERATION_HEADER_NAME
             )
         }
     else:
         return True, {}
Beispiel #3
0
 def setUp(self):
     self.user = User.objects.create(
         id=1,
         name='Gennady',
         age=24,
         last_name='Chibisov',
         email='*****@*****.**',
         password='******'
     )
     self.headers = {
         utils.prepare_header_name(extensions_api_settings.DEFAULT_BULK_OPERATION_HEADER_NAME): 'true'
     }
Beispiel #4
0
 def setUp(self):
     self.comments = [
         Comment.objects.create(
             id=1,
             email='*****@*****.**'
         ),
         Comment.objects.create(
             id=2,
             email='*****@*****.**'
         )
     ]
     self.protection_headers = {
         utils.prepare_header_name(extensions_api_settings.DEFAULT_BULK_OPERATION_HEADER_NAME): 'true'
     }
Beispiel #5
0
 def setUp(self):
     self.comments = [
         Comment.objects.create(
             id=1,
             email='*****@*****.**'
         ),
         Comment.objects.create(
             id=2,
             email='*****@*****.**'
         )
     ]
     self.protection_headers = {
         utils.prepare_header_name(extensions_api_settings.DEFAULT_BULK_OPERATION_HEADER_NAME): 'true'
     }
Beispiel #6
0
 def run_for_methods(self, methods, condition_failed_status):
     for method in methods:
         for exp in self.experiments:
             headers = {
                 prepare_header_name(self.header_name): exp['header_value']
             }
             request = getattr(factory, method.lower())('', **headers)
             response = self.view_instance.get(request)
             base_msg = (
                 'For "{method}" and {header_name} value {header_value} condition should'
             ).format(
                 method=method,
                 header_name=self.header_name,
                 header_value=exp['header_value'],
             )
             if exp['should_fail']:
                 msg = base_msg + (
                     ' fail and response must be returned with {condition_failed_status} status. '
                     'But it is {response_status}').format(
                         condition_failed_status=condition_failed_status,
                         response_status=response.status_code)
                 self.assertEqual(response.status_code,
                                  condition_failed_status,
                                  msg=msg)
                 msg = base_msg + ' fail and response must be empty'
                 self.assertEqual(response.data, None, msg=msg)
                 msg = (
                     'If precondition failed, then Etag must always be added to response. But it is {0}'
                 ).format(response.get('Etag'))
                 self.assertEqual(response.get('Etag'),
                                  self.expected_etag_value,
                                  msg=msg)
             else:
                 msg = base_msg + (
                     ' not fail and response must be returned with 200 status. '
                     'But it is "{response_status}"').format(
                         response_status=response.status_code)
                 self.assertEqual(response.status_code,
                                  status.HTTP_200_OK,
                                  msg=msg)
                 msg = base_msg + 'not fail and response must be filled'
                 self.assertEqual(response.data,
                                  'Response from method',
                                  msg=msg)
                 self.assertEqual(response.get('Etag'),
                                  self.expected_etag_value,
                                  msg=msg)
Beispiel #7
0
 def run_for_methods(self, methods, condition_failed_status, experiments=None):
     for method in methods:
         if experiments is None:
             experiments = self.experiments
         for exp in experiments:
             headers = {
                 prepare_header_name(self.header_name): exp['header_value']
             }
             request = getattr(factory, method.lower())('', **headers)
             response = getattr(self.view_instance, method.lower())(request)
             base_msg = (
                 'For "{method}" and {header_name} value {header_value} condition should'
             ).format(
                 method=method,
                 header_name=self.header_name,
                 header_value=exp['header_value'],
             )
             if exp['should_fail']:
                 msg = base_msg + (
                     ' fail and response must be returned with {condition_failed_status} status. '
                     'But it is {response_status}'
                 ).format(condition_failed_status=condition_failed_status, response_status=response.status_code)
                 self.assertEqual(response.status_code, condition_failed_status, msg=msg)
                 msg = base_msg + ' fail and response must be empty'
                 self.assertEqual(response.data, None, msg=msg)
                 msg = (
                     'If precondition failed, then Etag must always be added to response. But it is {0}'
                 ).format(response.get('Etag'))
                 self.assertEqual(response.get('Etag'), self.expected_etag_value, msg=msg)
             else:
                 if method.lower() == 'delete':
                     success_status = status.HTTP_204_NO_CONTENT
                 elif method.lower() == 'post':
                     success_status = status.HTTP_201_CREATED
                 else:
                     success_status = status.HTTP_200_OK
                 msg = base_msg + (
                     ' not fail and response must be returned with %s status. '
                     'But it is "{response_status}"'
                 ).format(success_status, response_status=response.status_code)
                 self.assertEqual(response.status_code, success_status, msg=msg)
                 msg = base_msg + 'not fail and response must be filled'
                 self.assertEqual(response.data, 'Response from %s method' % method.upper(), msg=msg)
                 self.assertEqual(response.get('Etag'), self.expected_etag_value, msg=msg)
Beispiel #8
0
 def evaluate_preconditions(self, request):
     """Evaluate whether the precondition for the request is met."""
     if request.method.upper() in self.precondition_map.keys():
         required_headers = self.precondition_map.get(request.method.upper(), [])
         # check the required headers
         for header in required_headers:
             if not request.META.get(prepare_header_name(header)):
                 # raise an error for each header that does not match
                 logger.warning('Precondition required: %s', request.path,
                                extra={
                                    'status_code': status.HTTP_428_PRECONDITION_REQUIRED,
                                    'request': request
                                }
                                )
                 # raise an RFC 6585 compliant exception
                 raise PreconditionRequiredException(detail='Precondition required. This "%s" request '
                                                            'is required to be conditional. '
                                                            'Try again using "%s".' % (request.method, header)
                                                     )
     return True
Beispiel #9
0
 def evaluate_preconditions(self, request):
     """Evaluate whether the precondition for the request is met."""
     if request.method.upper() in self.precondition_map.keys():
         required_headers = self.precondition_map.get(
             request.method.upper(), [])
         # check the required headers
         for header in required_headers:
             if not request.META.get(prepare_header_name(header)):
                 # raise an error for each header that does not match
                 logger.warning('Precondition required: %s', request.path,
                                extra={
                                    'status_code': status.HTTP_428_PRECONDITION_REQUIRED,
                                    'request': request
                                }
                                )
                 # raise an RFC 6585 compliant exception
                 raise PreconditionRequiredException(detail='Precondition required. This "%s" request '
                                                            'is required to be conditional. '
                                                            'Try again using "%s".' % (
                                                                request.method, header)
                                                     )
     return True
Beispiel #10
0
    def test_precondition_decorator_unsafe_methods_if_none_match(self):
        def dummy_etag_func(**kwargs):
            return 'some_etag'

        class TestView(views.APIView):
            @api_etag(dummy_etag_func)
            def put(self, request, *args, **kwargs):
                return Response('Response from PUT method')

            @api_etag(dummy_etag_func)
            def patch(self, request, *args, **kwargs):
                return Response('Response from PATCH method')

            @api_etag(dummy_etag_func)
            def delete(self, request, *args, **kwargs):
                return Response('Response from DELETE method',
                                status=status.HTTP_204_NO_CONTENT)

        headers = {prepare_header_name('if-none-match'): 'some_etag'}

        view_instance = TestView()
        with self.assertRaises(PreconditionRequiredException) as cm:
            view_instance.put(request=factory.put('', **headers))
        self.assertEqual(cm.exception.status_code,
                         status.HTTP_428_PRECONDITION_REQUIRED)
        self.assertIsNotNone(cm.exception.detail)

        with self.assertRaises(PreconditionRequiredException) as cm:
            view_instance.patch(request=factory.patch('', **headers))
        self.assertEqual(cm.exception.status_code,
                         status.HTTP_428_PRECONDITION_REQUIRED)
        self.assertIsNotNone(cm.exception.detail)

        with self.assertRaises(PreconditionRequiredException) as cm:
            view_instance.delete(request=factory.delete('', **headers))
        self.assertEqual(cm.exception.status_code,
                         status.HTTP_428_PRECONDITION_REQUIRED)
        self.assertIsNotNone(cm.exception.detail)
Beispiel #11
0
    def test_precondition_decorator_unsafe_methods_if_none_match(self):
        def dummy_etag_func(**kwargs):
            return 'some_etag'

        class TestView(views.APIView):
            @api_etag(dummy_etag_func)
            def put(self, request, *args, **kwargs):
                return Response('Response from PUT method')

            @api_etag(dummy_etag_func)
            def patch(self, request, *args, **kwargs):
                return Response('Response from PATCH method')

            @api_etag(dummy_etag_func)
            def delete(self, request, *args, **kwargs):
                return Response('Response from DELETE method',
                                status=status.HTTP_204_NO_CONTENT)

        headers = {
            prepare_header_name('if-none-match'): 'some_etag'
        }

        view_instance = TestView()
        with self.assertRaises(PreconditionRequiredException) as cm:
            view_instance.put(request=factory.put('', **headers))
        self.assertEqual(cm.exception.status_code, status.HTTP_428_PRECONDITION_REQUIRED)
        self.assertIsNotNone(cm.exception.detail)

        with self.assertRaises(PreconditionRequiredException) as cm:
            view_instance.patch(request=factory.patch('', **headers))
        self.assertEqual(cm.exception.status_code, status.HTTP_428_PRECONDITION_REQUIRED)
        self.assertIsNotNone(cm.exception.detail)

        with self.assertRaises(PreconditionRequiredException) as cm:
            view_instance.delete(request=factory.delete('', **headers))
        self.assertEqual(cm.exception.status_code, status.HTTP_428_PRECONDITION_REQUIRED)
        self.assertIsNotNone(cm.exception.detail)
Beispiel #12
0
    def prepare_key_for_value_retrieving(self, key):
        from rest_framework_extensions.utils import prepare_header_name

        return prepare_header_name(key.lower())  # Accept-Language => http_accept_language
Beispiel #13
0
 def test_strips_whitespaces(self):
     self.assertEqual(prepare_header_name('  Accept-Language  '),
                      'HTTP_ACCEPT_LANGUAGE')
Beispiel #14
0
 def test_adds_http_prefix(self):
     self.assertEqual(prepare_header_name('Accept-Language'),
                      'HTTP_ACCEPT_LANGUAGE')
Beispiel #15
0
 def test_upper(self):
     self.assertEqual(prepare_header_name('Accept'), 'HTTP_ACCEPT')
Beispiel #16
0
 def test_replace_dash_with_underscores(self):
     self.assertEqual(prepare_header_name('Accept-Language'),
                      'HTTP_ACCEPT_LANGUAGE')
Beispiel #17
0
 def test_replace_dash_with_underscores(self):
     self.assertEqual(
         prepare_header_name('Accept-Language'), 'HTTP_ACCEPT_LANGUAGE')
Beispiel #18
0
    def prepare_key_for_value_retrieving(self, key):
        from rest_framework_extensions.utils import prepare_header_name

        return prepare_header_name(key.lower())  # Accept-Language => http_accept_language
Beispiel #19
0
 def test_strips_whitespaces(self):
     self.assertEqual(
         prepare_header_name('  Accept-Language  '), 'HTTP_ACCEPT_LANGUAGE')
Beispiel #20
0
 def test_adds_http_prefix(self):
     self.assertEqual(
         prepare_header_name('Accept-Language'), 'HTTP_ACCEPT_LANGUAGE')
Beispiel #21
0
 def test_upper(self):
     self.assertEqual(prepare_header_name('Accept'), 'HTTP_ACCEPT')