Skip to content

Commit 823170e

Browse files
authored
Merge pull request smallstep#858 from smallstep/panos/api/read
api/read: initial implementation of the package
2 parents 1200035 + e6b2359 commit 823170e

19 files changed

+134
-88
lines changed

api/api.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020

2121
"github.com/go-chi/chi"
2222
"github.com/pkg/errors"
23+
2324
"github.com/smallstep/certificates/authority"
2425
"github.com/smallstep/certificates/authority/config"
2526
"github.com/smallstep/certificates/authority/provisioner"

api/api_test.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,17 @@ import (
2828

2929
"github.com/go-chi/chi"
3030
"github.com/pkg/errors"
31+
"golang.org/x/crypto/ssh"
32+
33+
"go.step.sm/crypto/jose"
34+
"go.step.sm/crypto/x509util"
35+
3136
"github.com/smallstep/assert"
3237
"github.com/smallstep/certificates/authority"
3338
"github.com/smallstep/certificates/authority/provisioner"
3439
"github.com/smallstep/certificates/errs"
3540
"github.com/smallstep/certificates/logging"
3641
"github.com/smallstep/certificates/templates"
37-
"go.step.sm/crypto/jose"
38-
"go.step.sm/crypto/x509util"
39-
"golang.org/x/crypto/ssh"
4042
)
4143

