Beispiel #1
0
class TestCorsMiddlewareProcessRequest(TestCase):
    def setUp(self):
        self.middleware = CorsMiddleware()

    def test_process_request(self):
        request = Mock(path="/")
        request.method = "OPTIONS"
        request.META = {"HTTP_ACCESS_CONTROL_REQUEST_METHOD": "value"}
        with settings_override(CORS_URLS_REGEX="^.*$"):
            response = self.middleware.process_request(request)
        self.assertIsInstance(response, HttpResponse)

    def test_process_request_empty_header(self):
        request = Mock(path="/")
        request.method = "OPTIONS"
        request.META = {"HTTP_ACCESS_CONTROL_REQUEST_METHOD": ""}
        with settings_override(CORS_URLS_REGEX="^.*$"):
            response = self.middleware.process_request(request)
        self.assertIsInstance(response, HttpResponse)

    def test_process_request_no_header(self):
        request = Mock(path="/")
        request.method = "OPTIONS"
        request.META = {}
        response = self.middleware.process_request(request)
        self.assertIsNone(response)

    def test_process_request_not_options(self):
        request = Mock(path="/")
        request.method = "GET"
        request.META = {"HTTP_ACCESS_CONTROL_REQUEST_METHOD": "value"}
        response = self.middleware.process_request(request)
        self.assertIsNone(response)
Beispiel #2
0
class TestCorsMiddlewareProcessRequest(TestCase):

    def setUp(self):
        self.middleware = CorsMiddleware()

    def test_process_request(self):
        request = Mock(path='/')
        request.method = 'OPTIONS'
        request.META = {'HTTP_ACCESS_CONTROL_REQUEST_METHOD': 'value'}
        with settings_override(CORS_URLS_REGEX='^.*$'):
            response = self.middleware.process_request(request)
        self.assertIsInstance(response, HttpResponse)

    def test_process_request_empty_header(self):
        request = Mock(path='/')
        request.method = 'OPTIONS'
        request.META = {'HTTP_ACCESS_CONTROL_REQUEST_METHOD': ''}
        with settings_override(CORS_URLS_REGEX='^.*$'):
            response = self.middleware.process_request(request)
        self.assertIsInstance(response, HttpResponse)

    def test_process_request_no_header(self):
        request = Mock(path='/')
        request.method = 'OPTIONS'
        request.META = {}
        response = self.middleware.process_request(request)
        self.assertIsNone(response)

    def test_process_request_not_options(self):
        request = Mock(path='/')
        request.method = 'GET'
        request.META = {'HTTP_ACCESS_CONTROL_REQUEST_METHOD': 'value'}
        response = self.middleware.process_request(request)
        self.assertIsNone(response)
Beispiel #3
0
class TestCorsMiddlewareProcessRequest(TestCase):
    def setUp(self):
        self.middleware = CorsMiddleware()

    def test_process_request(self):
        request = Mock(path='/')
        request.method = 'OPTIONS'
        request.META = {'HTTP_ACCESS_CONTROL_REQUEST_METHOD': 'value'}
        with settings_override(CORS_URLS_REGEX='^.*$'):
            response = self.middleware.process_request(request)
        self.assertIsInstance(response, HttpResponse)

    def test_process_request_empty_header(self):
        request = Mock(path='/')
        request.method = 'OPTIONS'
        request.META = {'HTTP_ACCESS_CONTROL_REQUEST_METHOD': ''}
        with settings_override(CORS_URLS_REGEX='^.*$'):
            response = self.middleware.process_request(request)
        self.assertIsInstance(response, HttpResponse)

    def test_process_request_no_header(self):
        request = Mock(path='/')
        request.method = 'OPTIONS'
        request.META = {}
        response = self.middleware.process_request(request)
        self.assertIsNone(response)

    def test_process_request_not_options(self):
        request = Mock(path='/')
        request.method = 'GET'
        request.META = {'HTTP_ACCESS_CONTROL_REQUEST_METHOD': 'value'}
        response = self.middleware.process_request(request)
        self.assertIsNone(response)
Beispiel #4
0
 def setUp(self):
     self.factory = RequestFactory()
     self.middleware = CorsMiddleware()
     self.url = '/api/v2/search'
     self.owner = create_user(username='******', password='******')
     self.project = get(
         Project,
         slug='pip',
         users=[self.owner],
         privacy_level='public',
         mail_language_project=None,
     )
     self.subproject = get(
         Project,
         users=[self.owner],
         privacy_level='public',
         mail_language_project=None,
     )
     self.relationship = get(
         ProjectRelationship,
         parent=self.project,
         child=self.subproject,
     )
     self.domain = get(Domain,
                       domain='my.valid.domain',
                       project=self.project)
def check_host(host: str) -> bool:
    """
    Check if the host is allowed
    """
    middleware = CorsMiddleware()
    if middleware.regex_domain_match(host):
        return True

    return ClientWebsite.objects.check_by_own_domain(host)
 def setUp(self):
     self.factory = RequestFactory()
     self.middleware = CorsMiddleware()
     self.url = '/api/v2/search'
     self.owner = create_user(username='******', password='******')
     self.pip = get(
         Project,
         slug='pip',
         users=[self.owner],
         privacy_level='public',
     )
     self.domain = get(Domain, domain='my.valid.domain', project=self.pip)
Beispiel #7
0
    def http_handler(self, message, **kwargs):
        """
        Called on HTTP request
        :param message: message received
        :return:
        """
        # Get Django HttpRequest object from ASGI Message
        request = AsgiRequest(message)

        # CORS
        response = CorsMiddleware().process_request(request)
        if not isinstance(response, HttpResponse):

            # Try to process content
            try:
                if request.method != 'POST':
                    raise MethodNotSupported('Only POST method is supported')
                content = request.body.decode('utf-8')
            except (UnicodeDecodeError, MethodNotSupported):
                content = ''
            result, is_notification = self.__handle(content, message, kwargs)

            # Set response status code
            # http://www.jsonrpc.org/historical/json-rpc-over-http.html#response-codes
            if not is_notification:
                # call response
                status_code = 200
                if 'error' in result:
                    code = result['error']['code']
                    status_code = self._http_codes[
                        code] if code in self._http_codes else 500
            else:
                # notification response
                status_code = 204
                if result and 'error' in result:
                    code = result['error']['code']
                    status_code = self._http_codes[
                        code] if code in self._http_codes else 500
                result = ''

            response = HttpResponse(self.__class__._encode(result),
                                    content_type='application/json-rpc',
                                    status=status_code)

        # CORS
        response = CorsMiddleware().process_response(request, response)

        # Encode that response into message format (ASGI)
        for chunk in AsgiHandler.encode_response(response):
            message.reply_channel.send(chunk)
 def setUp(self):
     self.factory = RequestFactory()
     self.middleware = CorsMiddleware()
     self.url = '/api/v2/search'
     self.owner = create_user(username='******', password='******')
     self.project = get(
         Project,
         slug='pip',
         users=[self.owner],
         privacy_level=PUBLIC,
         main_language_project=None,
     )
     self.project.versions.update(privacy_level=PUBLIC)
     self.version = self.project.versions.get(slug=LATEST)
     self.subproject = get(
         Project,
         users=[self.owner],
         privacy_level=PUBLIC,
         main_language_project=None,
     )
     self.subproject.versions.update(privacy_level=PUBLIC)
     self.version_subproject = self.subproject.versions.get(slug=LATEST)
     self.relationship = get(
         ProjectRelationship,
         parent=self.project,
         child=self.subproject,
     )
     self.domain = get(
         Domain,
         domain='my.valid.domain',
         project=self.project,
     )
     self.another_project = get(
         Project,
         privacy_level=PUBLIC,
         slug='another',
     )
     self.another_project.versions.update(privacy_level=PUBLIC)
     self.another_version = self.another_project.versions.get(slug=LATEST)
     self.another_domain = get(
         Domain,
         domain='another.valid.domain',
         project=self.another_project,
     )
 def setUp(self):
     self.factory = RequestFactory()
     self.middleware = CorsMiddleware()
     self.url = '/api/v2/search'
     self.owner = create_user(username='******', password='******')
     self.pip = get(
         Project, slug='pip',
         users=[self.owner], privacy_level='public',
     )
     self.domain = get(Domain, domain='my.valid.domain', project=self.pip)
class TestCORSMiddleware(TestCase):
    def setUp(self):
        self.factory = RequestFactory()
        self.middleware = CorsMiddleware()
        self.url = '/api/v2/search'
        self.owner = create_user(username='******', password='******')
        self.pip = get(
            Project,
            slug='pip',
            users=[self.owner],
            privacy_level='public',
        )
        self.domain = get(Domain, domain='my.valid.domain', project=self.pip)

    def test_proper_domain(self):
        request = self.factory.get(
            self.url,
            {'project': self.pip.slug},
            HTTP_ORIGIN='http://my.valid.domain',
        )
        resp = self.middleware.process_response(request, {})
        self.assertIn('Access-Control-Allow-Origin', resp)

    def test_invalid_domain(self):
        request = self.factory.get(
            self.url,
            {'project': self.pip.slug},
            HTTP_ORIGIN='http://invalid.domain',
        )
        resp = self.middleware.process_response(request, {})
        self.assertNotIn('Access-Control-Allow-Origin', resp)

    def test_invalid_project(self):
        request = self.factory.get(
            self.url,
            {'project': 'foo'},
            HTTP_ORIGIN='http://my.valid.domain',
        )
        resp = self.middleware.process_response(request, {})
        self.assertNotIn('Access-Control-Allow-Origin', resp)
class TestCORSMiddleware(TestCase):

    def setUp(self):
        self.factory = RequestFactory()
        self.middleware = CorsMiddleware()
        self.url = '/api/v2/search'
        self.owner = create_user(username='******', password='******')
        self.pip = get(
            Project, slug='pip',
            users=[self.owner], privacy_level='public',
        )
        self.domain = get(Domain, domain='my.valid.domain', project=self.pip)

    def test_proper_domain(self):
        request = self.factory.get(
            self.url,
            {'project': self.pip.slug},
            HTTP_ORIGIN='http://my.valid.domain',
        )
        resp = self.middleware.process_response(request, {})
        self.assertIn('Access-Control-Allow-Origin', resp)

    def test_invalid_domain(self):
        request = self.factory.get(
            self.url,
            {'project': self.pip.slug},
            HTTP_ORIGIN='http://invalid.domain',
        )
        resp = self.middleware.process_response(request, {})
        self.assertNotIn('Access-Control-Allow-Origin', resp)

    def test_invalid_project(self):
        request = self.factory.get(
            self.url,
            {'project': 'foo'},
            HTTP_ORIGIN='http://my.valid.domain',
        )
        resp = self.middleware.process_response(request, {})
        self.assertNotIn('Access-Control-Allow-Origin', resp)
Beispiel #12
0
 def test_cors(self):
     """
     Cross Origin Requests should be allowed.
     """
     request = Mock(path='https://api.data.amsterdam.nl/panorama/panoramas/?lat=52.3779561&lon=4.8970701')
     request.method = 'GET'
     request.is_secure = lambda: True
     request.META = {
         'HTTP_REFERER': 'https://foo.google.com',
         'HTTP_HOST': 'api.data.amsterdam.nl',
         'HTTP_ORIGIN': 'https://foo.google.com',
     }
     response = CorsMiddleware().process_response(request, HttpResponse())
     self.assertTrue('access-control-allow-origin' in response._headers)
     self.assertEquals(
         '*', response._headers['access-control-allow-origin'][1])
 def setUp(self):
     self.factory = RequestFactory()
     self.middleware = CorsMiddleware()
     self.url = '/api/v2/search'
     self.owner = create_user(username='******', password='******')
     self.project = get(
         Project, slug='pip',
         users=[self.owner], privacy_level='public',
         mail_language_project=None
     )
     self.subproject = get(
         Project,
         users=[self.owner],
         privacy_level='public',
         mail_language_project=None,
     )
     self.relationship = get(
         ProjectRelationship,
         parent=self.project,
         child=self.subproject
     )
     self.domain = get(Domain, domain='my.valid.domain', project=self.project)
Beispiel #14
0
class TestCorsMiddlewareProcessResponse(TestCase):
    def setUp(self):
        self.middleware = CorsMiddleware()

    def assertAccessControlAllowOriginEquals(self, response, header):
        self.assertIn(
            ACCESS_CONTROL_ALLOW_ORIGIN,
            response,
            "Response %r does " "NOT have %r header" % (response, ACCESS_CONTROL_ALLOW_ORIGIN),
        )
        self.assertEqual(response[ACCESS_CONTROL_ALLOW_ORIGIN], header)

    def test_process_response_no_origin(self, settings):
        settings.CORS_URLS_REGEX = "^.*$"
        response = HttpResponse()
        request = Mock(path="/", META={})
        processed = self.middleware.process_response(request, response)
        self.assertNotIn(ACCESS_CONTROL_ALLOW_ORIGIN, processed)

    def test_process_response_not_in_whitelist(self, settings):
        settings.CORS_ORIGIN_ALLOW_ALL = False
        settings.CORS_ORIGIN_WHITELIST = ["example.com"]
        settings.CORS_URLS_REGEX = "^.*$"
        response = HttpResponse()
        request = Mock(path="/", META={"HTTP_ORIGIN": "http://foobar.it"})
        processed = self.middleware.process_response(request, response)
        self.assertNotIn(ACCESS_CONTROL_ALLOW_ORIGIN, processed)

    def test_process_response_in_whitelist(self, settings):
        settings.CORS_ORIGIN_ALLOW_ALL = False
        settings.CORS_ORIGIN_WHITELIST = ["example.com", "foobar.it"]
        settings.CORS_URLS_REGEX = "^.*$"
        response = HttpResponse()
        request = Mock(path="/", META={"HTTP_ORIGIN": "http://foobar.it"})
        processed = self.middleware.process_response(request, response)
        self.assertAccessControlAllowOriginEquals(processed, "http://foobar.it")

    def test_process_response_expose_headers(self, settings):
        settings.CORS_ORIGIN_ALLOW_ALL = True
        settings.CORS_EXPOSE_HEADERS = ["accept", "origin", "content-type"]
        settings.CORS_URLS_REGEX = "^.*$"
        response = HttpResponse()
        request = Mock(path="/", META={"HTTP_ORIGIN": "http://example.com"})
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed[ACCESS_CONTROL_EXPOSE_HEADERS], "accept, origin, content-type")

    def test_process_response_dont_expose_headers(self, settings):
        settings.CORS_ORIGIN_ALLOW_ALL = True
        settings.CORS_EXPOSE_HEADERS = []
        settings.CORS_URLS_REGEX = "^.*$"
        response = HttpResponse()
        request = Mock(path="/", META={"HTTP_ORIGIN": "http://example.com"})
        processed = self.middleware.process_response(request, response)
        self.assertNotIn(ACCESS_CONTROL_EXPOSE_HEADERS, processed)

    def test_process_response_allow_credentials(self, settings):
        settings.CORS_ORIGIN_ALLOW_ALL = True
        settings.CORS_ALLOW_CREDENTIALS = True
        settings.CORS_URLS_REGEX = "^.*$"
        response = HttpResponse()
        request = Mock(path="/", META={"HTTP_ORIGIN": "http://example.com"})
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed[ACCESS_CONTROL_ALLOW_CREDENTIALS], "true")

    def test_process_response_dont_allow_credentials(self, settings):
        settings.CORS_ORIGIN_ALLOW_ALL = True
        settings.CORS_ALLOW_CREDENTIALS = False
        settings.CORS_URLS_REGEX = "^.*$"
        response = HttpResponse()
        request = Mock(path="/", META={"HTTP_ORIGIN": "http://example.com"})
        processed = self.middleware.process_response(request, response)
        self.assertNotIn(ACCESS_CONTROL_ALLOW_CREDENTIALS, processed)

    def test_process_response_options_method(self, settings):
        settings.CORS_ORIGIN_ALLOW_ALL = True
        settings.CORS_ALLOW_HEADERS = ["content-type", "origin"]
        settings.CORS_ALLOW_METHODS = ["GET", "OPTIONS"]
        settings.CORS_PREFLIGHT_MAX_AGE = 1002
        settings.CORS_URLS_REGEX = "^.*$"
        response = HttpResponse()
        request_headers = {"HTTP_ORIGIN": "http://example.com"}
        request = Mock(path="/", META=request_headers, method="OPTIONS")
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed[ACCESS_CONTROL_ALLOW_HEADERS], "content-type, origin")
        self.assertEqual(processed[ACCESS_CONTROL_ALLOW_METHODS], "GET, OPTIONS")
        self.assertEqual(processed[ACCESS_CONTROL_MAX_AGE], "1002")

    def test_process_response_options_method_no_max_age(self, settings):
        settings.CORS_ORIGIN_ALLOW_ALL = True
        settings.CORS_ALLOW_HEADERS = ["content-type", "origin"]
        settings.CORS_ALLOW_METHODS = ["GET", "OPTIONS"]
        settings.CORS_PREFLIGHT_MAX_AGE = 0
        settings.CORS_URLS_REGEX = "^.*$"
        response = HttpResponse()
        request_headers = {"HTTP_ORIGIN": "http://example.com"}
        request = Mock(path="/", META=request_headers, method="OPTIONS")
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed[ACCESS_CONTROL_ALLOW_HEADERS], "content-type, origin")
        self.assertEqual(processed[ACCESS_CONTROL_ALLOW_METHODS], "GET, OPTIONS")
        self.assertNotIn(ACCESS_CONTROL_MAX_AGE, processed)

    def test_process_response_whitelist_with_port(self, settings):
        settings.CORS_ORIGIN_ALLOW_ALL = False
        settings.CORS_ALLOW_METHODS = ["OPTIONS"]
        settings.CORS_ORIGIN_WHITELIST = ("localhost:9000",)
        settings.CORS_URLS_REGEX = "^.*$"
        response = HttpResponse()
        request_headers = {"HTTP_ORIGIN": "http://localhost:9000"}
        request = Mock(path="/", META=request_headers, method="OPTIONS")
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed.get(ACCESS_CONTROL_ALLOW_CREDENTIALS), "true")

    def test_process_response_adds_origin_when_domain_found_in_origin_regex_whitelist(self, settings):
        settings.CORS_ORIGIN_REGEX_WHITELIST = ("^http?://(\w+\.)?google\.com$",)
        settings.CORS_ALLOW_CREDENTIALS = True
        settings.CORS_ORIGIN_ALLOW_ALL = False
        settings.CORS_ALLOW_METHODS = ["OPTIONS"]
        settings.CORS_URLS_REGEX = "^.*$"
        response = HttpResponse()
        request_headers = {"HTTP_ORIGIN": "http://foo.google.com"}
        request = Mock(path="/", META=request_headers, method="OPTIONS")
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed.get(ACCESS_CONTROL_ALLOW_ORIGIN), "http://foo.google.com")

    def test_process_response_will_not_add_origin_when_domain_not_found_in_origin_regex_whitelist(self, settings):
        settings.CORS_ORIGIN_REGEX_WHITELIST = ("^http?://(\w+\.)?yahoo\.com$",)
        settings.CORS_ALLOW_CREDENTIALS = True
        settings.CORS_ORIGIN_ALLOW_ALL = False
        settings.CORS_ALLOW_METHODS = ["OPTIONS"]
        settings.CORS_URLS_REGEX = "^.*$"
        response = HttpResponse()
        request_headers = {"HTTP_ORIGIN": "http://foo.google.com"}
        request = Mock(path="/", META=request_headers, method="OPTIONS")
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed.get(ACCESS_CONTROL_ALLOW_ORIGIN), None)
class TestCorsMiddlewareProcessResponse(TestCase):
    def setUp(self):
        self.middleware = CorsMiddleware()

    def test_process_response_no_origin(self):
        response = HttpResponse()
        request = Mock(path='/', META={})
        processed = self.middleware.process_response(request, response)
        assert ACCESS_CONTROL_ALLOW_ORIGIN not in processed

    @override_settings(CORS_ORIGIN_WHITELIST=['example.com'])
    def test_process_response_not_in_whitelist(self):
        response = HttpResponse()
        request = Mock(path='/', META={'HTTP_ORIGIN': 'http://foobar.it'})
        processed = self.middleware.process_response(request, response)
        assert ACCESS_CONTROL_ALLOW_ORIGIN not in processed

    @override_settings(CORS_ORIGIN_WHITELIST=['example.com', 'foobar.it'])
    def test_process_response_in_whitelist(self):
        response = HttpResponse()
        request = Mock(path='/', META={'HTTP_ORIGIN': 'http://foobar.it'})
        processed = self.middleware.process_response(request, response)
        assert processed[ACCESS_CONTROL_ALLOW_ORIGIN] == 'http://foobar.it'

    @override_settings(
        CORS_ORIGIN_ALLOW_ALL=True,
        CORS_EXPOSE_HEADERS=['accept', 'origin', 'content-type'],
    )
    def test_process_response_expose_headers(self):
        response = HttpResponse()
        request = Mock(path='/', META={'HTTP_ORIGIN': 'http://example.com'})
        processed = self.middleware.process_response(request, response)
        assert processed[ACCESS_CONTROL_EXPOSE_HEADERS] == \
            'accept, origin, content-type'

    @override_settings(CORS_ORIGIN_ALLOW_ALL=True)
    def test_process_response_dont_expose_headers(self):
        response = HttpResponse()
        request = Mock(path='/', META={'HTTP_ORIGIN': 'http://example.com'})
        processed = self.middleware.process_response(request, response)
        assert ACCESS_CONTROL_EXPOSE_HEADERS not in processed

    @override_settings(
        CORS_ALLOW_CREDENTIALS=True,
        CORS_ORIGIN_ALLOW_ALL=True,
    )
    def test_process_response_allow_credentials(self):
        response = HttpResponse()
        request = Mock(path='/', META={'HTTP_ORIGIN': 'http://example.com'})
        processed = self.middleware.process_response(request, response)
        assert processed[ACCESS_CONTROL_ALLOW_CREDENTIALS] == 'true'

    @override_settings(CORS_ORIGIN_ALLOW_ALL=True)
    def test_process_response_dont_allow_credentials(self):
        response = HttpResponse()
        request = Mock(path='/', META={'HTTP_ORIGIN': 'http://example.com'})
        processed = self.middleware.process_response(request, response)
        assert ACCESS_CONTROL_ALLOW_CREDENTIALS not in processed

    @override_settings(
        CORS_ALLOW_HEADERS=['content-type', 'origin'],
        CORS_ALLOW_METHODS=['GET', 'OPTIONS'],
        CORS_PREFLIGHT_MAX_AGE=1002,
        CORS_ORIGIN_ALLOW_ALL=True,
    )
    def test_process_response_options_method(self):
        response = HttpResponse()
        request_headers = {'HTTP_ORIGIN': 'http://example.com'}
        request = Mock(path='/', META=request_headers, method='OPTIONS')
        processed = self.middleware.process_response(request, response)
        assert processed[
            ACCESS_CONTROL_ALLOW_HEADERS] == 'content-type, origin'
        assert processed[ACCESS_CONTROL_ALLOW_METHODS] == 'GET, OPTIONS'
        assert processed[ACCESS_CONTROL_MAX_AGE] == '1002'

    @override_settings(
        CORS_ALLOW_HEADERS=['content-type', 'origin'],
        CORS_ALLOW_METHODS=['GET', 'OPTIONS'],
        CORS_PREFLIGHT_MAX_AGE=0,
        CORS_ORIGIN_ALLOW_ALL=True,
    )
    def test_process_response_options_method_no_max_age(self):
        response = HttpResponse()
        request_headers = {'HTTP_ORIGIN': 'http://example.com'}
        request = Mock(path='/', META=request_headers, method='OPTIONS')
        processed = self.middleware.process_response(request, response)
        assert processed[ACCESS_CONTROL_ALLOW_HEADERS] == \
            'content-type, origin'
        assert processed[ACCESS_CONTROL_ALLOW_METHODS] == 'GET, OPTIONS'
        assert ACCESS_CONTROL_MAX_AGE not in processed

    @override_settings(
        CORS_ALLOW_METHODS=['OPTIONS'],
        CORS_ALLOW_CREDENTIALS=True,
        CORS_ORIGIN_WHITELIST=('localhost:9000', ),
    )
    def test_process_response_whitelist_with_port(self):
        response = HttpResponse()
        request_headers = {'HTTP_ORIGIN': 'http://localhost:9000'}
        request = Mock(path='/', META=request_headers, method='OPTIONS')
        processed = self.middleware.process_response(request, response)
        assert processed.get(ACCESS_CONTROL_ALLOW_CREDENTIALS, None) == 'true'

    @override_settings(
        CORS_ALLOW_METHODS=['OPTIONS'],
        CORS_ALLOW_CREDENTIALS=True,
        CORS_ORIGIN_REGEX_WHITELIST=('^http?://(\w+\.)?google\.com$', ),
    )
    def test_process_response_adds_origin_when_domain_found_in_origin_regex_whitelist(
            self):
        response = HttpResponse()
        request_headers = {'HTTP_ORIGIN': 'http://foo.google.com'}
        request = Mock(path='/', META=request_headers, method='OPTIONS')
        processed = self.middleware.process_response(request, response)
        assert processed.get(ACCESS_CONTROL_ALLOW_ORIGIN,
                             None) == 'http://foo.google.com'

    @override_settings(
        CORS_ALLOW_METHODS=['OPTIONS'],
        CORS_ALLOW_CREDENTIALS=True,
        CORS_ORIGIN_REGEX_WHITELIST=('^http?://(\w+\.)?yahoo\.com$', ),
    )
    def test_process_response_will_not_add_origin_when_domain_not_found_in_origin_regex_whitelist(
            self):
        response = HttpResponse()
        request_headers = {'HTTP_ORIGIN': 'http://foo.google.com'}
        request = Mock(path='/', META=request_headers, method='OPTIONS')
        processed = self.middleware.process_response(request, response)
        assert processed.get(ACCESS_CONTROL_ALLOW_ORIGIN, None) is None

    @override_settings(CORS_MODEL='corsheaders.CorsModel')
    def test_process_response_when_custom_model_enabled(self):
        from corsheaders.models import CorsModel
        CorsModel.objects.create(cors='foo.google.com')
        response = HttpResponse()
        request = Mock(path='/', META={'HTTP_ORIGIN': 'http://foo.google.com'})
        processed = self.middleware.process_response(request, response)
        assert processed.get(ACCESS_CONTROL_ALLOW_ORIGIN,
                             None) == 'http://foo.google.com'

    @override_settings(
        CORS_ALLOW_CREDENTIALS=True,
        CORS_ORIGIN_ALLOW_ALL=True,
    )
    def test_middleware_integration_get(self):
        response = self.client.get('/test-view/',
                                   HTTP_ORIGIN='http://foobar.it')
        assert response.status_code == 200
        assert response[ACCESS_CONTROL_ALLOW_ORIGIN] == 'http://foobar.it'

    @override_settings(
        CORS_ALLOW_CREDENTIALS=True,
        CORS_ORIGIN_ALLOW_ALL=True,
    )
    def test_middleware_integration_get_auth_view(self):
        """
        It's not clear whether the header should still be set for non-HTTP200
        when not a preflight request. However this is the existing behaviour for
        django-cors-middleware, so at least this test makes that explicit, especially
        since for the switch to Django 1.10, special-handling will need to be put in
        place to preserve this behaviour. See `ExceptionMiddleware` mention here:
        https://docs.djangoproject.com/en/1.10/topics/http/middleware/#upgrading-pre-django-1-10-style-middleware
        """
        response = self.client.get('/test-view-http401/',
                                   HTTP_ORIGIN='http://foobar.it')
        assert response.status_code == 401
        assert response[ACCESS_CONTROL_ALLOW_ORIGIN] == 'http://foobar.it'

    @override_settings(
        CORS_ALLOW_CREDENTIALS=True,
        CORS_ORIGIN_ALLOW_ALL=True,
    )
    def test_middleware_integration_preflight_auth_view(self):
        """
        Ensure HTTP200 and header still set, for preflight requests to views requiring
        authentication. See: https://github.com/ottoyiu/django-cors-headers/issues/3
        """
        response = self.client.options(
            '/test-view-http401/',
            HTTP_ORIGIN='http://foobar.it',
            HTTP_ACCESS_CONTROL_REQUEST_METHOD='value')
        assert response.status_code == 200
        assert response[ACCESS_CONTROL_ALLOW_ORIGIN] == 'http://foobar.it'

    def test_signal_that_returns_false(self):
        def handler(*args, **kwargs):
            return False

        check_request_enabled.connect(handler)

        resp = self.client.options(
            '/test-view/',
            HTTP_ORIGIN='http://foobar.it',
            HTTP_ACCESS_CONTROL_REQUEST_METHOD='value',
        )

        assert resp.status_code == 200
        assert ACCESS_CONTROL_ALLOW_ORIGIN not in resp

    def test_signal_that_returns_true(self):
        def handler(*args, **kwargs):
            return True

        check_request_enabled.connect(handler)

        resp = self.client.options(
            '/test-view/',
            HTTP_ORIGIN='http://foobar.it',
            HTTP_ACCESS_CONTROL_REQUEST_METHOD='value',
        )
        assert resp.status_code == 200
        assert resp[ACCESS_CONTROL_ALLOW_ORIGIN] == 'http://foobar.it'

    @override_settings(CORS_ORIGIN_WHITELIST=['example.com'])
    def test_signal_allow_some_urls_to_everyone(self):
        def allow_api_to_all(sender, request, **kwargs):
            return request.path.startswith('/api/')

        check_request_enabled.connect(allow_api_to_all)

        resp = self.client.options(
            '/test-view/',
            HTTP_ORIGIN='http://example.org',
            HTTP_ACCESS_CONTROL_REQUEST_METHOD='value',
        )
        assert resp.status_code == 200
        assert ACCESS_CONTROL_ALLOW_ORIGIN not in resp

        resp = self.client.options(
            '/api/something/',
            HTTP_ORIGIN='http://example.org',
            HTTP_ACCESS_CONTROL_REQUEST_METHOD='value',
        )
        assert resp.status_code == 200
        assert resp[ACCESS_CONTROL_ALLOW_ORIGIN] == 'http://example.org'
