Skip to content
Snippets Groups Projects
Unverified Commit 311f50bf authored by Noah Moss's avatar Noah Moss Committed by GitHub
Browse files

Move Google auth code into separate namespace (#16530)

parent 87fd8408
No related branches found
No related tags found
No related merge requests found
(ns metabase.api.session
"/api/session endpoints"
(:require [cemerick.friend.credentials :as creds]
[cheshire.core :as json]
[clj-http.client :as http]
[clojure.tools.logging :as log]
[compojure.core :refer [DELETE GET POST]]
[metabase.api.common :as api]
[metabase.config :as config]
[metabase.email.messages :as email]
[metabase.events :as events]
[metabase.integrations.google :as google]
[metabase.integrations.ldap :as ldap]
[metabase.models.login-history :refer [LoginHistory]]
[metabase.models.session :refer [Session]]
[metabase.models.setting :as setting :refer [defsetting]]
[metabase.models.setting :as setting]
[metabase.models.user :as user :refer [User]]
[metabase.public-settings :as public-settings]
[metabase.server.middleware.session :as mw.session]
......@@ -248,106 +247,26 @@
(when api/*is-superuser?*
(setting/properties :admin))))
;;; -------------------------------------------------- GOOGLE AUTH ---------------------------------------------------
;; TODO - The more I look at all this code the more I think it should go in its own namespace.
;; `metabase.integrations.google-auth` would be appropriate, or `metabase.integrations.auth.google` if we decide to
;; add more 3rd-party SSO options
(defsetting google-auth-client-id
(deferred-tru "Client ID for Google Auth SSO. If this is set, Google Auth is considered to be enabled.")
:visibility :public)
(defsetting google-auth-auto-create-accounts-domain
(deferred-tru "When set, allow users to sign up on their own if their Google account email address is from this domain."))
(def ^:private google-auth-token-info-url "https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=%s")
(defn- google-auth-token-info
([token-info-response]
(google-auth-token-info token-info-response (google-auth-client-id)))
([token-info-response client-id]
(let [{:keys [status body]} token-info-response]
(when-not (= status 200)
(throw (ex-info (tru "Invalid Google Auth token.") {:status-code 400})))
(u/prog1 (json/parse-string body keyword)
(let [audience (:aud <>)
audience (if (string? audience) [audience] audience)]
(when-not (contains? (set audience) client-id)
(throw (ex-info (str (deferred-tru "Google Auth token appears to be incorrect. ")
(deferred-tru "Double check that it matches in Google and Metabase."))
{:status-code 400}))))
(when-not (= (:email_verified <>) "true")
(throw (ex-info (tru "Email is not verified.") {:status-code 400})))))))
;; TODO - are these general enough to move to `metabase.util`?
(defn- email->domain ^String [email]
(last (re-find #"^.*@(.*$)" email)))
(defn- email-in-domain? ^Boolean [email domain]
{:pre [(u/email? email)]}
(= (email->domain email) domain))
(defn- autocreate-user-allowed-for-email? [email]
(when-let [domain (google-auth-auto-create-accounts-domain)]
(email-in-domain? email domain)))
(defn check-autocreate-user-allowed-for-email
"Throws if an admin needs to intervene in the account creation."
[email]
(when-not (autocreate-user-allowed-for-email? email)
;; Use some wacky status code (428 - Precondition Required) so we will know when to so the error screen specific
;; to this situation
(throw
(ex-info (tru "You''ll need an administrator to create a Metabase account before you can use Google to log in.")
{:status-code 428}))))
(s/defn ^:private google-auth-create-new-user!
[{:keys [email] :as new-user} :- user/NewUser]
(check-autocreate-user-allowed-for-email email)
;; this will just give the user a random password; they can go reset it if they ever change their mind and want to
;; log in without Google Auth; this lets us keep the NOT NULL constraints on password / salt without having to make
;; things hairy and only enforce those for non-Google Auth users
(user/create-new-google-auth-user! new-user))
(s/defn ^:private google-auth-fetch-or-create-user! :- (s/maybe {:id UUID, s/Keyword s/Any})
[first-name last-name email device-info :- request.u/DeviceInfo]
(when-let [user (or (db/select-one [User :id :last_login] :%lower.email (u/lower-case-en email))
(google-auth-create-new-user! {:first_name first-name
:last_name last-name
:email email}))]
(create-session! :sso user device-info)))
(defn do-google-auth
"Call to Google to perform an authentication"
[{{:keys [token]} :body, :as request}]
(let [token-info-response (http/post (format google-auth-token-info-url token))
{:keys [given_name family_name email]} (google-auth-token-info token-info-response)]
(log/info (trs "Successfully authenticated Google Auth token for: {0} {1}" given_name family_name))
(let [{session-uuid :id, :as session} (api/check-500
(google-auth-fetch-or-create-user!
given_name family_name email (request.u/device-info request)))
response {:id (str session-uuid)}
user (db/select-one [User :id :is_active], :email email)]
(if (and user (:is_active user))
(mw.session/set-session-cookie request response session)
(throw (ex-info (str disabled-account-message)
{:status-code 400
:errors {:account disabled-account-snippet}}))))))
(api/defendpoint POST "/google_auth"
"Login with Google Auth."
[:as {{:keys [token]} :body, :as request}]
{token su/NonBlankString}
(when-not (google-auth-client-id)
(when-not (google/google-auth-client-id)
(throw (ex-info "Google Auth is disabled." {:status-code 400})))
;; Verify the token is valid with Google
(if throttling-disabled?
(do-google-auth token)
(google/do-google-auth request)
(http-401-on-error
(throttle/with-throttling [(login-throttlers :ip-address) (request.u/ip-address request)]
(do-google-auth request)))))
(throttle/with-throttling [(login-throttlers :ip-address) (request.u/ip-address request)]
(let [user (google/do-google-auth request)
{session-uuid :id, :as session} (create-session! :sso user (request.u/device-info request))
response {:id (str session-uuid)}
user (db/select-one [User :id :is_active], :email (:email user))]
(if (and user (:is_active user))
(mw.session/set-session-cookie request response session)
(throw (ex-info (str disabled-account-message)
{:status-code 400
:errors {:account disabled-account-snippet}}))))))))
(defn- +log-all-request-failures [handler]
(fn [request respond raise]
......
......@@ -4,8 +4,8 @@
[compojure.core :refer [DELETE GET POST PUT]]
[honeysql.helpers :as hh]
[metabase.api.common :as api]
[metabase.api.session :as session-api]
[metabase.email.messages :as email]
[metabase.integrations.google :as google]
[metabase.integrations.ldap :as ldap]
[metabase.models.collection :as collection :refer [Collection]]
[metabase.models.permissions-group :as group]
......@@ -247,7 +247,7 @@
;; (see metabase#3323)
:google_auth (boolean (and (:google_auth existing-user)
;; if google-auth-client-id is set it means Google Auth is enabled
(session-api/google-auth-client-id)))
(google/google-auth-client-id)))
:ldap_auth (boolean (and (:ldap_auth existing-user)
(ldap/ldap-configured?))))
;; now return the existing user whether they were originally active or not
......
(ns metabase.integrations.google
(:require [cheshire.core :as json]
[clj-http.client :as http]
[clojure.tools.logging :as log]
[metabase.api.common :as api]
[metabase.models.setting :as setting :refer [defsetting]]
[metabase.models.user :as user :refer [User]]
[metabase.util :as u]
[metabase.util.i18n :as ui18n :refer [deferred-tru trs tru]]
[schema.core :as s]
[toucan.db :as db]))
(defsetting google-auth-client-id
(deferred-tru "Client ID for Google Auth SSO. If this is set, Google Auth is considered to be enabled.")
:visibility :public)
(defsetting google-auth-auto-create-accounts-domain
(deferred-tru "When set, allow users to sign up on their own if their Google account email address is from this domain."))
(def ^:private google-auth-token-info-url "https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=%s")
(defn- google-auth-token-info
([token-info-response]
(google-auth-token-info token-info-response (google-auth-client-id)))
([token-info-response client-id]
(let [{:keys [status body]} token-info-response]
(when-not (= status 200)
(throw (ex-info (tru "Invalid Google Auth token.") {:status-code 400})))
(u/prog1 (json/parse-string body keyword)
(let [audience (:aud <>)
audience (if (string? audience) [audience] audience)]
(when-not (contains? (set audience) client-id)
(throw (ex-info (str (deferred-tru "Google Auth token appears to be incorrect. ")
(deferred-tru "Double check that it matches in Google and Metabase."))
{:status-code 400}))))
(when-not (= (:email_verified <>) "true")
(throw (ex-info (tru "Email is not verified.") {:status-code 400})))))))
; TODO - are these general enough to move to `metabase.util`?
(defn- email->domain ^String [email]
(last (re-find #"^.*@(.*$)" email)))
(defn- email-in-domain? ^Boolean [email domain]
{:pre [(u/email? email)]}
(= (email->domain email) domain))
(defn- autocreate-user-allowed-for-email? [email]
(when-let [domain (google-auth-auto-create-accounts-domain)]
(email-in-domain? email domain)))
(defn- check-autocreate-user-allowed-for-email
"Throws if an admin needs to intervene in the account creation."
[email]
(when-not (autocreate-user-allowed-for-email? email)
;; Use some wacky status code (428 - Precondition Required) so we will know when to so the error screen specific
;; to this situation
(throw
(ex-info (tru "You''ll need an administrator to create a Metabase account before you can use Google to log in.")
{:status-code 428}))))
(s/defn ^:private google-auth-create-new-user!
[{:keys [email] :as new-user} :- user/NewUser]
(check-autocreate-user-allowed-for-email email)
;; this will just give the user a random password; they can go reset it if they ever change their mind and want to
;; log in without Google Auth; this lets us keep the NOT NULL constraints on password / salt without having to make
;; things hairy and only enforce those for non-Google Auth users
(user/create-new-google-auth-user! new-user))
(s/defn ^:private google-auth-fetch-or-create-user! :- metabase.models.user.UserInstance
[first-name last-name email]
(or (db/select-one [User :id :email :last_login] :%lower.email (u/lower-case-en email))
(google-auth-create-new-user! {:first_name first-name
:last_name last-name
:email email})))
(defn do-google-auth
"Call to Google to perform an authentication"
[{{:keys [token]} :body, :as request}]
(let [token-info-response (http/post (format google-auth-token-info-url token))
{:keys [given_name family_name email]} (google-auth-token-info token-info-response)]
(log/info (trs "Successfully authenticated Google Auth token for: {0} {1}" given_name family_name))
(api/check-500 (google-auth-fetch-or-create-user! given_name family_name email))))
......@@ -5,10 +5,10 @@
[clojure.tools.logging :as log]
[java-time :as t]
[medley.core :as m]
[metabase.api.session :as session-api]
[metabase.config :as config]
[metabase.driver :as driver]
[metabase.email :as email]
[metabase.integrations.google :as google]
[metabase.integrations.slack :as slack]
[metabase.models :refer [Card Collection Dashboard DashboardCard Database Field Metric PermissionsGroup Pulse PulseCard PulseChannel QueryCache QueryExecution Segment Table User]]
[metabase.models.humanization :as humanization]
......@@ -118,7 +118,7 @@
:friendly_names (= (humanization/humanization-strategy) "advanced")
:email_configured (email/email-configured?)
:slack_configured (slack/slack-configured?)
:sso_configured (boolean (session-api/google-auth-client-id))
:sso_configured (boolean (google/google-auth-client-id))
:instance_started (instance-start-date)
:has_sample_data (db/exists? Database, :is_sample true)})
......
......@@ -21,8 +21,7 @@
[metabase.util.schema :as su]
[schema.core :as s]
[toucan.db :as db])
(:import clojure.lang.ExceptionInfo
java.util.UUID))
(:import java.util.UUID))
;; one of the tests below compares the way properties for the H2 driver are translated, so we need to make sure it's
;; loaded
......@@ -367,123 +366,22 @@
:engines :h2 :details-fields first :display-name)))))))
;;; ------------------------------------------ TESTS FOR GOOGLE AUTH STUFF -------------------------------------------
;;; tests for email->domain
(deftest email->domain-test
(are [domain email] (is (= domain
(#'session-api/email->domain email))
(format "Domain of email address '%s'" email))
"metabase.com" "cam@metabase.com"
"metabase.co.uk" "cam@metabase.co.uk"
"metabase.com" "cam.saul+1@metabase.com"))
;;; tests for email-in-domain?
(deftest email-in-domain-test
(are [in-domain? email domain] (is (= in-domain?
(#'session-api/email-in-domain? email domain))
(format "Is email '%s' in domain '%s'?" email domain))
true "cam@metabase.com" "metabase.com"
false "cam.saul+1@metabase.co.uk" "metabase.com"
true "cam.saul+1@metabase.com" "metabase.com"))
;;; tests for autocreate-user-allowed-for-email?
(deftest allow-autocreation-test
(mt/with-temporary-setting-values [google-auth-auto-create-accounts-domain "metabase.com"]
(are [allowed? email] (is (= allowed?
(#'session-api/autocreate-user-allowed-for-email? email))
(format "Can we autocreate an account for email '%s'?" email))
true "cam@metabase.com"
false "cam@expa.com")))
(deftest google-auth-create-new-user!-test
(testing "shouldn't be allowed to create a new user via Google Auth if their email doesn't match the auto-create accounts domain"
(mt/with-temporary-setting-values [google-auth-auto-create-accounts-domain "sf-toucannery.com"]
(is (thrown?
clojure.lang.ExceptionInfo
(#'session-api/google-auth-create-new-user! {:first_name "Rasta"
:last_name "Toucan"
:email "rasta@metabase.com"})))))
(testing "should totally work if the email domains match up"
(et/with-fake-inbox
(mt/with-temporary-setting-values [google-auth-auto-create-accounts-domain "sf-toucannery.com"
admin-email "rasta@toucans.com"]
(try
(let [user (#'session-api/google-auth-create-new-user! {:first_name "Rasta"
:last_name "Toucan"
:email "rasta@sf-toucannery.com"})]
(is (= {:first_name "Rasta", :last_name "Toucan", :email "rasta@sf-toucannery.com"}
(select-keys user [:first_name :last_name :email]))))
(finally
(db/delete! User :email "rasta@sf-toucannery.com")))))))
;;; --------------------------------------------- google-auth-token-info ---------------------------------------------
(deftest google-auth-token-info-tests
(testing "Throws exception"
(testing "for non-200 status"
(is (= [400 "Invalid Google Auth token."]
(try
(#'session-api/google-auth-token-info {:status 400} "")
(catch Exception e
[(-> e ex-data :status-code) (.getMessage e)])))))
(testing "for invalid data."
(is (= [400 "Google Auth token appears to be incorrect. Double check that it matches in Google and Metabase."]
(try
(#'session-api/google-auth-token-info
{:status 200
:body "{\"aud\":\"BAD-GOOGLE-CLIENT-ID\"}"}
"PRETEND-GOOD-GOOGLE-CLIENT-ID")
(catch Exception e
[(-> e ex-data :status-code) (.getMessage e)]))))
(is (= [400 "Email is not verified."]
(try
(#'session-api/google-auth-token-info
{:status 200
:body (str "{\"aud\":\"PRETEND-GOOD-GOOGLE-CLIENT-ID\","
"\"email_verified\":false}")}
"PRETEND-GOOD-GOOGLE-CLIENT-ID")
(catch Exception e
[(-> e ex-data :status-code) (.getMessage e)]))))
(is (= {:aud "PRETEND-GOOD-GOOGLE-CLIENT-ID"
:email_verified "true"}
(try
(#'session-api/google-auth-token-info
{:status 200
:body (str "{\"aud\":\"PRETEND-GOOD-GOOGLE-CLIENT-ID\","
"\"email_verified\":\"true\"}")}
"PRETEND-GOOD-GOOGLE-CLIENT-ID")
(catch Exception e
[(-> e ex-data :status-code) (.getMessage e)]))))))
(testing "Supports multiple :aud token data fields"
(let [token-1 "GOOGLE-CLIENT-ID-1"
token-2 "GOOGLE-CLIENT-ID-2"]
(is (= [token-1 token-2]
(:aud (#'session-api/google-auth-token-info
{:status 200
:body (format "{\"aud\":[\"%s\",\"%s\"],\"email_verified\":\"true\"}"
token-1
token-2)}
token-1)))))))
(deftest google-auth-tests
(mt/with-temporary-setting-values [google-auth-client-id "PRETEND-GOOD-GOOGLE-CLIENT-ID"]
(testing "with an active account"
(mt/with-temp User [user {:email "test@metabase.com" :is_active true}]
(with-redefs [http/post (fn [url] {:status 200
:body (str "{\"aud\":\"PRETEND-GOOD-GOOGLE-CLIENT-ID\","
"\"email_verified\":\"true\","
"\"first_name\":\"test\","
"\"last_name\":\"user\","
"\"email\":\"test@metabase.com\"}")})]
;;; ------------------------------------------- TESTS FOR GOOGLE SIGN-IN ---------------------------------------------
(let [result (session-api/do-google-auth {:body {:token "foo"}})]
(is (= 200 (:status result)))))))
(testing "with a disabled account"
(deftest google-auth-test
(testing "POST /google_auth"
(mt/with-temporary-setting-values [google-auth-client-id "PRETEND-GOOD-GOOGLE-CLIENT-ID"]
(testing "Google auth works with an active account"
(mt/with-temp User [user {:email "test@metabase.com" :is_active true}]
(with-redefs [http/post (fn [url] {:status 200
:body (str "{\"aud\":\"PRETEND-GOOD-GOOGLE-CLIENT-ID\","
"\"email_verified\":\"true\","
"\"first_name\":\"test\","
"\"last_name\":\"user\","
"\"email\":\"test@metabase.com\"}")})]
(is (schema= SessionResponse
(mt/client :post 200 "session/google_auth" {:token "foo"}))))))
(testing "Google auth throws exception for a disabled account"
(mt/with-temp User [user {:email "test@metabase.com" :is_active false}]
(with-redefs [http/post (fn [url] {:status 200
:body (str "{\"aud\":\"PRETEND-GOOD-GOOGLE-CLIENT-ID\","
......@@ -491,46 +389,8 @@
"\"first_name\":\"test\","
"\"last_name\":\"user\","
"\"email\":\"test@metabase.com\"}")})]
(is (thrown-with-msg?
ExceptionInfo
#"Your account is disabled. Please contact your administrator."
(session-api/do-google-auth {:body {:token "foo"}}))))))))
;;; --------------------------------------- google-auth-fetch-or-create-user! ----------------------------------------
(deftest google-auth-fetch-or-create-user!-test
(testing "test that an existing user can log in with Google auth even if the auto-create accounts domain is different from"
(mt/with-temp User [user {:email "cam@sf-toucannery.com"}]
(mt/with-temporary-setting-values [google-auth-auto-create-accounts-domain "metabase.com"]
(testing "their account should return a Session"
(is (schema= {:id UUID
s/Keyword s/Any}
(#'session-api/google-auth-fetch-or-create-user!
"Cam" "Saul" "cam@sf-toucannery.com"
mock-device-info)))))))
(testing "test that a user that doesn't exist with a *different* domain than the auto-create accounts domain gets an exception"
(mt/with-temporary-setting-values [google-auth-auto-create-accounts-domain nil
admin-email "rasta@toucans.com"]
(is (thrown?
clojure.lang.ExceptionInfo
(#'session-api/google-auth-fetch-or-create-user!
"Rasta" "Can" "rasta@sf-toucannery.com"
mock-device-info)))))
(testing "test that a user that doesn't exist with the *same* domain as the auto-create accounts domain means a new user gets created"
(et/with-fake-inbox
(mt/with-temporary-setting-values [google-auth-auto-create-accounts-domain "sf-toucannery.com"
admin-email "rasta@toucans.com"]
(try
(is (schema= {:id UUID
s/Keyword s/Any}
(#'session-api/google-auth-fetch-or-create-user!
"Rasta" "Toucan" "rasta@sf-toucannery.com"
mock-device-info)))
(finally
(db/delete! User :email "rasta@sf-toucannery.com")))))))
(is (= {:errors {:account "Your account is disabled."}}
(mt/client :post 401 "session/google_auth" {:token "foo"})))))))))
;;; ------------------------------------------- TESTS FOR LDAP AUTH STUFF --------------------------------------------
......
(ns metabase.integrations.google-test
(:require
[clj-http.client :as http]
[clojure.test :refer :all]
[metabase.email-test :as et]
[metabase.integrations.google :as google]
[metabase.models.user :refer [User]]
[metabase.test :as mt]
[schema.core :as s]
[toucan.db :as db]))
;;; tests for email->domain
(deftest email->domain-test
(are [domain email] (is (= domain
(#'google/email->domain email))
(format "Domain of email address '%s'" email))
"metabase.com" "cam@metabase.com"
"metabase.co.uk" "cam@metabase.co.uk"
"metabase.com" "cam.saul+1@metabase.com"))
;;; tests for email-in-domain?
(deftest email-in-domain-test
(are [in-domain? email domain] (is (= in-domain?
(#'google/email-in-domain? email domain))
(format "Is email '%s' in domain '%s'?" email domain))
true "cam@metabase.com" "metabase.com"
false "cam.saul+1@metabase.co.uk" "metabase.com"
true "cam.saul+1@metabase.com" "metabase.com"))
;;; tests for autocreate-user-allowed-for-email?
(deftest allow-autocreation-test
(mt/with-temporary-setting-values [google-auth-auto-create-accounts-domain "metabase.com"]
(are [allowed? email] (is (= allowed?
(#'google/autocreate-user-allowed-for-email? email))
(format "Can we autocreate an account for email '%s'?" email))
true "cam@metabase.com"
false "cam@expa.com")))
(deftest google-auth-create-new-user!-test
(testing "shouldn't be allowed to create a new user via Google Auth if their email doesn't match the auto-create accounts domain"
(mt/with-temporary-setting-values [google-auth-auto-create-accounts-domain "sf-toucannery.com"]
(is (thrown?
clojure.lang.ExceptionInfo
(#'google/google-auth-create-new-user! {:first_name "Rasta"
:last_name "Toucan"
:email "rasta@metabase.com"})))))
(testing "should totally work if the email domains match up"
(et/with-fake-inbox
(mt/with-temporary-setting-values [google-auth-auto-create-accounts-domain "sf-toucannery.com"
admin-email "rasta@toucans.com"]
(try
(let [user (#'google/google-auth-create-new-user! {:first_name "Rasta"
:last_name "Toucan"
:email "rasta@sf-toucannery.com"})]
(is (= {:first_name "Rasta", :last_name "Toucan", :email "rasta@sf-toucannery.com"}
(select-keys user [:first_name :last_name :email]))))
(finally
(db/delete! User :email "rasta@sf-toucannery.com")))))))
;;; --------------------------------------------- google-auth-token-info ---------------------------------------------
(deftest google-auth-token-info-tests
(testing "Throws exception"
(testing "for non-200 status"
(is (= [400 "Invalid Google Auth token."]
(try
(#'google/google-auth-token-info {:status 400} "")
(catch Exception e
[(-> e ex-data :status-code) (.getMessage e)])))))
(testing "for invalid data."
(is (= [400 "Google Auth token appears to be incorrect. Double check that it matches in Google and Metabase."]
(try
(#'google/google-auth-token-info
{:status 200
:body "{\"aud\":\"BAD-GOOGLE-CLIENT-ID\"}"}
"PRETEND-GOOD-GOOGLE-CLIENT-ID")
(catch Exception e
[(-> e ex-data :status-code) (.getMessage e)]))))
(is (= [400 "Email is not verified."]
(try
(#'google/google-auth-token-info
{:status 200
:body (str "{\"aud\":\"PRETEND-GOOD-GOOGLE-CLIENT-ID\","
"\"email_verified\":false}")}
"PRETEND-GOOD-GOOGLE-CLIENT-ID")
(catch Exception e
[(-> e ex-data :status-code) (.getMessage e)]))))
(is (= {:aud "PRETEND-GOOD-GOOGLE-CLIENT-ID"
:email_verified "true"}
(try
(#'google/google-auth-token-info
{:status 200
:body (str "{\"aud\":\"PRETEND-GOOD-GOOGLE-CLIENT-ID\","
"\"email_verified\":\"true\"}")}
"PRETEND-GOOD-GOOGLE-CLIENT-ID")
(catch Exception e
[(-> e ex-data :status-code) (.getMessage e)]))))))
(testing "Supports multiple :aud token data fields"
(let [token-1 "GOOGLE-CLIENT-ID-1"
token-2 "GOOGLE-CLIENT-ID-2"]
(is (= [token-1 token-2]
(:aud (#'google/google-auth-token-info
{:status 200
:body (format "{\"aud\":[\"%s\",\"%s\"],\"email_verified\":\"true\"}"
token-1
token-2)}
token-1)))))))
;;; --------------------------------------- google-auth-fetch-or-create-user! ----------------------------------------
(deftest google-auth-fetch-or-create-user!-test
(testing "test that an existing user can log in with Google auth even if the auto-create accounts domain is different from"
(mt/with-temp User [user {:email "cam@sf-toucannery.com"}]
(mt/with-temporary-setting-values [google-auth-auto-create-accounts-domain "metabase.com"]
(testing "their account should return a UserInstance"
(is (schema= metabase.models.user.UserInstance
(#'google/google-auth-fetch-or-create-user!
"Cam" "Saul" "cam@sf-toucannery.com")))))))
(testing "test that a user that doesn't exist with a *different* domain than the auto-create accounts domain gets an exception"
(mt/with-temporary-setting-values [google-auth-auto-create-accounts-domain nil
admin-email "rasta@toucans.com"]
(is (thrown?
clojure.lang.ExceptionInfo
(#'google/google-auth-fetch-or-create-user!
"Rasta" "Can" "rasta@sf-toucannery.com")))))
(testing "test that a user that doesn't exist with the *same* domain as the auto-create accounts domain means a new user gets created"
(et/with-fake-inbox
(mt/with-temporary-setting-values [google-auth-auto-create-accounts-domain "sf-toucannery.com"
admin-email "rasta@toucans.com"]
(try
(is (schema= metabase.models.user.UserInstance
(#'google/google-auth-fetch-or-create-user!
"Rasta" "Toucan" "rasta@sf-toucannery.com")))
(finally
(db/delete! User :email "rasta@sf-toucannery.com")))))))
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