forked from TrueCloudLab/certificates
api: refactored to support api/render
This commit is contained in:
parent
833ea1e695
commit
9aa480a09a
11 changed files with 30 additions and 131 deletions
15
api/api.go
15
api/api.go
|
@ -21,6 +21,7 @@ import (
|
|||
"github.com/go-chi/chi"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/smallstep/certificates/api/render"
|
||||
"github.com/smallstep/certificates/authority"
|
||||
"github.com/smallstep/certificates/authority/config"
|
||||
"github.com/smallstep/certificates/authority/provisioner"
|
||||
|
@ -282,7 +283,7 @@ func (h *caHandler) Route(r Router) {
|
|||
// Version is an HTTP handler that returns the version of the server.
|
||||
func (h *caHandler) Version(w http.ResponseWriter, r *http.Request) {
|
||||
v := h.Authority.Version()
|
||||
JSON(w, VersionResponse{
|
||||
render.JSON(w, VersionResponse{
|
||||
Version: v.Version,
|
||||
RequireClientAuthentication: v.RequireClientAuthentication,
|
||||
})
|
||||
|
@ -290,7 +291,7 @@ func (h *caHandler) Version(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
// Health is an HTTP handler that returns the status of the server.
|
||||
func (h *caHandler) Health(w http.ResponseWriter, r *http.Request) {
|
||||
JSON(w, HealthResponse{Status: "ok"})
|
||||
render.JSON(w, HealthResponse{Status: "ok"})
|
||||
}
|
||||
|
||||
// Root is an HTTP handler that using the SHA256 from the URL, returns the root
|
||||
|
@ -305,7 +306,7 @@ func (h *caHandler) Root(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
JSON(w, &RootResponse{RootPEM: Certificate{cert}})
|
||||
render.JSON(w, &RootResponse{RootPEM: Certificate{cert}})
|
||||
}
|
||||
|
||||
func certChainToPEM(certChain []*x509.Certificate) []Certificate {
|
||||
|
@ -329,7 +330,7 @@ func (h *caHandler) Provisioners(w http.ResponseWriter, r *http.Request) {
|
|||
WriteError(w, errs.InternalServerErr(err))
|
||||
return
|
||||
}
|
||||
JSON(w, &ProvisionersResponse{
|
||||
render.JSON(w, &ProvisionersResponse{
|
||||
Provisioners: p,
|
||||
NextCursor: next,
|
||||
})
|
||||
|
@ -343,7 +344,7 @@ func (h *caHandler) ProvisionerKey(w http.ResponseWriter, r *http.Request) {
|
|||
WriteError(w, errs.NotFoundErr(err))
|
||||
return
|
||||
}
|
||||
JSON(w, &ProvisionerKeyResponse{key})
|
||||
render.JSON(w, &ProvisionerKeyResponse{key})
|
||||
}
|
||||
|
||||
// Roots returns all the root certificates for the CA.
|
||||
|
@ -359,7 +360,7 @@ func (h *caHandler) Roots(w http.ResponseWriter, r *http.Request) {
|
|||
certs[i] = Certificate{roots[i]}
|
||||
}
|
||||
|
||||
JSONStatus(w, &RootsResponse{
|
||||
render.JSONStatus(w, &RootsResponse{
|
||||
Certificates: certs,
|
||||
}, http.StatusCreated)
|
||||
}
|
||||
|
@ -377,7 +378,7 @@ func (h *caHandler) Federation(w http.ResponseWriter, r *http.Request) {
|
|||
certs[i] = Certificate{federated[i]}
|
||||
}
|
||||
|
||||
JSONStatus(w, &FederationResponse{
|
||||
render.JSONStatus(w, &FederationResponse{
|
||||
Certificates: certs,
|
||||
}, http.StatusCreated)
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/smallstep/certificates/api/read"
|
||||
"github.com/smallstep/certificates/api/render"
|
||||
"github.com/smallstep/certificates/errs"
|
||||
)
|
||||
|
||||
|
@ -55,7 +56,7 @@ func (h *caHandler) Rekey(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
LogCertificate(w, certChain[0])
|
||||
JSONStatus(w, &SignResponse{
|
||||
render.JSONStatus(w, &SignResponse{
|
||||
ServerPEM: certChainPEM[0],
|
||||
CaPEM: caPEM,
|
||||
CertChainPEM: certChainPEM,
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/smallstep/certificates/api/render"
|
||||
"github.com/smallstep/certificates/errs"
|
||||
)
|
||||
|
||||
|
@ -34,7 +35,7 @@ func (h *caHandler) Renew(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
LogCertificate(w, certChain[0])
|
||||
JSONStatus(w, &SignResponse{
|
||||
render.JSONStatus(w, &SignResponse{
|
||||
ServerPEM: certChainPEM[0],
|
||||
CaPEM: caPEM,
|
||||
CertChainPEM: certChainPEM,
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"golang.org/x/crypto/ocsp"
|
||||
|
||||
"github.com/smallstep/certificates/api/read"
|
||||
"github.com/smallstep/certificates/api/render"
|
||||
"github.com/smallstep/certificates/authority"
|
||||
"github.com/smallstep/certificates/authority/provisioner"
|
||||
"github.com/smallstep/certificates/errs"
|
||||
|
@ -103,7 +104,7 @@ func (h *caHandler) Revoke(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
logRevoke(w, opts)
|
||||
JSON(w, &RevokeResponse{Status: "ok"})
|
||||
render.JSON(w, &RevokeResponse{Status: "ok"})
|
||||
}
|
||||
|
||||
func logRevoke(w http.ResponseWriter, ri *authority.RevokeOptions) {
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/smallstep/certificates/api/read"
|
||||
"github.com/smallstep/certificates/api/render"
|
||||
"github.com/smallstep/certificates/authority/config"
|
||||
"github.com/smallstep/certificates/authority/provisioner"
|
||||
"github.com/smallstep/certificates/errs"
|
||||
|
@ -84,7 +85,7 @@ func (h *caHandler) Sign(w http.ResponseWriter, r *http.Request) {
|
|||
caPEM = certChainPEM[1]
|
||||
}
|
||||
LogCertificate(w, certChain[0])
|
||||
JSONStatus(w, &SignResponse{
|
||||
render.JSONStatus(w, &SignResponse{
|
||||
ServerPEM: certChainPEM[0],
|
||||
CaPEM: caPEM,
|
||||
CertChainPEM: certChainPEM,
|
||||
|
|
15
api/ssh.go
15
api/ssh.go
|
@ -12,6 +12,7 @@ import (
|
|||
"golang.org/x/crypto/ssh"
|
||||
|
||||
"github.com/smallstep/certificates/api/read"
|
||||
"github.com/smallstep/certificates/api/render"
|
||||
"github.com/smallstep/certificates/authority"
|
||||
"github.com/smallstep/certificates/authority/config"
|
||||
"github.com/smallstep/certificates/authority/provisioner"
|
||||
|
@ -334,7 +335,7 @@ func (h *caHandler) SSHSign(w http.ResponseWriter, r *http.Request) {
|
|||
identityCertificate = certChainToPEM(certChain)
|
||||
}
|
||||
|
||||
JSONStatus(w, &SSHSignResponse{
|
||||
render.JSONStatus(w, &SSHSignResponse{
|
||||
Certificate: SSHCertificate{cert},
|
||||
AddUserCertificate: addUserCertificate,
|
||||
IdentityCertificate: identityCertificate,
|
||||
|
@ -363,7 +364,7 @@ func (h *caHandler) SSHRoots(w http.ResponseWriter, r *http.Request) {
|
|||
resp.UserKeys = append(resp.UserKeys, SSHPublicKey{PublicKey: k})
|
||||
}
|
||||
|
||||
JSON(w, resp)
|
||||
render.JSON(w, resp)
|
||||
}
|
||||
|
||||
// SSHFederation is an HTTP handler that returns the federated SSH public keys
|
||||
|
@ -388,7 +389,7 @@ func (h *caHandler) SSHFederation(w http.ResponseWriter, r *http.Request) {
|
|||
resp.UserKeys = append(resp.UserKeys, SSHPublicKey{PublicKey: k})
|
||||
}
|
||||
|
||||
JSON(w, resp)
|
||||
render.JSON(w, resp)
|
||||
}
|
||||
|
||||
// SSHConfig is an HTTP handler that returns rendered templates for ssh clients
|
||||
|
@ -421,7 +422,7 @@ func (h *caHandler) SSHConfig(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
JSON(w, cfg)
|
||||
render.JSON(w, cfg)
|
||||
}
|
||||
|
||||
// SSHCheckHost is the HTTP handler that returns if a hosts certificate exists or not.
|
||||
|
@ -441,7 +442,7 @@ func (h *caHandler) SSHCheckHost(w http.ResponseWriter, r *http.Request) {
|
|||
WriteError(w, errs.InternalServerErr(err))
|
||||
return
|
||||
}
|
||||
JSON(w, &SSHCheckPrincipalResponse{
|
||||
render.JSON(w, &SSHCheckPrincipalResponse{
|
||||
Exists: exists,
|
||||
})
|
||||
}
|
||||
|
@ -458,7 +459,7 @@ func (h *caHandler) SSHGetHosts(w http.ResponseWriter, r *http.Request) {
|
|||
WriteError(w, errs.InternalServerErr(err))
|
||||
return
|
||||
}
|
||||
JSON(w, &SSHGetHostsResponse{
|
||||
render.JSON(w, &SSHGetHostsResponse{
|
||||
Hosts: hosts,
|
||||
})
|
||||
}
|
||||
|
@ -481,7 +482,7 @@ func (h *caHandler) SSHBastion(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
JSON(w, &SSHBastionResponse{
|
||||
render.JSON(w, &SSHBastionResponse{
|
||||
Hostname: body.Hostname,
|
||||
Bastion: bastion,
|
||||
})
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"golang.org/x/crypto/ssh"
|
||||
|
||||
"github.com/smallstep/certificates/api/read"
|
||||
"github.com/smallstep/certificates/api/render"
|
||||
"github.com/smallstep/certificates/authority/provisioner"
|
||||
"github.com/smallstep/certificates/errs"
|
||||
)
|
||||
|
@ -84,7 +85,7 @@ func (h *caHandler) SSHRekey(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
JSONStatus(w, &SSHRekeyResponse{
|
||||
render.JSONStatus(w, &SSHRekeyResponse{
|
||||
Certificate: SSHCertificate{newCert},
|
||||
IdentityCertificate: identity,
|
||||
}, http.StatusCreated)
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/smallstep/certificates/api/read"
|
||||
"github.com/smallstep/certificates/api/render"
|
||||
"github.com/smallstep/certificates/authority/provisioner"
|
||||
"github.com/smallstep/certificates/errs"
|
||||
)
|
||||
|
@ -76,7 +77,7 @@ func (h *caHandler) SSHRenew(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
JSONStatus(w, &SSHSignResponse{
|
||||
render.JSONStatus(w, &SSHSignResponse{
|
||||
Certificate: SSHCertificate{newCert},
|
||||
IdentityCertificate: identity,
|
||||
}, http.StatusCreated)
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"golang.org/x/crypto/ocsp"
|
||||
|
||||
"github.com/smallstep/certificates/api/read"
|
||||
"github.com/smallstep/certificates/api/render"
|
||||
"github.com/smallstep/certificates/authority"
|
||||
"github.com/smallstep/certificates/authority/provisioner"
|
||||
"github.com/smallstep/certificates/errs"
|
||||
|
@ -82,7 +83,7 @@ func (h *caHandler) SSHRevoke(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
logSSHRevoke(w, opts)
|
||||
JSON(w, &SSHRevokeResponse{Status: "ok"})
|
||||
render.JSON(w, &SSHRevokeResponse{Status: "ok"})
|
||||
}
|
||||
|
||||
func logSSHRevoke(w http.ResponseWriter, ri *authority.RevokeOptions) {
|
||||
|
|
57
api/utils.go
57
api/utils.go
|
@ -1,57 +0,0 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
"github.com/smallstep/certificates/api/log"
|
||||
)
|
||||
|
||||
// JSON writes the passed value into the http.ResponseWriter.
|
||||
func JSON(w http.ResponseWriter, v interface{}) {
|
||||
JSONStatus(w, v, http.StatusOK)
|
||||
}
|
||||
|
||||
// JSONStatus writes the given value into the http.ResponseWriter and the
|
||||
// given status is written as the status code of the response.
|
||||
func JSONStatus(w http.ResponseWriter, v interface{}, status int) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(status)
|
||||
if err := json.NewEncoder(w).Encode(v); err != nil {
|
||||
log.Error(w, err)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
log.EnabledResponse(w, v)
|
||||
}
|
||||
|
||||
// ProtoJSON writes the passed value into the http.ResponseWriter.
|
||||
func ProtoJSON(w http.ResponseWriter, m proto.Message) {
|
||||
ProtoJSONStatus(w, m, http.StatusOK)
|
||||
}
|
||||
|
||||
// ProtoJSONStatus writes the given value into the http.ResponseWriter and the
|
||||
// given status is written as the status code of the response.
|
||||
func ProtoJSONStatus(w http.ResponseWriter, m proto.Message, status int) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(status)
|
||||
|
||||
b, err := protojson.Marshal(m)
|
||||
if err != nil {
|
||||
log.Error(w, err)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if _, err := w.Write(b); err != nil {
|
||||
log.Error(w, err)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// log.EnabledResponse(w, v)
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/smallstep/certificates/logging"
|
||||
)
|
||||
|
||||
func TestJSON(t *testing.T) {
|
||||
type args struct {
|
||||
rw http.ResponseWriter
|
||||
v interface{}
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
ok bool
|
||||
}{
|
||||
{"ok", args{httptest.NewRecorder(), map[string]interface{}{"foo": "bar"}}, true},
|
||||
{"fail", args{httptest.NewRecorder(), make(chan int)}, false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
rw := logging.NewResponseLogger(tt.args.rw)
|
||||
JSON(rw, tt.args.v)
|
||||
|
||||
rr, ok := tt.args.rw.(*httptest.ResponseRecorder)
|
||||
if !ok {
|
||||
t.Error("ResponseWriter does not implement *httptest.ResponseRecorder")
|
||||
return
|
||||
}
|
||||
|
||||
fields := rw.Fields()
|
||||
if tt.ok {
|
||||
if body := rr.Body.String(); body != "{\"foo\":\"bar\"}\n" {
|
||||
t.Errorf(`Unexpected body = %v, want {"foo":"bar"}`, body)
|
||||
}
|
||||
if len(fields) != 0 {
|
||||
t.Errorf("ResponseLogger fields = %v, wants 0 elements", fields)
|
||||
}
|
||||
} else {
|
||||
if body := rr.Body.String(); body != "" {
|
||||
t.Errorf("Unexpected body = %s, want empty string", body)
|
||||
}
|
||||
if len(fields) != 1 {
|
||||
t.Errorf("ResponseLogger fields = %v, wants 1 element", fields)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue