From 53239bdf3791c87b4e16ac0a46c010379b88710f Mon Sep 17 00:00:00 2001
From: Robert Raposa <rraposa@edx.org>
Date: Mon, 22 Oct 2018 11:35:14 -0400
Subject: [PATCH] Remove JWT_COOKIES_FLAG.

The JWT_COOKIES_FLAG was a temporary flag used for rollout of the new
JWT cookies. These are live in Production, so we are removing the flag.

Without this flag, we set JWT cookies during login. However, this
requires an oAuth Client that isn't always available during unit tests.
We introduced a feature flag that is only used for unit tests to
disable setting the JWT cookies. The code explains a bit more why this
solution was selected over adding the oauth client to the database.

ARCH-247
---
 cms/envs/aws.py                               |  1 +
 cms/envs/bok_choy.auth.json                   |  5 +++
 cms/envs/bok_choy.env.json                    |  3 --
 cms/envs/bok_choy_docker.auth.json            |  5 +++
 cms/envs/bok_choy_docker.env.json             |  3 --
 cms/envs/production.py                        |  1 +
 cms/envs/test.py                              |  2 ++
 lms/envs/bok_choy.auth.json                   |  5 +++
 lms/envs/bok_choy.env.json                    |  3 --
 lms/envs/bok_choy_docker.auth.json            |  5 +++
 lms/envs/bok_choy_docker.env.json             |  3 --
 lms/envs/test.py                              |  3 +-
 .../user_api/accounts/tests/test_api.py       |  1 -
 openedx/core/djangoapps/user_authn/cookies.py | 23 +++++++------
 .../user_authn/tests/test_cookies.py          | 32 +++++++++----------
 .../user_authn/views/tests/test_login.py      | 11 +++----
 .../user_authn/views/tests/test_register.py   |  1 -
 openedx/core/djangoapps/user_authn/waffle.py  | 16 ----------
 18 files changed, 60 insertions(+), 63 deletions(-)
 delete mode 100644 openedx/core/djangoapps/user_authn/waffle.py

diff --git a/cms/envs/aws.py b/cms/envs/aws.py
index a7918cfd2e4..f5954abd411 100644
--- a/cms/envs/aws.py
+++ b/cms/envs/aws.py
@@ -518,6 +518,7 @@ OAUTH_OIDC_ISSUER = ENV_TOKENS['OAUTH_OIDC_ISSUER']
 
 #### JWT configuration ####
 JWT_AUTH.update(ENV_TOKENS.get('JWT_AUTH', {}))
+JWT_AUTH.update(AUTH_TOKENS.get('JWT_AUTH', {}))
 
 ######################## CUSTOM COURSES for EDX CONNECTOR ######################
 if FEATURES.get('CUSTOM_COURSES_EDX'):
diff --git a/cms/envs/bok_choy.auth.json b/cms/envs/bok_choy.auth.json
index 3adba233757..402121e7411 100644
--- a/cms/envs/bok_choy.auth.json
+++ b/cms/envs/bok_choy.auth.json
@@ -47,6 +47,11 @@
         ],
         "port": 27017
     },
+    "JWT_AUTH": {
+        "JWT_SECRET_KEY": "super-secret-key",
+        "JWT_PUBLIC_SIGNING_JWK_SET": "{\"keys\": [{\"kid\": \"BTZ9HA6K\", \"e\": \"AQAB\", \"kty\": \"RSA\", \"n\": \"o5cn3ljSRi6FaDEKTn0PS-oL9EFyv1pI7dRgffQLD1qf5D6sprmYfWWokSsrWig8u2y0HChSygR6Jn5KXBqQn6FpM0dDJLnWQDRXHLl3Ey1iPYgDSmOIsIGrV9ZyNCQwk03wAgWbfdBTig3QSDYD-sTNOs3pc4UD_PqAvU2nz_1SS2ZiOwOn5F6gulE1L0iE3KEUEvOIagfHNVhz0oxa_VRZILkzV-zr6R_TW1m97h4H8jXl_VJyQGyhMGGypuDrQ9_vaY_RLEulLCyY0INglHWQ7pckxBtI5q55-Vio2wgewe2_qYcGsnBGaDNbySAsvYcWRrqDiFyzrJYivodqTQ\"}]}",
+        "JWT_PRIVATE_SIGNING_JWK": "{\"e\": \"AQAB\", \"d\": \"HIiV7KNjcdhVbpn3KT-I9n3JPf5YbGXsCIedmPqDH1d4QhBofuAqZ9zebQuxkRUpmqtYMv0Zi6ECSUqH387GYQF_XvFUFcjQRPycISd8TH0DAKaDpGr-AYNshnKiEtQpINhcP44I1AYNPCwyoxXA1fGTtmkKChsuWea7o8kytwU5xSejvh5-jiqu2SF4GEl0BEXIAPZsgbzoPIWNxgO4_RzNnWs6nJZeszcaDD0CyezVSuH9QcI6g5QFzAC_YuykSsaaFJhZ05DocBsLczShJ9Omf6PnK9xlm26I84xrEh_7x4fVmNBg3xWTLh8qOnHqGko93A1diLRCrKHOvnpvgQ\", \"n\": \"o5cn3ljSRi6FaDEKTn0PS-oL9EFyv1pI7dRgffQLD1qf5D6sprmYfWWokSsrWig8u2y0HChSygR6Jn5KXBqQn6FpM0dDJLnWQDRXHLl3Ey1iPYgDSmOIsIGrV9ZyNCQwk03wAgWbfdBTig3QSDYD-sTNOs3pc4UD_PqAvU2nz_1SS2ZiOwOn5F6gulE1L0iE3KEUEvOIagfHNVhz0oxa_VRZILkzV-zr6R_TW1m97h4H8jXl_VJyQGyhMGGypuDrQ9_vaY_RLEulLCyY0INglHWQ7pckxBtI5q55-Vio2wgewe2_qYcGsnBGaDNbySAsvYcWRrqDiFyzrJYivodqTQ\", \"q\": \"3T3DEtBUka7hLGdIsDlC96Uadx_q_E4Vb1cxx_4Ss_wGp1Loz3N3ZngGyInsKlmbBgLo1Ykd6T9TRvRNEWEtFSOcm2INIBoVoXk7W5RuPa8Cgq2tjQj9ziGQ08JMejrPlj3Q1wmALJr5VTfvSYBu0WkljhKNCy1KB6fCby0C9WE\", \"p\": \"vUqzWPZnDG4IXyo-k5F0bHV0BNL_pVhQoLW7eyFHnw74IOEfSbdsMspNcPSFIrtgPsn7981qv3lN_staZ6JflKfHayjB_lvltHyZxfl0dvruShZOx1N6ykEo7YrAskC_qxUyrIvqmJ64zPW3jkuOYrFs7Ykj3zFx3Zq1H5568G0\", \"kid\": \"BTZ9HA6K\", \"kty\": \"RSA\"}"
+    },
     "MODULESTORE": {
         "default": {
             "ENGINE": "xmodule.modulestore.mixed.MixedModuleStore",
diff --git a/cms/envs/bok_choy.env.json b/cms/envs/bok_choy.env.json
index 69aa3de5895..352f3772008 100644
--- a/cms/envs/bok_choy.env.json
+++ b/cms/envs/bok_choy.env.json
@@ -79,9 +79,6 @@
     },
     "FEEDBACK_SUBMISSION_EMAIL": "",
     "GITHUB_REPO_ROOT": "** OVERRIDDEN **",
-    "JWT_AUTH": {
-        "JWT_SECRET_KEY": "super-secret-key"
-    },
     "GRADES_DOWNLOAD": {
         "BUCKET": "edx-grades",
         "ROOT_PATH": "/tmp/edx-s3/grades",
diff --git a/cms/envs/bok_choy_docker.auth.json b/cms/envs/bok_choy_docker.auth.json
index b70bd46ed13..00a7283b44a 100644
--- a/cms/envs/bok_choy_docker.auth.json
+++ b/cms/envs/bok_choy_docker.auth.json
@@ -47,6 +47,11 @@
         ],
         "port": 27017
     },
