Browse Source

$406: UI Server

Rafał Pitoń 10 years ago
parent
commit
503f3f766a

+ 60 - 0
misago/core/tests/test_uiviews.py

@@ -0,0 +1,60 @@
+from copy import copy
+
+from django.core.urlresolvers import reverse
+from django.http import JsonResponse
+from django.test import TestCase
+
+from misago.admin.testutils import AdminTestCase
+from misago.users.models import AnonymousUser
+
+from misago.core import uiviews
+
+
+class UIViewDecoratorTests(TestCase):
+    def setUp(self):
+        self._ui_views = copy(uiviews.UI_VIEWS)
+
+    def tearDown(self):
+        uiviews.UI_VIEWS = self._ui_views
+
+    def test_decorator(self):
+        """decorator registers view in UI"""
+        @uiviews.uiview('bigkahunaburger')
+        def fakey_view(request):
+            return {'is_tests': True}
+
+        for name, view in uiviews.UI_VIEWS:
+            if name == 'bigkahunaburger' and view == fakey_view:
+                break
+        else:
+            self.fail("uiviews.uiview decorator didn't register uiview")
+
+
+class UIServerTests(TestCase):
+    def test_server_response(self):
+        """UI Server returns JSON Response for valid request"""
+        headers = {
+            'HTTP_X_REQUESTED_WITH': 'XMLHttpRequest',
+            'HTTP_REFERER': 'http://test.com/',
+            'HTTP_HOST': 'test.com',
+        }
+        response = self.client.get(reverse('misago:ui_server'),
+                                   **headers)
+
+        self.assertTrue(isinstance(response, JsonResponse))
+        self.assertEqual(response.status_code, 200)
+
+
+class AuthenticatedUIServerTests(AdminTestCase):
+    def test_server_response(self):
+        """UI Server returns JSON Response for authenticated request"""
+        headers = {
+            'HTTP_X_REQUESTED_WITH': 'XMLHttpRequest',
+            'HTTP_REFERER': 'http://test.com/',
+            'HTTP_HOST': 'test.com',
+        }
+        response = self.client.get(reverse('misago:ui_server'),
+                                   **headers)
+
+        self.assertTrue(isinstance(response, JsonResponse))
+        self.assertEqual(response.status_code, 200)

+ 43 - 1
misago/core/tests/test_utils.py

