From 707425edfdfa41edf015402a952a4a3ed6e6e718 Mon Sep 17 00:00:00 2001 From: Daniel Higginbotham <daniel@flyingmachinestudios.com> Date: Mon, 16 Dec 2019 17:37:25 -0500 Subject: [PATCH] 11525 restore stencil templates in build (#11533) * apply @walterl's google auth fix * remove :omit-source flag because it excludes mustache files and might have other effects --- project.clj | 19 ++++++------ src/metabase/api/session.clj | 30 ++++++++++++------ test/metabase/api/session_test.clj | 50 ++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 19 deletions(-) diff --git a/project.clj b/project.clj index cdcdc9913b8..3923e08db42 100644 --- a/project.clj +++ b/project.clj @@ -140,10 +140,10 @@ :manifest {"Liquibase-Package" #= (eval - (str "liquibase.change,liquibase.changelog,liquibase.database,liquibase.parser,liquibase.precondition," - "liquibase.datatype,liquibase.serializer,liquibase.sqlgenerator,liquibase.executor," - "liquibase.snapshot,liquibase.logging,liquibase.diff,liquibase.structure," - "liquibase.structurecompare,liquibase.lockservice,liquibase.sdk,liquibase.ext"))} + (str "liquibase.change,liquibase.changelog,liquibase.database,liquibase.parser,liquibase.precondition," + "liquibase.datatype,liquibase.serializer,liquibase.sqlgenerator,liquibase.executor," + "liquibase.snapshot,liquibase.logging,liquibase.diff,liquibase.structure," + "liquibase.structurecompare,liquibase.lockservice,liquibase.sdk,liquibase.ext"))} :jvm-opts ["-XX:+IgnoreUnrecognizedVMOptions" ; ignore things not recognized for our Java version instead of refusing to start @@ -243,10 +243,10 @@ :include-all-drivers [:with-include-drivers-middleware - {:include-drivers :all - :injections - [(require 'metabase.plugins) - (metabase.plugins/load-plugins!)]}] + {:include-drivers :all + :injections + [(require 'metabase.plugins) + (metabase.plugins/load-plugins!)]}] :repl [:include-all-drivers @@ -308,8 +308,7 @@ ;; build the uberjar with `lein uberjar` :uberjar {:auto-clean true - :aot :all - :omit-source true} + :aot :all} ;; generate sample dataset with `lein generate-sample-dataset` :generate-sample-dataset diff --git a/src/metabase/api/session.clj b/src/metabase/api/session.clj index 7d3342c79ab..7bbff3589e1 100644 --- a/src/metabase/api/session.clj +++ b/src/metabase/api/session.clj @@ -252,13 +252,22 @@ (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.")) -(defn- google-auth-token-info [^String token] - (let [{:keys [status body]} (http/post (str "https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=" token))] - (when-not (= status 200) - (throw (ex-info (tru "Invalid Google Auth token.") {:status-code 400}))) - (u/prog1 (json/parse-string body keyword) - (when-not (= (:email_verified <>) "true") - (throw (ex-info (tru "Email is not verified.") {:status-code 400})))))) +(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 (tru "Google Auth token meant for a different site.") {: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] @@ -298,8 +307,9 @@ :email email}))] (create-session! :sso user))) -(defn- do-google-auth [{{:keys [token]} :body, :as request}] - (let [{:keys [given_name family_name email]} (google-auth-token-info token)] +(defn- do-google-auth [{{: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-id (api/check-500 (google-auth-fetch-or-create-user! given_name family_name email)) response {:id session-id}] @@ -309,6 +319,8 @@ "Login with Google Auth." [:as {{:keys [token]} :body, :as request}] {token su/NonBlankString} + (when-not (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) diff --git a/test/metabase/api/session_test.clj b/test/metabase/api/session_test.clj index 5b908fc6dc3..b46d10329cd 100644 --- a/test/metabase/api/session_test.clj +++ b/test/metabase/api/session_test.clj @@ -341,6 +341,56 @@ [:first_name :last_name :email])))) +;;; --------------------------------------------- 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 meant for a different site."] + (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))))))) + ;;; --------------------------------------- google-auth-fetch-or-create-user! ---------------------------------------- ;; test that an existing user can log in with Google auth even if the auto-create accounts domain is different from -- GitLab