ACME accountUpdate ignore fields not recognized by the server.

This commit is contained in:
max furman 2020-05-08 11:52:30 -07:00
parent e855707dc2
commit 4cb777bdc1
2 changed files with 37 additions and 3 deletions

View file

@ -65,7 +65,9 @@ func (u *UpdateAccountRequest) Validate() error {
}
return nil
default:
return acme.MalformedErr(errors.Errorf("empty update request"))
// According to the ACME spec (https://tools.ietf.org/html/rfc8555#section-7.3.2)
// accountUpdate should ignore any fields not recognized by the server.
return nil
}
}
@ -148,6 +150,8 @@ func (h *Handler) GetUpdateAccount(w http.ResponseWriter, r *http.Request) {
return
}
// If PostAsGet just respond with the account, otherwise process like a
// normal Post request.
if !payload.isPostAsGet {
var uar UpdateAccountRequest
if err := json.Unmarshal(payload.value, &uar); err != nil {
@ -159,9 +163,12 @@ func (h *Handler) GetUpdateAccount(w http.ResponseWriter, r *http.Request) {
return
}
var err error
// If neither the status nor the contacts are being updated then ignore
// the updates and return 200. This conforms with the behavior detailed
// in the ACME spec (https://tools.ietf.org/html/rfc8555#section-7.3.2).
if uar.IsDeactivateRequest() {
acc, err = h.Auth.DeactivateAccount(prov, acc.GetID())
} else {
} else if len(uar.Contact) > 0 {
acc, err = h.Auth.UpdateAccount(prov, acc.GetID(), uar.Contact)
}
if err != nil {

View file

@ -143,6 +143,11 @@ func TestUpdateAccountRequestValidate(t *testing.T) {
},
}
},
"ok/accept-empty": func(t *testing.T) test {
return test{
uar: &UpdateAccountRequest{},
}
},
}
for name, run := range tests {
tc := run(t)
@ -700,7 +705,29 @@ func TestHandlerGetUpdateAccount(t *testing.T) {
statusCode: 200,
}
},
"ok/new-account": func(t *testing.T) test {
"ok/update-empty": func(t *testing.T) test {
uar := &UpdateAccountRequest{}
b, err := json.Marshal(uar)
assert.FatalError(t, err)
ctx := context.WithValue(context.Background(), provisionerContextKey, prov)
ctx = context.WithValue(ctx, accContextKey, &acc)
ctx = context.WithValue(ctx, payloadContextKey, &payloadInfo{value: b})
return test{
auth: &mockAcmeAuthority{
getLink: func(typ acme.Link, provID string, abs bool, in ...string) string {
assert.Equals(t, typ, acme.AccountLink)
assert.Equals(t, provID, acme.URLSafeProvisionerName(prov))
assert.True(t, abs)
assert.Equals(t, in, []string{accID})
return fmt.Sprintf("https://ca.smallstep.com/acme/%s/account/%s",
acme.URLSafeProvisionerName(prov), accID)
},
},
ctx: ctx,
statusCode: 200,
}
},
"ok/update-contacts": func(t *testing.T) test {
uar := &UpdateAccountRequest{
Contact: []string{"foo", "bar"},
}