mirror of
https://github.com/penpot/penpot.git
synced 2026-04-25 11:18:36 +00:00
✨ Add create default team org for nitrate on adding an user to a team
This commit is contained in:
parent
74af101462
commit
1af2521f64
@ -54,10 +54,11 @@
|
||||
(if (>= status 400)
|
||||
;; For error status codes (4xx, 5xx), fail immediately without validation
|
||||
(do
|
||||
(l/error :hint "nitrate request failed with error status"
|
||||
:uri uri
|
||||
:status status
|
||||
:body (:body response))
|
||||
(when (not= status 404) ;; Don't need to log 404
|
||||
(l/error :hint "nitrate request failed with error status"
|
||||
:uri uri
|
||||
:status status
|
||||
:body (:body response)))
|
||||
nil)
|
||||
;; For success status codes, validate the response
|
||||
(let [coercer-http (sm/coercer schema
|
||||
@ -107,6 +108,11 @@
|
||||
[:organization-id ::sm/uuid]
|
||||
[:is-your-penpot :boolean]])
|
||||
|
||||
(def ^:private schema:profile-org
|
||||
[:map
|
||||
[:is-member :boolean]
|
||||
[:organization-id ::sm/uuid]])
|
||||
|
||||
;; TODO Unify with schemas on backend/src/app/http/management.clj
|
||||
(def ^:private schema:timestamp
|
||||
(sm/type-schema
|
||||
@ -179,7 +185,7 @@
|
||||
[:map
|
||||
[:licenses ::sm/boolean]])
|
||||
|
||||
(defn- get-team-org
|
||||
(defn- get-team-org-api
|
||||
[cfg {:keys [team-id] :as params}]
|
||||
(let [baseuri (cf/get :nitrate-backend-uri)]
|
||||
(request-to-nitrate cfg :get
|
||||
@ -188,7 +194,18 @@
|
||||
team-id)
|
||||
schema:organization params)))
|
||||
|
||||
(defn- set-team-org
|
||||
(defn- get-org-membership-by-team-api
|
||||
[cfg {:keys [profile-id team-id] :as params}]
|
||||
(let [baseuri (cf/get :nitrate-backend-uri)]
|
||||
(request-to-nitrate cfg :get
|
||||
(str baseuri
|
||||
"/api/teams/"
|
||||
team-id
|
||||
"/users/"
|
||||
profile-id)
|
||||
schema:profile-org params)))
|
||||
|
||||
(defn- set-team-org-api
|
||||
[cfg {:keys [organization-id team-id is-default] :as params}]
|
||||
(let [baseuri (cf/get :nitrate-backend-uri)
|
||||
params (assoc params :request-params {:team-id team-id
|
||||
@ -200,7 +217,18 @@
|
||||
"/add-team")
|
||||
schema:team params)))
|
||||
|
||||
(defn- get-subscription
|
||||
(defn- add-profile-to-org-api
|
||||
[cfg {:keys [profile-id org-id team-id] :as params}]
|
||||
(let [baseuri (cf/get :nitrate-backend-uri)
|
||||
params (assoc params :request-params {:user-id profile-id :team-id team-id})]
|
||||
(request-to-nitrate cfg :post
|
||||
(str baseuri
|
||||
"/api/organizations/"
|
||||
org-id
|
||||
"/add-user")
|
||||
schema:profile-org params)))
|
||||
|
||||
(defn- get-subscription-api
|
||||
[cfg {:keys [profile-id] :as params}]
|
||||
(let [baseuri (cf/get :nitrate-backend-uri)]
|
||||
(request-to-nitrate cfg :get
|
||||
@ -209,7 +237,7 @@
|
||||
profile-id)
|
||||
schema:subscription params)))
|
||||
|
||||
(defn- get-connectivity
|
||||
(defn- get-connectivity-api
|
||||
[cfg params]
|
||||
(let [baseuri (cf/get :nitrate-backend-uri)]
|
||||
(request-to-nitrate cfg :get
|
||||
@ -224,10 +252,12 @@
|
||||
(defmethod ig/init-key ::client
|
||||
[_ cfg]
|
||||
(when (contains? cf/flags :nitrate)
|
||||
{:get-team-org (partial get-team-org cfg)
|
||||
:set-team-org (partial set-team-org cfg)
|
||||
:get-subscription (partial get-subscription cfg)
|
||||
:connectivity (partial get-connectivity cfg)}))
|
||||
{:get-team-org (partial get-team-org-api cfg)
|
||||
:set-team-org (partial set-team-org-api cfg)
|
||||
:get-org-membership-by-team (partial get-org-membership-by-team-api cfg)
|
||||
:add-profile-to-org (partial add-profile-to-org-api cfg)
|
||||
:get-subscription (partial get-subscription-api cfg)
|
||||
:connectivity (partial get-connectivity-api cfg)}))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; UTILS
|
||||
@ -287,6 +317,9 @@
|
||||
:organization-id (:organization-id params)})))
|
||||
team))
|
||||
|
||||
|
||||
|
||||
(defn connectivity
|
||||
[cfg]
|
||||
(call cfg :connectivity {}))
|
||||
|
||||
|
||||
@ -371,9 +371,11 @@
|
||||
|
||||
|
||||
(defn create-profile-rels
|
||||
[conn {:keys [id] :as profile}]
|
||||
[{:keys [::db/conn] :as cfg} {:keys [id] :as profile}]
|
||||
(assert (db/connection-map? cfg)
|
||||
"expected cfg with valid connection")
|
||||
(let [features (cfeat/get-enabled-features cf/flags)
|
||||
team (teams/create-team conn
|
||||
team (teams/create-team cfg
|
||||
{:profile-id id
|
||||
:name "Default"
|
||||
:features features
|
||||
@ -426,7 +428,7 @@
|
||||
(assoc :is-active is-active)
|
||||
(update :password auth/derive-password))
|
||||
profile (->> (create-profile cfg params)
|
||||
(create-profile-rels conn))]
|
||||
(create-profile-rels cfg))]
|
||||
(vary-meta profile assoc :created true))))
|
||||
|
||||
created? (-> profile meta :created true?)
|
||||
|
||||
@ -49,9 +49,9 @@
|
||||
:deleted-at (ct/in-future (cf/get-deletion-delay))
|
||||
:password (derive-password password)
|
||||
:props {}}
|
||||
profile (db/tx-run! cfg (fn [{:keys [::db/conn] :as cfg}]
|
||||
profile (db/tx-run! cfg (fn [cfg]
|
||||
(->> (auth/create-profile cfg params)
|
||||
(auth/create-profile-rels conn))))]
|
||||
(auth/create-profile-rels cfg))))]
|
||||
(with-meta {:email email
|
||||
:password password}
|
||||
{::audit/profile-id (:id profile)})))
|
||||
|
||||
@ -84,5 +84,5 @@
|
||||
(profile/get-profile-by-email conn))
|
||||
(->> (assoc info :is-active true :is-demo false)
|
||||
(auth/create-profile cfg)
|
||||
(auth/create-profile-rels conn)
|
||||
(auth/create-profile-rels cfg)
|
||||
(profile/strip-private-attrs))))))
|
||||
|
||||
@ -207,8 +207,7 @@
|
||||
(update :team-id bfc/lookup-index)
|
||||
(assoc :created-at timestamp)
|
||||
(assoc :modified-at timestamp))]
|
||||
(db/insert! conn :team-profile-rel params
|
||||
{::db/return-keys false})))
|
||||
(teams/add-profile-to-team! cfg params {::db/return-keys false})))
|
||||
|
||||
;; Duplicate team fonts
|
||||
(doseq [font fonts]
|
||||
|
||||
@ -522,20 +522,78 @@
|
||||
(with-meta team
|
||||
{::audit/props {:id (:id team)}})))
|
||||
|
||||
|
||||
(defn create-default-org-team
|
||||
[cfg profile-id organization-id]
|
||||
(quotes/check! cfg {::quotes/id ::quotes/teams-per-profile
|
||||
::quotes/profile-id profile-id})
|
||||
|
||||
(let [features (-> (cfeat/get-enabled-features cf/flags)
|
||||
(set/difference cfeat/frontend-only-features)
|
||||
(set/difference cfeat/no-team-inheritable-features))
|
||||
params {:profile-id profile-id
|
||||
:name "Default"
|
||||
:features features
|
||||
:organization-id organization-id
|
||||
:is-default true}
|
||||
team (create-team cfg params)]
|
||||
(select-keys team [:id])))
|
||||
|
||||
(defn- initialize-user-in-nitrate-org
|
||||
"If needed, create a default team for the user on the organization,
|
||||
and notify Nitrate that an user has been added to an org."
|
||||
[cfg profile-id team-id]
|
||||
(assert (db/connection-map? cfg)
|
||||
"expected cfg with valid connection")
|
||||
(let [membership (nitrate/call cfg :get-org-membership-by-team {:profile-id profile-id :team-id team-id})]
|
||||
;; Only when the team belong to an organization and the user is not a member
|
||||
(when (and
|
||||
(some? (:organization-id membership)) ;; the team do belong to an organization
|
||||
(not (:is-member membership))) ;; the user is not a member of the org yet
|
||||
|
||||
(db/tx-run!
|
||||
cfg
|
||||
(fn [{:keys [::db/conn] :as tx-cfg}]
|
||||
(let [org-id (:organization-id membership)
|
||||
default-team (create-default-org-team (assoc tx-cfg ::db/conn conn) profile-id org-id)
|
||||
default-team-id (:id default-team)
|
||||
result (nitrate/call tx-cfg :add-profile-to-org {:profile-id profile-id
|
||||
:team-id default-team-id
|
||||
:org-id org-id})]
|
||||
(when (not (:is-member result))
|
||||
(ex/raise :type :internal
|
||||
:code :failed-add-profile-org-nitrate
|
||||
:context {:profile-id profile-id
|
||||
:team-id team-id
|
||||
:org-id org-id
|
||||
:default-team-id default-team-id}))
|
||||
nil))))))
|
||||
|
||||
(defn add-profile-to-team!
|
||||
([cfg params]
|
||||
(add-profile-to-team! cfg params nil))
|
||||
([{:keys [::db/conn] :as cfg} {:keys [:profile-id :team-id] :as params} options]
|
||||
(assert (db/connection-map? cfg)
|
||||
"expected cfg with valid connection")
|
||||
(when (contains? cf/flags :nitrate)
|
||||
(initialize-user-in-nitrate-org cfg profile-id team-id))
|
||||
(db/insert! conn :team-profile-rel params options)))
|
||||
|
||||
(defn create-team
|
||||
"This is a complete team creation process, it creates the team
|
||||
object and all related objects (default role and default project)."
|
||||
[cfg-or-conn params]
|
||||
(let [conn (db/get-connection cfg-or-conn)
|
||||
team (create-team* conn params)
|
||||
[{:keys [::db/conn] :as cfg} params]
|
||||
(assert (db/connection-map? cfg)
|
||||
"expected cfg with valid connection")
|
||||
(let [team (create-team* conn params)
|
||||
params (assoc params
|
||||
:team-id (:id team)
|
||||
:role :owner)
|
||||
project (create-team-default-project conn params)]
|
||||
(create-team-role conn params)
|
||||
(create-team-role cfg params)
|
||||
;; Set team organization in Nitrate if organization-id is provided
|
||||
(when (and (contains? cf/flags :nitrate) (:organization-id params))
|
||||
(nitrate/set-team-organization cfg-or-conn team params))
|
||||
(nitrate/set-team-organization cfg team params))
|
||||
(assoc team :default-project-id (:id project))))
|
||||
|
||||
(defn- create-team*
|
||||
@ -551,11 +609,13 @@
|
||||
(decode-row team)))
|
||||
|
||||
(defn- create-team-role
|
||||
[conn {:keys [profile-id team-id role] :as params}]
|
||||
[cfg {:keys [profile-id team-id role] :as params}]
|
||||
(assert (db/connection-map? cfg)
|
||||
"expected cfg with valid connection")
|
||||
(let [params {:team-id team-id
|
||||
:profile-id profile-id}]
|
||||
(->> (perms/assign-role-flags params role)
|
||||
(db/insert! conn :team-profile-rel))))
|
||||
(add-profile-to-team! cfg))))
|
||||
|
||||
(defn- create-team-default-project
|
||||
[conn {:keys [profile-id team-id] :as params}]
|
||||
|
||||
@ -85,7 +85,8 @@
|
||||
(defn- create-invitation
|
||||
[{:keys [::db/conn] :as cfg} {:keys [team profile role email] :as params}]
|
||||
|
||||
(assert (db/connection? conn) "expected valid connection on cfg parameter")
|
||||
(assert (db/connection-map? cfg)
|
||||
"expected cfg with valid connection")
|
||||
(assert (check-create-invitation-params params))
|
||||
|
||||
(let [email (profile/clean-email email)
|
||||
@ -104,8 +105,7 @@
|
||||
(get types.team/permissions-for-role role))]
|
||||
|
||||
;; Insert the invited member to the team
|
||||
(db/insert! conn :team-profile-rel params
|
||||
{::db/on-conflict-do-nothing? true})
|
||||
(teams/add-profile-to-team! cfg params {::db/on-conflict-do-nothing? true})
|
||||
|
||||
;; If profile is not yet verified, mark it as verified because
|
||||
;; accepting an invitation link serves as verification.
|
||||
@ -166,7 +166,9 @@
|
||||
itoken)))))
|
||||
|
||||
(defn- add-member-to-team
|
||||
[conn profile team role member]
|
||||
[{:keys [::db/conn] :as cfg} profile team role member]
|
||||
(assert (db/connection-map? cfg)
|
||||
"expected cfg with valid connection")
|
||||
|
||||
(let [team-id (:id team)
|
||||
params (merge
|
||||
@ -186,7 +188,7 @@
|
||||
::quotes/team-id team-id})
|
||||
|
||||
;; Insert the member to the team
|
||||
(db/insert! conn :team-profile-rel params {::db/on-conflict-do-nothing? true})
|
||||
(teams/add-profile-to-team! cfg params {::db/on-conflict-do-nothing? true})
|
||||
|
||||
;; Delete any request
|
||||
(db/delete! conn :team-access-request
|
||||
@ -268,7 +270,7 @@
|
||||
(filter #(contains? invitation-emails (key %)))
|
||||
(map (fn [[email member]]
|
||||
(let [role (:role (first (filter #(= (:email %) email) invitation-data)))]
|
||||
(add-member-to-team conn profile team role member))))
|
||||
(add-member-to-team cfg profile team role member))))
|
||||
(doall))
|
||||
|
||||
invitations))
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
[app.main :as-alias main]
|
||||
[app.rpc :as-alias rpc]
|
||||
[app.rpc.commands.profile :as profile]
|
||||
[app.rpc.commands.teams :as teams]
|
||||
[app.rpc.doc :as-alias doc]
|
||||
[app.rpc.helpers :as rph]
|
||||
[app.rpc.quotes :as quotes]
|
||||
@ -104,7 +105,7 @@
|
||||
::quotes/team-id team-id})
|
||||
|
||||
;; Insert the invited member to the team
|
||||
(db/insert! conn :team-profile-rel params {::db/on-conflict-do-nothing? true})
|
||||
(teams/add-profile-to-team! cfg params {::db/on-conflict-do-nothing? true})
|
||||
|
||||
;; If profile is not yet verified, mark it as verified because
|
||||
;; accepting an invitation link serves as verification.
|
||||
|
||||
@ -8,7 +8,6 @@
|
||||
"Internal Nitrate HTTP RPC API. Provides authenticated access to
|
||||
organization management and token validation endpoints."
|
||||
(:require
|
||||
[app.common.features :as cfeat]
|
||||
[app.common.schema :as sm]
|
||||
[app.common.types.profile :refer [schema:profile, schema:basic-profile]]
|
||||
[app.common.types.team :refer [schema:team]]
|
||||
@ -21,9 +20,7 @@
|
||||
[app.rpc.commands.profile :as profile]
|
||||
[app.rpc.commands.teams :as teams]
|
||||
[app.rpc.doc :as doc]
|
||||
[app.rpc.quotes :as quotes]
|
||||
[app.util.services :as sv]
|
||||
[clojure.set :as set]
|
||||
[cuerdas.core :as str]))
|
||||
|
||||
;; ---- API: authenticate
|
||||
@ -116,25 +113,15 @@
|
||||
[:organization-id ::sm/uuid]
|
||||
[:role ::sm/text]])
|
||||
|
||||
|
||||
|
||||
(sv/defmethod ::notify-user-added-to-organization
|
||||
"Notify to Penpot that an user has joined an org from nitrate"
|
||||
{::doc/added "2.14"
|
||||
::sm/params schema:notify-user-added-to-organization
|
||||
::rpc/auth false}
|
||||
[cfg {:keys [profile-id organization-id]}]
|
||||
(quotes/check! cfg {::quotes/id ::quotes/teams-per-profile
|
||||
::quotes/profile-id profile-id})
|
||||
|
||||
(let [features (-> (cfeat/get-enabled-features cf/flags)
|
||||
(set/difference cfeat/frontend-only-features)
|
||||
(set/difference cfeat/no-team-inheritable-features))
|
||||
params {:profile-id profile-id
|
||||
:name "Default"
|
||||
:features features
|
||||
:organization-id organization-id
|
||||
:is-default true}
|
||||
team (db/tx-run! cfg teams/create-team params)]
|
||||
(select-keys team [:id])))
|
||||
(db/tx-run! cfg teams/create-default-org-team profile-id organization-id))
|
||||
|
||||
|
||||
;; ---- API: get-managed-profiles
|
||||
|
||||
@ -53,7 +53,7 @@
|
||||
:or {is-active true}}]
|
||||
(some-> (get-current-system)
|
||||
(db/tx-run!
|
||||
(fn [{:keys [::db/conn] :as system}]
|
||||
(fn [system]
|
||||
(let [password (derive-password password)
|
||||
params {:id (uuid/next)
|
||||
:email email
|
||||
@ -62,7 +62,7 @@
|
||||
:password password
|
||||
:props {}}]
|
||||
(->> (cmd.auth/create-profile system params)
|
||||
(cmd.auth/create-profile-rels conn)))))))
|
||||
(cmd.auth/create-profile-rels system)))))))
|
||||
|
||||
(defmethod exec-command "update-profile"
|
||||
[{:keys [fullname email password is-active]}]
|
||||
|
||||
@ -905,5 +905,4 @@
|
||||
(let [params (-> rel
|
||||
(assoc :id (uuid/next))
|
||||
(assoc :team-id (:id team)))]
|
||||
(db/insert! conn :team-profile-rel params
|
||||
{::db/return-keys false}))))))))
|
||||
(teams/add-profile-to-team! cfg params {::db/return-keys false}))))))))
|
||||
|
||||
@ -186,10 +186,10 @@
|
||||
:is-demo false}
|
||||
params)]
|
||||
(db/run! system
|
||||
(fn [{:keys [::db/conn] :as cfg}]
|
||||
(fn [cfg]
|
||||
(->> params
|
||||
(cmd.auth/create-profile cfg)
|
||||
(cmd.auth/create-profile-rels conn)))))))
|
||||
(cmd.auth/create-profile-rels cfg)))))))
|
||||
|
||||
(defn create-project*
|
||||
([i params] (create-project* *system* i params))
|
||||
@ -234,10 +234,10 @@
|
||||
(dm/with-open [conn (db/open system)]
|
||||
(let [id (mk-uuid "team" i)
|
||||
features (cfeat/get-enabled-features cf/flags)]
|
||||
(teams/create-team conn {:id id
|
||||
:profile-id profile-id
|
||||
:features features
|
||||
:name (str "team" i)})))))
|
||||
(teams/create-team {::db/conn conn} {:id id
|
||||
:profile-id profile-id
|
||||
:features features
|
||||
:name (str "team" i)})))))
|
||||
|
||||
(defn create-file-media-object*
|
||||
([params] (create-file-media-object* *system* params))
|
||||
@ -283,9 +283,10 @@
|
||||
([params] (create-team-role* *system* params))
|
||||
([system {:keys [team-id profile-id role] :or {role :owner}}]
|
||||
(dm/with-open [conn (db/open system)]
|
||||
(#'teams/create-team-role conn {:team-id team-id
|
||||
:profile-id profile-id
|
||||
:role role}))))
|
||||
(#'teams/create-team-role {::db/conn conn}
|
||||
{:team-id team-id
|
||||
:profile-id profile-id
|
||||
:role role}))))
|
||||
|
||||
(defn create-project-role*
|
||||
([params] (create-project-role* *system* params))
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user