Beispiel #16
0
class TestCORSMiddleware(TestCase):

    def setUp(self):
        self.factory = RequestFactory()
        self.middleware = CorsMiddleware()
        self.url = '/api/v2/search'
        self.owner = create_user(username='******', password='******')
        self.project = get(
            Project, slug='pip',
            users=[self.owner], privacy_level='public',
            mail_language_project=None
        )
        self.subproject = get(
            Project,
            users=[self.owner],
            privacy_level='public',
            mail_language_project=None,
        )
        self.relationship = get(
            ProjectRelationship,
            parent=self.project,
            child=self.subproject
        )
        self.domain = get(Domain, domain='my.valid.domain', project=self.project)

    def test_proper_domain(self):
        request = self.factory.get(
            self.url,
            {'project': self.project.slug},
            HTTP_ORIGIN='http://my.valid.domain',
        )
        resp = self.middleware.process_response(request, {})
        self.assertIn('Access-Control-Allow-Origin', resp)

    def test_invalid_domain(self):
        request = self.factory.get(
            self.url,
            {'project': self.project.slug},
            HTTP_ORIGIN='http://invalid.domain',
        )
        resp = self.middleware.process_response(request, {})
        self.assertNotIn('Access-Control-Allow-Origin', resp)

    def test_invalid_project(self):
        request = self.factory.get(
            self.url,
            {'project': 'foo'},
            HTTP_ORIGIN='http://my.valid.domain',
        )
        resp = self.middleware.process_response(request, {})
        self.assertNotIn('Access-Control-Allow-Origin', resp)

    def test_valid_subproject(self):
        self.assertTrue(
            Project.objects.filter(
                pk=self.project.pk,
                subprojects__child=self.subproject
            ).exists()
        )
        request = self.factory.get(
            self.url,
            {'project': self.subproject.slug},
            HTTP_ORIGIN='http://my.valid.domain',
        )
        resp = self.middleware.process_response(request, {})
        self.assertIn('Access-Control-Allow-Origin', resp)
Beispiel #17
0
 def setUp(self):
     self.middleware = CorsMiddleware()
class TestCorsMiddlewareProcessRequest(TestCase):
    def setUp(self):
        self.middleware = CorsMiddleware()

    def test_process_request(self):
        request = Mock(path='/')
        request.method = 'OPTIONS'
        request.META = {'HTTP_ACCESS_CONTROL_REQUEST_METHOD': 'value'}
        response = self.middleware.process_request(request)
        assert isinstance(response, HttpResponse)

    def test_process_request_empty_header(self):
        request = Mock(path='/')
        request.method = 'OPTIONS'
        request.META = {'HTTP_ACCESS_CONTROL_REQUEST_METHOD': ''}
        response = self.middleware.process_request(request)
        assert isinstance(response, HttpResponse)

    def test_process_request_no_header(self):
        request = Mock(path='/')
        request.method = 'OPTIONS'
        request.META = {}
        response = self.middleware.process_request(request)
        assert response is None

    def test_process_request_not_options(self):
        request = Mock(path='/')
        request.method = 'GET'
        request.META = {'HTTP_ACCESS_CONTROL_REQUEST_METHOD': 'value'}
        response = self.middleware.process_request(request)
        assert response is None

    @override_settings(
        CORS_ORIGIN_REGEX_WHITELIST='.*google.*',
        CORS_REPLACE_HTTPS_REFERER=True,
    )
    def test_process_request_replace_https_referer(self):
        post_middleware = CorsPostCsrfMiddleware()
        request = Mock(path='/')
        request.method = 'GET'
        request.is_secure = lambda: True

        # make sure it doesnt blow up when HTTP_REFERER is not present
        request.META = {
            'HTTP_HOST': 'foobar.com',
            'HTTP_ORIGIN': 'https://foo.google.com',
        }
        response = self.middleware.process_request(request)
        assert response is None

        # make sure it doesnt blow up when HTTP_HOST is not present
        request.META = {
            'HTTP_REFERER': 'http://foo.google.com/',
            'HTTP_ORIGIN': 'https://foo.google.com',
        }
        response = self.middleware.process_request(request)
        assert response is None

        request.is_secure = lambda: False
        request.META = {
            'HTTP_REFERER': 'http://foo.google.com/',
            'HTTP_HOST': 'foobar.com',
            'HTTP_ORIGIN': 'http://foo.google.com',
        }

        # test that we won't replace if the request is not secure
        response = self.middleware.process_request(request)
        assert response is None
        assert 'ORIGINAL_HTTP_REFERER' not in request.META
        assert request.META['HTTP_REFERER'] == 'http://foo.google.com/'

        request.is_secure = lambda: True
        request.META = {
            'HTTP_REFERER': 'https://foo.google.com/',
            'HTTP_HOST': 'foobar.com',
            'HTTP_ORIGIN': 'https://foo.google.com',
        }

        # test that we won't replace with the setting off
        with override_settings(CORS_REPLACE_HTTPS_REFERER=False):
            response = self.middleware.process_request(request)
        assert response is None
        assert 'ORIGINAL_HTTP_REFERER' not in request.META
        assert request.META['HTTP_REFERER'] == 'https://foo.google.com/'

        response = self.middleware.process_request(request)
        assert response is None
        assert request.META[
            'ORIGINAL_HTTP_REFERER'] == 'https://foo.google.com/'
        assert request.META['HTTP_REFERER'] == 'https://foobar.com/'

        # make sure the replace code is idempotent
        response = self.middleware.process_view(request, None, None, None)
        assert response is None
        assert request.META[
            'ORIGINAL_HTTP_REFERER'] == 'https://foo.google.com/'
        assert request.META['HTTP_REFERER'] == 'https://foobar.com/'

        post_middleware.process_request(request)
        assert 'ORIGINAL_HTTP_REFERER' not in request.META
        assert request.META['HTTP_REFERER'] == 'https://foo.google.com/'

        response = post_middleware.process_request(request)
        assert response is None

    @override_settings(
        CORS_ORIGIN_REGEX_WHITELIST='.*google.*',
        CORS_REPLACE_HTTPS_REFERER=True,
    )
    def test_process_view_replace_https_referer(self):
        post_middleware = CorsPostCsrfMiddleware()
        request = Mock(path='/')
        request.method = 'GET'
        request.is_secure = lambda: True
        request.META = {
            'HTTP_REFERER': 'https://foo.google.com/',
            'HTTP_HOST': 'foobar.com',
            'HTTP_ORIGIN': 'https://foo.google.com',
        }
        response = self.middleware.process_view(request, None, None, None)
        assert response is None
        assert request.META[
            'ORIGINAL_HTTP_REFERER'] == 'https://foo.google.com/'
        assert request.META['HTTP_REFERER'] == 'https://foobar.com/'

        post_middleware.process_view(request, None, None, None)
        assert 'ORIGINAL_HTTP_REFERER' not in request.META
        assert request.META['HTTP_REFERER'] == 'https://foo.google.com/'

        response = post_middleware.process_view(request, None, None, None)
        assert response is None
	def process_request(self, request):
		pretty = True if 'HTTP_X_CSAPI_PRETTY' in request.META and request.META['HTTP_X_CSAPI_PRETTY'].lower() in ['true', 'on', '1' ] else False
		request.META = request.META.copy()
		request.META['HTTP_X_CSAPI_PRETTY'] = pretty
		
		try:		
			view_func = resolve(request.META['PATH_INFO'])[0]
			app_label = view_func.__module__.rsplit('.', 1)[1]
			view_name = view_func.__name__
			methods = settings.ALLOW_EXPOSE_CORS_DATA[app_label][view_name]['METHODS']
			if methods:
				if getattr(request, "_CorsMiddleware", False) is False:
					self._CorsMiddleware = CorsMiddleware()

				response = self._CorsMiddleware.process_request(request)
				if response and request.method == "OPTIONS":
					response = self._CorsMiddleware.process_response(request, response)
					response[ACCESS_CONTROL_ALLOW_METHODS] = ", ".join(methods)
					try:
						headers = settings.ALLOW_EXPOSE_CORS_DATA[app_label][view_name]['EXPOSE_HEADERS']						
						if headers:
							response[ACCESS_CONTROL_EXPOSE_HEADERS] =  ", ".join(headers)
					except Exception as e:
						raise e


					try:
						headers = settings.ALLOW_EXPOSE_CORS_DATA[app_label][view_name]['ALLOW_HEADERS']						
						if headers:
							response[ACCESS_CONTROL_ALLOW_HEADERS] =  ", ".join(headers)
					except Exception as e:
						raise e
					response[ACCESS_CONTROL_ALLOW_HEADERS] = '*'
					response[ACCESS_CONTROL_EXPOSE_HEADERS] = []
					setattr(request, "_cors_enabled", False)
					return response
		except Exception as e:
			raise e
		

		
		request.META['_time'] = time.time()
		""" """
		req_key = 'HTTP_X_CSAPI_REQUEST_URL'
		req_val = None
		url     = request.META[req_key] if req_key in request.META else None
		req_val = ConsoleAPI.Filter_Request_Url(url)

		request.META[req_key] = req_val

		#
		req_key = 'HTTP_X_CSAPI_AUTHORIZATION'
		req_val     = request.META[req_key] if req_key in request.META else None
		if req_val:
			req_val = str(req_val)
		request.META[req_key] = req_val

		
		#
		req_key = 'HTTP_X_CSAPI_COOKIE'
		req_val     = request.META[req_key] if req_key in request.META else None
		if req_val:
			req_val = str(req_val)
		request.META[req_key] = req_val


		#
		req_key = 'HTTP_X_CSAPI_DEBUG'
		req_val     = request.META[req_key] if req_key in request.META else None
		req_val = True if req_val in ['true', 'on', '1', 'yes' ] else False
		request.META[req_key] = req_val

		#
		req_key = 'HTTP_X_CSAPI_FOLLOW_REDIRECTION'
		req_val     = request.META[req_key] if req_key in request.META else None
		req_val = True if req_val in ['true', 'on', '1', 'yes' ] else False
		request.META[req_key] = req_val

		#
		req_key = 'HTTP_X_CSAPI_HTTP_VERSION'
		req_val     = request.META[req_key] if req_key in request.META else None
		req_val = 1.0 if req_val in ['1', '1.0'] else ( 1.1 if req_val in ['1.1'] else 2.0 if req_val in ['2', '2.0'] else "2P" if  req_val in ['2p', '2P'] else 1.1)
		request.META[req_key] = req_val

		#
		req_key = 'HTTP_X_CSAPI_IPV6'
		req_val     = request.META[req_key] if req_key in request.META else None
		req_val = 6 if req_val in ['6'] else 4
		request.META[req_key] = req_val

		#
		req_key = 'HTTP_X_CSAPI_PRETTY'
		req_val     = request.META[req_key] if req_key in request.META else None
		req_val = True if req_val in ['true', 'on', '1', 'yes' ] else False
		request.META[req_key] = req_val

		
		#
		req_key = 'HTTP_X_CSAPI_REFERER'
		req_val     = request.META[req_key] if req_key in request.META else None		
		request.META[req_key] = req_val


		#
		req_key = 'HTTP_X_CSAPI_PROXY'
		req_val     = request.META[req_key] if req_key in request.META else None
		if req_val:
			pu = urlparse(req_val)
			scheme = pu.scheme
			netloc = pu.netloc
			if not netloc:
				req_val = None
			else:
				scheme   = 'https' if 'https' in scheme else ('http1.0' if 'http1.0' in scheme else ('http' if 'http' in scheme else ('socks4a' if 'socks4a' in scheme else ('socks4' if 'socks4' in scheme else ('socks5' if 'socks5' in scheme else 'socks5_hostname' if 'socks5_hostname' in scheme else 'http')))))
				netlocs  =  netloc.rsplit("@")
				userpass = netlocs[0] if len(netlocs)>1 else None
				netloc   = netlocs[1] if len(netlocs)>1 else netlocs[0]
				netlocs  = netloc.rsplit(":")
				netloc   = netlocs[0] 
				port     = netlocs[1] if len(netlocs)>1 else None
				username = None
				password = None
				if userpass:
					userpasss = userpass.split(":")
					username  = userpasss[0]
					password  = userpasss[1] if len(userpasss[0])>1 else None

				req_val = {'ip':netloc, 'port':port, 'scheme':scheme, 'username':username, 'password':password}
			request.META[req_key] = req_val
		

		#
		req_key = 'HTTP_X_CSAPI_SSL_VERIFIER'
		req_val     = request.META[req_key] if req_key in request.META else None		
		req_val = True if req_val in ['true', 'on', '1', 'yes' ] else False
		request.META[req_key] = req_val

		#
		req_key = 'HTTP_X_CSAPI_USER_AGENT'
		req_val     = request.META[req_key] if req_key in request.META else None		
		request.META[req_key] = req_val


		#
		req_key = 'HTTP_X_CSAPI_ACCEPT_LANGUAGE'
		req_val     = request.META[req_key] if req_key in request.META else None		
		request.META[req_key] = req_val

		#
		req_key = 'HTTP_X_CSAPI_ACCEPT_ENCODING'
		req_val     = request.META[req_key] if req_key in request.META else None		
		request.META[req_key] = req_val
		

		
		#
		req_key = 'HTTP_X_CSAPI_ACCEPT'
		req_val     = request.META[req_key] if req_key in request.META else None		
		request.META[req_key] = req_val
		


		#
		req_key = 'HTTP_X_CSAPI_TIMEOUT'
		req_val     = request.META[req_key] if req_key in request.META else None
		if req_val:
			try:
				req_val = int(req_val)
				req_val = 60 if req_val >60 else req_val
			except Exception as e:
				req_val = 60
		request.META[req_key] = req_val

		"""  Extra Headers """
		req_key = 'HTTP_X_CSAPI_XHEADERS'
		req_val = []
		for meta in request.META:
			xmatch = re.match(r'^(HTTP_X_CSAPI_(.*))', meta)
			if xmatch:
				xmkey = xmatch.group(2)				
				if xmkey not in ['XHEADERS', 'TIMEOUT', 'SSL_VERIFIER', 'USER_AGENT', 'REQUEST_URL', 'PROXY', 'REFERER', 'PRETTY', 'IPV6', 'HTTP_VERSION', 'FOLLOW_REDIRECTION', 'DEBUG', 'ACCEPT', 'ACCEPT_ENCODING', 'ACCEPT_LANGUAGE']:
					req_val.append({ xmkey.lower().replace('_', '-').title() :request.META[ xmatch.group(0)]})


		request.META[req_key] = req_val
		print(request.META['HTTP_X_CSAPI_XHEADERS'])
		print(request.META['HTTP_X_CSAPI_TIMEOUT'])
		print(request.META['HTTP_X_CSAPI_SSL_VERIFIER'])
		print(request.META['HTTP_X_CSAPI_PROXY'])
		print(request.META['HTTP_X_CSAPI_PRETTY'])
		print(request.META['HTTP_X_CSAPI_IPV6'])
		print(request.META['HTTP_X_CSAPI_HTTP_VERSION'])
		print(request.META['HTTP_X_CSAPI_DEBUG'])
		print(request.META['HTTP_X_CSAPI_FOLLOW_REDIRECTION'])
		print(request.META['HTTP_X_CSAPI_COOKIE'])
		print(request.META['HTTP_X_CSAPI_AUTHORIZATION'])
		print(request.META['HTTP_X_CSAPI_COOKIE'])
		print(request.META['HTTP_X_CSAPI_REQUEST_URL'])
		print(request.META['HTTP_X_CSAPI_USER_AGENT'])
		print(request.META['HTTP_X_CSAPI_ACCEPT_LANGUAGE'])
		print(request.META['HTTP_X_CSAPI_ACCEPT_ENCODING'])
		print(request.META['HTTP_X_CSAPI_ACCEPT'])
		return None