@@ -4,7 +4,7 @@ from django.test import TestCase
 from django.test.client import RequestFactory
 from django.test.client import RequestFactory
 
 
 from misago.core.utils import (clean_return_path, is_request_to_misago,
 from misago.core.utils import (clean_return_path, is_request_to_misago,
-                               slugify, time_amount)
+                               slugify, time_amount, is_referer_local)
 
 
 
 
 VALID_PATHS = (
 VALID_PATHS = (
@@ -115,6 +115,48 @@ class CleanReturnPathTests(TestCase):
         self.assertEqual(clean_return_path(ok_request), '/register/')
         self.assertEqual(clean_return_path(ok_request), '/register/')
 
 
 
 
+class IsRefererLocalTests(TestCase):
+    def test_local_referers(self):
+        """local referers return true"""
+        ok_request = MockRequest('GET', {
+            'HTTP_REFERER': 'http://misago-project.org/',
+            'HTTP_HOST': 'misago-project.org/'
+        })
+        self.assertTrue(is_referer_local(ok_request))
+
+        ok_request = MockRequest('GET', {
+            'HTTP_REFERER': 'http://misago-project.org/',
+            'HTTP_HOST': 'misago-project.org/'
+        })
+        self.assertTrue(is_referer_local(ok_request))
+
+        ok_request = MockRequest('GET', {
+            'HTTP_REFERER': 'http://misago-project.org/register/',
+            'HTTP_HOST': 'misago-project.org/'
+        })
+        self.assertTrue(is_referer_local(ok_request))
+
+    def test_foreign_referers(self):
+        """non-local referers return false"""
+        bad_request = MockRequest('GET', {
+            'HTTP_REFERER': 'http://else-project.org/',
+            'HTTP_HOST': 'misago-project.org/'
+        })
+        self.assertFalse(is_referer_local(bad_request))
+
+        bad_request = MockRequest('GET', {
+            'HTTP_REFERER': 'https://misago-project.org/',
+            'HTTP_HOST': 'misago-project.org/'
+        })
+        self.assertFalse(is_referer_local(bad_request))
+
+        bad_request = MockRequest('GET', {
+            'HTTP_REFERER': 'http://misago-project.org/',
+            'HTTP_HOST': 'misago-project.org/assadsa/'
+        })
+        self.assertFalse(is_referer_local(bad_request))
+
+
 class TimeAmountTests(TestCase):
 class TimeAmountTests(TestCase):
     def test_single_units(self):
     def test_single_units(self):
         """time_amount return correct amount of time for 1 precision"""
         """time_amount return correct amount of time for 1 precision"""

+ 4 - 4
misago/core/uiviews.py

@@ -9,7 +9,7 @@ from django.core.urlresolvers import resolve
 from django.http import Http404, JsonResponse
 from django.http import Http404, JsonResponse
 
 
 from misago.core.decorators import ajax_only
 from misago.core.decorators import ajax_only
-from misago.core.utils import is_request_local
+from misago.core.utils import is_referer_local
 
 
 
 
 __all__ = ['uiview', 'uiserver']
 __all__ = ['uiview', 'uiserver']
@@ -29,9 +29,6 @@ def uiview(name):
 
 
 
 
 def get_resolver_match(request):
 def get_resolver_match(request):
-    if not is_request_local(request):
-        raise PermissionDenied()
-
     requesting_path = request.META['HTTP_REFERER']
     requesting_path = request.META['HTTP_REFERER']
     requesting_path = requesting_path[len(request.scheme) + 3:]
     requesting_path = requesting_path[len(request.scheme) + 3:]
     requesting_path = requesting_path[len(request.META['HTTP_HOST']):]
     requesting_path = requesting_path[len(request.META['HTTP_HOST']):]
@@ -41,6 +38,9 @@ def get_resolver_match(request):
 
 
 @ajax_only
 @ajax_only
 def uiserver(request):
 def uiserver(request):
+    if not is_referer_local(request):
+        raise PermissionDenied()
+
     resolver_match = get_resolver_match(request)
     resolver_match = get_resolver_match(request)
     response_dict = {'total_count': 0}
     response_dict = {'total_count': 0}
 
 

+ 1 - 1
misago/core/utils.py

@@ -79,7 +79,7 @@ def is_request_to_misago(request):
         return request._request_to_misago
         return request._request_to_misago
 
 
 
 
-def is_request_local(request):
+def is_referer_local(request):
     referer = request.META.get('HTTP_REFERER')
     referer = request.META.get('HTTP_REFERER')
 
 
     if not referer:
     if not referer:

+ 1 - 0
misago/notifications/views.py

@@ -33,6 +33,7 @@ def full_page(request):
 
 
 
 
 @uiview('misago_notifications')
 @uiview('misago_notifications')
+@deny_guests
 def event_sender(request, resolver_match):
 def event_sender(request, resolver_match):
     if request.user.new_notifications:
     if request.user.new_notifications:
         message = ungettext("You have %(notifications)s new notification",
         message = ungettext("You have %(notifications)s new notification",

+ 1 - 1
misago/templates/misago/base.html

@@ -41,7 +41,7 @@
         timeout: "{% trans "Request has timed out." %}"
         timeout: "{% trans "Request has timed out." %}"
       };
       };
 
 
-      var uiserver_url = "{% url 'misago:uiserver' %}";
+      var uiserver_url = "{% url 'misago:ui_server' %}";
     </script>
     </script>
     {% compressed_js 'misago' %}
     {% compressed_js 'misago' %}
     <script lang="JavaScript">
     <script lang="JavaScript">

+ 1 - 1
misago/urls.py

@@ -16,7 +16,7 @@ urlpatterns += patterns('',
     url(r'^', include('misago.users.urls')),
     url(r'^', include('misago.users.urls')),
     url(r'^', include('misago.notifications.urls')),
     url(r'^', include('misago.notifications.urls')),
     # UI Server view that handles realtime updates of Misago UI
     # UI Server view that handles realtime updates of Misago UI
-    url(r'^ui-server/$', 'misago.core.uiviews.uiserver', name="uiserver"),
+    url(r'^ui-server/$', 'misago.core.uiviews.uiserver', name="ui_server"),
 )
 )