(ns metabase.setup.core (:require [environ.core :as env] [metabase.config :as config] [metabase.db :as mdb] [metabase.models.setting :as setting :refer [defsetting]] [metabase.util.i18n :refer [deferred-tru tru]] [toucan2.core :as t2])) | |
(set! *warn-on-reflection* true) | |
A token used to signify that an instance has permissions to create the initial User. This is created upon the first launch of Metabase, by the first instance; once used, it is cleared out, never to be used again. | (defsetting setup-token :visibility :public :setter :none :audit :never) |
Function for checking if the supplied string matches our setup token.
Returns boolean | (defn token-match?
[token]
{:pre [(string? token)]}
(= token (setup-token))) |
Create and set a new setup token, if one has not already been created. Returns the newly created token. | (defn create-token!
[]
;; fetch the value directly from the DB; *do not* rely on cached value, in case a different instance came along and
;; already created it
;;
;; TODO -- 95% sure we can just use [[setup-token]] directly now and not worry about manually fetching the env var
;; value or setting DB values and the like
(or (when-let [mb-setup-token (env/env :mb-setup-token)]
(setting/set-value-of-type! :string :setup-token mb-setup-token))
(t2/select-one-fn :value :model/Setting :key "setup-token")
(setting/set-value-of-type! :string :setup-token (str (random-uuid))))) |
(defsetting has-user-setup
(deferred-tru "A value that is true iff the metabase instance has one or more users registered.")
:visibility :public
:type :boolean
:setter (fn [value]
(if (or config/is-dev? config/is-test?)
(setting/set-value-of-type! :boolean :has-user-setup value)
(throw (ex-info (tru "Cannot set `has-user-setup`.")
{:value value}))))
;; Once a User is created it's impossible for this to ever become falsey -- deleting the last User is disallowed.
;; After this returns true once the result is cached and it will continue to return true forever without any
;; additional DB hits.
;;
;; This is keyed by the unique identifier for the application database, to support resetting it in tests or swapping
;; it out in the REPL
:getter (let [app-db-id->user-exists? (atom {})]
(fn []
(let [possible-override (when (or config/is-dev? config/is-test?)
;; allow for overriding in dev and test
(setting/get-value-of-type :boolean :has-user-setup))]
;; override could be false so have to check non-nil
(if (some? possible-override)
possible-override
(or (get @app-db-id->user-exists? (mdb/unique-identifier))
(let [exists? (boolean (seq (t2/select :model/User {:where [:not= :id config/internal-mb-user-id]})))]
(swap! app-db-id->user-exists? assoc (mdb/unique-identifier) exists?)
exists?))))))
:doc false
:audit :never) | |