+    "JWT_AUTH": {
+        "JWT_SECRET_KEY": "super-secret-key",
+        "JWT_PUBLIC_SIGNING_JWK_SET": "{\"keys\": [{\"kid\": \"BTZ9HA6K\", \"e\": \"AQAB\", \"kty\": \"RSA\", \"n\": \"o5cn3ljSRi6FaDEKTn0PS-oL9EFyv1pI7dRgffQLD1qf5D6sprmYfWWokSsrWig8u2y0HChSygR6Jn5KXBqQn6FpM0dDJLnWQDRXHLl3Ey1iPYgDSmOIsIGrV9ZyNCQwk03wAgWbfdBTig3QSDYD-sTNOs3pc4UD_PqAvU2nz_1SS2ZiOwOn5F6gulE1L0iE3KEUEvOIagfHNVhz0oxa_VRZILkzV-zr6R_TW1m97h4H8jXl_VJyQGyhMGGypuDrQ9_vaY_RLEulLCyY0INglHWQ7pckxBtI5q55-Vio2wgewe2_qYcGsnBGaDNbySAsvYcWRrqDiFyzrJYivodqTQ\"}]}",
+        "JWT_PRIVATE_SIGNING_JWK": "{\"e\": \"AQAB\", \"d\": \"HIiV7KNjcdhVbpn3KT-I9n3JPf5YbGXsCIedmPqDH1d4QhBofuAqZ9zebQuxkRUpmqtYMv0Zi6ECSUqH387GYQF_XvFUFcjQRPycISd8TH0DAKaDpGr-AYNshnKiEtQpINhcP44I1AYNPCwyoxXA1fGTtmkKChsuWea7o8kytwU5xSejvh5-jiqu2SF4GEl0BEXIAPZsgbzoPIWNxgO4_RzNnWs6nJZeszcaDD0CyezVSuH9QcI6g5QFzAC_YuykSsaaFJhZ05DocBsLczShJ9Omf6PnK9xlm26I84xrEh_7x4fVmNBg3xWTLh8qOnHqGko93A1diLRCrKHOvnpvgQ\", \"n\": \"o5cn3ljSRi6FaDEKTn0PS-oL9EFyv1pI7dRgffQLD1qf5D6sprmYfWWokSsrWig8u2y0HChSygR6Jn5KXBqQn6FpM0dDJLnWQDRXHLl3Ey1iPYgDSmOIsIGrV9ZyNCQwk03wAgWbfdBTig3QSDYD-sTNOs3pc4UD_PqAvU2nz_1SS2ZiOwOn5F6gulE1L0iE3KEUEvOIagfHNVhz0oxa_VRZILkzV-zr6R_TW1m97h4H8jXl_VJyQGyhMGGypuDrQ9_vaY_RLEulLCyY0INglHWQ7pckxBtI5q55-Vio2wgewe2_qYcGsnBGaDNbySAsvYcWRrqDiFyzrJYivodqTQ\", \"q\": \"3T3DEtBUka7hLGdIsDlC96Uadx_q_E4Vb1cxx_4Ss_wGp1Loz3N3ZngGyInsKlmbBgLo1Ykd6T9TRvRNEWEtFSOcm2INIBoVoXk7W5RuPa8Cgq2tjQj9ziGQ08JMejrPlj3Q1wmALJr5VTfvSYBu0WkljhKNCy1KB6fCby0C9WE\", \"p\": \"vUqzWPZnDG4IXyo-k5F0bHV0BNL_pVhQoLW7eyFHnw74IOEfSbdsMspNcPSFIrtgPsn7981qv3lN_staZ6JflKfHayjB_lvltHyZxfl0dvruShZOx1N6ykEo7YrAskC_qxUyrIvqmJ64zPW3jkuOYrFs7Ykj3zFx3Zq1H5568G0\", \"kid\": \"BTZ9HA6K\", \"kty\": \"RSA\"}"
+    },
     "MODULESTORE": {
         "default": {
             "ENGINE": "xmodule.modulestore.mixed.MixedModuleStore",
diff --git a/cms/envs/bok_choy_docker.env.json b/cms/envs/bok_choy_docker.env.json
index 540b4263d06..373cd2cec12 100644
--- a/cms/envs/bok_choy_docker.env.json
+++ b/cms/envs/bok_choy_docker.env.json
@@ -79,9 +79,6 @@
     },
     "FEEDBACK_SUBMISSION_EMAIL": "",
     "GITHUB_REPO_ROOT": "** OVERRIDDEN **",
-    "JWT_AUTH": {
-        "JWT_SECRET_KEY": "super-secret-key"
-    },
     "GRADES_DOWNLOAD": {
         "BUCKET": "edx-grades",
         "ROOT_PATH": "/tmp/edx-s3/grades",
diff --git a/cms/envs/production.py b/cms/envs/production.py
index 65f6f8813a7..88c873f107d 100644
--- a/cms/envs/production.py
+++ b/cms/envs/production.py
@@ -517,6 +517,7 @@ OAUTH_OIDC_ISSUER = ENV_TOKENS['OAUTH_OIDC_ISSUER']
 
 #### JWT configuration ####
 JWT_AUTH.update(ENV_TOKENS.get('JWT_AUTH', {}))
+JWT_AUTH.update(AUTH_TOKENS.get('JWT_AUTH', {}))
 
 ######################## CUSTOM COURSES for EDX CONNECTOR ######################
 if FEATURES.get('CUSTOM_COURSES_EDX'):
diff --git a/cms/envs/test.py b/cms/envs/test.py
index c6689932e21..543cff7d830 100644
--- a/cms/envs/test.py
+++ b/cms/envs/test.py
@@ -192,6 +192,8 @@ PASSWORD_HASHERS = [
 # No segment key
 CMS_SEGMENT_KEY = None
 
+FEATURES['DISABLE_SET_JWT_COOKIES_FOR_TESTS'] = True
+
 FEATURES['ENABLE_SERVICE_STATUS'] = True
 
 # Toggles embargo on for testing
diff --git a/lms/envs/bok_choy.auth.json b/lms/envs/bok_choy.auth.json
index e8a9e618948..53c7d7501ba 100644
--- a/lms/envs/bok_choy.auth.json
+++ b/lms/envs/bok_choy.auth.json
@@ -74,6 +74,11 @@
             }
         }
     },