Beispiel #20
0
class TestCorsMiddlewareProcessResponse(TestCase):

    def setUp(self):
        self.middleware = CorsMiddleware()

    def assertAccessControlAllowOriginEquals(self, response, header):
        self.assertIn(ACCESS_CONTROL_ALLOW_ORIGIN, response, "Response %r does "
            "NOT have %r header" % (response, ACCESS_CONTROL_ALLOW_ORIGIN))
        self.assertEqual(response[ACCESS_CONTROL_ALLOW_ORIGIN], header)

    def test_process_response_no_origin(self, settings):
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request = Mock(path='/', META={})
        processed = self.middleware.process_response(request, response)
        self.assertNotIn(ACCESS_CONTROL_ALLOW_ORIGIN, processed)

    def test_process_response_not_in_whitelist(self, settings):
        settings.CORS_ORIGIN_ALLOW_ALL = False
        settings.CORS_ORIGIN_WHITELIST = ['example.com']
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request = Mock(path='/', META={'HTTP_ORIGIN': 'http://foobar.it'})
        processed = self.middleware.process_response(request, response)
        self.assertNotIn(ACCESS_CONTROL_ALLOW_ORIGIN, processed)

    def test_process_response_in_whitelist(self, settings):
        settings.CORS_ORIGIN_ALLOW_ALL = False
        settings.CORS_ORIGIN_WHITELIST = ['example.com', 'foobar.it']
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request = Mock(path='/', META={'HTTP_ORIGIN': 'http://foobar.it'})
        processed = self.middleware.process_response(request, response)
        self.assertAccessControlAllowOriginEquals(processed, 'http://foobar.it')

    def test_process_response_expose_headers(self, settings):
        settings.CORS_ORIGIN_ALLOW_ALL = True
        settings.CORS_EXPOSE_HEADERS = ['accept', 'origin', 'content-type']
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request = Mock(path='/', META={'HTTP_ORIGIN': 'http://example.com'})
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed[ACCESS_CONTROL_EXPOSE_HEADERS],
            'accept, origin, content-type')

    def test_process_response_dont_expose_headers(self, settings):
        settings.CORS_ORIGIN_ALLOW_ALL = True
        settings.CORS_EXPOSE_HEADERS = []
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request = Mock(path='/', META={'HTTP_ORIGIN': 'http://example.com'})
        processed = self.middleware.process_response(request, response)
        self.assertNotIn(ACCESS_CONTROL_EXPOSE_HEADERS, processed)

    def test_process_response_allow_credentials(self, settings):
        settings.CORS_ORIGIN_ALLOW_ALL = True
        settings.CORS_ALLOW_CREDENTIALS = True
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request = Mock(path='/', META={'HTTP_ORIGIN': 'http://example.com'})
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed[ACCESS_CONTROL_ALLOW_CREDENTIALS], 'true')

    def test_process_response_dont_allow_credentials(self, settings):
        settings.CORS_ORIGIN_ALLOW_ALL = True
        settings.CORS_ALLOW_CREDENTIALS = False
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request = Mock(path='/', META={'HTTP_ORIGIN': 'http://example.com'})
        processed = self.middleware.process_response(request, response)
        self.assertNotIn(ACCESS_CONTROL_ALLOW_CREDENTIALS, processed)

    def test_process_response_options_method(self, settings):
        settings.CORS_ORIGIN_ALLOW_ALL = True
        settings.CORS_ALLOW_HEADERS = ['content-type', 'origin']
        settings.CORS_ALLOW_METHODS = ['GET', 'OPTIONS']
        settings.CORS_PREFLIGHT_MAX_AGE = 1002
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request_headers = {'HTTP_ORIGIN': 'http://example.com'}
        request = Mock(path='/', META=request_headers, method='OPTIONS')
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed[ACCESS_CONTROL_ALLOW_HEADERS],
            'content-type, origin')
        self.assertEqual(processed[ACCESS_CONTROL_ALLOW_METHODS], 'GET, OPTIONS')
        self.assertEqual(processed[ACCESS_CONTROL_MAX_AGE], '1002')

    def test_process_response_options_method_no_max_age(self, settings):
        settings.CORS_ORIGIN_ALLOW_ALL = True
        settings.CORS_ALLOW_HEADERS = ['content-type', 'origin']
        settings.CORS_ALLOW_METHODS = ['GET', 'OPTIONS']
        settings.CORS_PREFLIGHT_MAX_AGE = 0
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request_headers = {'HTTP_ORIGIN': 'http://example.com'}
        request = Mock(path='/', META=request_headers, method='OPTIONS')
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed[ACCESS_CONTROL_ALLOW_HEADERS],
            'content-type, origin')
        self.assertEqual(processed[ACCESS_CONTROL_ALLOW_METHODS], 'GET, OPTIONS')
        self.assertNotIn(ACCESS_CONTROL_MAX_AGE, processed)

    def test_process_response_whitelist_with_port(self, settings):
        settings.CORS_ORIGIN_ALLOW_ALL = False
        settings.CORS_ALLOW_METHODS = ['OPTIONS']
        settings.CORS_ORIGIN_WHITELIST = ('localhost:9000',)
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request_headers = {'HTTP_ORIGIN': 'http://localhost:9000'}
        request = Mock(path='/', META=request_headers, method='OPTIONS')
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed.get(ACCESS_CONTROL_ALLOW_CREDENTIALS), 'true')

    def test_process_response_adds_origin_when_domain_found_in_origin_regex_whitelist(self, settings):
        settings.CORS_ORIGIN_REGEX_WHITELIST = ('^http?://(\w+\.)?google\.com$', )
        settings.CORS_ALLOW_CREDENTIALS = True
        settings.CORS_ORIGIN_ALLOW_ALL = False
        settings.CORS_ALLOW_METHODS = ['OPTIONS']
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request_headers = {'HTTP_ORIGIN': 'http://foo.google.com'}
        request = Mock(path='/', META=request_headers, method='OPTIONS')
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed.get(ACCESS_CONTROL_ALLOW_ORIGIN), 'http://foo.google.com')

    def test_process_response_will_not_add_origin_when_domain_not_found_in_origin_regex_whitelist(self, settings):
        settings.CORS_ORIGIN_REGEX_WHITELIST = ('^http?://(\w+\.)?yahoo\.com$', )
        settings.CORS_ALLOW_CREDENTIALS = True
        settings.CORS_ORIGIN_ALLOW_ALL = False
        settings.CORS_ALLOW_METHODS = ['OPTIONS']
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request_headers = {'HTTP_ORIGIN': 'http://foo.google.com'}
        request = Mock(path='/', META=request_headers, method='OPTIONS')
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed.get(ACCESS_CONTROL_ALLOW_ORIGIN), None)
Beispiel #21
0
class TestCorsMiddlewareProcessRequest(TestCase):

    req_factory = RequestFactory()

    def setUp(self):
        self.middleware = CorsMiddleware()

    def test_process_request(self):
        request = self.req_factory.options(
            '/',
            HTTP_ACCESS_CONTROL_REQUEST_METHOD='value',
        )
        response = self.middleware.process_request(request)
        assert isinstance(response, HttpResponse)

    def test_process_request_empty_header(self):
        request = self.req_factory.options(
            '/',
            HTTP_ACCESS_CONTROL_REQUEST_METHOD='',
        )
        response = self.middleware.process_request(request)
        assert isinstance(response, HttpResponse)

    def test_process_request_no_header(self):
        request = self.req_factory.options('/')
        response = self.middleware.process_request(request)
        assert response is None

    def test_process_request_not_options(self):
        request = self.req_factory.get(
            '/',
            HTTP_ACCESS_CONTROL_REQUEST_METHOD='value',
        )
        response = self.middleware.process_request(request)
        assert response is None

    @override_settings(
        CORS_ORIGIN_REGEX_WHITELIST='.*google.*',
        CORS_REPLACE_HTTPS_REFERER=True,
        SECURE_PROXY_SSL_HEADER=('HTTP_FAKE_SECURE', 'true'),
    )
    def test_process_request_replace_https_referer(self):
        post_middleware = CorsPostCsrfMiddleware()

        # make sure it doesnt blow up when HTTP_REFERER is not present
        request = self.req_factory.get(
            '/',
            HTTP_FAKE_SECURE='true',
            HTTP_HOST='foobar.com',
            HTTP_ORIGIN='https://foo.google.com',
        )
        response = self.middleware.process_request(request)
        assert response is None

        # make sure it doesnt blow up when HTTP_HOST is not present
        request = self.req_factory.get(
            '/',
            HTTP_FAKE_SECURE='true',
            HTTP_ORIGIN='https://foo.google.com',
            HTTP_REFERER='http://foo.google.com/',
        )
        response = self.middleware.process_request(request)
        assert response is None

        # test that we won't replace if the request is not secure
        request = self.req_factory.get(
            '/',
            HTTP_HOST='foobar.com',
            HTTP_ORIGIN='http://foo.google.com',
            HTTP_REFERER='http://foo.google.com/',
        )
        response = self.middleware.process_request(request)
        assert response is None
        assert 'ORIGINAL_HTTP_REFERER' not in request.META
        assert request.META['HTTP_REFERER'] == 'http://foo.google.com/'

        # test that we won't replace with the setting off
        request = self.req_factory.get(
            '/',
            HTTP_FAKE_SECURE='true',
            HTTP_HOST='foobar.com',
            HTTP_ORIGIN='https://foo.google.com',
            HTTP_REFERER='https://foo.google.com/',
        )
        with override_settings(CORS_REPLACE_HTTPS_REFERER=False):
            response = self.middleware.process_request(request)
        assert response is None
        assert 'ORIGINAL_HTTP_REFERER' not in request.META
        assert request.META['HTTP_REFERER'] == 'https://foo.google.com/'

        response = self.middleware.process_request(request)
        assert response is None
        assert request.META['ORIGINAL_HTTP_REFERER'] == 'https://foo.google.com/'
        assert request.META['HTTP_REFERER'] == 'https://foobar.com/'

        # make sure the replace code is idempotent
        response = self.middleware.process_view(request, None, None, None)
        assert response is None
        assert request.META['ORIGINAL_HTTP_REFERER'] == 'https://foo.google.com/'
        assert request.META['HTTP_REFERER'] == 'https://foobar.com/'

        post_middleware.process_request(request)
        assert 'ORIGINAL_HTTP_REFERER' not in request.META
        assert request.META['HTTP_REFERER'] == 'https://foo.google.com/'

        response = post_middleware.process_request(request)
        assert response is None

    @override_settings(
        CORS_ORIGIN_REGEX_WHITELIST='.*google.*',
        CORS_REPLACE_HTTPS_REFERER=True,
        SECURE_PROXY_SSL_HEADER=('HTTP_FAKE_SECURE', 'true'),
    )
    def test_process_view_replace_https_referer(self):
        post_middleware = CorsPostCsrfMiddleware()
        request = self.req_factory.get(
            '/',
            HTTP_FAKE_SECURE='true',
            HTTP_HOST='foobar.com',
            HTTP_ORIGIN='https://foo.google.com',
            HTTP_REFERER='https://foo.google.com/',
        )
        response = self.middleware.process_view(request, None, None, None)
        assert response is None
        assert request.META['ORIGINAL_HTTP_REFERER'] == 'https://foo.google.com/'
        assert request.META['HTTP_REFERER'] == 'https://foobar.com/'

        post_middleware.process_view(request, None, None, None)
        assert 'ORIGINAL_HTTP_REFERER' not in request.META
        assert request.META['HTTP_REFERER'] == 'https://foo.google.com/'

        response = post_middleware.process_view(request, None, None, None)
        assert response is None
