diff --git a/.gitignore b/.gitignore index e04714b..d0184fc 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,5 @@ pom.xml.asc *.class /.lein-* /.nrepl-port +.idea/ +*.iml diff --git a/src/vault/authenticate.clj b/src/vault/authenticate.clj index 44e60af..2bdb138 100644 --- a/src/vault/authenticate.clj +++ b/src/vault/authenticate.clj @@ -132,3 +132,35 @@ :content-type :json :accept :json :as :json}))))) + + +(defmethod authenticate* :aws + [client _ credentials] + (let [{:keys [api-path iam-http-request-method iam-request-url iam-request-body + iam-request-headers role]} credentials + api-path (or api-path (str "/v1/auth/aws/" (:auth-mount-point client) "login"))] + (when-not iam-http-request-method + (throw (IllegalArgumentException. "AWS auth credentials must include :iam-http-request-method"))) + (when-not iam-request-url + (throw (IllegalArgumentException. "AWS auth credentials must include :iam-request-url"))) + (when-not iam-request-body + (throw (IllegalArgumentException. "AWS auth credentials must include :iam-request-body"))) + (when-not iam-request-headers + (throw (IllegalArgumentException. "AWS auth credentials must include :iam-request-headers"))) + (when-not role + (throw (IllegalArgumentException. "AWS auth credentials must include :role"))) + (api-auth! + (str "AWS auth role=" role) + (:auth client) + (api-util/do-api-request + :post (str (:api-url client) api-path) + (merge + (:http-opts client) + {:form-params {:iam_http_request_method iam-http-request-method + :iam_request_url iam-request-url + :iam_request_body iam-request-body + :iam_request_headers iam-request-headers + :role role} + :content-type :json + :accept :json + :as :json}))))) diff --git a/test/vault/client/http_test.clj b/test/vault/client/http_test.clj index af7dce5..874f03c 100644 --- a/test/vault/client/http_test.clj +++ b/test/vault/client/http_test.clj @@ -90,3 +90,111 @@ (vault/authenticate! client :k8s {:jwt "fake-jwt-goes-here"}))) (is (empty? @api-requests)) (is (empty? @api-auths)))))) + + +(deftest authenticate-via-aws + (testing "When all parameters are specified" + (let [client (http-client example-url) + api-requests (atom []) + api-auths (atom [])] + (with-redefs [api-util/do-api-request (fn [& args] + (swap! api-requests conj args) + :do-api-request-response) + authenticate/api-auth! (fn [& args] + (swap! api-auths conj args) + :api-auth!-response)] + (vault/authenticate! client :aws {:role "my-role" + :iam-http-request-method "POST" + :iam-request-url "fake.sts.com" + :iam-request-body "FakeAction&Version=1" + :iam-request-headers "{'foo':'bar'}"}) + (is (= [[:post + (str example-url "/v1/auth/aws/login") + {:form-params {:iam_http_request_method "POST" + :iam_request_url "fake.sts.com" + :iam_request_body "FakeAction&Version=1" + :iam_request_headers "{'foo':'bar'}" + :role "my-role"} + :content-type :json + :accept :json + :as :json}]] + @api-requests)) + (is (= [[(str "AWS auth role=my-role") + (:auth client) + :do-api-request-response]] + @api-auths))))) + (testing "When no iam-http-request-method is specified" + (let [client (http-client example-url) + api-requests (atom []) + api-auths (atom [])] + (with-redefs [api-util/do-api-request (fn [& args] + (swap! api-requests conj args)) + authenticate/api-auth! (fn [& args] + (swap! api-auths conj args))] + (is (thrown? IllegalArgumentException + (vault/authenticate! client :aws {:role "my-role" + :iam-request-url "fake.sts.com" + :iam-request-body "FakeAction&Version=1" + :iam-request-headers "{'foo':'bar'}"}))) + (is (empty? @api-requests)) + (is (empty? @api-auths))))) + (testing "When no iam-request-url is specified" + (let [client (http-client example-url) + api-requests (atom []) + api-auths (atom [])] + (with-redefs [api-util/do-api-request (fn [& args] + (swap! api-requests conj args)) + authenticate/api-auth! (fn [& args] + (swap! api-auths conj args))] + (is (thrown? IllegalArgumentException + (vault/authenticate! client :aws {:role "my-role" + :iam-http-request-method "POST" + :iam-request-body "FakeAction&Version=1" + :iam-request-headers "{'foo':'bar'}"}))) + (is (empty? @api-requests)) + (is (empty? @api-auths))))) + (testing "When no iam-request-body is specified" + (let [client (http-client example-url) + api-requests (atom []) + api-auths (atom [])] + (with-redefs [api-util/do-api-request (fn [& args] + (swap! api-requests conj args)) + authenticate/api-auth! (fn [& args] + (swap! api-auths conj args))] + (is (thrown? IllegalArgumentException + (vault/authenticate! client :aws {:role "my-role" + :iam-http-request-method "POST" + :iam-request-url "fake.sts.com" + :iam-request-headers "{'foo':'bar'}"}))) + (is (empty? @api-requests)) + (is (empty? @api-auths))))) + (testing "When no iam-request-headers is specified" + (let [client (http-client example-url) + api-requests (atom []) + api-auths (atom [])] + (with-redefs [api-util/do-api-request (fn [& args] + (swap! api-requests conj args)) + authenticate/api-auth! (fn [& args] + (swap! api-auths conj args))] + (is (thrown? IllegalArgumentException + (vault/authenticate! client :aws {:role "my-role" + :iam-http-request-method "POST" + :iam-request-url "fake.sts.com" + :iam-request-body "FakeAction&Version=1"}))) + (is (empty? @api-requests)) + (is (empty? @api-auths))))) + (testing "When no role is specified" + (let [client (http-client example-url) + api-requests (atom []) + api-auths (atom [])] + (with-redefs [api-util/do-api-request (fn [& args] + (swap! api-requests conj args)) + authenticate/api-auth! (fn [& args] + (swap! api-auths conj args))] + (is (thrown? IllegalArgumentException + (vault/authenticate! client :aws {:iam-http-request-method "POST" + :iam-request-url "fake.sts.com" + :iam-request-body "FakeAction&Version=1" + :iam-request-headers "{'foo':'bar'}"}))) + (is (empty? @api-requests)) + (is (empty? @api-auths))))))