+    "JWT_AUTH": {
+        "JWT_SECRET_KEY": "super-secret-key",
+        "JWT_PUBLIC_SIGNING_JWK_SET": "{\"keys\": [{\"kid\": \"BTZ9HA6K\", \"e\": \"AQAB\", \"kty\": \"RSA\", \"n\": \"o5cn3ljSRi6FaDEKTn0PS-oL9EFyv1pI7dRgffQLD1qf5D6sprmYfWWokSsrWig8u2y0HChSygR6Jn5KXBqQn6FpM0dDJLnWQDRXHLl3Ey1iPYgDSmOIsIGrV9ZyNCQwk03wAgWbfdBTig3QSDYD-sTNOs3pc4UD_PqAvU2nz_1SS2ZiOwOn5F6gulE1L0iE3KEUEvOIagfHNVhz0oxa_VRZILkzV-zr6R_TW1m97h4H8jXl_VJyQGyhMGGypuDrQ9_vaY_RLEulLCyY0INglHWQ7pckxBtI5q55-Vio2wgewe2_qYcGsnBGaDNbySAsvYcWRrqDiFyzrJYivodqTQ\"}]}",
+        "JWT_PRIVATE_SIGNING_JWK": "{\"e\": \"AQAB\", \"d\": \"HIiV7KNjcdhVbpn3KT-I9n3JPf5YbGXsCIedmPqDH1d4QhBofuAqZ9zebQuxkRUpmqtYMv0Zi6ECSUqH387GYQF_XvFUFcjQRPycISd8TH0DAKaDpGr-AYNshnKiEtQpINhcP44I1AYNPCwyoxXA1fGTtmkKChsuWea7o8kytwU5xSejvh5-jiqu2SF4GEl0BEXIAPZsgbzoPIWNxgO4_RzNnWs6nJZeszcaDD0CyezVSuH9QcI6g5QFzAC_YuykSsaaFJhZ05DocBsLczShJ9Omf6PnK9xlm26I84xrEh_7x4fVmNBg3xWTLh8qOnHqGko93A1diLRCrKHOvnpvgQ\", \"n\": \"o5cn3ljSRi6FaDEKTn0PS-oL9EFyv1pI7dRgffQLD1qf5D6sprmYfWWokSsrWig8u2y0HChSygR6Jn5KXBqQn6FpM0dDJLnWQDRXHLl3Ey1iPYgDSmOIsIGrV9ZyNCQwk03wAgWbfdBTig3QSDYD-sTNOs3pc4UD_PqAvU2nz_1SS2ZiOwOn5F6gulE1L0iE3KEUEvOIagfHNVhz0oxa_VRZILkzV-zr6R_TW1m97h4H8jXl_VJyQGyhMGGypuDrQ9_vaY_RLEulLCyY0INglHWQ7pckxBtI5q55-Vio2wgewe2_qYcGsnBGaDNbySAsvYcWRrqDiFyzrJYivodqTQ\", \"q\": \"3T3DEtBUka7hLGdIsDlC96Uadx_q_E4Vb1cxx_4Ss_wGp1Loz3N3ZngGyInsKlmbBgLo1Ykd6T9TRvRNEWEtFSOcm2INIBoVoXk7W5RuPa8Cgq2tjQj9ziGQ08JMejrPlj3Q1wmALJr5VTfvSYBu0WkljhKNCy1KB6fCby0C9WE\", \"p\": \"vUqzWPZnDG4IXyo-k5F0bHV0BNL_pVhQoLW7eyFHnw74IOEfSbdsMspNcPSFIrtgPsn7981qv3lN_staZ6JflKfHayjB_lvltHyZxfl0dvruShZOx1N6ykEo7YrAskC_qxUyrIvqmJ64zPW3jkuOYrFs7Ykj3zFx3Zq1H5568G0\", \"kid\": \"BTZ9HA6K\", \"kty\": \"RSA\"}"
+    },
     "MODULESTORE": {
         "default": {
             "ENGINE": "xmodule.modulestore.mixed.MixedModuleStore",
diff --git a/lms/envs/bok_choy.env.json b/lms/envs/bok_choy.env.json
index 7bb9b3756c4..5b644dcc9c9 100644
--- a/lms/envs/bok_choy.env.json
+++ b/lms/envs/bok_choy.env.json
@@ -92,9 +92,6 @@
     },
     "FEEDBACK_SUBMISSION_EMAIL": "",
     "GITHUB_REPO_ROOT": "** OVERRIDDEN **",
-    "JWT_AUTH": {
-        "JWT_SECRET_KEY": "super-secret-key"
-    },
     "LMS_BASE": "localhost:8003",
     "LMS_ROOT_URL": "http://localhost:8003",
     "LOCAL_LOGLEVEL": "INFO",
diff --git a/lms/envs/bok_choy_docker.auth.json b/lms/envs/bok_choy_docker.auth.json
index 9313c402503..767c4044962 100644
--- a/lms/envs/bok_choy_docker.auth.json
+++ b/lms/envs/bok_choy_docker.auth.json
@@ -82,6 +82,11 @@
             }
         }
     },