Beispiel #22
0
from django.core.urlresolvers import RegexURLResolver
from django.views.decorators.csrf import csrf_exempt

from functools import wraps

from .utils import CaseInsensitiveDict

logger = logging.getLogger(__name__)

__all__ = ('SimpleHttpException', 'api_handler', 'api_export')
__version__ = '1.4.0'

cors_middleware = None

if getattr(settings, 'SIMPLEAPI_ENABLE_CORS', False):
    cors_middleware = CorsMiddleware()


def allow_cors(func):
    def func_wrapper(request, *args, **kwargs):
        resp = cors_middleware.process_request(request)
        if not resp:
            resp = func(request, *args, **kwargs)

        resp = cors_middleware.process_response(request, resp)

        return resp

    return func_wrapper

class TestCorsMiddlewareProcessRequest(TestCase):

    def setUp(self):
        self.middleware = CorsMiddleware()

    def test_process_request(self):
        request = Mock(path='/')
        request.method = 'OPTIONS'
        request.META = {'HTTP_ACCESS_CONTROL_REQUEST_METHOD': 'value'}
        with settings_override(CORS_URLS_REGEX='^.*$'):
            response = self.middleware.process_request(request)
        self.assertIsInstance(response, HttpResponse)

    def test_process_request_empty_header(self):
        request = Mock(path='/')
        request.method = 'OPTIONS'
        request.META = {'HTTP_ACCESS_CONTROL_REQUEST_METHOD': ''}
        with settings_override(CORS_URLS_REGEX='^.*$'):
            response = self.middleware.process_request(request)
        self.assertIsInstance(response, HttpResponse)

    def test_process_request_no_header(self):
        request = Mock(path='/')
        request.method = 'OPTIONS'
        request.META = {}
        response = self.middleware.process_request(request)
        self.assertIsNone(response)

    def test_process_request_not_options(self):
        request = Mock(path='/')
        request.method = 'GET'
        request.META = {'HTTP_ACCESS_CONTROL_REQUEST_METHOD': 'value'}
        response = self.middleware.process_request(request)
        self.assertIsNone(response)

    def test_process_request_replace_https_referer(self):
        post_middleware = CorsPostCsrfMiddleware()
        request = Mock(path='/')
        request.method = 'GET'
        request.is_secure = lambda: True

        # make sure it doesnt blow up when HTTP_REFERER is not present
        request.META = {
            'HTTP_HOST': 'foobar.com',
            'HTTP_ORIGIN': 'https://foo.google.com',
        }
        with settings_override(CORS_URLS_REGEX='^.*$',
                               CORS_ORIGIN_REGEX_WHITELIST='.*google.*',
                               CORS_REPLACE_HTTPS_REFERER=True):
            response = self.middleware.process_request(request)
        self.assertIsNone(response)

        # make sure it doesnt blow up when HTTP_HOST is not present
        request.META = {
            'HTTP_REFERER': 'http://foo.google.com/',
            'HTTP_ORIGIN': 'https://foo.google.com',
        }
        with settings_override(CORS_URLS_REGEX='^.*$',
                               CORS_ORIGIN_REGEX_WHITELIST='.*google.*',
                               CORS_REPLACE_HTTPS_REFERER=True):
            response = self.middleware.process_request(request)
        self.assertIsNone(response)

        request.is_secure = lambda: False
        request.META = {
            'HTTP_REFERER': 'http://foo.google.com/',
            'HTTP_HOST': 'foobar.com',
            'HTTP_ORIGIN': 'http://foo.google.com',
        }

        # test that we won't replace if the request is not secure
        with settings_override(CORS_URLS_REGEX='^.*$',
                               CORS_ORIGIN_REGEX_WHITELIST='.*google.*',
                               CORS_REPLACE_HTTPS_REFERER=True):
            response = self.middleware.process_request(request)
        self.assertIsNone(response)
        self.assertTrue('ORIGINAL_HTTP_REFERER' not in request.META)
        self.assertEquals(request.META['HTTP_REFERER'], 'http://foo.google.com/')

        request.is_secure = lambda: True
        request.META = {
            'HTTP_REFERER': 'https://foo.google.com/',
            'HTTP_HOST': 'foobar.com',
            'HTTP_ORIGIN': 'https://foo.google.com',
        }

        # test that we won't replace with the setting off
        with settings_override(CORS_URLS_REGEX='^.*$',
                               CORS_ORIGIN_REGEX_WHITELIST='.*google.*'):
            response = self.middleware.process_request(request)
        self.assertIsNone(response)
        self.assertTrue('ORIGINAL_HTTP_REFERER' not in request.META)
        self.assertEquals(request.META['HTTP_REFERER'], 'https://foo.google.com/')

        with settings_override(CORS_URLS_REGEX='^.*$',
                               CORS_ORIGIN_REGEX_WHITELIST='.*google.*',
                               CORS_REPLACE_HTTPS_REFERER=True):
            response = self.middleware.process_request(request)
        self.assertIsNone(response)
        self.assertEquals(request.META['ORIGINAL_HTTP_REFERER'], 'https://foo.google.com/')
        self.assertEquals(request.META['HTTP_REFERER'], 'https://foobar.com/')

        # make sure the replace code is idempotent
        with settings_override(CORS_URLS_REGEX='^.*$',
                               CORS_ORIGIN_REGEX_WHITELIST='.*google.*',
                               CORS_REPLACE_HTTPS_REFERER=True):
            response = self.middleware.process_view(request, None, None, None)
        self.assertIsNone(response)
        self.assertEquals(request.META['ORIGINAL_HTTP_REFERER'], 'https://foo.google.com/')
        self.assertEquals(request.META['HTTP_REFERER'], 'https://foobar.com/')

        with settings_override(CORS_URLS_REGEX='^.*$', CORS_REPLACE_HTTPS_REFERER=True):
            post_middleware.process_request(request)
        self.assertTrue('ORIGINAL_HTTP_REFERER' not in request.META)
        self.assertEquals(request.META['HTTP_REFERER'], 'https://foo.google.com/')

        with settings_override(CORS_URLS_REGEX='^.*$', CORS_REPLACE_HTTPS_REFERER=True):
            response = post_middleware.process_request(request)
        self.assertIsNone(response)

    def test_process_view_replace_https_referer(self):
        post_middleware = CorsPostCsrfMiddleware()
        request = Mock(path='/')
        request.method = 'GET'
        request.is_secure = lambda: True
        request.META = {
            'HTTP_REFERER': 'https://foo.google.com/',
            'HTTP_HOST': 'foobar.com',
            'HTTP_ORIGIN': 'https://foo.google.com',
        }
        with settings_override(CORS_URLS_REGEX='^.*$',
                               CORS_ORIGIN_REGEX_WHITELIST='.*google.*',
                               CORS_REPLACE_HTTPS_REFERER=True):
            response = self.middleware.process_view(request, None, None, None)
        self.assertIsNone(response)
        self.assertEquals(request.META['ORIGINAL_HTTP_REFERER'], 'https://foo.google.com/')
        self.assertEquals(request.META['HTTP_REFERER'], 'https://foobar.com/')

        with settings_override(CORS_URLS_REGEX='^.*$', CORS_REPLACE_HTTPS_REFERER=True):
            post_middleware.process_view(request, None, None, None)
        self.assertTrue('ORIGINAL_HTTP_REFERER' not in request.META)
        self.assertEquals(request.META['HTTP_REFERER'], 'https://foo.google.com/')

        with settings_override(CORS_URLS_REGEX='^.*$', CORS_REPLACE_HTTPS_REFERER=True):
            response = post_middleware.process_view(request, None, None, None)
        self.assertIsNone(response)
