Skip to content

Commit

Permalink
(PE-37345) Create new bulk signing endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
artlawson committed Dec 19, 2023
1 parent 83f6be3 commit f96d9b4
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 3 deletions.
29 changes: 26 additions & 3 deletions src/clj/puppetlabs/services/ca/certificate_authority_core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
[ring.util.request :as request]
[ring.util.response :as rr]
[schema.core :as schema]
[slingshot.slingshot :as sling])
[slingshot.slingshot :refer [try+]])
(:import (clojure.lang IFn)
(java.io ByteArrayInputStream InputStream StringWriter)
(java.security.cert X509Certificate)
Expand Down Expand Up @@ -77,7 +77,7 @@
[ca-settings :- ca/CaSettings
report-activity
{:keys [body] {:keys [subject]} :route-params :as request}]
(sling/try+
(try+
(let [report-activity-fn (ca/create-report-activity-fn report-activity request)]
(ca/process-csr-submission! subject body ca-settings report-activity-fn)
(rr/content-type (rr/response nil) "text/plain"))
Expand Down Expand Up @@ -257,6 +257,25 @@
request-cert)
(log/warn (i18n/trs "Request is missing a certificate for an endpoint that requires a certificate."))))))

(schema/def Certnames [schema/Str])

(schema/defn handle-bulk-cert-signing
[request
_ca-settings :- ca/CaSettings]
(let [json-body (try-to-parse (:body request))
certnames (:certnames json-body)]
(schema/validate Certnames certnames)
(-> (rr/response (cheshire/generate-string {}))
(rr/status 200)
(rr/content-type "application/json"))))

(schema/defn handle-bulk-cert-signing-all
[_request
_ca-settings :- ca/CaSettings]
(-> (rr/response (cheshire/generate-string {}))
(rr/status 200)
(rr/content-type "application/json")))

(schema/defn ^:always-validate
handle-cert-renewal
"Given a request and the CA settings, if there is a cert present in the request
Expand Down Expand Up @@ -540,7 +559,11 @@
(PUT ["/clean"] request
(handle-cert-clean request ca-settings report-activity))
(POST ["/certificate_renewal"] request
(handle-cert-renewal request ca-settings report-activity)))
(handle-cert-renewal request ca-settings report-activity))
(POST ["/sign"] request
(handle-bulk-cert-signing request ca-settings))
(POST ["/sign/all"] request
(handle-bulk-cert-signing-all request ca-settings)))
(comidi/not-found "Not Found")))

(schema/defn ^:always-validate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
(:require
[cheshire.core :as json]
[clj-time.core :as time]
[cheshire.core :as cheshire]
[clj-time.format :as time-format]
[clojure.java.io :as io]
[clojure.test :refer [deftest is testing use-fixtures]]
Expand Down Expand Up @@ -1152,6 +1153,66 @@
:body "Bad data"})]
(is (= 400 (:status response)))))))

(deftest ca-bulk-signing-endpoint-test
(testing "ca bulk signing endpoint "
(bootstrap/with-puppetserver-running-with-mock-jrubies
"JRuby mocking is safe here because all of the requests are to the CA
endpoints, which are implemented in Clojure."
app
{:jruby-puppet
{:gem-path [(ks/absolute-path jruby-testutils/gem-path)]}
:webserver
{:ssl-cert (str bootstrap/server-conf-dir "/ssl/certs/localhost.pem")
:ssl-key (str bootstrap/server-conf-dir "/ssl/private_keys/localhost.pem")
:ssl-ca-cert (str bootstrap/server-conf-dir "/ca/ca_crt.pem")
:ssl-crl-path (str bootstrap/server-conf-dir "/ssl/crl.pem")}}

(testing "returns 200 with valid payload"
(let [random-certname (ks/rand-str :alpha-lower 16)
response (http-client/post
"https://localhost:8140/puppet-ca/v1/sign"
{:body (json/encode {:certnames [random-certname]})
:ssl-cert (str bootstrap/server-conf-dir "/ca/ca_crt.pem")
:ssl-key (str bootstrap/server-conf-dir "/ca/ca_key.pem")
:ssl-ca-cert (str bootstrap/server-conf-dir "/ca/ca_crt.pem")
:as :text
:headers {"Accept" "application/json"}})]
(is (= 200 (:status response)))))
(testing "returns 500 with invalid payload"
(let [response (http-client/post
"https://localhost:8140/puppet-ca/v1/sign"
{:body (json/encode {:certnames [1 2 3]})
:ssl-cert (str bootstrap/server-conf-dir "/ca/ca_crt.pem")
:ssl-key (str bootstrap/server-conf-dir "/ca/ca_key.pem")
:ssl-ca-cert (str bootstrap/server-conf-dir "/ca/ca_crt.pem")
:as :text
:headers {"Accept" "application/json"}})]
(clojure.pprint/pprint ((cheshire/parse-stream (io/reader (:body response)) true)))
(is (= 500 (:status response)))
)))))

(deftest ca-bulk-signing-all-endpoint-test
(testing "returns 200 response"
(bootstrap/with-puppetserver-running-with-mock-jrubies
"JRuby mocking is safe here because all of the requests are to the CA
endpoints, which are implemented in Clojure."
app
{:jruby-puppet
{:gem-path [(ks/absolute-path jruby-testutils/gem-path)]}
:webserver
{:ssl-cert (str bootstrap/server-conf-dir "/ssl/certs/localhost.pem")
:ssl-key (str bootstrap/server-conf-dir "/ssl/private_keys/localhost.pem")
:ssl-ca-cert (str bootstrap/server-conf-dir "/ca/ca_crt.pem")
:ssl-crl-path (str bootstrap/server-conf-dir "/ssl/crl.pem")}}
(let [response (http-client/post
"https://localhost:8140/puppet-ca/v1/sign/all"
{:ssl-cert (str bootstrap/server-conf-dir "/ca/ca_crt.pem")
:ssl-key (str bootstrap/server-conf-dir "/ca/ca_key.pem")
:ssl-ca-cert (str bootstrap/server-conf-dir "/ca/ca_crt.pem")
:as :text
:headers {"Accept" "application/json"}})]
(is (= 200 (:status response)))))))

(deftest ca-certificate-renew-endpoint-test
(testing "with the feature enabled"
(testing "with allow-header-cert-info = false (default)"
Expand Down

0 comments on commit f96d9b4

Please sign in to comment.