diff --git a/backend/resources/app/templates/debug.tmpl b/backend/resources/app/templates/debug.tmpl index 4432de6f6..a630e8fbd 100644 --- a/backend/resources/app/templates/debug.tmpl +++ b/backend/resources/app/templates/debug.tmpl @@ -151,6 +151,78 @@ Debug Main Page +
+ +
+ + + + +
+

Feature Flags

+
+ Enable + Add a feature flag to a team +
+
+ +
+
+ +
+ +
+ + +
+ + Do not check if the feature is supported + +
+ +
+ + +
+ + This is a just a security double check for prevent non intentional submits. + +
+ +
+ +
+
+
+
+ Disable + Remove a feature flag from a team +
+
+ +
+
+ +
+ +
+ + +
+ + Do not check if the feature is supported + +
+ +
+ + +
+ + This is a just a security double check for prevent non intentional submits. + +
+
diff --git a/backend/src/app/http/debug.clj b/backend/src/app/http/debug.clj index 5c6f5cce1..3afa932fd 100644 --- a/backend/src/app/http/debug.clj +++ b/backend/src/app/http/debug.clj @@ -430,6 +430,50 @@ ::yres/body "OK"})) +(defn- add-team-feature + [{:keys [params] :as request}] + (let [team-id (some-> params :team-id d/parse-uuid) + feature (some-> params :feature str) + skip-check (contains? params :skip-check)] + + (when-not (contains? params :force) + (ex/raise :type :validation + :code :missing-force + :hint "missing force checkbox")) + + (when (nil? team-id) + (ex/raise :type :validation + :code :invalid-team-id + :hint "provided invalid team id")) + + (srepl/enable-team-feature! team-id feature :skip-check skip-check) + + {::yres/status 200 + ::yres/headers {"content-type" "text/plain"} + ::yres/body "OK"})) + +(defn- remove-team-feature + [{:keys [params] :as request}] + (let [team-id (some-> params :team-id d/parse-uuid) + feature (some-> params :feature str) + skip-check (contains? params :skip-check)] + + (when-not (contains? params :force) + (ex/raise :type :validation + :code :missing-force + :hint "missing force checkbox")) + + (when (nil? team-id) + (ex/raise :type :validation + :code :invalid-team-id + :hint "provided invalid team id")) + + (srepl/disable-team-feature! team-id feature :skip-check skip-check) + + {::yres/status 200 + ::yres/headers {"content-type" "text/plain"} + ::yres/body "OK"})) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; OTHER SMALL VIEWS/HANDLERS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -500,6 +544,10 @@ {:handler (partial resend-email-notification cfg)}] ["/actions/reset-file-version" {:handler (partial reset-file-version cfg)}] + ["/actions/add-team-feature" + {:handler (partial add-team-feature)}] + ["/actions/remove-team-feature" + {:handler (partial remove-team-feature)}] ["/file/export" {:handler (partial export-handler cfg)}] ["/file/import" {:handler (partial import-handler cfg)}] ["/file/data" {:handler (partial file-data-handler cfg)}] diff --git a/backend/src/app/srepl/helpers.clj b/backend/src/app/srepl/helpers.clj index d8293253e..31e6ca765 100644 --- a/backend/src/app/srepl/helpers.clj +++ b/backend/src/app/srepl/helpers.clj @@ -10,12 +10,15 @@ (:require [app.binfile.common :as bfc] [app.common.data :as d] + [app.common.exceptions :as ex] + [app.common.features :as cfeat] [app.common.files.validate :as cfv] [app.db :as db] [app.features.components-v2 :as feat.comp-v2] [app.main :as main] [app.rpc.commands.files :as files] [app.rpc.commands.files-snapshot :as fsnap] + [app.srepl.helpers :as h] [app.util.time :as dt])) (def ^:dynamic *system* nil) @@ -85,6 +88,44 @@ WHERE file_id = ANY(?) AND id IS NOT NULL") +(defn enable-team-feature! + [team-id feature & {:keys [skip-check] :or {skip-check false}}] + (when (and (not skip-check) (not (contains? cfeat/supported-features feature))) + (ex/raise :type :assertion + :code :feature-not-supported + :hint (str "feature '" feature "' not supported"))) + + (let [team-id (h/parse-uuid team-id)] + (db/tx-run! main/system + (fn [{:keys [::db/conn]}] + (let [team (-> (db/get conn :team {:id team-id}) + (update :features db/decode-pgarray #{})) + features (conj (:features team) feature)] + (when (not= features (:features team)) + (db/update! conn :team + {:features (db/create-array conn "text" features)} + {:id team-id}) + :enabled)))))) + +(defn disable-team-feature! + [team-id feature & {:keys [skip-check] :or {skip-check false}}] + (when (and (not skip-check) (not (contains? cfeat/supported-features feature))) + (ex/raise :type :assertion + :code :feature-not-supported + :hint (str "feature '" feature "' not supported"))) + + (let [team-id (h/parse-uuid team-id)] + (db/tx-run! main/system + (fn [{:keys [::db/conn]}] + (let [team (-> (db/get conn :team {:id team-id}) + (update :features db/decode-pgarray #{})) + features (disj (:features team) feature)] + (when (not= features (:features team)) + (db/update! conn :team + {:features (db/create-array conn "text" features)} + {:id team-id}) + :disabled)))))) + (defn search-file-snapshots "Get a seq parirs of file-id and snapshot-id for a set of files and specified label" diff --git a/backend/src/app/srepl/main.clj b/backend/src/app/srepl/main.clj index 9a69b52fd..db818c457 100644 --- a/backend/src/app/srepl/main.clj +++ b/backend/src/app/srepl/main.clj @@ -161,44 +161,6 @@ (enable-objects-map-feature-on-file! file-id opts) (enable-pointer-map-feature-on-file! file-id opts)) -(defn enable-team-feature! - [team-id feature] - (when-not (contains? cfeat/supported-features feature) - (ex/raise :type :assertion - :code :feature-not-supported - :hint (str "feature '" feature "' not supported"))) - - (let [team-id (h/parse-uuid team-id)] - (db/tx-run! main/system - (fn [{:keys [::db/conn]}] - (let [team (-> (db/get conn :team {:id team-id}) - (update :features db/decode-pgarray #{})) - features (conj (:features team) feature)] - (when (not= features (:features team)) - (db/update! conn :team - {:features (db/create-array conn "text" features)} - {:id team-id}) - :enabled)))))) - -(defn disable-team-feature! - [team-id feature] - - (when-not (contains? cfeat/supported-features feature) - (ex/raise :type :assertion - :code :feature-not-supported - :hint (str "feature '" feature "' not supported"))) - - (let [team-id (h/parse-uuid team-id)] - (db/tx-run! main/system - (fn [{:keys [::db/conn]}] - (let [team (-> (db/get conn :team {:id team-id}) - (update :features db/decode-pgarray #{})) - features (disj (:features team) feature)] - (when (not= features (:features team)) - (db/update! conn :team - {:features (db/create-array conn "text" features)} - {:id team-id}) - :disabled)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; NOTIFICATIONS