From b1594c631ed49a64a06b95929e5e270ca5d9b7a7 Mon Sep 17 00:00:00 2001
From: Uku Taht <uku.taht@gmail.com>
Date: Thu, 21 Oct 2021 11:01:02 +0200
Subject: [PATCH] Adjust API key limits for enterprise plans

---
 lib/plausible/billing/billing.ex        | 26 ++++++++++-
 test/plausible/billing/billing_test.exs | 58 +++++++++++++++++++++++++
 2 files changed, 82 insertions(+), 2 deletions(-)

diff --git a/lib/plausible/billing/billing.ex b/lib/plausible/billing/billing.ex
index e754b5ad..f61919d2 100644
--- a/lib/plausible/billing/billing.ex
+++ b/lib/plausible/billing/billing.ex
@@ -18,14 +18,18 @@ defmodule Plausible.Billing do
 
     changeset = Subscription.changeset(%Subscription{}, format_subscription(params))
 
-    Repo.insert(changeset) |> check_lock_status
+    Repo.insert(changeset)
+    |> check_lock_status
+    |> maybe_adjust_api_key_limits
   end
 
   def subscription_updated(params) do
     subscription = Repo.get_by!(Subscription, paddle_subscription_id: params["subscription_id"])
     changeset = Subscription.changeset(subscription, format_subscription(params))
 
-    Repo.update(changeset) |> check_lock_status
+    Repo.update(changeset)
+    |> check_lock_status
+    |> maybe_adjust_api_key_limits
   end
 
   def subscription_cancelled(params) do
@@ -236,5 +240,23 @@ defmodule Plausible.Billing do
 
   defp check_lock_status(err), do: err
 
+  defp maybe_adjust_api_key_limits({:ok, subscription}) do
+    plan =
+      Repo.get_by(Plausible.Billing.EnterprisePlan,
+        user_id: subscription.user_id,
+        paddle_plan_id: subscription.paddle_plan_id
+      )
+
+    if plan do
+      user_id = subscription.user_id
+      api_keys = from(key in Plausible.Auth.ApiKey, where: key.user_id == ^user_id)
+      Repo.update_all(api_keys, set: [hourly_request_limit: plan.hourly_api_request_limit])
+    end
+
+    {:ok, subscription}
+  end
+
+  defp maybe_adjust_api_key_limits(err), do: err
+
   defp paddle_api(), do: Application.fetch_env!(:plausible, :paddle_api)
 end
diff --git a/test/plausible/billing/billing_test.exs b/test/plausible/billing/billing_test.exs
index 86d9e084..b079c0b7 100644
--- a/test/plausible/billing/billing_test.exs
+++ b/test/plausible/billing/billing_test.exs
@@ -286,6 +286,34 @@ defmodule Plausible.BillingTest do
 
       refute Repo.reload!(site).locked
     end
+
+    test "if user upgraded to an enterprise plan, their API key limits are automatically adjusted" do
+      user = insert(:user)
+
+      plan =
+        insert(:enterprise_plan,
+          user: user,
+          paddle_plan_id: @plan_id,
+          hourly_api_request_limit: 10_000
+        )
+
+      api_key = insert(:api_key, user: user, hourly_request_limit: 1)
+
+      Billing.subscription_created(%{
+        "alert_name" => "subscription_created",
+        "subscription_id" => @subscription_id,
+        "subscription_plan_id" => @plan_id,
+        "update_url" => "update_url.com",
+        "cancel_url" => "cancel_url.com",
+        "passthrough" => user.id,
+        "status" => "active",
+        "next_bill_date" => "2019-06-01",
+        "unit_price" => "6.00",
+        "currency" => "EUR"
+      })
+
+      assert Repo.reload!(api_key).hourly_request_limit == plan.hourly_api_request_limit
+    end
   end
 
   describe "subscription_updated" do
@@ -332,6 +360,36 @@ defmodule Plausible.BillingTest do
 
       refute Repo.reload!(site).locked
     end
+
+    test "if user upgraded to an enterprise plan, their API key limits are automatically adjusted" do
+      user = insert(:user)
+      subscription = insert(:subscription, user: user)
+
+      plan =
+        insert(:enterprise_plan,
+          user: user,
+          paddle_plan_id: "new-plan-id",
+          hourly_api_request_limit: 10_000
+        )
+
+      api_key = insert(:api_key, user: user, hourly_request_limit: 1)
+
+      Billing.subscription_updated(%{
+        "alert_name" => "subscription_updated",
+        "subscription_id" => subscription.paddle_subscription_id,
+        "subscription_plan_id" => "new-plan-id",
+        "update_url" => "update_url.com",
+        "cancel_url" => "cancel_url.com",
+        "passthrough" => user.id,
+        "old_status" => "past_due",
+        "status" => "active",
+        "next_bill_date" => "2019-06-01",
+        "new_unit_price" => "12.00",
+        "currency" => "EUR"
+      })
+
+      assert Repo.reload!(api_key).hourly_request_limit == plan.hourly_api_request_limit
+    end
   end
 
   describe "subscription_cancelled" do
-- 
GitLab