Skip to content

Commit

Permalink
Add support for all forms of Authenticated Origin Pulls (cloudflare#501)
Browse files Browse the repository at this point in the history
* 498: Add support for Global Authenticated Origin Pulls (tls_client_auth)

- Global AOP requires that an mTLS connection is established between the edge and origin, where the origin
receives a static shared client certificate from the edge and may verify it to check that it's talking
to the edge.
- The API is a simple on/off toggle for this to be enabled for all requests in the zone.

* 498: Add support for per-zone AOP

- Per Zone AOP is when you upload a client certificate to the edge and enable it to be sent to the
origin for all requests to any hostname in your zone.
- These certificates can be listed, get'd, and deleted.

* 498: Add support for Per Hostname AOP

- Per Hostname AOP allows you to upload a client certificate and apply it to individual
hostnames within a zone.
- The edge will use the configured client certificate for perfoming AOP with the origin.

Closes cloudflare#498
  • Loading branch information
dhaynespls authored Jul 14, 2020
1 parent 42c4be6 commit 0b251f8
Show file tree
Hide file tree
Showing 6 changed files with 970 additions and 0 deletions.
65 changes: 65 additions & 0 deletions authenticated_origin_pulls.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package cloudflare

import (
"encoding/json"
"time"

"github.com/pkg/errors"
)

// AuthenticatedOriginPulls represents global AuthenticatedOriginPulls (tls_client_auth) metadata.
type AuthenticatedOriginPulls struct {
ID string `json:"id"`
Value string `json:"value"`
Editable bool `json:"editable"`
ModifiedOn time.Time `json:"modified_on"`
}

// AuthenticatedOriginPullsResponse represents the response from the global AuthenticatedOriginPulls (tls_client_auth) details endpoint.
type AuthenticatedOriginPullsResponse struct {
Response
Result AuthenticatedOriginPulls `json:"result"`
}

// GetAuthenticatedOriginPullsStatus returns the configuration details for global AuthenticatedOriginPulls (tls_client_auth).
//
// API reference: https://api.cloudflare.com/#zone-settings-get-tls-client-auth-setting
func (api *API) GetAuthenticatedOriginPullsStatus(zoneID string) (AuthenticatedOriginPulls, error) {
uri := "/zones/" + zoneID + "/settings/tls_client_auth"
res, err := api.makeRequest("GET", uri, nil)
if err != nil {
return AuthenticatedOriginPulls{}, errors.Wrap(err, errMakeRequestError)
}
var r AuthenticatedOriginPullsResponse
if err := json.Unmarshal(res, &r); err != nil {
return AuthenticatedOriginPulls{}, errors.Wrap(err, errUnmarshalError)
}
return r.Result, nil
}

// SetAuthenticatedOriginPullsStatus toggles whether global AuthenticatedOriginPulls is enabled for the zone.
//
// API reference: https://api.cloudflare.com/#zone-settings-change-tls-client-auth-setting
func (api *API) SetAuthenticatedOriginPullsStatus(zoneID string, enable bool) (AuthenticatedOriginPulls, error) {
uri := "/zones/" + zoneID + "/settings/tls_client_auth"
var val string
if enable {
val = "on"
} else {
val = "off"
}
params := struct {
Value string `json:"value"`
}{
Value: val,
}
res, err := api.makeRequest("PATCH", uri, params)
if err != nil {
return AuthenticatedOriginPulls{}, errors.Wrap(err, errMakeRequestError)
}
var r AuthenticatedOriginPullsResponse
if err := json.Unmarshal(res, &r); err != nil {
return AuthenticatedOriginPulls{}, errors.Wrap(err, errUnmarshalError)
}
return r.Result, nil
}
149 changes: 149 additions & 0 deletions authenticated_origin_pulls_per_hostname.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
package cloudflare

import (
"encoding/json"
"time"

"github.com/pkg/errors"
)

// PerHostnameAuthenticatedOriginPullsCertificateDetails represents the metadata for a Per Hostname AuthenticatedOriginPulls certificate.
type PerHostnameAuthenticatedOriginPullsCertificateDetails struct {
ID string `json:"id"`
Certificate string `json:"certificate"`
Issuer string `json:"issuer"`
Signature string `json:"signature"`
SerialNumber string `json:"serial_number"`
ExpiresOn time.Time `json:"expires_on"`
Status string `json:"status"`
UploadedOn time.Time `json:"uploaded_on"`
}

// PerHostnameAuthenticatedOriginPullsCertificateResponse represents the response from endpoints relating to creating and deleting a Per Hostname AuthenticatedOriginPulls certificate.
type PerHostnameAuthenticatedOriginPullsCertificateResponse struct {
Response
Result PerHostnameAuthenticatedOriginPullsCertificateDetails `json:"result"`
}

// PerHostnameAuthenticatedOriginPullsDetails contains metadata about the Per Hostname AuthenticatedOriginPulls configuration on a hostname.
type PerHostnameAuthenticatedOriginPullsDetails struct {
Hostname string `json:"hostname"`
CertID string `json:"cert_id"`
Enabled bool `json:"enabled"`
Status string `json:"status"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
CertStatus string `json:"cert_status"`
Issuer string `json:"issuer"`
Signature string `json:"signature"`
SerialNumber string `json:"serial_number"`
Certificate string `json:"certificate"`
CertUploadedOn time.Time `json:"cert_uploaded_on"`
CertUpdatedAt time.Time `json:"cert_updated_at"`
ExpiresOn time.Time `json:"expires_on"`
}

// PerHostnameAuthenticatedOriginPullsDetailsResponse represents Per Hostname AuthenticatedOriginPulls configuration metadata for a single hostname.
type PerHostnameAuthenticatedOriginPullsDetailsResponse struct {
Response
Result PerHostnameAuthenticatedOriginPullsDetails `json:"result"`
}

// PerHostnamesAuthenticatedOriginPullsDetailsResponse represents Per Hostname AuthenticatedOriginPulls configuration metadata for multiple hostnames.
type PerHostnamesAuthenticatedOriginPullsDetailsResponse struct {
Response
Result []PerHostnameAuthenticatedOriginPullsDetails `json:"result"`
}

// PerHostnameAuthenticatedOriginPullsCertificateParams represents the required data related to the client certificate being uploaded to be used in Per Hostname AuthenticatedOriginPulls.
type PerHostnameAuthenticatedOriginPullsCertificateParams struct {
Certificate string `json:"certificate"`
PrivateKey string `json:"private_key"`
}

// PerHostnameAuthenticatedOriginPullsConfig represents the config state for Per Hostname AuthenticatedOriginPulls applied on a hostname.
type PerHostnameAuthenticatedOriginPullsConfig struct {
Hostname string `json:"hostname"`
CertID string `json:"cert_id"`
Enabled bool `json:"enabled"`
}

// UploadPerHostnameAuthenticatedOriginPullsCertificate will upload the provided certificate and private key to the edge under Per Hostname AuthenticatedOriginPulls.
//
// API reference: https://api.cloudflare.com/#per-hostname-authenticated-origin-pull-upload-a-hostname-client-certificate
func (api *API) UploadPerHostnameAuthenticatedOriginPullsCertificate(zoneID string, params PerHostnameAuthenticatedOriginPullsCertificateParams) (PerHostnameAuthenticatedOriginPullsCertificateDetails, error) {
uri := "/zones/" + zoneID + "/origin_tls_client_auth/hostnames/certificates"
res, err := api.makeRequest("POST", uri, params)
if err != nil {
return PerHostnameAuthenticatedOriginPullsCertificateDetails{}, errors.Wrap(err, errMakeRequestError)
}
var r PerHostnameAuthenticatedOriginPullsCertificateResponse
if err := json.Unmarshal(res, &r); err != nil {
return PerHostnameAuthenticatedOriginPullsCertificateDetails{}, errors.Wrap(err, errUnmarshalError)
}
return r.Result, nil
}

// GetPerHostnameAuthenticatedOriginPullsCertificate retrieves certificate metadata about the requested Per Hostname certificate.
//
// API reference: https://api.cloudflare.com/#per-hostname-authenticated-origin-pull-get-the-hostname-client-certificate
func (api *API) GetPerHostnameAuthenticatedOriginPullsCertificate(zoneID, certificateID string) (PerHostnameAuthenticatedOriginPullsCertificateDetails, error) {
uri := "/zones/" + zoneID + "/origin_tls_client_auth/hostnames/certificates/" + certificateID
res, err := api.makeRequest("GET", uri, nil)
if err != nil {
return PerHostnameAuthenticatedOriginPullsCertificateDetails{}, errors.Wrap(err, errMakeRequestError)
}
var r PerHostnameAuthenticatedOriginPullsCertificateResponse
if err := json.Unmarshal(res, &r); err != nil {
return PerHostnameAuthenticatedOriginPullsCertificateDetails{}, errors.Wrap(err, errUnmarshalError)
}
return r.Result, nil
}

// DeletePerHostnameAuthenticatedOriginPullsCertificate will remove the requested Per Hostname certificate from the edge.
//
// API reference: https://api.cloudflare.com/#per-hostname-authenticated-origin-pull-delete-hostname-client-certificate
func (api *API) DeletePerHostnameAuthenticatedOriginPullsCertificate(zoneID, certificateID string) (PerHostnameAuthenticatedOriginPullsCertificateDetails, error) {
uri := "/zones/" + zoneID + "/origin_tls_client_auth/hostnames/certificates/" + certificateID
res, err := api.makeRequest("DELETE", uri, nil)
if err != nil {
return PerHostnameAuthenticatedOriginPullsCertificateDetails{}, errors.Wrap(err, errMakeRequestError)
}
var r PerHostnameAuthenticatedOriginPullsCertificateResponse
if err := json.Unmarshal(res, &r); err != nil {
return PerHostnameAuthenticatedOriginPullsCertificateDetails{}, errors.Wrap(err, errUnmarshalError)
}
return r.Result, nil
}

// EditPerHostnameAuthenticatedOriginPullsConfig applies the supplied Per Hostname AuthenticatedOriginPulls config onto a hostname(s) in the edge.
//
// API reference: https://api.cloudflare.com/#per-hostname-authenticated-origin-pull-enable-or-disable-a-hostname-for-client-authentication
func (api *API) EditPerHostnameAuthenticatedOriginPullsConfig(zoneID string, config []PerHostnameAuthenticatedOriginPullsConfig) ([]PerHostnameAuthenticatedOriginPullsDetails, error) {
uri := "/zones/" + zoneID + "/origin_tls_client_auth/hostnames"
res, err := api.makeRequest("PUT", uri, nil)
if err != nil {
return []PerHostnameAuthenticatedOriginPullsDetails{}, errors.Wrap(err, errMakeRequestError)
}
var r PerHostnamesAuthenticatedOriginPullsDetailsResponse
if err := json.Unmarshal(res, &r); err != nil {
return []PerHostnameAuthenticatedOriginPullsDetails{}, errors.Wrap(err, errUnmarshalError)
}
return r.Result, nil
}

// GetPerHostnameAuthenticatedOriginPullsConfig returns the config state of Per Hostname AuthenticatedOriginPulls of the provided hostname within a zone.
//
// API reference: https://api.cloudflare.com/#per-hostname-authenticated-origin-pull-get-the-hostname-status-for-client-authentication
func (api *API) GetPerHostnameAuthenticatedOriginPullsConfig(zoneID, hostname string) (PerHostnameAuthenticatedOriginPullsDetails, error) {
uri := "/zones/" + zoneID + "/origin_tls_client_auth/hostnames/" + hostname
res, err := api.makeRequest("GET", uri, nil)
if err != nil {
return PerHostnameAuthenticatedOriginPullsDetails{}, errors.Wrap(err, errMakeRequestError)
}
var r PerHostnameAuthenticatedOriginPullsDetailsResponse
if err := json.Unmarshal(res, &r); err != nil {
return PerHostnameAuthenticatedOriginPullsDetails{}, errors.Wrap(err, errUnmarshalError)
}
return r.Result, nil
}
Loading

0 comments on commit 0b251f8

Please sign in to comment.