Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
users.clj 2.58 KiB
(ns metabase-enterprise.config-from-file.users
  (:require
   [clojure.spec.alpha :as s]
   [clojure.tools.logging :as log]
   [metabase-enterprise.config-from-file.interface :as config-from-file.i]
   [metabase.models.user :refer [User]]
   [metabase.util :as u]
   [metabase.util.i18n :as i18n :refer [trs]]
   [toucan.db :as db]))

(s/def :metabase-enterprise.config-from-file.users.config-file-spec/first_name
  string?)

(s/def :metabase-enterprise.config-from-file.users.config-file-spec/last_name
  string?)

(s/def :metabase-enterprise.config-from-file.users.config-file-spec/password
  string?)

(s/def :metabase-enterprise.config-from-file.users.config-file-spec/email
  string?)

(s/def ::config-file-spec
  (s/keys :req-un [:metabase-enterprise.config-from-file.users.config-file-spec/first_name
                   :metabase-enterprise.config-from-file.users.config-file-spec/last_name
                   :metabase-enterprise.config-from-file.users.config-file-spec/password
                   :metabase-enterprise.config-from-file.users.config-file-spec/email]))

(defmethod config-from-file.i/section-spec :users
  [_section]
  (s/spec (s/* ::config-file-spec)))

(defn- init-from-config-file-is-first-user?
  "For [[init-from-config-file!]]: `true` if this the first User being created for this instance. If so, we will ALWAYS
  create that User as a superuser, regardless of what is specified in the config file. (It doesn't make sense to
  create the first User as anything other than a superuser)."
  []
  (zero? (db/count User)))

(defn- init-from-config-file!
  [user]
  ;; TODO -- if this is the FIRST user, we should probably make them a superuser, right?
  (if-let [existing-user-id (db/select-one-id User :email (:email user))]
    (do
      (log/info (u/colorize :blue (trs "Updating User with email {0}" (pr-str (:email user)))))
      (db/update! User existing-user-id user))
    ;; create a new user. If they are the first User, force them to be an admin.
    (let [user (cond-> user
                 (init-from-config-file-is-first-user?) (assoc :is_superuser true))]
      (log/info (u/colorize :green (trs "Creating the first User for this instance. The first user is always created as an admin.")))
      (log/info (u/colorize :green (trs "Creating new User {0} with email {1}"
                                        (pr-str (str (:first_name user) \space (:last_name user)))
                                        (pr-str (:email user)))))
      (db/insert! User user))))

(defmethod config-from-file.i/initialize-section! :users
  [_section-name users]
  (doseq [user users]
    (init-from-config-file! user)))