+    "JWT_AUTH": {
+        "JWT_SECRET_KEY": "super-secret-key",
+        "JWT_PUBLIC_SIGNING_JWK_SET": "{\"keys\": [{\"kid\": \"BTZ9HA6K\", \"e\": \"AQAB\", \"kty\": \"RSA\", \"n\": \"o5cn3ljSRi6FaDEKTn0PS-oL9EFyv1pI7dRgffQLD1qf5D6sprmYfWWokSsrWig8u2y0HChSygR6Jn5KXBqQn6FpM0dDJLnWQDRXHLl3Ey1iPYgDSmOIsIGrV9ZyNCQwk03wAgWbfdBTig3QSDYD-sTNOs3pc4UD_PqAvU2nz_1SS2ZiOwOn5F6gulE1L0iE3KEUEvOIagfHNVhz0oxa_VRZILkzV-zr6R_TW1m97h4H8jXl_VJyQGyhMGGypuDrQ9_vaY_RLEulLCyY0INglHWQ7pckxBtI5q55-Vio2wgewe2_qYcGsnBGaDNbySAsvYcWRrqDiFyzrJYivodqTQ\"}]}",
+        "JWT_PRIVATE_SIGNING_JWK": "{\"e\": \"AQAB\", \"d\": \"HIiV7KNjcdhVbpn3KT-I9n3JPf5YbGXsCIedmPqDH1d4QhBofuAqZ9zebQuxkRUpmqtYMv0Zi6ECSUqH387GYQF_XvFUFcjQRPycISd8TH0DAKaDpGr-AYNshnKiEtQpINhcP44I1AYNPCwyoxXA1fGTtmkKChsuWea7o8kytwU5xSejvh5-jiqu2SF4GEl0BEXIAPZsgbzoPIWNxgO4_RzNnWs6nJZeszcaDD0CyezVSuH9QcI6g5QFzAC_YuykSsaaFJhZ05DocBsLczShJ9Omf6PnK9xlm26I84xrEh_7x4fVmNBg3xWTLh8qOnHqGko93A1diLRCrKHOvnpvgQ\", \"n\": \"o5cn3ljSRi6FaDEKTn0PS-oL9EFyv1pI7dRgffQLD1qf5D6sprmYfWWokSsrWig8u2y0HChSygR6Jn5KXBqQn6FpM0dDJLnWQDRXHLl3Ey1iPYgDSmOIsIGrV9ZyNCQwk03wAgWbfdBTig3QSDYD-sTNOs3pc4UD_PqAvU2nz_1SS2ZiOwOn5F6gulE1L0iE3KEUEvOIagfHNVhz0oxa_VRZILkzV-zr6R_TW1m97h4H8jXl_VJyQGyhMGGypuDrQ9_vaY_RLEulLCyY0INglHWQ7pckxBtI5q55-Vio2wgewe2_qYcGsnBGaDNbySAsvYcWRrqDiFyzrJYivodqTQ\", \"q\": \"3T3DEtBUka7hLGdIsDlC96Uadx_q_E4Vb1cxx_4Ss_wGp1Loz3N3ZngGyInsKlmbBgLo1Ykd6T9TRvRNEWEtFSOcm2INIBoVoXk7W5RuPa8Cgq2tjQj9ziGQ08JMejrPlj3Q1wmALJr5VTfvSYBu0WkljhKNCy1KB6fCby0C9WE\", \"p\": \"vUqzWPZnDG4IXyo-k5F0bHV0BNL_pVhQoLW7eyFHnw74IOEfSbdsMspNcPSFIrtgPsn7981qv3lN_staZ6JflKfHayjB_lvltHyZxfl0dvruShZOx1N6ykEo7YrAskC_qxUyrIvqmJ64zPW3jkuOYrFs7Ykj3zFx3Zq1H5568G0\", \"kid\": \"BTZ9HA6K\", \"kty\": \"RSA\"}"
+    },
     "MODULESTORE": {
         "default": {
             "ENGINE": "xmodule.modulestore.mixed.MixedModuleStore",
diff --git a/lms/envs/bok_choy_docker.env.json b/lms/envs/bok_choy_docker.env.json
index 713ce3d22f5..b2a799da2f7 100644
--- a/lms/envs/bok_choy_docker.env.json
+++ b/lms/envs/bok_choy_docker.env.json
@@ -92,9 +92,6 @@
     },
     "FEEDBACK_SUBMISSION_EMAIL": "",
     "GITHUB_REPO_ROOT": "** OVERRIDDEN **",
-    "JWT_AUTH": {
-        "JWT_SECRET_KEY": "super-secret-key"
-    },
     "LMS_BASE": "http://edx.devstack.lms:18003",
     "LMS_ROOT_URL": "http://edx.devstack.lms:18003",
     "LOCAL_LOGLEVEL": "INFO",
diff --git a/lms/envs/test.py b/lms/envs/test.py
index 08cfdd4e7e6..f8c2f2a83c6 100644
--- a/lms/envs/test.py
+++ b/lms/envs/test.py
@@ -50,6 +50,8 @@ os.environ['DJANGO_LIVE_TEST_SERVER_ADDRESS'] = 'localhost:8000-9000'
 
 THIS_UUID = uuid4().hex[:5]
 
+FEATURES['DISABLE_SET_JWT_COOKIES_FOR_TESTS'] = True
+
 # can't test start dates with this True, but on the other hand,
 # can test everything else :)
 FEATURES['DISABLE_START_DATES'] = True
@@ -596,7 +598,6 @@ JWT_AUTH.update({
         'ayjB_lvltHyZxfl0dvruShZOx1N6ykEo7YrAskC_qxUyrIvqmJ64zPW3jkuOYrFs7Ykj3zFx3Zq1H5568G0", "kid": "BTZ9HA6K", "kty"'
         ': "RSA"}'
     ),
-    'JWT_LOGIN_CLIENT_ID': 'test-login-service-client-id',
 })
 
 ####################### Plugin Settings ##########################
diff --git a/openedx/core/djangoapps/user_api/accounts/tests/test_api.py b/openedx/core/djangoapps/user_api/accounts/tests/test_api.py
index cf100131236..48e54f483d1 100644
--- a/openedx/core/djangoapps/user_api/accounts/tests/test_api.py
+++ b/openedx/core/djangoapps/user_api/accounts/tests/test_api.py
@@ -57,7 +57,6 @@ from openedx.core.djangoapps.user_api.errors import (
     UserNotAuthorized,
     UserNotFound
 )
-from openedx.core.djangoapps.waffle_utils.testutils import override_waffle_flag
 from openedx.core.djangolib.testing.utils import skip_unless_lms
 from openedx.core.lib.tests import attr
 from student.models import PendingEmailChange
diff --git a/openedx/core/djangoapps/user_authn/cookies.py b/openedx/core/djangoapps/user_authn/cookies.py
index 242edf0aeb9..38d9e012a4d 100644
--- a/openedx/core/djangoapps/user_authn/cookies.py
+++ b/openedx/core/djangoapps/user_authn/cookies.py
@@ -22,7 +22,6 @@ from openedx.core.djangoapps.oauth_dispatch.api import create_dot_access_token,
 from openedx.core.djangoapps.oauth_dispatch.jwt import create_jwt_from_token
 from openedx.core.djangoapps.user_api.accounts.utils import retrieve_last_sitewide_block_completed
 from openedx.core.djangoapps.user_authn.exceptions import AuthFailedError
-from openedx.core.djangoapps.user_authn.waffle import JWT_COOKIES_FLAG
 from student.models import CourseEnrollment
 
 
