Skip to content
Snippets Groups Projects
Unverified Commit e0d24077 authored by dpsutton's avatar dpsutton Committed by GitHub
Browse files

Throttle reset_password endpoint (#40760)

parent 23bda114
No related branches found
No related tags found
No related merge requests found
......@@ -273,11 +273,17 @@
(when (< token-age (reset-token-ttl-ms))
user)))))))
(def reset-password-throttler
"Throttler for password_reset. There's no good field to mark so use password as a default."
(throttle/make-throttler :password :attempts-threshold 10))
(api/defendpoint POST "/reset_password"
"Reset password with a reset token."
[:as {{:keys [token password]} :body, :as request}]
{token ms/NonBlankString
password ms/ValidPassword}
(let [request-source (req.util/ip-address request)]
(throttle-check reset-password-throttler request-source))
(or (when-let [{user-id :id, :as user} (valid-reset-token->user token)]
(let [reset-token (t2/select-one-fn :reset_token :model/User :id user-id)]
(user/set-password! user-id password)
......
......@@ -33,7 +33,8 @@
(defn- reset-throttlers! []
(doseq [throttler (vals @#'api.session/login-throttlers)]
(reset! (:attempts throttler) nil)))
(reset! (:attempts throttler) nil))
(reset! (:attempts (var-get #'api.session/reset-password-throttler)) nil))
(def ^:private SessionResponse
[:map
......@@ -317,7 +318,24 @@
(testing "check that reset token was cleared"
(is (= {:reset_token nil
:reset_triggered nil}
(mt/derecordize (t2/select-one [User :reset_token :reset_triggered], :id id))))))))))))
(mt/derecordize (t2/select-one [User :reset_token :reset_triggered], :id id))))))))))
(testing "Reset password endpoint is throttled on endpoint"
(reset-throttlers!)
(let [try! (fn []
(try
(http/post (client/build-url "session/reset_password" {})
{:form-params {"token" (str (random-uuid))
"password" (str (random-uuid))}
:content-type :json})
::succeeded
(catch Exception e
(or (some-> (ex-data e) :body (json/parse-string true))
::unknown-error))))
responses (into [] (repeatedly 30 try!))]
(is (nil? (some #{::succeeded ::unknown-error} responses)))
(is (every? (comp :password :errors) responses))
(is (some (comp #(re-find #"Invalid reset token" %) :password :errors) responses))
(is (some (comp #(re-find #"Too many attempts!" %) :password :errors) responses))))))
(deftest reset-password-successful-event-test
(reset-throttlers!)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment