Add stronger validationt to auth/register rpc methods

This commit is contained in:
Andrey Antukh 2023-07-04 13:36:14 +02:00
parent 068d2f13f4
commit be652b909e
5 changed files with 61 additions and 41 deletions

View file

@ -8,9 +8,10 @@
(:require (:require
[app.auth :as auth] [app.auth :as auth]
[app.common.data :as d] [app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.exceptions :as ex] [app.common.exceptions :as ex]
[app.common.logging :as l] [app.common.logging :as l]
[app.common.spec :as us] [app.common.schema :as sm]
[app.common.uuid :as uuid] [app.common.uuid :as uuid]
[app.config :as cf] [app.config :as cf]
[app.db :as db] [app.db :as db]
@ -26,18 +27,13 @@
[app.tokens :as tokens] [app.tokens :as tokens]
[app.util.services :as sv] [app.util.services :as sv]
[app.util.time :as dt] [app.util.time :as dt]
[clojure.spec.alpha :as s]
[cuerdas.core :as str])) [cuerdas.core :as str]))
(s/def ::email ::us/email) (def schema:password
(s/def ::fullname ::us/not-empty-string) [::sm/word-string {:max 500}])
(s/def ::lang ::us/string)
(s/def ::path ::us/string) (def schema:token
(s/def ::password ::us/not-empty-string) [::sm/word-string {:max 1000}])
(s/def ::old-password ::us/not-empty-string)
(s/def ::theme ::us/string)
(s/def ::invitation-token ::us/not-empty-string)
(s/def ::token ::us/not-empty-string)
;; ---- COMMAND: login with password ;; ---- COMMAND: login with password
@ -101,22 +97,22 @@
(rph/with-meta {::audit/props (audit/profile->props profile) (rph/with-meta {::audit/props (audit/profile->props profile)
::audit/profile-id (:id profile)})))))) ::audit/profile-id (:id profile)}))))))
(s/def ::login-with-password (def schema:login-with-password
(s/keys :req-un [::email ::password] [:map {:title "login-with-password"}
:opt-un [::invitation-token])) [:email ::sm/email]
[:password schema:password]
[:invitation-token {:optional true} schema:token]])
(sv/defmethod ::login-with-password (sv/defmethod ::login-with-password
"Performs authentication using penpot password." "Performs authentication using penpot password."
{::rpc/auth false {::rpc/auth false
::doc/added "1.15"} ::doc/added "1.15"
::sm/params schema:login-with-password}
[cfg params] [cfg params]
(login-with-password cfg params)) (login-with-password cfg params))
;; ---- COMMAND: Logout ;; ---- COMMAND: Logout
(s/def ::logout
(s/keys :opt [::rpc/profile-id]))
(sv/defmethod ::logout (sv/defmethod ::logout
"Clears the authentication cookie and logout the current session." "Clears the authentication cookie and logout the current session."
{::rpc/auth false {::rpc/auth false
@ -141,13 +137,15 @@
(update-password conn)) (update-password conn))
nil))) nil)))
(s/def ::token ::us/not-empty-string) (def schema:recover-profile
(s/def ::recover-profile [:map {:title "recover-profile"}
(s/keys :req-un [::token ::password])) [:token schema:token]
[:password schema:password]])
(sv/defmethod ::recover-profile (sv/defmethod ::recover-profile
{::rpc/auth false {::rpc/auth false
::doc/added "1.15"} ::doc/added "1.15"
::sm/params schema:recover-profile}
[cfg params] [cfg params]
(recover-profile cfg params)) (recover-profile cfg params))
@ -228,13 +226,16 @@
(with-meta {:token token} (with-meta {:token token}
{::audit/profile-id uuid/zero}))) {::audit/profile-id uuid/zero})))
(s/def ::prepare-register-profile (def schema:prepare-register-profile
(s/keys :req-un [::email ::password] [:map {:title "prepare-register-profile"}
:opt-un [::invitation-token])) [:email ::sm/email]
[:password schema:password]
[:invitation-token {:optional true} schema:token]])
(sv/defmethod ::prepare-register-profile (sv/defmethod ::prepare-register-profile
{::rpc/auth false {::rpc/auth false
::doc/added "1.15"} ::doc/added "1.15"
::sm/params schema:prepare-register-profile}
[cfg params] [cfg params]
(prepare-register cfg params)) (prepare-register cfg params))
@ -244,7 +245,7 @@
"Create the profile entry on the database with limited set of input "Create the profile entry on the database with limited set of input
attrs (all the other attrs are filled with default values)." attrs (all the other attrs are filled with default values)."
[conn {:keys [email] :as params}] [conn {:keys [email] :as params}]
(us/assert! ::us/email email) (dm/assert! ::sm/email email)
(let [id (or (:id params) (uuid/next)) (let [id (or (:id params) (uuid/next))
props (-> (audit/extract-utm-params params) props (-> (audit/extract-utm-params params)
(merge (:props params)) (merge (:props params))
@ -391,12 +392,16 @@
{::audit/replace-props (audit/profile->props profile) {::audit/replace-props (audit/profile->props profile)
::audit/profile-id (:id profile)}))))) ::audit/profile-id (:id profile)})))))
(s/def ::register-profile
(s/keys :req-un [::token ::fullname])) (def schema:register-profile
[:map {:title "register-profile"}
[:token schema:token]
[:fullname [::sm/word-string {:max 100}]]])
(sv/defmethod ::register-profile (sv/defmethod ::register-profile
{::rpc/auth false {::rpc/auth false
::doc/added "1.15"} ::doc/added "1.15"
::sm/params schema:register-profile}
[{:keys [::db/pool] :as cfg} params] [{:keys [::db/pool] :as cfg} params]
(db/with-atomic [conn pool] (db/with-atomic [conn pool]
(-> (assoc cfg ::db/conn conn) (-> (assoc cfg ::db/conn conn)
@ -448,12 +453,15 @@
(create-recovery-token) (create-recovery-token)
(send-email-notification conn)))))) (send-email-notification conn))))))
(s/def ::request-profile-recovery
(s/keys :req-un [::email])) (def schema:request-profile-recovery
[:map {:title "request-profile-recovery"}
[:email ::sm/email]])
(sv/defmethod ::request-profile-recovery (sv/defmethod ::request-profile-recovery
{::rpc/auth false {::rpc/auth false
::doc/added "1.15"} ::doc/added "1.15"
::sm/params schema:request-profile-recovery}
[cfg params] [cfg params]
(request-profile-recovery cfg params)) (request-profile-recovery cfg params))