Beispiel #24
0
class TestCorsMiddlewareProcessResponse(TestCase):
    def setUp(self):
        self.middleware = CorsMiddleware()

    def assertAccessControlAllowOriginEquals(self, response, header):
        self.assertIn(
            ACCESS_CONTROL_ALLOW_ORIGIN, response, "Response %r does "
            "NOT have %r header" % (response, ACCESS_CONTROL_ALLOW_ORIGIN))
        self.assertEqual(response[ACCESS_CONTROL_ALLOW_ORIGIN], header)

    def test_process_response_no_origin(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request = Mock(path='/', META={})
        processed = self.middleware.process_response(request, response)
        self.assertNotIn(ACCESS_CONTROL_ALLOW_ORIGIN, processed)

    def test_process_response_not_in_whitelist(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = False
        settings.CORS_ORIGIN_WHITELIST = ['example.com']
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request = Mock(path='/', META={'HTTP_ORIGIN': 'http://foobar.it'})
        processed = self.middleware.process_response(request, response)
        self.assertNotIn(ACCESS_CONTROL_ALLOW_ORIGIN, processed)

    def test_process_response_signal_works(self, settings):
        def handler(sender, request, **kwargs):
            return True

        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = False
        settings.CORS_ORIGIN_WHITELIST = ['example.com']
        settings.CORS_URLS_REGEX = '^.*$'
        signals.check_request_enabled.connect(handler)
        response = HttpResponse()
        request = Mock(path='/', META={'HTTP_ORIGIN': 'http://foobar.it'})
        processed = self.middleware.process_response(request, response)
        self.assertIn(ACCESS_CONTROL_ALLOW_ORIGIN, processed)

    def test_process_response_in_whitelist(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = False
        settings.CORS_ORIGIN_WHITELIST = ['example.com', 'foobar.it']
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request = Mock(path='/', META={'HTTP_ORIGIN': 'http://foobar.it'})
        processed = self.middleware.process_response(request, response)
        self.assertAccessControlAllowOriginEquals(processed,
                                                  'http://foobar.it')

    def test_process_response_expose_headers(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = True
        settings.CORS_EXPOSE_HEADERS = ['accept', 'origin', 'content-type']
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request = Mock(path='/', META={'HTTP_ORIGIN': 'http://example.com'})
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed[ACCESS_CONTROL_EXPOSE_HEADERS],
                         'accept, origin, content-type')

    def test_process_response_dont_expose_headers(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = True
        settings.CORS_EXPOSE_HEADERS = []
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request = Mock(path='/', META={'HTTP_ORIGIN': 'http://example.com'})
        processed = self.middleware.process_response(request, response)
        self.assertNotIn(ACCESS_CONTROL_EXPOSE_HEADERS, processed)

    def test_process_response_allow_credentials(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = True
        settings.CORS_ALLOW_CREDENTIALS = True
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request = Mock(path='/', META={'HTTP_ORIGIN': 'http://example.com'})
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed[ACCESS_CONTROL_ALLOW_CREDENTIALS], 'true')

    def test_process_response_dont_allow_credentials(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = True
        settings.CORS_ALLOW_CREDENTIALS = False
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request = Mock(path='/', META={'HTTP_ORIGIN': 'http://example.com'})
        processed = self.middleware.process_response(request, response)
        self.assertNotIn(ACCESS_CONTROL_ALLOW_CREDENTIALS, processed)

    def test_process_response_options_method(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = True
        settings.CORS_ALLOW_HEADERS = ['content-type', 'origin']
        settings.CORS_ALLOW_METHODS = ['GET', 'OPTIONS']
        settings.CORS_PREFLIGHT_MAX_AGE = 1002
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request_headers = {'HTTP_ORIGIN': 'http://example.com'}
        request = Mock(path='/', META=request_headers, method='OPTIONS')
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed[ACCESS_CONTROL_ALLOW_HEADERS],
                         'content-type, origin')
        self.assertEqual(processed[ACCESS_CONTROL_ALLOW_METHODS],
                         'GET, OPTIONS')
        self.assertEqual(processed[ACCESS_CONTROL_MAX_AGE], '1002')

    def test_process_response_options_method_no_max_age(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = True
        settings.CORS_ALLOW_HEADERS = ['content-type', 'origin']
        settings.CORS_ALLOW_METHODS = ['GET', 'OPTIONS']
        settings.CORS_PREFLIGHT_MAX_AGE = 0
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request_headers = {'HTTP_ORIGIN': 'http://example.com'}
        request = Mock(path='/', META=request_headers, method='OPTIONS')
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed[ACCESS_CONTROL_ALLOW_HEADERS],
                         'content-type, origin')
        self.assertEqual(processed[ACCESS_CONTROL_ALLOW_METHODS],
                         'GET, OPTIONS')
        self.assertNotIn(ACCESS_CONTROL_MAX_AGE, processed)

    def test_process_response_whitelist_with_port(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = False
        settings.CORS_ALLOW_METHODS = ['OPTIONS']
        settings.CORS_ORIGIN_WHITELIST = ('localhost:9000', )
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request_headers = {'HTTP_ORIGIN': 'http://localhost:9000'}
        request = Mock(path='/', META=request_headers, method='OPTIONS')
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed.get(ACCESS_CONTROL_ALLOW_CREDENTIALS, None),
                         'true')

    def test_process_response_adds_origin_when_domain_found_in_origin_regex_whitelist(
            self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_REGEX_WHITELIST = (
            '^http?://(\w+\.)?google\.com$', )
        settings.CORS_ALLOW_CREDENTIALS = True
        settings.CORS_ORIGIN_ALLOW_ALL = False
        settings.CORS_ALLOW_METHODS = ['OPTIONS']
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request_headers = {'HTTP_ORIGIN': 'http://foo.google.com'}
        request = Mock(path='/', META=request_headers, method='OPTIONS')
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed.get(ACCESS_CONTROL_ALLOW_ORIGIN, None),
                         'http://foo.google.com')

    def test_process_response_will_not_add_origin_when_domain_not_found_in_origin_regex_whitelist(
            self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_REGEX_WHITELIST = (
            '^http?://(\w+\.)?yahoo\.com$', )
        settings.CORS_ALLOW_CREDENTIALS = True
        settings.CORS_ORIGIN_ALLOW_ALL = False
        settings.CORS_ALLOW_METHODS = ['OPTIONS']
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request_headers = {'HTTP_ORIGIN': 'http://foo.google.com'}
        request = Mock(path='/', META=request_headers, method='OPTIONS')
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed.get(ACCESS_CONTROL_ALLOW_ORIGIN, None),
                         None)

    def test_process_response_when_custom_model_enabled(self, settings):
        from corsheaders.models import CorsModel
        CorsModel.objects.create(cors='foo.google.com')
        settings.CORS_ORIGIN_REGEX_WHITELIST = ()
        settings.CORS_ALLOW_CREDENTIALS = False
        settings.CORS_ORIGIN_ALLOW_ALL = False
        settings.CORS_ALLOW_METHODS = settings.default_methods
        settings.CORS_URLS_REGEX = '^.*$'
        settings.CORS_MODEL = 'corsheaders.CorsModel'
        response = HttpResponse()
        request = Mock(path='/', META={'HTTP_ORIGIN': 'http://foo.google.com'})
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed.get(ACCESS_CONTROL_ALLOW_ORIGIN, None),
                         'http://foo.google.com')

    def test_process_response_in_allow_all_path(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = False
        # settings.CORS_ORIGIN_WHITELIST = ['example.com', 'foobar.it']
        settings.CORS_URLS_REGEX = '^.*$'
        settings.CORS_URLS_ALLOW_ALL_REGEX = (r'^/api/.*$', )
        response = HttpResponse()
        request = Mock(path='/api/data',
                       META={'HTTP_ORIGIN': 'http://foobar.it'})
        processed = self.middleware.process_response(request, response)
        self.assertAccessControlAllowOriginEquals(processed,
                                                  'http://foobar.it')

    def test_process_response_not_in_allow_all_path(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = False
        # settings.CORS_ORIGIN_WHITELIST = ['example.com', 'foobar.it']
        settings.CORS_URLS_REGEX = '^.*$'
        settings.CORS_URLS_ALLOW_ALL_REGEX = (r'^/api/.*$', )
        response = HttpResponse()
        request = Mock(path='/data', META={'HTTP_ORIGIN': 'http://foobar.it'})
        processed = self.middleware.process_response(request, response)
        self.assertNotIn(ACCESS_CONTROL_ALLOW_ORIGIN, processed)

    def test_middleware_integration_get(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = True
        settings.CORS_URLS_REGEX = '^.*$'
        response = self.client.get('/test-view/',
                                   HTTP_ORIGIN='http://foobar.it')
        self.assertEqual(response.status_code, 200)
        self.assertAccessControlAllowOriginEquals(response, 'http://foobar.it')

    def test_middleware_integration_options(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_URLS_REGEX = '^.*$'
        settings.CORS_ALLOW_CREDENTIALS = True
        settings.CORS_ORIGIN_ALLOW_ALL = True
        response = self.client.options(
            '/test-view/',
            HTTP_ORIGIN='http://foobar.it',
            HTTP_ACCESS_CONTROL_REQUEST_METHOD='value',
        )
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response[ACCESS_CONTROL_ALLOW_ORIGIN],
                         'http://foobar.it')
        self.assertEqual(response['Vary'], 'Origin')

    def test_middleware_integration_get_auth_view(self, settings):
        """
        It's not clear whether the header should still be set for non-HTTP200
        when not a preflight request. However this is the existing behaviour for
        django-cors-middleware, so at least this test makes that explicit, especially
        since for the switch to Django 1.10, special-handling will need to be put in
        place to preserve this behaviour. See `ExceptionMiddleware` mention here:
        https://docs.djangoproject.com/en/1.10/topics/http/middleware/#upgrading-pre-django-1-10-style-middleware
        """
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = True
        settings.CORS_URLS_REGEX = '^.*$'
        response = self.client.get('/test-view-http401/',
                                   HTTP_ORIGIN='http://foobar.it')
        self.assertEqual(response.status_code, 401)
        self.assertAccessControlAllowOriginEquals(response, 'http://foobar.it')

    def test_middleware_integration_preflight_auth_view(self, settings):
        """
        Ensure HTTP200 and header still set, for preflight requests to views requiring
        authentication. See: https://github.com/ottoyiu/django-cors-headers/issues/3
        """
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = True
        settings.CORS_URLS_REGEX = '^.*$'
        response = self.client.options(
            '/test-view-http401/',
            HTTP_ORIGIN='http://foobar.it',
            HTTP_ACCESS_CONTROL_REQUEST_METHOD='value')
        self.assertEqual(response.status_code, 200)
        self.assertAccessControlAllowOriginEquals(response, 'http://foobar.it')
Beispiel #25
0
class TestCorsMiddlewareProcessRequest(TestCase):

    def setUp(self):
        self.middleware = CorsMiddleware()

    def test_process_request(self):
        request = Mock(path='/')
        request.method = 'OPTIONS'
        request.META = {'HTTP_ACCESS_CONTROL_REQUEST_METHOD': 'value'}
        with settings_override(CORS_URLS_REGEX='^.*$'):
            response = self.middleware.process_request(request)
        self.assertIsInstance(response, HttpResponse)

    def test_process_request_empty_header(self):
        request = Mock(path='/')
        request.method = 'OPTIONS'
        request.META = {'HTTP_ACCESS_CONTROL_REQUEST_METHOD': ''}
        with settings_override(CORS_URLS_REGEX='^.*$'):
            response = self.middleware.process_request(request)
        self.assertIsInstance(response, HttpResponse)

    def test_process_request_no_header(self):
        request = Mock(path='/')
        request.method = 'OPTIONS'
        request.META = {}
        response = self.middleware.process_request(request)
        self.assertIsNone(response)

    def test_process_request_not_options(self):
        request = Mock(path='/')
        request.method = 'GET'
        request.META = {'HTTP_ACCESS_CONTROL_REQUEST_METHOD': 'value'}
        response = self.middleware.process_request(request)
        self.assertIsNone(response)

    def test_process_request_replace_https_referer(self):
        post_middleware = CorsPostCsrfMiddleware()
        request = Mock(path='/')
        request.method = 'GET'
        request.is_secure = lambda: False
        request.META = {
            'HTTP_REFERER': 'http://foo.google.com/',
            'HTTP_HOST': 'foobar.com',
            'HTTP_ORIGIN': 'http://foo.google.com',
        }

        # test that we won't replace if the request is not secure
        with settings_override(CORS_URLS_REGEX='^.*$',
                               CORS_ORIGIN_REGEX_WHITELIST='.*google.*',
                               CORS_REPLACE_HTTPS_REFERER=True):
            response = self.middleware.process_request(request)
        self.assertIsNone(response)
        self.assertTrue('ORIGINAL_HTTP_REFERER' not in request.META)
        self.assertEquals(request.META['HTTP_REFERER'], 'http://foo.google.com/')

        request.is_secure = lambda: True
        request.META = {
            'HTTP_REFERER': 'https://foo.google.com/',
            'HTTP_HOST': 'foobar.com',
            'HTTP_ORIGIN': 'https://foo.google.com',
        }

        # test that we won't replace with the setting off
        with settings_override(CORS_URLS_REGEX='^.*$',
                               CORS_ORIGIN_REGEX_WHITELIST='.*google.*'):
            response = self.middleware.process_request(request)
        self.assertIsNone(response)
        self.assertTrue('ORIGINAL_HTTP_REFERER' not in request.META)
        self.assertEquals(request.META['HTTP_REFERER'], 'https://foo.google.com/')

        with settings_override(CORS_URLS_REGEX='^.*$',
                               CORS_ORIGIN_REGEX_WHITELIST='.*google.*',
                               CORS_REPLACE_HTTPS_REFERER=True):
            response = self.middleware.process_request(request)
        self.assertIsNone(response)
        self.assertEquals(request.META['ORIGINAL_HTTP_REFERER'], 'https://foo.google.com/')
        self.assertEquals(request.META['HTTP_REFERER'], 'https://foobar.com/')

        # make sure the replace code is idempotent
        with settings_override(CORS_URLS_REGEX='^.*$',
                               CORS_ORIGIN_REGEX_WHITELIST='.*google.*',
                               CORS_REPLACE_HTTPS_REFERER=True):
            response = self.middleware.process_view(request, None, None, None)
        self.assertIsNone(response)
        self.assertEquals(request.META['ORIGINAL_HTTP_REFERER'], 'https://foo.google.com/')
        self.assertEquals(request.META['HTTP_REFERER'], 'https://foobar.com/')

        with settings_override(CORS_URLS_REGEX='^.*$', CORS_REPLACE_HTTPS_REFERER=True):
            post_middleware.process_request(request)
        self.assertTrue('ORIGINAL_HTTP_REFERER' not in request.META)
        self.assertEquals(request.META['HTTP_REFERER'], 'https://foo.google.com/')

        with settings_override(CORS_URLS_REGEX='^.*$', CORS_REPLACE_HTTPS_REFERER=True):
            response = post_middleware.process_request(request)
        self.assertIsNone(response)

    def test_process_view_replace_https_referer(self):
        post_middleware = CorsPostCsrfMiddleware()
        request = Mock(path='/')
        request.method = 'GET'
        request.is_secure = lambda: True
        request.META = {
            'HTTP_REFERER': 'https://foo.google.com/',
            'HTTP_HOST': 'foobar.com',
            'HTTP_ORIGIN': 'https://foo.google.com',
        }
        with settings_override(CORS_URLS_REGEX='^.*$',
                               CORS_ORIGIN_REGEX_WHITELIST='.*google.*',
                               CORS_REPLACE_HTTPS_REFERER=True):
            response = self.middleware.process_view(request, None, None, None)
        self.assertIsNone(response)
        self.assertEquals(request.META['ORIGINAL_HTTP_REFERER'], 'https://foo.google.com/')
        self.assertEquals(request.META['HTTP_REFERER'], 'https://foobar.com/')

        with settings_override(CORS_URLS_REGEX='^.*$', CORS_REPLACE_HTTPS_REFERER=True):
            post_middleware.process_view(request, None, None, None)
        self.assertTrue('ORIGINAL_HTTP_REFERER' not in request.META)
        self.assertEquals(request.META['HTTP_REFERER'], 'https://foo.google.com/')

        with settings_override(CORS_URLS_REGEX='^.*$', CORS_REPLACE_HTTPS_REFERER=True):
            response = post_middleware.process_view(request, None, None, None)
        self.assertIsNone(response)
Beispiel #26
0
class TestCorsMiddlewareProcessResponse(TestCase):

    def setUp(self):
        self.middleware = CorsMiddleware()

    def assertAccessControlAllowOriginEquals(self, response, header):
        self.assertIn(ACCESS_CONTROL_ALLOW_ORIGIN, response, "Response %r does "
            "NOT have %r header" % (response, ACCESS_CONTROL_ALLOW_ORIGIN))
        self.assertEqual(response[ACCESS_CONTROL_ALLOW_ORIGIN], header)

    def test_process_response_no_origin(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request = Mock(path='/', META={})
        processed = self.middleware.process_response(request, response)
        self.assertNotIn(ACCESS_CONTROL_ALLOW_ORIGIN, processed)

    def test_process_response_not_in_whitelist(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = False
        settings.CORS_ORIGIN_WHITELIST = ['example.com']
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request = Mock(path='/', META={'HTTP_ORIGIN': 'http://foobar.it'})
        processed = self.middleware.process_response(request, response)
        self.assertNotIn(ACCESS_CONTROL_ALLOW_ORIGIN, processed)

    def test_process_response_in_whitelist(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = False
        settings.CORS_ORIGIN_WHITELIST = ['example.com', 'foobar.it']
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request = Mock(path='/', META={'HTTP_ORIGIN': 'http://foobar.it'})
        processed = self.middleware.process_response(request, response)
        self.assertAccessControlAllowOriginEquals(processed, 'http://foobar.it')

    def test_process_response_expose_headers(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = True
        settings.CORS_EXPOSE_HEADERS = ['accept', 'origin', 'content-type']
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request = Mock(path='/', META={'HTTP_ORIGIN': 'http://example.com'})
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed[ACCESS_CONTROL_EXPOSE_HEADERS],
            'accept, origin, content-type')

    def test_process_response_dont_expose_headers(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = True
        settings.CORS_EXPOSE_HEADERS = []
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request = Mock(path='/', META={'HTTP_ORIGIN': 'http://example.com'})
        processed = self.middleware.process_response(request, response)
        self.assertNotIn(ACCESS_CONTROL_EXPOSE_HEADERS, processed)

    def test_process_response_allow_credentials(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = True
        settings.CORS_ALLOW_CREDENTIALS = True
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request = Mock(path='/', META={'HTTP_ORIGIN': 'http://example.com'})
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed[ACCESS_CONTROL_ALLOW_CREDENTIALS], 'true')

    def test_process_response_dont_allow_credentials(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = True
        settings.CORS_ALLOW_CREDENTIALS = False
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request = Mock(path='/', META={'HTTP_ORIGIN': 'http://example.com'})
        processed = self.middleware.process_response(request, response)
        self.assertNotIn(ACCESS_CONTROL_ALLOW_CREDENTIALS, processed)

    def test_process_response_options_method(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = True
        settings.CORS_ALLOW_HEADERS = ['content-type', 'origin']
        settings.CORS_ALLOW_METHODS = ['GET', 'OPTIONS']
        settings.CORS_PREFLIGHT_MAX_AGE = 1002
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request_headers = {'HTTP_ORIGIN': 'http://example.com'}
        request = Mock(path='/', META=request_headers, method='OPTIONS')
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed[ACCESS_CONTROL_ALLOW_HEADERS],
            'content-type, origin')
        self.assertEqual(processed[ACCESS_CONTROL_ALLOW_METHODS], 'GET, OPTIONS')
        self.assertEqual(processed[ACCESS_CONTROL_MAX_AGE], '1002')

    def test_process_response_options_method_no_max_age(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = True
        settings.CORS_ALLOW_HEADERS = ['content-type', 'origin']
        settings.CORS_ALLOW_METHODS = ['GET', 'OPTIONS']
        settings.CORS_PREFLIGHT_MAX_AGE = 0
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request_headers = {'HTTP_ORIGIN': 'http://example.com'}
        request = Mock(path='/', META=request_headers, method='OPTIONS')
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed[ACCESS_CONTROL_ALLOW_HEADERS],
            'content-type, origin')
        self.assertEqual(processed[ACCESS_CONTROL_ALLOW_METHODS], 'GET, OPTIONS')
        self.assertNotIn(ACCESS_CONTROL_MAX_AGE, processed)

    def test_process_response_whitelist_with_port(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = False
        settings.CORS_ALLOW_METHODS = ['OPTIONS']
        settings.CORS_ORIGIN_WHITELIST = ('localhost:9000',)
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request_headers = {'HTTP_ORIGIN': 'http://localhost:9000'}
        request = Mock(path='/', META=request_headers, method='OPTIONS')
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed.get(ACCESS_CONTROL_ALLOW_CREDENTIALS, None), 'true')

    def test_process_response_adds_origin_when_domain_found_in_origin_regex_whitelist(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_REGEX_WHITELIST = ('^http?://(\w+\.)?google\.com$', )
        settings.CORS_ALLOW_CREDENTIALS = True
        settings.CORS_ORIGIN_ALLOW_ALL = False
        settings.CORS_ALLOW_METHODS = ['OPTIONS']
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request_headers = {'HTTP_ORIGIN': 'http://foo.google.com'}
        request = Mock(path='/', META=request_headers, method='OPTIONS')
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed.get(ACCESS_CONTROL_ALLOW_ORIGIN, None), 'http://foo.google.com')

    def test_process_response_will_not_add_origin_when_domain_not_found_in_origin_regex_whitelist(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_REGEX_WHITELIST = ('^http?://(\w+\.)?yahoo\.com$', )
        settings.CORS_ALLOW_CREDENTIALS = True
        settings.CORS_ORIGIN_ALLOW_ALL = False
        settings.CORS_ALLOW_METHODS = ['OPTIONS']
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request_headers = {'HTTP_ORIGIN': 'http://foo.google.com'}
        request = Mock(path='/', META=request_headers, method='OPTIONS')
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed.get(ACCESS_CONTROL_ALLOW_ORIGIN, None), None)

    def test_process_response_when_custom_model_enabled(self, settings):
        from corsheaders.models import CorsModel
        CorsModel.objects.create(cors='foo.google.com')
        settings.CORS_ORIGIN_REGEX_WHITELIST = ()
        settings.CORS_ALLOW_CREDENTIALS = False
        settings.CORS_ORIGIN_ALLOW_ALL = False
        settings.CORS_ALLOW_METHODS = settings.default_methods
        settings.CORS_URLS_REGEX = '^.*$'
        settings.CORS_MODEL = 'corsheaders.CorsModel'
        response = HttpResponse()
        request = Mock(path='/', META={'HTTP_ORIGIN': 'http://foo.google.com'})
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed.get(ACCESS_CONTROL_ALLOW_ORIGIN, None), 'http://foo.google.com')
Beispiel #27
0
class TestCORSMiddleware(TestCase):

    def setUp(self):
        self.factory = RequestFactory()
        self.middleware = CorsMiddleware()
        self.url = '/api/v2/search'
        self.owner = create_user(username='******', password='******')
        self.project = get(
            Project, slug='pip',
            users=[self.owner],
            privacy_level=PUBLIC,
            main_language_project=None,
        )
        self.project.versions.update(privacy_level=PUBLIC)
        self.version = self.project.versions.get(slug=LATEST)
        self.subproject = get(
            Project,
            users=[self.owner],
            privacy_level=PUBLIC,
            main_language_project=None,
        )
        self.subproject.versions.update(privacy_level=PUBLIC)
        self.version_subproject = self.subproject.versions.get(slug=LATEST)
        self.relationship = get(
            ProjectRelationship,
            parent=self.project,
            child=self.subproject,
        )
        self.domain = get(
            Domain,
            domain='my.valid.domain',
            project=self.project,
        )
        self.another_project = get(
            Project,
            privacy_level=PUBLIC,
            slug='another',
        )
        self.another_project.versions.update(privacy_level=PUBLIC)
        self.another_version = self.another_project.versions.get(slug=LATEST)
        self.another_domain = get(
            Domain,
            domain='another.valid.domain',
            project=self.another_project,
        )

    def test_allow_linked_domain_from_public_version(self):
        request = self.factory.get(
            self.url,
            {'project': self.project.slug, 'version': self.version.slug},
            HTTP_ORIGIN='http://my.valid.domain',
        )
        resp = self.middleware.process_response(request, {})
        self.assertIn('Access-Control-Allow-Origin', resp)

    def test_dont_allow_linked_domain_from_private_version(self):
        self.version.privacy_level = PRIVATE
        self.version.save()
        request = self.factory.get(
            self.url,
            {'project': self.project.slug, 'version': self.version.slug},
            HTTP_ORIGIN='http://my.valid.domain',
        )
        resp = self.middleware.process_response(request, {})
        self.assertNotIn('Access-Control-Allow-Origin', resp)

    def test_allowed_api_public_version_from_another_domain(self):
        request = self.factory.get(
            self.url,
            {'project': self.project.slug, 'version': self.version.slug},
            HTTP_ORIGIN='http://docs.another.domain',
        )
        resp = self.middleware.process_response(request, {})
        self.assertIn('Access-Control-Allow-Origin', resp)

        request = self.factory.get(
            self.url,
            {'project': self.project.slug, 'version': self.version.slug},
            HTTP_ORIGIN='http://another.valid.domain',
        )
        resp = self.middleware.process_response(request, {})
        self.assertIn('Access-Control-Allow-Origin', resp)

    def test_not_allowed_api_private_version_from_another_domain(self):
        self.version.privacy_level = PRIVATE
        self.version.save()
        request = self.factory.get(
            self.url,
            {'project': self.project.slug, 'version': self.version.slug},
            HTTP_ORIGIN='http://docs.another.domain',
        )
        resp = self.middleware.process_response(request, {})
        self.assertNotIn('Access-Control-Allow-Origin', resp)

        request = self.factory.get(
            self.url,
            {'project': self.project.slug, 'version': self.version.slug},
            HTTP_ORIGIN='http://another.valid.domain',
        )
        resp = self.middleware.process_response(request, {})
        self.assertNotIn('Access-Control-Allow-Origin', resp)

    def test_valid_subproject(self):
        self.assertTrue(
            Project.objects.filter(
                pk=self.project.pk,
                subprojects__child=self.subproject,
            ).exists(),
        )
        request = self.factory.get(
            self.url,
            {'project': self.project.slug, 'version': self.version.slug},
            HTTP_ORIGIN='http://my.valid.domain',
        )
        resp = self.middleware.process_response(request, {})
        self.assertIn('Access-Control-Allow-Origin', resp)

    def test_embed_api_private_version_linked_domain(self):
        self.version.privacy_level = PRIVATE
        self.version.save()
        request = self.factory.get(
            '/api/v2/embed/',
            {'project': self.project.slug, 'version': self.version.slug},
            HTTP_ORIGIN='http://my.valid.domain',
        )
        resp = self.middleware.process_response(request, {})
        self.assertNotIn('Access-Control-Allow-Origin', resp)

    @mock.patch('readthedocs.core.signals._has_donate_app')
    def test_sustainability_endpoint_allways_allowed(self, has_donate_app):
        has_donate_app.return_value = True
        request = self.factory.get(
            '/api/v2/sustainability/',
            {'project': self.project.slug, 'active': True, 'version': self.version.slug},
            HTTP_ORIGIN='http://invalid.domain',
        )
        resp = self.middleware.process_response(request, {})
        self.assertIn('Access-Control-Allow-Origin', resp)

        request = self.factory.get(
            '/api/v2/sustainability/',
            {'project': self.project.slug, 'active': True, 'version': self.version.slug},
            HTTP_ORIGIN='http://my.valid.domain',
        )
        resp = self.middleware.process_response(request, {})
        self.assertIn('Access-Control-Allow-Origin', resp)

    @mock.patch('readthedocs.core.signals._has_donate_app')
    def test_sustainability_endpoint_no_ext(self, has_donate_app):
        has_donate_app.return_value = False
        request = self.factory.get(
            '/api/v2/sustainability/',
            {'project': self.project.slug, 'active': True, 'version': self.version.slug},
            HTTP_ORIGIN='http://invalid.domain',
        )
        resp = self.middleware.process_response(request, {})
        self.assertNotIn('Access-Control-Allow-Origin', resp)

        request = self.factory.get(
            '/api/v2/sustainability/',
            {'project': self.project.slug, 'active': True, 'version': self.version.slug},
            HTTP_ORIGIN='http://my.valid.domain',
        )
        resp = self.middleware.process_response(request, {})
        self.assertNotIn('Access-Control-Allow-Origin', resp)

    def test_apiv2_endpoint_not_allowed(self):
        request = self.factory.get(
            '/api/v2/version/',
            {'project': self.project.slug, 'active': True, 'version': self.version.slug},
            HTTP_ORIGIN='http://invalid.domain',
        )
        resp = self.middleware.process_response(request, {})
        self.assertNotIn('Access-Control-Allow-Origin', resp)

        # This also doesn't work on registered domains.
        request = self.factory.get(
            '/api/v2/version/',
            {'project': self.project.slug, 'active': True, 'version': self.version.slug},
            HTTP_ORIGIN='http://my.valid.domain',
        )
        resp = self.middleware.process_response(request, {})
        self.assertNotIn('Access-Control-Allow-Origin', resp)

        # Or from our public domain.
        request = self.factory.get(
            '/api/v2/version/',
            {'project': self.project.slug, 'active': True, 'version': self.version.slug},
            HTTP_ORIGIN='http://docs.readthedocs.io/',
        )
        resp = self.middleware.process_response(request, {})
        self.assertNotIn('Access-Control-Allow-Origin', resp)

        # POST is not allowed
        request = self.factory.post(
            '/api/v2/version/',
            {'project': self.project.slug, 'active': True, 'version': self.version.slug},
            HTTP_ORIGIN='http://my.valid.domain',
        )
        resp = self.middleware.process_response(request, {})
        self.assertNotIn('Access-Control-Allow-Origin', resp)
Beispiel #28
0
 def setUp(self):
     self.middleware = CorsMiddleware()
class TestCorsMiddlewareProcessResponse(TestCase):

    def setUp(self):
        self.middleware = CorsMiddleware()

    def assertAccessControlAllowOriginEquals(self, response, header):
        self.assertIn(ACCESS_CONTROL_ALLOW_ORIGIN, response, "Response %r does "
            "NOT have %r header" % (response, ACCESS_CONTROL_ALLOW_ORIGIN))
        self.assertEqual(response[ACCESS_CONTROL_ALLOW_ORIGIN], header)

    def test_process_response_no_origin(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request = Mock(path='/', META={})
        processed = self.middleware.process_response(request, response)
        self.assertNotIn(ACCESS_CONTROL_ALLOW_ORIGIN, processed)

    def test_process_response_not_in_whitelist(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = False
        settings.CORS_ORIGIN_WHITELIST = ['example.com']
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request = Mock(path='/', META={'HTTP_ORIGIN': 'http://foobar.it'})
        processed = self.middleware.process_response(request, response)
        self.assertNotIn(ACCESS_CONTROL_ALLOW_ORIGIN, processed)

    def test_process_response_signal_works(self, settings):
        def handler(sender, request, **kwargs):
            return True
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = False
        settings.CORS_ORIGIN_WHITELIST = ['example.com']
        settings.CORS_URLS_REGEX = '^.*$'
        signals.check_request_enabled.connect(handler)
        response = HttpResponse()
        request = Mock(path='/', META={'HTTP_ORIGIN': 'http://foobar.it'})
        processed = self.middleware.process_response(request, response)
        self.assertIn(ACCESS_CONTROL_ALLOW_ORIGIN, processed)

    def test_process_response_in_whitelist(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = False
        settings.CORS_ORIGIN_WHITELIST = ['example.com', 'foobar.it']
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request = Mock(path='/', META={'HTTP_ORIGIN': 'http://foobar.it'})
        processed = self.middleware.process_response(request, response)
        self.assertAccessControlAllowOriginEquals(processed, 'http://foobar.it')

    def test_process_response_expose_headers(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = True
        settings.CORS_EXPOSE_HEADERS = ['accept', 'origin', 'content-type']
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request = Mock(path='/', META={'HTTP_ORIGIN': 'http://example.com'})
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed[ACCESS_CONTROL_EXPOSE_HEADERS],
            'accept, origin, content-type')

    def test_process_response_dont_expose_headers(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = True
        settings.CORS_EXPOSE_HEADERS = []
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request = Mock(path='/', META={'HTTP_ORIGIN': 'http://example.com'})
        processed = self.middleware.process_response(request, response)
        self.assertNotIn(ACCESS_CONTROL_EXPOSE_HEADERS, processed)

    def test_process_response_allow_credentials(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = True
        settings.CORS_ALLOW_CREDENTIALS = True
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request = Mock(path='/', META={'HTTP_ORIGIN': 'http://example.com'})
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed[ACCESS_CONTROL_ALLOW_CREDENTIALS], 'true')

    def test_process_response_dont_allow_credentials(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = True
        settings.CORS_ALLOW_CREDENTIALS = False
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request = Mock(path='/', META={'HTTP_ORIGIN': 'http://example.com'})
        processed = self.middleware.process_response(request, response)
        self.assertNotIn(ACCESS_CONTROL_ALLOW_CREDENTIALS, processed)

    def test_process_response_options_method(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = True
        settings.CORS_ALLOW_HEADERS = ['content-type', 'origin']
        settings.CORS_ALLOW_METHODS = ['GET', 'OPTIONS']
        settings.CORS_PREFLIGHT_MAX_AGE = 1002
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request_headers = {'HTTP_ORIGIN': 'http://example.com'}
        request = Mock(path='/', META=request_headers, method='OPTIONS')
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed[ACCESS_CONTROL_ALLOW_HEADERS],
            'content-type, origin')
        self.assertEqual(processed[ACCESS_CONTROL_ALLOW_METHODS], 'GET, OPTIONS')
        self.assertEqual(processed[ACCESS_CONTROL_MAX_AGE], '1002')

    def test_process_response_options_method_no_max_age(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = True
        settings.CORS_ALLOW_HEADERS = ['content-type', 'origin']
        settings.CORS_ALLOW_METHODS = ['GET', 'OPTIONS']
        settings.CORS_PREFLIGHT_MAX_AGE = 0
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request_headers = {'HTTP_ORIGIN': 'http://example.com'}
        request = Mock(path='/', META=request_headers, method='OPTIONS')
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed[ACCESS_CONTROL_ALLOW_HEADERS],
            'content-type, origin')
        self.assertEqual(processed[ACCESS_CONTROL_ALLOW_METHODS], 'GET, OPTIONS')
        self.assertNotIn(ACCESS_CONTROL_MAX_AGE, processed)

    def test_process_response_whitelist_with_port(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = False
        settings.CORS_ALLOW_METHODS = ['OPTIONS']
        settings.CORS_ORIGIN_WHITELIST = ('localhost:9000',)
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request_headers = {'HTTP_ORIGIN': 'http://localhost:9000'}
        request = Mock(path='/', META=request_headers, method='OPTIONS')
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed.get(ACCESS_CONTROL_ALLOW_CREDENTIALS, None), 'true')

    def test_process_response_adds_origin_when_domain_found_in_origin_regex_whitelist(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_REGEX_WHITELIST = ('^http?://(\w+\.)?google\.com$', )
        settings.CORS_ALLOW_CREDENTIALS = True
        settings.CORS_ORIGIN_ALLOW_ALL = False
        settings.CORS_ALLOW_METHODS = ['OPTIONS']
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request_headers = {'HTTP_ORIGIN': 'http://foo.google.com'}
        request = Mock(path='/', META=request_headers, method='OPTIONS')
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed.get(ACCESS_CONTROL_ALLOW_ORIGIN, None), 'http://foo.google.com')

    def test_process_response_will_not_add_origin_when_domain_not_found_in_origin_regex_whitelist(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_REGEX_WHITELIST = ('^http?://(\w+\.)?yahoo\.com$', )
        settings.CORS_ALLOW_CREDENTIALS = True
        settings.CORS_ORIGIN_ALLOW_ALL = False
        settings.CORS_ALLOW_METHODS = ['OPTIONS']
        settings.CORS_URLS_REGEX = '^.*$'
        response = HttpResponse()
        request_headers = {'HTTP_ORIGIN': 'http://foo.google.com'}
        request = Mock(path='/', META=request_headers, method='OPTIONS')
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed.get(ACCESS_CONTROL_ALLOW_ORIGIN, None), None)

    def test_process_response_when_custom_model_enabled(self, settings):
        from corsheaders.models import CorsModel
        CorsModel.objects.create(cors='foo.google.com')
        settings.CORS_ORIGIN_REGEX_WHITELIST = ()
        settings.CORS_ALLOW_CREDENTIALS = False
        settings.CORS_ORIGIN_ALLOW_ALL = False
        settings.CORS_ALLOW_METHODS = settings.default_methods
        settings.CORS_URLS_REGEX = '^.*$'
        settings.CORS_MODEL = 'corsheaders.CorsModel'
        response = HttpResponse()
        request = Mock(path='/', META={'HTTP_ORIGIN': 'http://foo.google.com'})
        processed = self.middleware.process_response(request, response)
        self.assertEqual(processed.get(ACCESS_CONTROL_ALLOW_ORIGIN, None), 'http://foo.google.com')

    def test_process_response_in_allow_all_path(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = False
        # settings.CORS_ORIGIN_WHITELIST = ['example.com', 'foobar.it']
        settings.CORS_URLS_REGEX = '^.*$'
        settings.CORS_URLS_ALLOW_ALL_REGEX = (r'^/api/.*$',)
        response = HttpResponse()
        request = Mock(path='/api/data', META={'HTTP_ORIGIN': 'http://foobar.it'})
        processed = self.middleware.process_response(request, response)
        self.assertAccessControlAllowOriginEquals(processed, 'http://foobar.it')

    def test_process_response_not_in_allow_all_path(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = False
        # settings.CORS_ORIGIN_WHITELIST = ['example.com', 'foobar.it']
        settings.CORS_URLS_REGEX = '^.*$'
        settings.CORS_URLS_ALLOW_ALL_REGEX = (r'^/api/.*$',)
        response = HttpResponse()
        request = Mock(path='/data', META={'HTTP_ORIGIN': 'http://foobar.it'})
        processed = self.middleware.process_response(request, response)
        self.assertNotIn(ACCESS_CONTROL_ALLOW_ORIGIN, processed)

    def test_middleware_integration_get(self, settings):
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = True
        settings.CORS_URLS_REGEX = '^.*$'
        response = self.client.get('/test-view/', HTTP_ORIGIN='http://foobar.it')
        self.assertEqual(response.status_code, 200)
        self.assertAccessControlAllowOriginEquals(response, 'http://foobar.it')

    def test_middleware_integration_get_auth_view(self, settings):
        """
        It's not clear whether the header should still be set for non-HTTP200
        when not a preflight request. However this is the existing behaviour for
        django-cors-middleware, so at least this test makes that explicit, especially
        since for the switch to Django 1.10, special-handling will need to be put in
        place to preserve this behaviour. See `ExceptionMiddleware` mention here:
        https://docs.djangoproject.com/en/1.10/topics/http/middleware/#upgrading-pre-django-1-10-style-middleware
        """
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = True
        settings.CORS_URLS_REGEX = '^.*$'
        response = self.client.get('/test-view-http401/', HTTP_ORIGIN='http://foobar.it')
        self.assertEqual(response.status_code, 401)
        self.assertAccessControlAllowOriginEquals(response, 'http://foobar.it')

    def test_middleware_integration_preflight_auth_view(self, settings):
        """
        Ensure HTTP200 and header still set, for preflight requests to views requiring
        authentication. See: https://github.com/ottoyiu/django-cors-headers/issues/3
        """
        settings.CORS_MODEL = None
        settings.CORS_ORIGIN_ALLOW_ALL = True
        settings.CORS_URLS_REGEX = '^.*$'
        response = self.client.options('/test-view-http401/',
                                       HTTP_ORIGIN='http://foobar.it',
                                       HTTP_ACCESS_CONTROL_REQUEST_METHOD='value')
        self.assertEqual(response.status_code, 200)
        self.assertAccessControlAllowOriginEquals(response, 'http://foobar.it')