;; This Source Code Form is subject to the terms of the Mozilla Public ;; License, v. 2.0. If a copy of the MPL was not distributed with this ;; file, You can obtain one at http://mozilla.org/MPL/2.0/. ;; ;; Copyright (c) UXBOX Labs SL (ns app.setup "Initial data setup of instance." (:require [app.common.logging :as l] [app.common.uuid :as uuid] [app.db :as db] [buddy.core.codecs :as bc] [buddy.core.nonce :as bn] [clojure.spec.alpha :as s] [integrant.core :as ig])) (defn- generate-random-key [] (-> (bn/random-bytes 64) (bc/bytes->b64u) (bc/bytes->str))) (defn- retrieve-all [conn] (->> (db/query conn :server-prop {:preload true}) (filter #(not= "secret-key" (:id %))) (map (fn [row] [(keyword (:id row)) (db/decode-transit-pgobject (:content row))])) (into {}))) (defn- handle-instance-id [instance-id conn read-only?] (or instance-id (let [instance-id (uuid/random)] (when-not read-only? (try (db/insert! conn :server-prop {:id "instance-id" :preload true :content (db/tjson instance-id)}) (catch Throwable cause (l/warn :hint "unable to persist instance-id" :instance-id instance-id :cause cause)))) instance-id))) (defmethod ig/pre-init-spec ::props [_] (s/keys :req-un [::db/pool])) (defmethod ig/init-key ::props [_ {:keys [pool key] :as cfg}] (db/with-atomic [conn pool] (db/xact-lock! conn 0) (when-not key (l/warn :hint (str "using autogenerated secret-key, it will change on each restart and will invalidate " "all sessions on each restart, it is hightly recommeded setting up the " "PENPOT_SECRET_KEY environment variable"))) (let [stored (-> (retrieve-all conn) (assoc :secret-key (or key (generate-random-key))))] (update stored :instance-id handle-instance-id conn (db/read-only? pool)))))