0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-24 23:49:45 -05:00

🎉 Add specific profile registration and activation metrics.

This commit is contained in:
Andrey Antukh 2021-02-22 12:52:27 +01:00 committed by Andrés Moya
parent 5ce450f578
commit 19f098359b
3 changed files with 84 additions and 49 deletions

View file

@ -37,11 +37,19 @@
:max-pool-size 20}
:app.metrics/metrics
{}
{:definitions
{:profile-register
{:name "actions_profile_register_count"
:help "A global counter of user registrations."
:type :counter}
:profile-activation
{:name "actions_profile_activation_count"
:help "A global counter of profile activations"
:type :counter}}}
:app.migrations/all
{:main (ig/ref :app.migrations/migrations)
:telemetry (ig/ref :app.telemetry/migrations)}
{:main (ig/ref :app.migrations/migrations)
:telemetry (ig/ref :app.telemetry/migrations)}
:app.migrations/migrations
{}

View file

@ -26,7 +26,6 @@
[app.util.time :as dt]
[buddy.hashers :as hashers]
[clojure.spec.alpha :as s]
[clojure.tools.logging :as log]
[cuerdas.core :as str]))
;; --- Helpers & Specs
@ -42,10 +41,12 @@
;; --- Mutation: Register Profile
(declare annotate-profile-register)
(declare check-profile-existence!)
(declare create-profile)
(declare create-profile-relations)
(declare email-domain-in-whitelist?)
(declare register-profile)
(s/def ::invitation-token ::us/not-empty-string)
(s/def ::register-profile
@ -63,48 +64,64 @@
:code :email-domain-is-not-allowed))
(db/with-atomic [conn pool]
(check-profile-existence! conn params)
(let [profile (->> (create-profile conn params)
(create-profile-relations conn))]
(create-profile-initial-data conn profile)
(let [cfg (assoc cfg :conn conn)]
(register-profile cfg params))))
(if-let [token (:invitation-token params)]
;; If invitation token comes in params, this is because the
;; user comes from team-invitation process; in this case,
;; regenerate token and send back to the user a new invitation
;; token (and mark current session as logged).
(let [claims (tokens :verify {:token token :iss :team-invitation})
claims (assoc claims
:member-id (:id profile)
:member-email (:email profile))
token (tokens :generate claims)]
(with-meta
{:invitation-token token}
{:transform-response ((:create session) (:id profile))}))
(defn- annotate-profile-register
"A helper for properly increase the profile-register metric once the
transaction is completed."
[metrics profile]
(fn []
(when (::created profile)
((get-in metrics [:definitions :profile-register]) :inc))))
;; If no token is provided, send a verification email
(let [vtoken (tokens :generate
{:iss :verify-email
:exp (dt/in-future "48h")
:profile-id (:id profile)
:email (:email profile)})
ptoken (tokens :generate-predefined
{:iss :profile-identity
:profile-id (:id profile)})]
(defn- register-profile
[{:keys [conn tokens session metrics] :as cfg} params]
(check-profile-existence! conn params)
(let [profile (->> (create-profile conn params)
(create-profile-relations conn))
profile (assoc profile ::created true)]
(create-profile-initial-data conn profile)
;; Don't allow proceed in register page if the email is
;; already reported as permanent bounced
(when (emails/has-bounce-reports? conn (:email profile))
(ex/raise :type :validation
:code :email-has-permanent-bounces
:hint "looks like the email has one or many bounces reported"))
(if-let [token (:invitation-token params)]
;; If invitation token comes in params, this is because the
;; user comes from team-invitation process; in this case,
;; regenerate token and send back to the user a new invitation
;; token (and mark current session as logged).
(let [claims (tokens :verify {:token token :iss :team-invitation})
claims (assoc claims
:member-id (:id profile)
:member-email (:email profile))
token (tokens :generate claims)
resp {:invitation-token token}]
(with-meta resp
{:transform-response ((:create session) (:id profile))
:before-complete (annotate-profile-register metrics profile)}))
(emails/send! conn emails/register
{:to (:email profile)
:name (:fullname profile)
:token vtoken
:extra-data ptoken})
profile)))))
;; If no token is provided, send a verification email
(let [vtoken (tokens :generate
{:iss :verify-email
:exp (dt/in-future "48h")
:profile-id (:id profile)
:email (:email profile)})
ptoken (tokens :generate-predefined
{:iss :profile-identity
:profile-id (:id profile)})]
;; Don't allow proceed in register page if the email is
;; already reported as permanent bounced
(when (emails/has-bounce-reports? conn (:email profile))
(ex/raise :type :validation
:code :email-has-permanent-bounces
:hint "looks like the email has one or many bounces reported"))
(emails/send! conn emails/register
{:to (:email profile)
:name (:fullname profile)
:token vtoken
:extra-data ptoken})
(with-meta profile
{:before-complete (annotate-profile-register metrics profile)})))))
(defn email-domain-in-whitelist?
"Returns true if email's domain is in the given whitelist or if given
@ -142,7 +159,7 @@
[attempt password]
(try
(hashers/verify attempt password)
(catch Exception e
(catch Exception _e
{:update false
:valid false})))
@ -268,10 +285,12 @@
(s/keys :req-un [::email ::fullname ::backend]))
(sv/defmethod ::login-or-register {:auth false}
[{:keys [pool] :as cfg} params]
[{:keys [pool metrics] :as cfg} params]
(db/with-atomic [conn pool]
(-> (assoc cfg :conn conn)
(login-or-register params))))
(let [profile (-> (assoc cfg :conn conn)
(login-or-register params))]
(with-meta profile
{:before-complete (annotate-profile-register metrics profile)}))))
(defn login-or-register
[{:keys [conn] :as cfg} {:keys [email backend] :as params}]
@ -293,7 +312,7 @@
(let [profile (->> (create-profile conn params)
(create-profile-relations conn))]
(create-profile-initial-data conn profile)
profile))]
(assoc profile ::created true)))]
(let [profile (profile/retrieve-profile-data-by-email conn email)
profile (if profile

View file

@ -40,8 +40,15 @@
{:id profile-id})
claims)
(defn- annotate-profile-activation
"A helper for properly increase the profile-activation metric once the
transaction is completed."
[metrics]
(fn []
((get-in metrics [:definitions :profile-activation]) :inc)))
(defmethod process-token :verify-email
[{:keys [conn session] :as cfg} _params {:keys [profile-id] :as claims}]
[{:keys [conn session metrics] :as cfg} _ {:keys [profile-id] :as claims}]
(let [profile (profile/retrieve-profile conn profile-id)
claims (assoc claims :profile profile)]
@ -56,7 +63,8 @@
{:id (:id profile)}))
(with-meta claims
{:transform-response ((:create session) profile-id)})))
{:transform-response ((:create session) profile-id)
:before-complete (annotate-profile-activation metrics)})))
(defmethod process-token :auth
[{:keys [conn] :as cfg} _params {:keys [profile-id] :as claims}]