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:
		
							parent
							
								
									2e6ed805ed
								
							
						
					
					
						commit
						7ff30cf857
					
				| 
						 | 
				
			
			@ -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"`
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -37,7 +37,8 @@
 | 
			
		|||
    },
 | 
			
		||||
    "features": {
 | 
			
		||||
      "HeadNonceStatusOK": true,
 | 
			
		||||
      "NewAuthorizationSchema": true
 | 
			
		||||
      "NewAuthorizationSchema": true,
 | 
			
		||||
      "RemoveWFE2AccountID": true
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										10
									
								
								wfe2/wfe.go
								
								
								
								
							
							
						
						
									
										10
									
								
								wfe2/wfe.go
								
								
								
								
							| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue