acme/api: Set Link and Location headers for all 200

On the challenge resource, set "Link" and "Location" headers for all
successful requests to the challenge resource.
This commit is contained in:
David Cowden 2020-05-13 11:10:14 -07:00
parent 5354906b9c
commit 5e5a76c3b5
2 changed files with 29 additions and 14 deletions

View file

@ -216,23 +216,17 @@ func (h *Handler) GetChallenge(w http.ResponseWriter, r *http.Request) {
return
}
switch ch.Status {
case acme.StatusPending:
panic("validation attempt did not move challenge to the processing state")
// When a transient error occurs, the challenge will not be progressed to the `invalid` state.
// Add a Retry-After header to indicate that the client should check again in the future.
case acme.StatusProcessing:
getLink := h.Auth.GetLink
w.Header().Add("Link", link(getLink(acme.AuthzLink, acme.URLSafeProvisionerName(prov), true, ch.GetAuthzID()), "up"))
w.Header().Set("Location", getLink(acme.ChallengeLink, acme.URLSafeProvisionerName(prov), true, ch.GetID()))
if ch.Status == acme.StatusProcessing {
w.Header().Add("Retry-After", ch.RetryAfter)
// 200s are cachable. Don't cache this because it will likely change.
w.Header().Add("Cache-Control", "no-cache")
api.JSON(w, ch)
case acme.StatusValid, acme.StatusInvalid:
getLink := h.Auth.GetLink
w.Header().Add("Link", link(getLink(acme.AuthzLink, acme.URLSafeProvisionerName(prov), true, ch.GetAuthzID()), "up"))
w.Header().Set("Location", getLink(acme.ChallengeLink, acme.URLSafeProvisionerName(prov), true, ch.GetID()))
api.JSON(w, ch)
default:
panic("unexpected challenge state" + ch.Status)
}
api.JSON(w, ch)
}
// GetCertificate ACME api for retrieving a Certificate.

View file

@ -742,6 +742,7 @@ func TestHandlerGetChallenge(t *testing.T) {
chJSON, err := json.Marshal(ch)
assert.FatalError(t, err)
ctx = context.WithValue(ctx, payloadContextKey, &payloadInfo{value: chJSON})
count := 0
return test{
auth: &mockAcmeAuthority{
validateChallenge: func(p provisioner.Interface, accID, id string, jwk *jose.JSONWebKey) (*acme.Challenge, error) {
@ -751,7 +752,27 @@ func TestHandlerGetChallenge(t *testing.T) {
assert.Equals(t, jwk.KeyID, key.KeyID)
return &ch, nil
},
getLink: func(typ acme.Link, provID string, abs bool, in ...string) string {
var ret string
switch count {
case 0:
assert.Equals(t, typ, acme.AuthzLink)
assert.Equals(t, provID, acme.URLSafeProvisionerName(prov))
assert.True(t, abs)
assert.Equals(t, in, []string{ch.AuthzID})
ret = fmt.Sprintf("https://ca.smallstep.com/acme/authz/%s", ch.AuthzID)
case 1:
assert.Equals(t, typ, acme.ChallengeLink)
assert.Equals(t, provID, acme.URLSafeProvisionerName(prov))
assert.True(t, abs)
assert.Equals(t, in, []string{ch.ID})
ret = url
}
count++
return ret
},
},
ctx: ctx,
statusCode: 200,
ch: ch,