Browse Source

Support CORS check on POST

Fixes GH-1383
Matt Robenolt 9 years ago
parent
commit
eb2194443f
3 changed files with 47 additions and 2 deletions
  1. 23 0
      src/sentry/testutils/cases.py
  2. 2 2
      src/sentry/web/api.py
  3. 22 0
      tests/integration/tests.py

+ 23 - 0
src/sentry/testutils/cases.py

@@ -182,6 +182,29 @@ class BaseTestCase(Fixtures, Exam):
             )
         return resp
 
+    def _postWithReferer(self, data, key=None, referer='getsentry.com', protocol='4'):
+        if key is None:
+            key = self.projectkey.public_key
+
+        headers = {}
+        if referer is not None:
+            headers['HTTP_REFERER'] = referer
+
+        message = self._makeMessage(data)
+        qs = {
+            'sentry_version': protocol,
+            'sentry_client': 'raven-js/lol',
+            'sentry_key': key,
+        }
+        with self.tasks():
+            resp = self.client.post(
+                '%s?%s' % (reverse('sentry-api-store', args=(self.project.pk,)), urllib.urlencode(qs)),
+                data=message,
+                content_type='application/json',
+                **headers
+            )
+        return resp
+
     _postWithSignature = _postWithHeader
     _postWithNewSignature = _postWithHeader
 

+ 2 - 2
src/sentry/web/api.py

@@ -202,9 +202,9 @@ class APIView(BaseView):
                         # Special case an error message for a None origin when None wasn't allowed
                         raise APIForbidden('Missing required Origin or Referer header')
                 else:
-                    # Version 3 enforces secret key for server side requests
                     if not auth.secret_key:
-                        raise APIForbidden('Missing required attribute in authentication header: sentry_secret')
+                        if origin is None and not is_valid_origin(origin, project):
+                            raise APIForbidden('Missing required attribute in authentication header: sentry_secret')
 
             response = super(APIView, self).dispatch(
                 request=request,

+ 22 - 0
tests/integration/tests.py

@@ -206,6 +206,28 @@ class SentryRemoteTest(TestCase):
         resp = self._getWithReferer(kwargs, referer=None, protocol='4')
         assert resp.status_code == 200, (resp.status_code, resp.get('X-Sentry-Error'))
 
+    @override_settings(SENTRY_ALLOW_ORIGIN='getsentry.com')
+    def test_correct_data_with_post_referer(self):
+        kwargs = {'message': 'hello'}
+        resp = self._postWithReferer(kwargs)
+        assert resp.status_code == 200, resp.content
+        instance = Event.objects.get()
+        assert instance.message == 'hello'
+
+    @override_settings(SENTRY_ALLOW_ORIGIN='getsentry.com')
+    def test_post_without_referer(self):
+        self.project.update_option('sentry:origins', '')
+        kwargs = {'message': 'hello'}
+        resp = self._postWithReferer(kwargs, referer=None, protocol='4')
+        assert resp.status_code == 403, (resp.status_code, resp.get('X-Sentry-Error'))
+
+    @override_settings(SENTRY_ALLOW_ORIGIN='*')
+    def test_post_without_referer_allowed(self):
+        self.project.update_option('sentry:origins', '')
+        kwargs = {'message': 'hello'}
+        resp = self._postWithReferer(kwargs, referer=None, protocol='4')
+        assert resp.status_code == 200, (resp.status_code, resp.get('X-Sentry-Error'))
+
     def test_signature(self):
         kwargs = {'message': 'hello'}