From 12932296e74151ab38cbc40676788eda188943df Mon Sep 17 00:00:00 2001 From: Livio Bieri Date: Fri, 8 Dec 2023 10:23:04 +0100 Subject: [PATCH] wip: pass next on signup sso --- .../vbv_lernwelt/sso/tests/test_sso_flow.py | 15 +++++--- server/vbv_lernwelt/sso/views.py | 34 +++++++++++++++---- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/server/vbv_lernwelt/sso/tests/test_sso_flow.py b/server/vbv_lernwelt/sso/tests/test_sso_flow.py index bb3c283c..31c2d4e7 100644 --- a/server/vbv_lernwelt/sso/tests/test_sso_flow.py +++ b/server/vbv_lernwelt/sso/tests/test_sso_flow.py @@ -236,9 +236,13 @@ class TestSignIn(TestCase): @patch("vbv_lernwelt.sso.views.oauth") def test_signin_with_state_param(self, mock_oauth): # GIVEN - state_param = "vv-de" + course = "vv-de" - expected_state = {"course": state_param, "next": None} + state_param = base64.urlsafe_b64encode( + json.dumps({"course": course, "next": None}).encode() + ).decode() + + expected_state = {"course": course, "next": None} expected_state_encoded = base64.urlsafe_b64encode( json.dumps(expected_state).encode() ).decode() @@ -324,9 +328,10 @@ class TestSignUp(TestCase): def test_signup_with_course_param(self, mock_oauth): # GIVEN course_param = "vv-de" + next_param = "/some-next-url" language = "fr" - expected_state = {"course": course_param, "next": None} + expected_state = {"course": course_param, "next": next_param} expected_state_encoded = base64.urlsafe_b64encode( json.dumps(expected_state).encode() ).decode() @@ -339,13 +344,13 @@ class TestSignUp(TestCase): # WHEN self.client.get( reverse("sso:signup"), - {"course": course_param, "lang": language}, + {"course": course_param, "next": next_param, "lang": language}, ) # THEN mock_oauth.signup.authorize_redirect.assert_called_once_with( ANY, "/sso/login", - state=course_param, + state=expected_state_encoded, lang=language, ) diff --git a/server/vbv_lernwelt/sso/views.py b/server/vbv_lernwelt/sso/views.py index b8c9b1d1..d48a019a 100644 --- a/server/vbv_lernwelt/sso/views.py +++ b/server/vbv_lernwelt/sso/views.py @@ -19,20 +19,42 @@ logger = structlog.get_logger(__name__) def signup(request): - course = request.GET.get("course") + course_param = request.GET.get("course") + next_param = request.GET.get("next") + + state_json = json.dumps({"course": course_param, "next": next_param}) + state_encoded = base64.urlsafe_b64encode(state_json.encode()).decode() redirect_uri = settings.OAUTH_SIGNUP_REDIRECT_URI - logger.debug(f"SSO Signup (course={course})", sso_signup_redirect_uri=redirect_uri) + + logger.debug( + f"SSO Signup (course={course_param}, next={next_param})", + sso_signup_redirect_uri=redirect_uri, + ) return oauth.signup.authorize_redirect( - request, redirect_uri, state=course, lang=request.GET.get("lang", "de") + request, redirect_uri, state=state_encoded, lang=request.GET.get("lang", "de") ) def signin(request): - # course query OR state when coming from signup (oauth) - course_param = request.GET.get("course", request.GET.get("state")) - next_param = request.GET.get("next") + """ + Called directly from the frontend AND as a redirect from signup! + """ + + # redirect from signup + if "state" in request.GET: + state_decoded = json.loads( + base64.urlsafe_b64decode(request.GET.get("state").encode()).decode() + ) + state_course_param = state_decoded.get("course") + state_next_param = state_decoded.get("next") + else: + state_course_param = None + state_next_param = None + + course_param = request.GET.get("course", state_course_param) + next_param = request.GET.get("next", state_next_param) state_json = json.dumps({"course": course_param, "next": next_param}) state_encoded = base64.urlsafe_b64encode(state_json.encode()).decode()