View file

@ -14,6 +14,7 @@
[app.common.pages :as cp] [app.common.pages :as cp]
[app.common.pprint :as pp] [app.common.pprint :as pp]
[app.common.spec :as us] [app.common.spec :as us]
[app.common.schema :as sm]
[app.common.uuid :as uuid] [app.common.uuid :as uuid]
[app.config :as cf] [app.config :as cf]
[app.db :as db] [app.db :as db]
@ -414,6 +415,14 @@
(println (println
(us/pretty-explain data)) (us/pretty-explain data))
(= :params-validation (:code data))
(app.common.pprint/pprint
(sm/humanize-data (::sm/explain data)))
(= :data-validation (:code data))
(app.common.pprint/pprint
(sm/humanize-data (::sm/explain data)))
(= :service-error (:type data)) (= :service-error (:type data))
(print-error! (.getCause ^Throwable error)) (print-error! (.getCause ^Throwable error))

View file

@ -39,8 +39,8 @@
params {::th/type :push-audit-events params {::th/type :push-audit-events
::rpc/profile-id (:id prof) ::rpc/profile-id (:id prof)
:events [{:name "navigate" :events [{:name "navigate"
:props {:project-id proj-id :props {:project-id (str proj-id)
:team-id team-id :team-id (str team-id)
:route "dashboard-files"} :route "dashboard-files"}
:context {:engine "blink"} :context {:engine "blink"}
:profile-id (:id prof) :profile-id (:id prof)
@ -71,8 +71,8 @@
params {::th/type :push-audit-events params {::th/type :push-audit-events
::rpc/profile-id (:id prof) ::rpc/profile-id (:id prof)
:events [{:name "navigate" :events [{:name "navigate"
:props {:project-id proj-id :props {:project-id (str proj-id)
:team-id team-id :team-id (str team-id)
:route "dashboard-files"} :route "dashboard-files"}
:context {:engine "blink"} :context {:engine "blink"}
:profile-id uuid/zero :profile-id uuid/zero
@ -91,6 +91,8 @@
(t/is (= 1 (count rows))) (t/is (= 1 (count rows)))
(t/is (= (:id prof) (:profile-id row))) (t/is (= (:id prof) (:profile-id row)))
(t/is (= "navigate" (:name row))) (t/is (= "navigate" (:name row)))
(t/is (= "frontend" (:source row))))))) (t/is (= "frontend" (:source row))))
)))

View file

@ -252,6 +252,7 @@
:components-v2 true :components-v2 true
:changes changes} :changes changes}
out (th/command! params)] out (th/command! params)]
;; (th/print-result! out)
(t/is (nil? (:error out))) (t/is (nil? (:error out)))
(:result out)))] (:result out)))]
@ -286,7 +287,7 @@
:frame-id uuid/zero :frame-id uuid/zero
:parent-id uuid/zero :parent-id uuid/zero
:type :image :type :image
:metadata {:id (:id fmo1)}}}]) :metadata {:id (:id fmo1) :width 200 :height 200 :mtype "image/jpeg"}}}])
;; Check that reference storage objects on filemediaobjects ;; Check that reference storage objects on filemediaobjects
;; are the same because of deduplication feature. ;; are the same because of deduplication feature.

View file

@ -278,7 +278,7 @@
(let [error (:error out)] (let [error (:error out)]
(t/is (th/ex-info? error)) (t/is (th/ex-info? error))
(t/is (th/ex-of-type? error :validation)) (t/is (th/ex-of-type? error :validation))
(t/is (th/ex-of-code? error :spec-validation)))) (t/is (th/ex-of-code? error :params-validation))))
;; try correct register ;; try correct register
(let [data {::th/type :register-profile (let [data {::th/type :register-profile