From f1606cb2bdbb7fe69af9a0baf9d979691df46f4a Mon Sep 17 00:00:00 2001 From: Noah Moss <32746338+noahmoss@users.noreply.github.com> Date: Fri, 3 Dec 2021 10:37:35 -0500 Subject: [PATCH] Fix LDAP port validation and add LDAP API tests (#19185) --- src/metabase/api/ldap.clj | 9 ++++--- test/metabase/api/ldap_test.clj | 34 ++++++++++++++++++++++++ test/metabase/integrations/ldap_test.clj | 25 ++++++----------- test/metabase/test/integrations/ldap.clj | 9 +++++++ 4 files changed, 56 insertions(+), 21 deletions(-) create mode 100644 test/metabase/api/ldap_test.clj diff --git a/src/metabase/api/ldap.clj b/src/metabase/api/ldap.clj index e26175a04d6..05ddb388859 100644 --- a/src/metabase/api/ldap.clj +++ b/src/metabase/api/ldap.clj @@ -90,10 +90,11 @@ [:as {settings :body}] {settings su/Map} (api/check-superuser) - (let [ldap-settings (select-keys settings (keys mb-settings->ldap-details)) - ldap-details (-> (set/rename-keys ldap-settings mb-settings->ldap-details) - (assoc :port (when-let [^String ldap-port (not-empty (:ldap-port settings))] - (Long/parseLong ldap-port)))) + (let [ldap-settings (-> settings + (select-keys (keys mb-settings->ldap-details)) + (assoc :ldap-port (when-let [^String ldap-port (not-empty (str (:ldap-port settings)))] + (Long/parseLong ldap-port)))) + ldap-details (set/rename-keys ldap-settings mb-settings->ldap-details) results (if-not (:ldap-enabled settings) ;; when disabled just respond with a success message {:status :SUCCESS} diff --git a/test/metabase/api/ldap_test.clj b/test/metabase/api/ldap_test.clj new file mode 100644 index 00000000000..157743a3059 --- /dev/null +++ b/test/metabase/api/ldap_test.clj @@ -0,0 +1,34 @@ +(ns metabase.api.ldap-test + (:require [clojure.set :as set] + [clojure.test :refer :all] + [metabase.api.ldap :as ldap-api] + [metabase.integrations.ldap :as ldap] + [metabase.test :as mt] + [metabase.test.integrations.ldap :as ldap.test])) + +(deftest ldap-settings-test + (testing "PUT /api/ldap/settings" + (ldap.test/with-ldap-server + (let [ldap-test-details (-> (ldap.test/get-ldap-details) + (set/rename-keys (set/map-invert @#'ldap-api/mb-settings->ldap-details)) + (assoc :ldap-enabled true))] + (testing "Valid LDAP settings can be saved via an API call" + (mt/user-http-request :crowberto :put 200 "ldap/settings" ldap-test-details)) + + (testing "Invalid LDAP settings return a server error" + (mt/user-http-request :crowberto :put 500 "ldap/settings" + (assoc ldap-test-details :ldap-password "wrong-password"))) + + (testing "Invalid LDAP settings can be saved if LDAP is disabled" + (mt/user-http-request :crowberto :put 200 "ldap/settings" + (assoc ldap-test-details :ldap-password "wrong-password" :ldap-enabled false))) + + (testing "Valid LDAP settings can still be saved if port is a integer (#18936)" + (mt/user-http-request :crowberto :put 200 "ldap/settings" + (assoc ldap-test-details + :ldap-port (Integer. (ldap.test/get-ldap-port))))) + + (testing "LDAP port is saved as default value if passed as an empty string (#18936)" + (mt/user-http-request :crowberto :put 200 "ldap/settings" + (assoc ldap-test-details :ldap-port "" :ldap-enabled false)) + (is (= 389 (ldap/ldap-port)))))))) diff --git a/test/metabase/integrations/ldap_test.clj b/test/metabase/integrations/ldap_test.clj index b4150106aab..6e1206a165d 100644 --- a/test/metabase/integrations/ldap_test.clj +++ b/test/metabase/integrations/ldap_test.clj @@ -9,15 +9,6 @@ [toucan.db :as db]) (:import com.unboundid.ldap.sdk.LDAPConnectionPool)) -(defn- get-ldap-details [] - {:host "localhost" - :port (ldap.test/get-ldap-port) - :bind-dn "cn=Directory Manager" - :password "password" - :security :none - :user-base "dc=metabase,dc=com" - :group-base "dc=metabase,dc=com"}) - ;; See test_resources/ldap.ldif for fixtures ;; The connection test should pass with valid settings @@ -26,24 +17,24 @@ (testing "anonymous binds" (testing "successfully connect to IPv4 host" (is (= {:status :SUCCESS} - (ldap/test-ldap-connection (get-ldap-details)))))) + (ldap/test-ldap-connection (ldap.test/get-ldap-details)))))) (testing "invalid user search base" (is (= :ERROR - (:status (ldap/test-ldap-connection (assoc (get-ldap-details) + (:status (ldap/test-ldap-connection (assoc (ldap.test/get-ldap-details) :user-base "dc=example,dc=com")))))) (testing "invalid group search base" (is (= :ERROR - (:status (ldap/test-ldap-connection (assoc (get-ldap-details) :group-base "dc=example,dc=com")))))) + (:status (ldap/test-ldap-connection (assoc (ldap.test/get-ldap-details) :group-base "dc=example,dc=com")))))) (testing "invalid bind DN" (is (= :ERROR - (:status (ldap/test-ldap-connection (assoc (get-ldap-details) :bind-dn "cn=Not Directory Manager")))))) + (:status (ldap/test-ldap-connection (assoc (ldap.test/get-ldap-details) :bind-dn "cn=Not Directory Manager")))))) (testing "invalid bind password" (is (= :ERROR - (:status (ldap/test-ldap-connection (assoc (get-ldap-details) :password "wrong")))))) + (:status (ldap/test-ldap-connection (assoc (ldap.test/get-ldap-details) :password "wrong")))))) (testing "basic get-connection works, will throw otherwise" (is (= nil @@ -107,7 +98,7 @@ :last-name "Miller" :email "jane.miller@metabase.com" :groups []} - (ldap/find-user "jane.miller@metabase.com"))) + (ldap/find-user "jane.miller@metabase.com"))))) ;; Test group lookups for directory servers that use the memberOf attribute overlay, such as Active Directory (ldap.test/with-active-directory-ldap-server @@ -126,7 +117,7 @@ :email "sally.brown@metabase.com" :groups ["cn=Accounting,ou=Groups,dc=metabase,dc=com", "cn=Engineering,ou=Groups,dc=metabase,dc=com"]} - (ldap/find-user "sbrown20"))))))))) + (ldap/find-user "sbrown20"))))))) (deftest fetch-or-create-user-test ;; there are EE-specific versions of this test in `metabase-enterprise.enhancements.integrations.ldap-test` @@ -181,7 +172,7 @@ (deftest ipv6-test (testing "successfully connect to IPv6 host" (let [actual (ldap.test/with-ldap-server - (ldap/test-ldap-connection (assoc (get-ldap-details) + (ldap/test-ldap-connection (assoc (ldap.test/get-ldap-details) :host "[::1]")))] (if (= (:status actual) :ERROR) (is (re-matches #"An error occurred while attempting to connect to server \[::1].*" (:message actual))) diff --git a/test/metabase/test/integrations/ldap.clj b/test/metabase/test/integrations/ldap.clj index b361dc8c0b2..0c3f863895f 100644 --- a/test/metabase/test/integrations/ldap.clj +++ b/test/metabase/test/integrations/ldap.clj @@ -33,6 +33,15 @@ [] (.getListenPort *ldap-server*)) +(defn get-ldap-details [] + {:host "localhost" + :port (get-ldap-port) + :bind-dn "cn=Directory Manager" + :password "password" + :security :none + :user-base "dc=metabase,dc=com" + :group-base "dc=metabase,dc=com"}) + (defn get-default-schema "Get the default schema for the directory server." [] -- GitLab