Remove account ID in WFE2 if feature enabled (#4160)

This helps encourage ACME client developers to use the RFC 8555
specified `Location` header instead.

Fixes #4136.
This commit is contained in:
Roland Bracewell Shoemaker 2019-04-17 10:38:25 -07:00 committed by Daniel McCarney
parent 2e6ed805ed
commit 7ff30cf857
6 changed files with 58 additions and 6 deletions

View File

@ -140,7 +140,7 @@ func (cr CertificateRequest) MarshalJSON() ([]byte, error) {
// to account keys.
type Registration struct {
// Unique identifier
ID int64 `json:"id" db:"id"`
ID int64 `json:"id,omitempty" db:"id"`
// Account key to which the details are attached
Key *jose.JSONWebKey `json:"key"`

View File

@ -24,11 +24,12 @@ func _() {
_ = x[EarlyOrderRateLimit-13]
_ = x[EnforceMultiVA-14]
_ = x[MultiVAFullResults-15]
_ = x[RemoveWFE2AccountID-16]
}
const _FeatureFlag_name = "unusedPerformValidationRPCACME13KeyRolloverSimplifiedVAHTTPTLSSNIRevalidationAllowRenewalFirstRLCAAValidationMethodsCAAAccountURIProbeCTLogsHeadNonceStatusOKNewAuthorizationSchemaRevokeAtRASetIssuedNamesRenewalBitEarlyOrderRateLimitEnforceMultiVAMultiVAFullResults"
const _FeatureFlag_name = "unusedPerformValidationRPCACME13KeyRolloverSimplifiedVAHTTPTLSSNIRevalidationAllowRenewalFirstRLCAAValidationMethodsCAAAccountURIProbeCTLogsHeadNonceStatusOKNewAuthorizationSchemaRevokeAtRASetIssuedNamesRenewalBitEarlyOrderRateLimitEnforceMultiVAMultiVAFullResultsRemoveWFE2AccountID"
var _FeatureFlag_index = [...]uint16{0, 6, 26, 43, 59, 77, 96, 116, 129, 140, 157, 179, 189, 213, 232, 246, 264}
var _FeatureFlag_index = [...]uint16{0, 6, 26, 43, 59, 77, 96, 116, 129, 140, 157, 179, 189, 213, 232, 246, 264, 283}
func (i FeatureFlag) String() string {
if i < 0 || i >= FeatureFlag(len(_FeatureFlag_index)-1) {

View File

@ -44,6 +44,9 @@ const (
// MultiVAFullResults will cause the main VA to wait for all of the remote VA
// results, not just the threshold required to make a decision.
MultiVAFullResults
// RemoveWFE2AccountID will remove the account ID from account objects returned
// from the new-account endpoint if enabled.
RemoveWFE2AccountID
)
// List of features and their default value, protected by fMu
@ -64,6 +67,7 @@ var features = map[FeatureFlag]bool{
EarlyOrderRateLimit: false,
EnforceMultiVA: false,
MultiVAFullResults: false,
RemoveWFE2AccountID: false,
}
var fMu = new(sync.RWMutex)

View File

@ -37,7 +37,8 @@
},
"features": {
"HeadNonceStatusOK": true,
"NewAuthorizationSchema": true
"NewAuthorizationSchema": true,
"RemoveWFE2AccountID": true
}
},

View File

@ -494,6 +494,11 @@ func (wfe *WebFrontEndImpl) NewAccount(
web.RelativeEndpoint(request, fmt.Sprintf("%s%d", acctPath, existingAcct.ID)))
logEvent.Requester = existingAcct.ID
if features.Enabled(features.RemoveWFE2AccountID) {
// Zero out the account ID so that it isn't marshalled
existingAcct.ID = 0
}
err = wfe.writeJsonResponse(response, logEvent, http.StatusOK, existingAcct)
if err != nil {
// ServerInternal because we just created this account, and it
@ -569,6 +574,11 @@ func (wfe *WebFrontEndImpl) NewAccount(
response.Header().Add("Link", link(wfe.SubscriberAgreementURL, "terms-of-service"))
}
if features.Enabled(features.RemoveWFE2AccountID) {
// Zero out the account ID so that it isn't marshalled
acct.ID = 0
}
err = wfe.writeJsonResponse(response, logEvent, http.StatusCreated, acct)
if err != nil {
// ServerInternal because we just created this account, and it

View File

@ -211,6 +211,7 @@ type MockRegistrationAuthority struct {
}
func (ra *MockRegistrationAuthority) NewRegistration(ctx context.Context, acct core.Registration) (core.Registration, error) {
acct.ID = 1
return acct, nil
}
@ -1247,7 +1248,7 @@ func TestNewECDSAAccount(t *testing.T) {
test.AssertEquals(t, acct.Agreement, "")
test.AssertEquals(t, acct.InitialIP.String(), "1.1.1.1")
test.AssertEquals(t, responseWriter.Header().Get("Location"), "http://localhost/acme/acct/0")
test.AssertEquals(t, responseWriter.Header().Get("Location"), "http://localhost/acme/acct/1")
key = loadKey(t, []byte(testE1KeyPrivatePEM))
_, ok = key.(*ecdsa.PrivateKey)
@ -1393,7 +1394,7 @@ func TestNewAccount(t *testing.T) {
test.AssertEquals(
t, responseWriter.Header().Get("Location"),
"http://localhost/acme/acct/0")
"http://localhost/acme/acct/1")
// Load an existing key
key = loadKey(t, []byte(test1KeyPrivatePEM))
@ -1415,6 +1416,41 @@ func TestNewAccount(t *testing.T) {
test.AssertEquals(t, responseWriter.Body.String(), "{\n \"id\": 1,\n \"key\": {\n \"kty\": \"RSA\",\n \"n\": \"yNWVhtYEKJR21y9xsHV-PD_bYwbXSeNuFal46xYxVfRL5mqha7vttvjB_vc7Xg2RvgCxHPCqoxgMPTzHrZT75LjCwIW2K_klBYN8oYvTwwmeSkAz6ut7ZxPv-nZaT5TJhGk0NT2kh_zSpdriEJ_3vW-mqxYbbBmpvHqsa1_zx9fSuHYctAZJWzxzUZXykbWMWQZpEiE0J4ajj51fInEzVn7VxV-mzfMyboQjujPh7aNJxAWSq4oQEJJDgWwSh9leyoJoPpONHxh5nEE5AjE01FkGICSxjpZsF-w8hOTI3XXohUdu29Se26k2B0PolDSuj0GIQU6-W9TdLXSjBb2SpQ\",\n \"e\": \"AQAB\"\n },\n \"contact\": [\n \"mailto:person@mail.com\"\n ],\n \"agreement\": \"http://example.invalid/terms\",\n \"initialIp\": \"\",\n \"createdAt\": \"0001-01-01T00:00:00Z\",\n \"status\": \"valid\"\n}")
}
func TestNewAccountNoID(t *testing.T) {
wfe, _ := setupWFE(t)
key := loadKey(t, []byte(test2KeyPrivatePEM))
_, ok := key.(*rsa.PrivateKey)
test.Assert(t, ok, "Couldn't load test2 key")
path := newAcctPath
signedURL := fmt.Sprintf("http://localhost%s", path)
_ = features.Set(map[string]bool{
"RemoveWFE2AccountID": true,
})
payload := `{"contact":["mailto:person@mail.com"],"termsOfServiceAgreed":true}`
_, _, body := signRequestEmbed(t, key, signedURL, payload, wfe.nonceService)
request := makePostRequestWithPath(path, body)
responseWriter := httptest.NewRecorder()
wfe.NewAccount(ctx, newRequestEvent(), responseWriter, request)
responseBody := responseWriter.Body.String()
test.AssertUnmarshaledEquals(t, responseBody, `{
"key": {
"kty": "RSA",
"n": "qnARLrT7Xz4gRcKyLdydmCr-ey9OuPImX4X40thk3on26FkMznR3fRjs66eLK7mmPcBZ6uOJseURU6wAaZNmemoYx1dMvqvWWIyiQleHSD7Q8vBrhR6uIoO4jAzJZR-ChzZuSDt7iHN-3xUVspu5XGwXU_MVJZshTwp4TaFx5elHIT_ObnTvTOU3Xhish07AbgZKmWsVbXh5s-CrIicU4OexJPgunWZ_YJJueOKmTvnLlTV4MzKR2oZlBKZ27S0-SfdV_QDx_ydle5oMAyKVtlAV35cyPMIsYNwgUGBCdY_2Uzi5eX0lTc7MPRwz6qR1kip-i59VcGcUQgqHV6Fyqw",
"e": "AQAB"
},
"contact": [
"mailto:person@mail.com"
],
"initialIp": "1.1.1.1",
"createdAt": "0001-01-01T00:00:00Z",
"status": ""
}`)
}
func TestGetAuthorization(t *testing.T) {
wfe, _ := setupWFE(t)