Repository: uclapi/uclapi

Issue:
OAuth: Useless Error With No Callback URL
1) Create an app
2) Attach an integration via OAuth
3) Attempt to Authenticate
4) Error about invalid signed data. Instead, we should put an error on screen that says a callback URL is required. In fact, authentication shouldn't even begin without a valid callback URL.


Discussion:

Resolving patch:
diff --git a/backend/uclapi/oauth/views.py b/backend/uclapi/oauth/views.py
--- a/backend/uclapi/oauth/views.py
+++ b/backend/uclapi/oauth/views.py
@@ -50,10 +50,17 @@ def authorise(request):
         response.status_code = 400
         return response
 
-    if app.callback_url is None:
+    if app.callback_url is None or app.callback_url.strip() == "":
         response = PrettyJsonResponse({
             "ok": False,
-            "error": "No callback URL set for this app."
+            "error": (
+                "This app does not have a callback URL set. "
+                "If you are the developer of this app, "
+                "please ensure you have set a valid callback "
+                "URL for your application in the Dashboard. "
+                "If you are a user, please contact the app's "
+                "developer to rectify this."
+            )
         })
         response.status_code = 400
         return response


Test patch:
diff --git a/backend/uclapi/oauth/tests.py b/backend/uclapi/oauth/tests.py
--- a/backend/uclapi/oauth/tests.py
+++ b/backend/uclapi/oauth/tests.py
@@ -12,7 +12,7 @@
 from .app_helpers import generate_random_verification_code
 from .models import OAuthScope, OAuthToken
 from .scoping import Scopes
-
+from .views import authorise
 
 @uclapi_protected_endpoint(personal_data=True, required_scopes=["timetable"])
 def test_timetable_request(request, *args, **kwargs):
@@ -311,6 +311,38 @@ def test_decorator_everything_passes(self):
 
         self.assertEqual(response.status_code, 200)
 
+    def test_no_callback_url(self):
+        user_ = User.objects.create(
+            email="test@ucl.ac.uk",
+            cn="test",
+            given_name="Test Test"
+        )
+        app_ = App.objects.create(user=user_, name="An App")
+        request = self.factory.get(
+            '/oauth/authorise',
+            {
+                'client_id': app_.client_id,
+                'state': 1
+            }
+        )
+        try:
+            response = authorise(request)
+            content = json.loads(response.content.decode())
+            self.assertEqual(response.status_code, 400)
+            self.assertEqual(
+                content["error"],
+                (
+                    "This app does not have a callback URL set. "
+                    "If you are the developer of this app, "
+                    "please ensure you have set a valid callback "
+                    "URL for your application in the Dashboard. "
+                    "If you are a user, please contact the app's "
+                    "developer to rectify this."
+                )
+            )
+        except json.decoder.JSONDecodeError:
+            self.fail("Got through to authorize page with no callback URL set")
+
 
 class AppHelpersTestCase(TestCase):
     def test_generate_random_verification_code(self):