4244
const (

api/errors.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"os"
88

99
"github.com/pkg/errors"
10+
1011
"github.com/smallstep/certificates/acme"
1112
"github.com/smallstep/certificates/authority/admin"
1213
"github.com/smallstep/certificates/errs"

api/read/read.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Package read implements request object readers.
2+
package read
3+
4+
import (
5+
"encoding/json"
6+
"io"
7+
8+
"google.golang.org/protobuf/encoding/protojson"
9+
"google.golang.org/protobuf/proto"
10+
11+
"github.com/smallstep/certificates/errs"
12+
)
13+
14+
// JSON reads JSON from the request body and stores it in the value
15+
// pointed by v.
16+
func JSON(r io.Reader, v interface{}) error {
17+
if err := json.NewDecoder(r).Decode(v); err != nil {
18+
return errs.BadRequestErr(err, "error decoding json")
19+
}
20+
return nil
21+
}
22+
23+
// ProtoJSON reads JSON from the request body and stores it in the value
24+
// pointed by v.
25+
func ProtoJSON(r io.Reader, m proto.Message) error {
26+
data, err := io.ReadAll(r)
27+
if err != nil {
28+
return errs.BadRequestErr(err, "error reading request body")
29+
}
30+
return protojson.Unmarshal(data, m)
31+
}

api/read/read_test.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package read
2+
3+
import (
4+
"io"
5+
"reflect"
6+
"strings"
7+
"testing"
8+
9+
"github.com/smallstep/certificates/errs"
10+
)
11+
12+
func TestJSON(t *testing.T) {
13+
type args struct {
14+
r io.Reader
15+
v interface{}
16+
}
17+
tests := []struct {
18+
name string
19+
args args
20+
wantErr bool
21+
}{
22+
{"ok", args{strings.NewReader(`{"foo":"bar"}`), make(map[string]interface{})}, false},
23+
{"fail", args{strings.NewReader(`{"foo"}`), make(map[string]interface{})}, true},
24+
}
25+
for _, tt := range tests {
26+
t.Run(tt.name, func(t *testing.T) {
27+
err := JSON(tt.args.r, &tt.args.v)
28+
if (err != nil) != tt.wantErr {
29+
t.Errorf("JSON() error = %v, wantErr %v", err, tt.wantErr)
30+
}
31+
32+
if tt.wantErr {
33+
e, ok := err.(*errs.Error)
34+
if ok {
35+
if code := e.StatusCode(); code != 400 {
36+
t.Errorf("error.StatusCode() = %v, wants 400", code)
37+
}
38+
} else {
39+
t.Errorf("error type = %T, wants *Error", err)
40+
}
41+
} else if !reflect.DeepEqual(tt.args.v, map[string]interface{}{"foo": "bar"}) {
42+
t.Errorf("JSON value = %v, wants %v", tt.args.v, map[string]interface{}{"foo": "bar"})
43+
}
44+
})
45+
}
46+
}

api/rekey.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package api
33
import (
44
"net/http"
55

6+
"github.com/smallstep/certificates/api/read"
67
"github.com/smallstep/certificates/errs"
78
)
89

@@ -32,7 +33,7 @@ func (h *caHandler) Rekey(w http.ResponseWriter, r *http.Request) {
3233
}
3334

3435
var body RekeyRequest
35-
if err := ReadJSON(r.Body, &body); err != nil {
36+
if err := read.JSON(r.Body, &body); err != nil {
3637
WriteError(w, errs.BadRequestErr(err, "error reading request body"))
3738
return
3839
}

api/revoke.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ import (
44
"context"
55
"net/http"
66

7+
"golang.org/x/crypto/ocsp"
8+
9+
"github.com/smallstep/certificates/api/read"
710
"github.com/smallstep/certificates/authority"
811
"github.com/smallstep/certificates/authority/provisioner"
912
"github.com/smallstep/certificates/errs"
1013
"github.com/smallstep/certificates/logging"
11-
"golang.org/x/crypto/ocsp"
1214
)
1315

1416
// RevokeResponse is the response object that returns the health of the server.
@@ -48,7 +50,7 @@ func (r *RevokeRequest) Validate() (err error) {
4850
// TODO: Add CRL and OCSP support.
4951
func (h *caHandler) Revoke(w http.ResponseWriter, r *http.Request) {
5052
var body RevokeRequest
51-
if err := ReadJSON(r.Body, &body); err != nil {
53+
if err := read.JSON(r.Body, &body); err != nil {
5254
WriteError(w, errs.BadRequestErr(err, "error reading request body"))
5355
return
5456
}

api/revoke_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"testing"
1414

1515
"github.com/pkg/errors"
16+
1617
"github.com/smallstep/assert"
1718
"github.com/smallstep/certificates/authority"
1819
"github.com/smallstep/certificates/authority/provisioner"

api/sign.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"encoding/json"
66
"net/http"
77

8+
"github.com/smallstep/certificates/api/read"
89
"github.com/smallstep/certificates/authority/config"
910
"github.com/smallstep/certificates/authority/provisioner"
1011
"github.com/smallstep/certificates/errs"
@@ -49,7 +50,7 @@ type SignResponse struct {
4950
// information in the certificate request.
5051
func (h *caHandler) Sign(w http.ResponseWriter, r *http.Request) {
5152
var body SignRequest
52-
if err := ReadJSON(r.Body, &body); err != nil {
53+
if err := read.JSON(r.Body, &body); err != nil {
5354
WriteError(w, errs.BadRequestErr(err, "error reading request body"))
5455
return
5556
}

api/ssh.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@ import (
99
"time"
1010

1111
"github.com/pkg/errors"
12+
"golang.org/x/crypto/ssh"
13+
14+
"github.com/smallstep/certificates/api/read"
1215
"github.com/smallstep/certificates/authority"
1316
"github.com/smallstep/certificates/authority/config"
1417
"github.com/smallstep/certificates/authority/provisioner"
1518
"github.com/smallstep/certificates/errs"
1619
"github.com/smallstep/certificates/templates"
17-
"golang.org/x/crypto/ssh"
1820
)
1921

2022
// SSHAuthority is the interface implemented by a SSH CA authority.
@@ -249,7 +251,7 @@ type SSHBastionResponse struct {
249251
// the request.
250252
func (h *caHandler) SSHSign(w http.ResponseWriter, r *http.Request) {
251253
var body SSHSignRequest
252-
if err := ReadJSON(r.Body, &body); err != nil {
254+
if err := read.JSON(r.Body, &body); err != nil {
253255
WriteError(w, errs.BadRequestErr(err, "error reading request body"))
254256
return
255257
}
@@ -393,7 +395,7 @@ func (h *caHandler) SSHFederation(w http.ResponseWriter, r *http.Request) {
393395
// and servers.
394396
func (h *caHandler) SSHConfig(w http.ResponseWriter, r *http.Request) {
395397
var body SSHConfigRequest
396-
if err := ReadJSON(r.Body, &body); err != nil {
398+
if err := read.JSON(r.Body, &body); err != nil {
397399
WriteError(w, errs.BadRequestErr(err, "error reading request body"))
398400
return
399401
}
@@ -425,7 +427,7 @@ func (h *caHandler) SSHConfig(w http.ResponseWriter, r *http.Request) {
425427
// SSHCheckHost is the HTTP handler that returns if a hosts certificate exists or not.
426428
func (h *caHandler) SSHCheckHost(w http.ResponseWriter, r *http.Request) {
427429
var body SSHCheckPrincipalRequest
428-
if err := ReadJSON(r.Body, &body); err != nil {
430+
if err := read.JSON(r.Body, &body); err != nil {
429431
WriteError(w, errs.BadRequestErr(err, "error reading request body"))
430432
return
431433
}
@@ -464,7 +466,7 @@ func (h *caHandler) SSHGetHosts(w http.ResponseWriter, r *http.Request) {
464466
// SSHBastion provides returns the bastion configured if any.
465467
func (h *caHandler) SSHBastion(w http.ResponseWriter, r *http.Request) {
466468
var body SSHBastionRequest
467-
if err := ReadJSON(r.Body, &body); err != nil {
469+
if err := read.JSON(r.Body, &body); err != nil {
468470
WriteError(w, errs.BadRequestErr(err, "error reading request body"))
469471
return
470472
}

0 commit comments

Comments
 (0)