@@ -152,15 +151,14 @@ def refresh_jwt_cookies(request, response):
     Resets the JWT related cookies in the response, while expecting a refresh
     cookie in the request.
     """
-    if JWT_COOKIES_FLAG.is_enabled():
-        try:
-            refresh_token = request.COOKIES[jwt_cookies.jwt_refresh_cookie_name()]
-        except KeyError:
-            raise AuthFailedError(u"JWT Refresh Cookie not found in request.")
+    try:
+        refresh_token = request.COOKIES[jwt_cookies.jwt_refresh_cookie_name()]
+    except KeyError:
+        raise AuthFailedError(u"JWT Refresh Cookie not found in request.")
 
-        # TODO don't extend the cookie expiration - reuse value from existing cookie
-        cookie_settings = standard_cookie_settings(request)
-        _create_and_set_jwt_cookies(response, request, cookie_settings, refresh_token=refresh_token)
+    # TODO don't extend the cookie expiration - reuse value from existing cookie
+    cookie_settings = standard_cookie_settings(request)
+    _create_and_set_jwt_cookies(response, request, cookie_settings, refresh_token=refresh_token)
     return response
 
 
@@ -248,7 +246,12 @@ def _get_user_info_cookie_data(request, user):
 
 def _create_and_set_jwt_cookies(response, request, cookie_settings, user=None, refresh_token=None):
     """ Sets a cookie containing a JWT on the response. """
-    if not JWT_COOKIES_FLAG.is_enabled():
+
+    # Skip setting JWT cookies for most unit tests, since it raises errors when
+    # a login oauth client cannot be found in the database in ``_get_login_oauth_client``.
+    # This solution is not ideal, but see https://github.com/edx/edx-platform/pull/19180#issue-226706355
+    # for a discussion of alternative solutions that did not work or were halted.
+    if settings.FEATURES.get('DISABLE_SET_JWT_COOKIES_FOR_TESTS', False):
         return
 
     # For security reasons, the JWT that is embedded inside the cookie expires
diff --git a/openedx/core/djangoapps/user_authn/tests/test_cookies.py b/openedx/core/djangoapps/user_authn/tests/test_cookies.py
index daefd24fc67..ce903d37086 100644
--- a/openedx/core/djangoapps/user_authn/tests/test_cookies.py
+++ b/openedx/core/djangoapps/user_authn/tests/test_cookies.py
@@ -1,7 +1,7 @@
 # pylint: disable=missing-docstring
 from __future__ import unicode_literals
 
-from mock import MagicMock
+from mock import MagicMock, patch
 import six
 from django.conf import settings
 from django.http import HttpResponse
@@ -108,14 +108,14 @@ class CookieTests(TestCase):
         self._assert_consistent_expires(response)
         self._assert_recreate_jwt_from_cookies(response, can_recreate=False)
 
+    @patch.dict("django.conf.settings.FEATURES", {"DISABLE_SET_JWT_COOKIES_FOR_TESTS": False})
     def test_set_logged_in_jwt_cookies(self):
         setup_login_oauth_client()
         self._set_use_jwt_cookie_header(self.request)
-        with cookies_api.JWT_COOKIES_FLAG.override(True):
-            response = cookies_api.set_logged_in_cookies(self.request, HttpResponse(), self.user)
-            self._assert_cookies_present(response, cookies_api.ALL_LOGGED_IN_COOKIE_NAMES)
-            self._assert_consistent_expires(response)
-            self._assert_recreate_jwt_from_cookies(response, can_recreate=True)
+        response = cookies_api.set_logged_in_cookies(self.request, HttpResponse(), self.user)
+        self._assert_cookies_present(response, cookies_api.ALL_LOGGED_IN_COOKIE_NAMES)
+        self._assert_consistent_expires(response)
+        self._assert_recreate_jwt_from_cookies(response, can_recreate=True)
 
     def test_delete_and_is_logged_in_cookie_set(self):
         response = cookies_api.set_logged_in_cookies(self.request, HttpResponse(), self.user)
@@ -126,19 +126,19 @@ class CookieTests(TestCase):
         self._copy_cookies_to_request(response, self.request)
         self.assertFalse(cookies_api.is_logged_in_cookie_set(self.request))
 
+    @patch.dict("django.conf.settings.FEATURES", {"DISABLE_SET_JWT_COOKIES_FOR_TESTS": False})
     def test_refresh_jwt_cookies(self):
         def _get_refresh_token_value(response):
             return response.cookies[cookies_api.jwt_cookies.jwt_refresh_cookie_name()].value
 
         setup_login_oauth_client()
         self._set_use_jwt_cookie_header(self.request)
-        with cookies_api.JWT_COOKIES_FLAG.override(True):
-            response = cookies_api.set_logged_in_cookies(self.request, HttpResponse(), self.user)
-            self._copy_cookies_to_request(response, self.request)
-
-            new_response = cookies_api.refresh_jwt_cookies(self.request, HttpResponse())
-            self._assert_recreate_jwt_from_cookies(new_response, can_recreate=True)
-            self.assertNotEqual(
-                _get_refresh_token_value(response),
-                _get_refresh_token_value(new_response),
-            )
+        response = cookies_api.set_logged_in_cookies(self.request, HttpResponse(), self.user)
+        self._copy_cookies_to_request(response, self.request)
+
+        new_response = cookies_api.refresh_jwt_cookies(self.request, HttpResponse())
+        self._assert_recreate_jwt_from_cookies(new_response, can_recreate=True)
+        self.assertNotEqual(
+            _get_refresh_token_value(response),
+            _get_refresh_token_value(new_response),
+        )
diff --git a/openedx/core/djangoapps/user_authn/views/tests/test_login.py b/openedx/core/djangoapps/user_authn/views/tests/test_login.py
index bfb6db00691..0e69f90f2a2 100644
--- a/openedx/core/djangoapps/user_authn/views/tests/test_login.py
+++ b/openedx/core/djangoapps/user_authn/views/tests/test_login.py
@@ -26,7 +26,6 @@ from openedx.core.djangoapps.password_policy.compliance import (
 from openedx.core.djangoapps.user_api.config.waffle import PREVENT_AUTH_USER_WRITES, waffle
 from openedx.core.djangoapps.user_authn.cookies import jwt_cookies
 from openedx.core.djangoapps.user_authn.tests.utils import setup_login_oauth_client
-from openedx.core.djangoapps.user_authn.waffle import JWT_COOKIES_FLAG
 from openedx.core.djangolib.testing.utils import CacheIsolationTestCase
 from student.tests.factories import RegistrationFactory, UserFactory, UserProfileFactory
 from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
@@ -292,18 +291,18 @@ class LoginTest(CacheIsolationTestCase):
         response, _audit_log = self._login_response('test@edx.org', 'wrong_password')
         self._assert_response(response, success=False, value='Too many failed login attempts')
 
+    @patch.dict("django.conf.settings.FEATURES", {"DISABLE_SET_JWT_COOKIES_FOR_TESTS": False})
     def test_login_refresh(self):
         def _assert_jwt_cookie_present(response):
             self.assertEqual(response.status_code, 200)
             self.assertIn(jwt_cookies.jwt_refresh_cookie_name(), self.client.cookies)
 
         setup_login_oauth_client()
-        with JWT_COOKIES_FLAG.override(True):
-            response, _ = self._login_response('test@edx.org', 'test_password')
-            _assert_jwt_cookie_present(response)
+        response, _ = self._login_response('test@edx.org', 'test_password')
+        _assert_jwt_cookie_present(response)
 
-            response = self.client.post(reverse('login_refresh'))
-            _assert_jwt_cookie_present(response)
+        response = self.client.post(reverse('login_refresh'))
+        _assert_jwt_cookie_present(response)
 
     @patch.dict("django.conf.settings.FEATURES", {'PREVENT_CONCURRENT_LOGINS': True})
     def test_single_session(self):
diff --git a/openedx/core/djangoapps/user_authn/views/tests/test_register.py b/openedx/core/djangoapps/user_authn/views/tests/test_register.py
index 749b76e8ec2..98a0d3bfcf9 100644
--- a/openedx/core/djangoapps/user_authn/views/tests/test_register.py
+++ b/openedx/core/djangoapps/user_authn/views/tests/test_register.py
@@ -25,7 +25,6 @@ from openedx.core.djangoapps.user_authn.views.register import (
     _skip_activation_email,
 )
 from openedx.core.djangoapps.external_auth.models import ExternalAuthMap
-from openedx.core.djangoapps.waffle_utils.testutils import override_waffle_flag
 from openedx.core.djangoapps.lang_pref import LANGUAGE_KEY
 from openedx.core.djangoapps.site_configuration.tests.mixins import SiteMixin
 from openedx.core.djangoapps.user_api.accounts import (
diff --git a/openedx/core/djangoapps/user_authn/waffle.py b/openedx/core/djangoapps/user_authn/waffle.py
deleted file mode 100644
index 79fae6db817..00000000000
--- a/openedx/core/djangoapps/user_authn/waffle.py
+++ /dev/null
@@ -1,16 +0,0 @@
-"""
-Feature toggles for user_authn.
-"""
-from openedx.core.djangoapps.waffle_utils import WaffleFlagNamespace, WaffleFlag
-
-# Namespace
-_WAFFLE_NAMESPACE = u'user_authn'
-_WAFFLE_FLAG_NAMESPACE = WaffleFlagNamespace(_WAFFLE_NAMESPACE)
-
-# Flags
-
-# TODO (ARCH-247)
-# Intended as a temporary toggle for roll-out of jwt cookies feature.
-# Satisfies Use Case #3 "Ops - Monitored Rollout" from
-# https://open-edx-proposals.readthedocs.io/en/latest/oep-0017-bp-feature-toggles.html
-JWT_COOKIES_FLAG = WaffleFlag(_WAFFLE_FLAG_NAMESPACE, u'jwt_cookies')
-- 
GitLab