Skip to content

Commit

Permalink
Merge pull request #2799 from artlawson/PE-37345
Browse files Browse the repository at this point in the history
(PE-37345) Create new bulk signing endpoints
  • Loading branch information
steveax authored Dec 21, 2023
2 parents 921e004 + eb544c5 commit f9971f4
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 3 deletions.
34 changes: 31 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,30 @@
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)]
(if-let [schema-error (schema/check Certnames certnames)]
(-> (rr/response (cheshire/generate-string {:kind :schema-violation
:submitted certnames
:error (str schema-error)}))
(rr/status 422)
(rr/content-type "application/json"))
(-> (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 +564,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 @@ -1152,6 +1152,67 @@
: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 "throws schema violation for invalid certname"
(let [error-msg "{\"kind\":\"schema-violation\""
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"}})
body (:body response)]
(is (= 422 (:status response)))
(is (.contains body error-msg)))))))

(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 f9971f4

Please sign in to comment.