Skip to content

Commit 00f181d

Browse files
committed
Use contexts in admin api handlers
1 parent 623c296 commit 00f181d

File tree

5 files changed

+95
-72
lines changed

5 files changed

+95
-72
lines changed

authority/admin/api/acme.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,11 @@ type GetExternalAccountKeysResponse struct {
4040

4141
// requireEABEnabled is a middleware that ensures ACME EAB is enabled
4242
// before serving requests that act on ACME EAB credentials.
43-
func (h *Handler) requireEABEnabled(next nextHTTP) nextHTTP {
43+
func requireEABEnabled(next nextHTTP) nextHTTP {
4444
return func(w http.ResponseWriter, r *http.Request) {
4545
ctx := r.Context()
4646
provName := chi.URLParam(r, "provisionerName")
47-
eabEnabled, prov, err := h.provisionerHasEABEnabled(ctx, provName)
47+
eabEnabled, prov, err := provisionerHasEABEnabled(ctx, provName)
4848
if err != nil {
4949
render.Error(w, err)
5050
return
@@ -60,16 +60,20 @@ func (h *Handler) requireEABEnabled(next nextHTTP) nextHTTP {
6060

6161
// provisionerHasEABEnabled determines if the "requireEAB" setting for an ACME
6262
// provisioner is set to true and thus has EAB enabled.
63-
func (h *Handler) provisionerHasEABEnabled(ctx context.Context, provisionerName string) (bool, *linkedca.Provisioner, error) {
63+
func provisionerHasEABEnabled(ctx context.Context, provisionerName string) (bool, *linkedca.Provisioner, error) {
6464
var (
6565
p provisioner.Interface
6666
err error
6767
)
68-
if p, err = h.auth.LoadProvisionerByName(provisionerName); err != nil {
68+
69+
auth := mustAuthority(ctx)
70+
db := admin.MustFromContext(ctx)
71+
72+
if p, err = auth.LoadProvisionerByName(provisionerName); err != nil {
6973
return false, nil, admin.WrapErrorISE(err, "error loading provisioner %s", provisionerName)
7074
}
7175

72-
prov, err := h.adminDB.GetProvisioner(ctx, p.GetID())
76+
prov, err := db.GetProvisioner(ctx, p.GetID())
7377
if err != nil {
7478
return false, nil, admin.WrapErrorISE(err, "error getting provisioner with ID: %s", p.GetID())
7579
}

authority/admin/api/admin.go

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,10 @@ type DeleteResponse struct {
8181
}
8282

8383
// GetAdmin returns the requested admin, or an error.
84-
func (h *Handler) GetAdmin(w http.ResponseWriter, r *http.Request) {
84+
func GetAdmin(w http.ResponseWriter, r *http.Request) {
8585
id := chi.URLParam(r, "id")
8686

87-
adm, ok := h.auth.LoadAdminByID(id)
87+
adm, ok := mustAuthority(r.Context()).LoadAdminByID(id)
8888
if !ok {
8989
render.Error(w, admin.NewError(admin.ErrorNotFoundType,
9090
"admin %s not found", id))
@@ -94,15 +94,15 @@ func (h *Handler) GetAdmin(w http.ResponseWriter, r *http.Request) {
9494
}
9595

9696
// GetAdmins returns a segment of admins associated with the authority.
97-
func (h *Handler) GetAdmins(w http.ResponseWriter, r *http.Request) {
97+
func GetAdmins(w http.ResponseWriter, r *http.Request) {
9898
cursor, limit, err := api.ParseCursor(r)
9999
if err != nil {
100100
render.Error(w, admin.WrapError(admin.ErrorBadRequestType, err,
101101
"error parsing cursor and limit from query params"))
102102
return
103103
}
104104

105-
admins, nextCursor, err := h.auth.GetAdmins(cursor, limit)
105+
admins, nextCursor, err := mustAuthority(r.Context()).GetAdmins(cursor, limit)
106106
if err != nil {
107107
render.Error(w, admin.WrapErrorISE(err, "error retrieving paginated admins"))
108108
return
@@ -114,7 +114,7 @@ func (h *Handler) GetAdmins(w http.ResponseWriter, r *http.Request) {
114114
}
115115

116116
// CreateAdmin creates a new admin.
117-
func (h *Handler) CreateAdmin(w http.ResponseWriter, r *http.Request) {
117+
func CreateAdmin(w http.ResponseWriter, r *http.Request) {
118118
var body CreateAdminRequest
119119
if err := read.JSON(r.Body, &body); err != nil {
120120
render.Error(w, admin.WrapError(admin.ErrorBadRequestType, err, "error reading request body"))
@@ -126,7 +126,8 @@ func (h *Handler) CreateAdmin(w http.ResponseWriter, r *http.Request) {
126126
return
127127
}
128128

129-
p, err := h.auth.LoadProvisionerByName(body.Provisioner)
129+
auth := mustAuthority(r.Context())
130+
p, err := auth.LoadProvisionerByName(body.Provisioner)
130131
if err != nil {
131132
render.Error(w, admin.WrapErrorISE(err, "error loading provisioner %s", body.Provisioner))
132133
return
@@ -137,7 +138,7 @@ func (h *Handler) CreateAdmin(w http.ResponseWriter, r *http.Request) {
137138
Type: body.Type,
138139
}
139140
// Store to authority collection.
140-
if err := h.auth.StoreAdmin(r.Context(), adm, p); err != nil {
141+
if err := auth.StoreAdmin(r.Context(), adm, p); err != nil {
141142
render.Error(w, admin.WrapErrorISE(err, "error storing admin"))
142143
return
143144
}
@@ -146,10 +147,10 @@ func (h *Handler) CreateAdmin(w http.ResponseWriter, r *http.Request) {
146147
}
147148

148149
// DeleteAdmin deletes admin.
149-
func (h *Handler) DeleteAdmin(w http.ResponseWriter, r *http.Request) {
150+
func DeleteAdmin(w http.ResponseWriter, r *http.Request) {
150151
id := chi.URLParam(r, "id")
151152

152-
if err := h.auth.RemoveAdmin(r.Context(), id); err != nil {
153+
if err := mustAuthority(r.Context()).RemoveAdmin(r.Context(), id); err != nil {
153154
render.Error(w, admin.WrapErrorISE(err, "error deleting admin %s", id))
154155
return
155156
}
@@ -158,7 +159,7 @@ func (h *Handler) DeleteAdmin(w http.ResponseWriter, r *http.Request) {
158159
}
159160

160161
// UpdateAdmin updates an existing admin.
161-
func (h *Handler) UpdateAdmin(w http.ResponseWriter, r *http.Request) {
162+
func UpdateAdmin(w http.ResponseWriter, r *http.Request) {
162163
var body UpdateAdminRequest
163164
if err := read.JSON(r.Body, &body); err != nil {
164165
render.Error(w, admin.WrapError(admin.ErrorBadRequestType, err, "error reading request body"))
@@ -171,8 +172,8 @@ func (h *Handler) UpdateAdmin(w http.ResponseWriter, r *http.Request) {
171172
}
172173

173174
id := chi.URLParam(r, "id")
174-
175-
adm, err := h.auth.UpdateAdmin(r.Context(), id, &linkedca.Admin{Type: body.Type})
175+
auth := mustAuthority(r.Context())
176+
adm, err := auth.UpdateAdmin(r.Context(), id, &linkedca.Admin{Type: body.Type})
176177
if err != nil {
177178
render.Error(w, admin.WrapErrorISE(err, "error updating admin %s", id))
178179
return

authority/admin/api/handler.go

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,66 @@
11
package api
22

33
import (
4+
"context"
5+
46
"github.com/smallstep/certificates/acme"
57
"github.com/smallstep/certificates/api"
8+
"github.com/smallstep/certificates/authority"
69
"github.com/smallstep/certificates/authority/admin"
710
)
811

912
// Handler is the Admin API request handler.
1013
type Handler struct {
11-
adminDB admin.DB
12-
auth adminAuthority
13-
acmeDB acme.DB
1414
acmeResponder acmeAdminResponderInterface
1515
}
1616

17+
// Route traffic and implement the Router interface.
18+
//
19+
// Deprecated: use Route(r api.Router, acmeResponder acmeAdminResponderInterface)
20+
func (h *Handler) Route(r api.Router) {
21+
Route(r, h.acmeResponder)
22+
}
23+
1724
// NewHandler returns a new Authority Config Handler.
25+
//
26+
// Deprecated: use Route(r api.Router, acmeResponder acmeAdminResponderInterface)
1827
func NewHandler(auth adminAuthority, adminDB admin.DB, acmeDB acme.DB, acmeResponder acmeAdminResponderInterface) api.RouterHandler {
1928
return &Handler{
20-
auth: auth,
21-
adminDB: adminDB,
22-
acmeDB: acmeDB,
2329
acmeResponder: acmeResponder,
2430
}
2531
}
2632

33+
var mustAuthority = func(ctx context.Context) adminAuthority {
34+
return authority.MustFromContext(ctx)
35+
}
36+
2737
// Route traffic and implement the Router interface.
28-
func (h *Handler) Route(r api.Router) {
38+
func Route(r api.Router, acmeResponder acmeAdminResponderInterface) {
2939
authnz := func(next nextHTTP) nextHTTP {
30-
return h.extractAuthorizeTokenAdmin(h.requireAPIEnabled(next))
40+
return extractAuthorizeTokenAdmin(requireAPIEnabled(next))
3141
}
3242

3343
requireEABEnabled := func(next nextHTTP) nextHTTP {
34-
return h.requireEABEnabled(next)
44+
return requireEABEnabled(next)
3545
}
3646

3747
// Provisioners
38-
r.MethodFunc("GET", "/provisioners/{name}", authnz(h.GetProvisioner))
39-
r.MethodFunc("GET", "/provisioners", authnz(h.GetProvisioners))
40-
r.MethodFunc("POST", "/provisioners", authnz(h.CreateProvisioner))
41-
r.MethodFunc("PUT", "/provisioners/{name}", authnz(h.UpdateProvisioner))
42-
r.MethodFunc("DELETE", "/provisioners/{name}", authnz(h.DeleteProvisioner))
48+
r.MethodFunc("GET", "/provisioners/{name}", authnz(GetProvisioner))
49+
r.MethodFunc("GET", "/provisioners", authnz(GetProvisioners))
50+
r.MethodFunc("POST", "/provisioners", authnz(CreateProvisioner))
51+
r.MethodFunc("PUT", "/provisioners/{name}", authnz(UpdateProvisioner))
52+
r.MethodFunc("DELETE", "/provisioners/{name}", authnz(DeleteProvisioner))
4353

4454
// Admins
45-
r.MethodFunc("GET", "/admins/{id}", authnz(h.GetAdmin))
46-
r.MethodFunc("GET", "/admins", authnz(h.GetAdmins))
47-
r.MethodFunc("POST", "/admins", authnz(h.CreateAdmin))
48-
r.MethodFunc("PATCH", "/admins/{id}", authnz(h.UpdateAdmin))
49-
r.MethodFunc("DELETE", "/admins/{id}", authnz(h.DeleteAdmin))
55+
r.MethodFunc("GET", "/admins/{id}", authnz(GetAdmin))
56+
r.MethodFunc("GET", "/admins", authnz(GetAdmins))
57+
r.MethodFunc("POST", "/admins", authnz(CreateAdmin))
58+
r.MethodFunc("PATCH", "/admins/{id}", authnz(UpdateAdmin))
59+
r.MethodFunc("DELETE", "/admins/{id}", authnz(DeleteAdmin))
5060

5161
// ACME External Account Binding Keys
52-
r.MethodFunc("GET", "/acme/eab/{provisionerName}/{reference}", authnz(requireEABEnabled(h.acmeResponder.GetExternalAccountKeys)))
53-
r.MethodFunc("GET", "/acme/eab/{provisionerName}", authnz(requireEABEnabled(h.acmeResponder.GetExternalAccountKeys)))
54-
r.MethodFunc("POST", "/acme/eab/{provisionerName}", authnz(requireEABEnabled(h.acmeResponder.CreateExternalAccountKey)))
55-
r.MethodFunc("DELETE", "/acme/eab/{provisionerName}/{id}", authnz(requireEABEnabled(h.acmeResponder.DeleteExternalAccountKey)))
62+
r.MethodFunc("GET", "/acme/eab/{provisionerName}/{reference}", authnz(requireEABEnabled(acmeResponder.GetExternalAccountKeys)))
63+
r.MethodFunc("GET", "/acme/eab/{provisionerName}", authnz(requireEABEnabled(acmeResponder.GetExternalAccountKeys)))
64+
r.MethodFunc("POST", "/acme/eab/{provisionerName}", authnz(requireEABEnabled(acmeResponder.CreateExternalAccountKey)))
65+
r.MethodFunc("DELETE", "/acme/eab/{provisionerName}/{id}", authnz(requireEABEnabled(acmeResponder.DeleteExternalAccountKey)))
5666
}

authority/admin/api/middleware.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,18 @@ type nextHTTP = func(http.ResponseWriter, *http.Request)
1212

1313
// requireAPIEnabled is a middleware that ensures the Administration API
1414
// is enabled before servicing requests.
15-
func (h *Handler) requireAPIEnabled(next nextHTTP) nextHTTP {
15+
func requireAPIEnabled(next nextHTTP) nextHTTP {
1616
return func(w http.ResponseWriter, r *http.Request) {
17-
if !h.auth.IsAdminAPIEnabled() {
18-
render.Error(w, admin.NewError(admin.ErrorNotImplementedType,
19-
"administration API not enabled"))
17+
if !mustAuthority(r.Context()).IsAdminAPIEnabled() {
18+
render.Error(w, admin.NewError(admin.ErrorNotImplementedType, "administration API not enabled"))
2019
return
2120
}
2221
next(w, r)
2322
}
2423
}
2524

2625
// extractAuthorizeTokenAdmin is a middleware that extracts and caches the bearer token.
27-
func (h *Handler) extractAuthorizeTokenAdmin(next nextHTTP) nextHTTP {
26+
func extractAuthorizeTokenAdmin(next nextHTTP) nextHTTP {
2827
return func(w http.ResponseWriter, r *http.Request) {
2928
tok := r.Header.Get("Authorization")
3029
if tok == "" {
@@ -33,13 +32,14 @@ func (h *Handler) extractAuthorizeTokenAdmin(next nextHTTP) nextHTTP {
3332
return
3433
}
3534

36-
adm, err := h.auth.AuthorizeAdminToken(r, tok)
35+
ctx := r.Context()
36+
adm, err := mustAuthority(ctx).AuthorizeAdminToken(r, tok)
3737
if err != nil {
3838
render.Error(w, err)
3939
return
4040
}
4141

42-
ctx := context.WithValue(r.Context(), adminContextKey, adm)
42+
ctx = context.WithValue(ctx, adminContextKey, adm)
4343
next(w, r.WithContext(ctx))
4444
}
4545
}

0 commit comments

Comments
 (0)