Repository: mdn/kuma

Issue:
Use waffle Switch to protect the subscription config URL
In https://github.com/mdn/kuma/commit/5f09827177eb895c3fa1b277fa2edaa077953651 we made it so that `/api/v1/subscriptions/config/` is protected by the `subscriptions` waffle **flag** but that means it's dependent on the user (e.g. staff users only). That means we can't reach it from the Prod or Stage builds in GitHub Action and thus never expose it in Yari. 

If we switch to a Switch instead, we can make the config exposed on Stage without allowing people to use the checkout or customer portal until we're ready. 


Discussion:

Resolving patch:
diff --git a/kuma/api/v1/subscription.py b/kuma/api/v1/subscription.py
--- a/kuma/api/v1/subscription.py
+++ b/kuma/api/v1/subscription.py
@@ -12,7 +12,7 @@
 from django.views.decorators.csrf import csrf_exempt
 from django.views.decorators.http import require_GET, require_POST
 from raven.contrib.django.models import client as raven_client
-from waffle import flag_is_active
+from waffle import switch_is_active
 
 from kuma.core.ga_tracking import (
     ACTION_SUBSCRIPTION_CANCELED,
@@ -27,7 +27,7 @@
 @require_GET
 @never_cache
 def subscription_config(request):
-    if not flag_is_active(request, "subscription"):
+    if not switch_is_active("subscription"):
         return HttpResponseForbidden("subscription is not enabled")
 
     prices = []
@@ -52,7 +52,7 @@ def subscription_checkout(request):
     user = request.user
     if not user.is_authenticated:
         return HttpResponseForbidden("user not authenticated")
-    elif not flag_is_active(request, "subscription"):
+    elif not switch_is_active("subscription"):
         return HttpResponseForbidden("subscription is not enabled")
 
     data = request.POST
@@ -84,7 +84,7 @@ def subscription_customer_portal(request):
     user = request.user
     if not user.is_authenticated:
         return HttpResponseForbidden("user not authenticated")
-    elif not flag_is_active(request, "subscription"):
+    elif not switch_is_active("subscription"):
         return HttpResponseForbidden("subscription is not enabled")
     elif not user.stripe_customer_id:
         return HttpResponseForbidden("no existing stripe_customer_id")
diff --git a/kuma/core/migrations/0018_auto_20210623_1220.py b/kuma/core/migrations/0018_auto_20210623_1220.py
new file mode 100644
--- /dev/null
+++ b/kuma/core/migrations/0018_auto_20210623_1220.py
@@ -0,0 +1,22 @@
+# Generated by Django 2.2.21 on 2021-06-23 12:20
+
+from django.db import migrations
+
+
+def forward(apps, schema_editor):
+    Switch = apps.get_model("waffle", "Switch")
+    Flag = apps.get_model("waffle", "Flag")
+    if not Switch.objects.filter(name="subscription").exists():
+        Switch.objects.create(
+            name="subscription", note="Protecting API endpoints related to subscription"
+        )
+        Flag.objects.filter(name__startswith="subscription").delete()
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("core", "0017_delete_banners"),
+    ]
+
+    operations = [migrations.RunPython(forward)]


Test patch:
diff --git a/kuma/api/v1/tests/test_subscription.py b/kuma/api/v1/tests/test_subscription.py
--- a/kuma/api/v1/tests/test_subscription.py
+++ b/kuma/api/v1/tests/test_subscription.py
@@ -3,7 +3,7 @@
 
 import pytest
 from stripe.error import APIError
-from waffle.testutils import override_flag
+from waffle.testutils import override_switch
 
 from kuma.core.ga_tracking import (
     ACTION_SUBSCRIPTION_CANCELED,
@@ -156,7 +156,7 @@ def mocked_get_price(id):
 
     mock_retrieve.side_effect = mocked_get_price
     url = reverse("api.v1.subscriptions.config")
-    with override_flag("subscription", active=True):
+    with override_switch("subscription", active=True):
         response = client.get(url)
         assert response.status_code == 200
         assert response.json()["public_key"] == settings.STRIPE_PUBLIC_KEY
@@ -186,7 +186,7 @@ def mocked_create_session(customer, return_url):
     assert response.status_code == 403
     assert "subscription is not enabled" in response.content.decode()
 
-    with override_flag("subscription", active=True):
+    with override_switch("subscription", active=True):
         response = user_client.post(url)
         assert response.status_code == 403
         assert "no existing stripe_customer_id" in response.content.decode()
@@ -232,7 +232,7 @@ def mocked_create_customer(email):
     assert response.status_code == 403
     assert "subscription is not enabled" in response.content.decode()
 
-    with override_flag("subscription", active=True):
+    with override_switch("subscription", active=True):
         response = user_client.post(url)
         assert response.status_code == 200
         assert response.json()["sessionId"] == fake_session_id