Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add BE for routing billing status #38153

Merged
merged 18 commits into from
Feb 9, 2024
4 changes: 4 additions & 0 deletions enterprise/backend/src/metabase_enterprise/api/routes.clj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
:as advanced-permissions]
[metabase-enterprise.api.routes.common :as ee.api.common]
[metabase-enterprise.audit-app.api.routes :as audit-app]
[metabase-enterprise.billing.api.routes :as billing]
[metabase-enterprise.content-verification.api.routes
:as content-verification]
[metabase-enterprise.sandbox.api.routes :as sandbox]
Expand All @@ -28,6 +29,9 @@
;; and follow the convention.
(compojure/context
"/ee" []
(compojure/context
"/billing" []
billing/routes)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I add a premium feature here? Unsure because it seems like anyone with a token should access this, but no other route is like this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems fine

(compojure/context
"/audit-app" []
(ee.api.common/+require-premium-feature :audit-app (deferred-tru "Audit app") audit-app/routes))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
(ns metabase-enterprise.billing.api.routes
"API endpoint(s) that are only enabled if ee is enabled. These live under `/api/ee/billing/`. We don't feature flag this
endpoint unlike other ee endpoints."
(:require
[compojure.core :as compojure]
[metabase-enterprise.billing.billing :as billing]
[metabase.api.routes.common :refer [+auth]]))

(compojure/defroutes ^{:doc "Ring routes for billing API endpoints."} routes
(compojure/context "/" [] (+auth billing/routes)))
43 changes: 43 additions & 0 deletions enterprise/backend/src/metabase_enterprise/billing/billing.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
(ns metabase-enterprise.billing.billing
"`/api/ee/billing/` endpoint(s)"
(:require
[cheshire.core :as json]
[clj-http.client :as http]
[clojure.core.memoize :as memoize]
[compojure.core :as compojure :refer [GET]]
[metabase.api.common :as api]
[metabase.public-settings.premium-features :as premium-features]
[metabase.util :as u]
[metabase.util.i18n :as i18n]
[toucan2.core :as t2])
(:import
[com.fasterxml.jackson.core JsonParseException]))

(set! *warn-on-reflection* true)

(def ^:private ^String metabase-billing-info-url "https://store-api.metabase.com/api/v2/metabase/billing_info")

(def ^:private ^{:arglists '([token email language])} fetch-billing-status*
(memoize/ttl
^{::memoize/args-fn (fn [[token email language]] [token email language])}
(fn [token email language]
(try (some-> metabase-billing-info-url
(http/get {:basic-auth [email token]
:language language
:content-type :json})
:body
(json/parse-string keyword))
(catch JsonParseException _
{:content nil})))
:ttl/threshold (u/hours->ms 5)))

(api/defendpoint GET "/"
"Get billing information. This acts as a proxy between `metabase-billing-info-url` and the client,
using the embedding token and signed in user's email to fetch the billing information."
[]
(let [token (premium-features/premium-embedding-token)
email (t2/select-one-fn :email :model/User :id api/*current-user-id*)
language (i18n/user-locale-string)]
(fetch-billing-status* token email language)))

(api/define-routes)
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
(ns metabase-enterprise.billing.billing-test
(:require [clj-http.client :as http]
[clojure.test :refer :all]
[metabase.test :as mt]))

(deftest fetch-billing-status-test
(testing "Passes through billing status fetched from server"
(binding [http/request (fn [& _]
{:status 200
:body "{\"version\":\"v1\",\"content\":null}"})]
(is (= {:version "v1"
:content nil}
(mt/user-http-request :rasta :get 200 "/ee/billing"))))))

(deftest fetch-billing-status-error-test
(testing "When receiving a non json result consume the error and return an empty content blob"
(binding [http/request (fn [& _]
{:status 404
:body "error"})]
(is (= {:content nil}
(mt/user-http-request :crowberto :get 200 "/ee/billing"))))))
2 changes: 1 addition & 1 deletion src/metabase/api/routes.clj
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
[metabase.api.pulse :as api.pulse]
[metabase.api.revision :as api.revision]
[metabase.api.routes.common
:refer [+static-apikey +auth +message-only-exceptions +public-exceptions]]
:refer [+auth +message-only-exceptions +public-exceptions +static-apikey]]
[metabase.api.search :as api.search]
[metabase.api.segment :as api.segment]
[metabase.api.session :as api.session]
Expand Down