From da85276c07fad5fb1df42564e221bbfb6a2fa832 Mon Sep 17 00:00:00 2001
From: abdul aziz ali <abdulazizali@acm.org>
Date: Thu, 24 Aug 2023 07:12:28 +0800
Subject: [PATCH] Add new environment setting reset-token-ttl-hours (#32132)

* Add new setting reset-token-ttl-h. Expose in selectors (#12829)

* Add reset-token-ttl-h setter, fix call in reset-token-ttl-ms. Add additional reset-token-ttl-h tests. (#12829)

* Revert previous changes. Define reset-token-ttl-hours and reset-token-ttl-hours-test (#12829)

* Fix formatting errors (#12829)
---
 src/metabase/api/session.clj       | 18 +++++++++++++-----
 test/metabase/api/session_test.clj | 22 ++++++++++++++++++++++
 2 files changed, 35 insertions(+), 5 deletions(-)

diff --git a/src/metabase/api/session.clj b/src/metabase/api/session.clj
index b8856e1b717..19b3ff54986 100644
--- a/src/metabase/api/session.clj
+++ b/src/metabase/api/session.clj
@@ -15,7 +15,7 @@
    [metabase.models.login-history :refer [LoginHistory]]
    [metabase.models.pulse :as pulse]
    [metabase.models.session :refer [Session]]
-   [metabase.models.setting :as setting]
+   [metabase.models.setting :as setting :refer [defsetting]]
    [metabase.models.user :as user :refer [User]]
    [metabase.public-settings :as public-settings]
    [metabase.server.middleware.session :as mw.session]
@@ -232,9 +232,17 @@
   (forgot-password-impl email)
   api/generic-204-no-content)
 
-(def ^:private ^:const reset-token-ttl-ms
-  "Number of milliseconds a password reset is considered valid."
-  (* 48 60 60 1000)) ; token considered valid for 48 hours
+
+(defsetting reset-token-ttl-hours
+  (deferred-tru "Number of hours a password reset is considered valid.")
+  :visibility :internal
+  :type       :integer
+  :default    48)
+
+(defn reset-token-ttl-ms
+  "number of milliseconds a password reset is considered valid."
+  []
+  (* (reset-token-ttl-hours) 60 60 1000))
 
 (defn- valid-reset-token->user
   "Check if a password reset token is valid. If so, return the `User` ID it corresponds to."
@@ -249,7 +257,7 @@
                 (u.password/bcrypt-verify token reset_token))
           ;; check that the reset was triggered within the last 48 HOURS, after that the token is considered expired
           (let [token-age (- (System/currentTimeMillis) reset_triggered)]
-            (when (< token-age reset-token-ttl-ms)
+            (when (< token-age (reset-token-ttl-ms))
               user)))))))
 
 #_{:clj-kondo/ignore [:deprecated-var]}
diff --git a/test/metabase/api/session_test.clj b/test/metabase/api/session_test.clj
index 881783f098d..a80be1933fd 100644
--- a/test/metabase/api/session_test.clj
+++ b/test/metabase/api/session_test.clj
@@ -358,6 +358,28 @@
         (is (= {:valid false}
                (mt/client :get 200 "session/password_reset_token_valid", :token token)))))))
 
+(deftest reset-token-ttl-hours-test
+  (testing "Test reset-token-ttl-hours-test"
+    (testing "reset-token-ttl-hours-test is reset to default when not set"
+      (mt/with-temp-env-var-value [mb-reset-token-ttl-hours nil]
+        (is (= 48 (setting/get-value-of-type :integer :reset-token-ttl-hours)))))
+
+    (testing "reset-token-ttl-hours-test is set to positive value"
+      (mt/with-temp-env-var-value [mb-reset-token-ttl-hours 36]
+        (is (= 36 (setting/get-value-of-type :integer :reset-token-ttl-hours)))))
+
+    (testing "reset-token-ttl-hours-test is set to large positive value"
+      (mt/with-temp-env-var-value [mb-reset-token-ttl-hours (+ Integer/MAX_VALUE 1)]
+        (is (= (+ Integer/MAX_VALUE 1) (setting/get-value-of-type :integer :reset-token-ttl-hours)))))
+
+    (testing "reset-token-ttl-hours-test is set to zero"
+      (mt/with-temp-env-var-value [mb-reset-token-ttl-hours 0]
+        (is (= 0 (setting/get-value-of-type :integer :reset-token-ttl-hours)))))
+
+    (testing "reset-token-ttl-hours-test is set to negative value"
+      (mt/with-temp-env-var-value [mb-reset-token-ttl-hours -1]
+        (is (= -1 (setting/get-value-of-type :integer :reset-token-ttl-hours)))))))
+
 (deftest properties-test
   (reset-throttlers!)
   (testing "GET /session/properties"
-- 
GitLab