Enable integration tests for authz2 and fix a few bugs (#4221)
Enables integration tests for authz2 and fixes a few bugs that were flagged up during the process. Disables expired-authorization-purger integration tests if config-next is being used as expired-authz-purger expects to purge some stuff but doesn't know about authz2 authorizations, a new test will be added with #4188. Fixes #4079.
This commit is contained in:
		
							parent
							
								
									1014a81606
								
							
						
					
					
						commit
						4d40cf58e4
					
				|  | @ -421,7 +421,7 @@ func orderValid(order *corepb.Order) bool { | ||||||
| // `order.CertificateSerial` to be nil such that it can be used in places where
 | // `order.CertificateSerial` to be nil such that it can be used in places where
 | ||||||
| // the order has not been finalized yet.
 | // the order has not been finalized yet.
 | ||||||
| func newOrderValid(order *corepb.Order) bool { | func newOrderValid(order *corepb.Order) bool { | ||||||
| 	return !(order.RegistrationID == nil || order.Expires == nil || order.Authorizations == nil || order.Names == nil) | 	return !(order.RegistrationID == nil || order.Expires == nil || (order.Authorizations == nil && order.V2Authorizations == nil) || order.Names == nil) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func authorizationValid(authz *corepb.Authorization) bool { | func authorizationValid(authz *corepb.Authorization) bool { | ||||||
|  |  | ||||||
|  | @ -1213,7 +1213,7 @@ func (sas StorageAuthorityServerWrapper) FinalizeAuthorization2(ctx context.Cont | ||||||
| 		return nil, errIncompleteRequest | 		return nil, errIncompleteRequest | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return nil, sas.inner.FinalizeAuthorization2(ctx, req) | 	return &corepb.Empty{}, sas.inner.FinalizeAuthorization2(ctx, req) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (sas StorageAuthorityServerWrapper) GetPendingAuthorization2(ctx context.Context, req *sapb.GetPendingAuthorizationRequest) (*corepb.Authorization, error) { | func (sas StorageAuthorityServerWrapper) GetPendingAuthorization2(ctx context.Context, req *sapb.GetPendingAuthorizationRequest) (*corepb.Authorization, error) { | ||||||
|  |  | ||||||
|  | @ -47,7 +47,8 @@ | ||||||
|     }, |     }, | ||||||
|     "features": { |     "features": { | ||||||
|       "RevokeAtRA": true, |       "RevokeAtRA": true, | ||||||
|       "EarlyOrderRateLimit": true |       "EarlyOrderRateLimit": true, | ||||||
|  |       "NewAuthorizationSchema": true | ||||||
|     }, |     }, | ||||||
|     "CTLogGroups2": [ |     "CTLogGroups2": [ | ||||||
|       { |       { | ||||||
|  |  | ||||||
|  | @ -31,6 +31,7 @@ | ||||||
|       "timeout": "15s" |       "timeout": "15s" | ||||||
|     }, |     }, | ||||||
|     "features": { |     "features": { | ||||||
|  |       "NewAuthorizationSchema": true | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -239,7 +239,8 @@ def main(): | ||||||
|     # traffic. |     # traffic. | ||||||
|     if not args.test_case_filter: |     if not args.test_case_filter: | ||||||
|         check_balance() |         check_balance() | ||||||
|     run_expired_authz_purger() |     if not CONFIG_NEXT: | ||||||
|  |         run_expired_authz_purger() | ||||||
| 
 | 
 | ||||||
|     # Run the load-generator last. run_loadtest will stop the |     # Run the load-generator last. run_loadtest will stop the | ||||||
|     # pebble-challtestsrv before running the load-generator and will not restart |     # pebble-challtestsrv before running the load-generator and will not restart | ||||||
|  |  | ||||||
							
								
								
									
										45
									
								
								wfe/wfe.go
								
								
								
								
							
							
						
						
									
										45
									
								
								wfe/wfe.go
								
								
								
								
							|  | @ -58,6 +58,8 @@ const ( | ||||||
| 	rolloverPath   = "/acme/key-change" | 	rolloverPath   = "/acme/key-change" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | const authz2Prefix = "v2" | ||||||
|  | 
 | ||||||
| // WebFrontEndImpl provides all the logic for Boulder's web-facing interface,
 | // WebFrontEndImpl provides all the logic for Boulder's web-facing interface,
 | ||||||
| // i.e., ACME.  Its members configure the paths for various ACME functions,
 | // i.e., ACME.  Its members configure the paths for various ACME functions,
 | ||||||
| // plus a few other data items used in ACME.  Its methods are primarily handlers
 | // plus a few other data items used in ACME.  Its methods are primarily handlers
 | ||||||
|  | @ -688,7 +690,12 @@ func (wfe *WebFrontEndImpl) NewAuthorization(ctx context.Context, logEvent *web. | ||||||
| 	logEvent.Created = authz.ID | 	logEvent.Created = authz.ID | ||||||
| 
 | 
 | ||||||
| 	// Make a URL for this authz, then blow away the ID and RegID before serializing
 | 	// Make a URL for this authz, then blow away the ID and RegID before serializing
 | ||||||
| 	authzURL := web.RelativeEndpoint(request, authzPath+string(authz.ID)) | 	var authzURL string | ||||||
|  | 	if authz.V2 { | ||||||
|  | 		authzURL = web.RelativeEndpoint(request, fmt.Sprintf("%s%s/%s", authzPath, authz2Prefix, authz.ID)) | ||||||
|  | 	} else { | ||||||
|  | 		authzURL = web.RelativeEndpoint(request, authzPath+string(authz.ID)) | ||||||
|  | 	} | ||||||
| 	wfe.prepAuthorizationForDisplay(request, &authz) | 	wfe.prepAuthorizationForDisplay(request, &authz) | ||||||
| 
 | 
 | ||||||
| 	response.Header().Add("Location", authzURL) | 	response.Header().Add("Location", authzURL) | ||||||
|  | @ -703,16 +710,34 @@ func (wfe *WebFrontEndImpl) NewAuthorization(ctx context.Context, logEvent *web. | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (wfe *WebFrontEndImpl) regHoldsAuthorizations(ctx context.Context, regID int64, names []string) (bool, error) { | func (wfe *WebFrontEndImpl) regHoldsAuthorizations(ctx context.Context, regID int64, names []string) (bool, error) { | ||||||
| 	authz, err := wfe.SA.GetValidAuthorizations(ctx, regID, names, wfe.clk.Now()) | 	var authzMap map[string]*core.Authorization | ||||||
| 	if err != nil { | 	if features.Enabled(features.NewAuthorizationSchema) { | ||||||
| 		return false, err | 		now := wfe.clk.Now().UnixNano() | ||||||
|  | 		authzMapPB, err := wfe.SA.GetValidAuthorizations2(ctx, &sapb.GetValidAuthorizationsRequest{ | ||||||
|  | 			RegistrationID: ®ID, | ||||||
|  | 			Domains:        names, | ||||||
|  | 			Now:            &now, | ||||||
|  | 		}) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return false, err | ||||||
|  | 		} | ||||||
|  | 		authzMap, err = bgrpc.PBToAuthzMap(authzMapPB) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return false, err | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		var err error | ||||||
|  | 		authzMap, err = wfe.SA.GetValidAuthorizations(ctx, regID, names, wfe.clk.Now()) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return false, err | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 	if len(names) != len(authz) { | 	if len(names) != len(authzMap) { | ||||||
| 		return false, nil | 		return false, nil | ||||||
| 	} | 	} | ||||||
| 	missingNames := false | 	missingNames := false | ||||||
| 	for _, name := range names { | 	for _, name := range names { | ||||||
| 		if _, present := authz[name]; !present { | 		if _, present := authzMap[name]; !present { | ||||||
| 			missingNames = true | 			missingNames = true | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | @ -955,7 +980,7 @@ func (wfe *WebFrontEndImpl) Challenge( | ||||||
| 	var err error | 	var err error | ||||||
| 	var v2 bool | 	var v2 bool | ||||||
| 	if len(slug) == 3 { | 	if len(slug) == 3 { | ||||||
| 		if !features.Enabled(features.NewAuthorizationSchema) || slug[0] != "v2" { | 		if !features.Enabled(features.NewAuthorizationSchema) || slug[0] != authz2Prefix { | ||||||
| 			notFound() | 			notFound() | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
|  | @ -1042,7 +1067,7 @@ func (wfe *WebFrontEndImpl) Challenge( | ||||||
| func (wfe *WebFrontEndImpl) prepChallengeForDisplay(request *http.Request, authz core.Authorization, challenge *core.Challenge) { | func (wfe *WebFrontEndImpl) prepChallengeForDisplay(request *http.Request, authz core.Authorization, challenge *core.Challenge) { | ||||||
| 	// Update the challenge URI to be relative to the HTTP request Host
 | 	// Update the challenge URI to be relative to the HTTP request Host
 | ||||||
| 	if authz.V2 { | 	if authz.V2 { | ||||||
| 		challenge.URI = web.RelativeEndpoint(request, fmt.Sprintf("%sv2/%s/%s", challengePath, authz.ID, challenge.StringID())) | 		challenge.URI = web.RelativeEndpoint(request, fmt.Sprintf("%s%s/%s/%s", challengePath, authz2Prefix, authz.ID, challenge.StringID())) | ||||||
| 	} else { | 	} else { | ||||||
| 		challenge.URI = web.RelativeEndpoint(request, fmt.Sprintf("%s%s/%d", challengePath, authz.ID, challenge.ID)) | 		challenge.URI = web.RelativeEndpoint(request, fmt.Sprintf("%s%s/%d", challengePath, authz.ID, challenge.ID)) | ||||||
| 	} | 	} | ||||||
|  | @ -1324,8 +1349,8 @@ func (wfe *WebFrontEndImpl) Authorization(ctx context.Context, logEvent *web.Req | ||||||
| 	id := request.URL.Path | 	id := request.URL.Path | ||||||
| 	var authz core.Authorization | 	var authz core.Authorization | ||||||
| 	var err error | 	var err error | ||||||
| 	if features.Enabled(features.NewAuthorizationSchema) && strings.HasPrefix(id, "/v2/") { | 	if features.Enabled(features.NewAuthorizationSchema) && strings.HasPrefix(id, authz2Prefix) { | ||||||
| 		authzID, err := strconv.ParseInt(id[4:], 10, 64) | 		authzID, err := strconv.ParseInt(strings.TrimPrefix(id, authz2Prefix+"/"), 10, 64) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			wfe.sendError(response, logEvent, probs.NotFound("No such authorization"), nil) | 			wfe.sendError(response, logEvent, probs.NotFound("No such authorization"), nil) | ||||||
| 			return | 			return | ||||||
|  |  | ||||||
|  | @ -1845,7 +1845,7 @@ func TestAuthorization(t *testing.T) { | ||||||
| 	// Test retrieving a v2 style authorization
 | 	// Test retrieving a v2 style authorization
 | ||||||
| 	responseWriter = httptest.NewRecorder() | 	responseWriter = httptest.NewRecorder() | ||||||
| 	wfe.Authorization(ctx, newRequestEvent(), responseWriter, &http.Request{ | 	wfe.Authorization(ctx, newRequestEvent(), responseWriter, &http.Request{ | ||||||
| 		URL:    mustParseURL("/v2/1"), | 		URL:    mustParseURL("v2/1"), | ||||||
| 		Method: "GET", | 		Method: "GET", | ||||||
| 	}) | 	}) | ||||||
| 	test.AssertEquals(t, responseWriter.Code, http.StatusOK) | 	test.AssertEquals(t, responseWriter.Code, http.StatusOK) | ||||||
|  |  | ||||||
							
								
								
									
										40
									
								
								wfe2/wfe.go
								
								
								
								
							
							
						
						
									
										40
									
								
								wfe2/wfe.go
								
								
								
								
							|  | @ -58,6 +58,8 @@ const ( | ||||||
| 	finalizeOrderPath = "/acme/finalize/" | 	finalizeOrderPath = "/acme/finalize/" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | const authz2Prefix = "v2" | ||||||
|  | 
 | ||||||
| // WebFrontEndImpl provides all the logic for Boulder's web-facing interface,
 | // WebFrontEndImpl provides all the logic for Boulder's web-facing interface,
 | ||||||
| // i.e., ACME.  Its members configure the paths for various ACME functions,
 | // i.e., ACME.  Its members configure the paths for various ACME functions,
 | ||||||
| // plus a few other data items used in ACME.  Its methods are primarily handlers
 | // plus a few other data items used in ACME.  Its methods are primarily handlers
 | ||||||
|  | @ -593,16 +595,34 @@ func (wfe *WebFrontEndImpl) NewAccount( | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (wfe *WebFrontEndImpl) acctHoldsAuthorizations(ctx context.Context, acctID int64, names []string) (bool, error) { | func (wfe *WebFrontEndImpl) acctHoldsAuthorizations(ctx context.Context, acctID int64, names []string) (bool, error) { | ||||||
| 	authz, err := wfe.SA.GetValidAuthorizations(ctx, acctID, names, wfe.clk.Now()) | 	var authzMap map[string]*core.Authorization | ||||||
| 	if err != nil { | 	if features.Enabled(features.NewAuthorizationSchema) { | ||||||
| 		return false, err | 		now := wfe.clk.Now().UnixNano() | ||||||
|  | 		authzMapPB, err := wfe.SA.GetValidAuthorizations2(ctx, &sapb.GetValidAuthorizationsRequest{ | ||||||
|  | 			RegistrationID: &acctID, | ||||||
|  | 			Domains:        names, | ||||||
|  | 			Now:            &now, | ||||||
|  | 		}) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return false, err | ||||||
|  | 		} | ||||||
|  | 		authzMap, err = bgrpc.PBToAuthzMap(authzMapPB) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return false, err | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		var err error | ||||||
|  | 		authzMap, err = wfe.SA.GetValidAuthorizations(ctx, acctID, names, wfe.clk.Now()) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return false, err | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 	if len(names) != len(authz) { | 	if len(names) != len(authzMap) { | ||||||
| 		return false, nil | 		return false, nil | ||||||
| 	} | 	} | ||||||
| 	missingNames := false | 	missingNames := false | ||||||
| 	for _, name := range names { | 	for _, name := range names { | ||||||
| 		if _, present := authz[name]; !present { | 		if _, present := authzMap[name]; !present { | ||||||
| 			missingNames = true | 			missingNames = true | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | @ -865,7 +885,7 @@ func (wfe *WebFrontEndImpl) Challenge( | ||||||
| 	var err error | 	var err error | ||||||
| 	var v2 bool | 	var v2 bool | ||||||
| 	if len(slug) == 3 { | 	if len(slug) == 3 { | ||||||
| 		if !features.Enabled(features.NewAuthorizationSchema) || slug[0] != "v2" { | 		if !features.Enabled(features.NewAuthorizationSchema) || slug[0] != authz2Prefix { | ||||||
| 			notFound() | 			notFound() | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
|  | @ -952,7 +972,7 @@ func (wfe *WebFrontEndImpl) Challenge( | ||||||
| func (wfe *WebFrontEndImpl) prepChallengeForDisplay(request *http.Request, authz core.Authorization, challenge *core.Challenge) { | func (wfe *WebFrontEndImpl) prepChallengeForDisplay(request *http.Request, authz core.Authorization, challenge *core.Challenge) { | ||||||
| 	// Update the challenge URL to be relative to the HTTP request Host
 | 	// Update the challenge URL to be relative to the HTTP request Host
 | ||||||
| 	if authz.V2 { | 	if authz.V2 { | ||||||
| 		challenge.URL = web.RelativeEndpoint(request, fmt.Sprintf("%sv2/%s/%s", challengePath, authz.ID, challenge.StringID())) | 		challenge.URL = web.RelativeEndpoint(request, fmt.Sprintf("%s%s/%s/%s", challengePath, authz2Prefix, authz.ID, challenge.StringID())) | ||||||
| 	} else { | 	} else { | ||||||
| 		challenge.URL = web.RelativeEndpoint(request, fmt.Sprintf("%s%s/%d", challengePath, authz.ID, challenge.ID)) | 		challenge.URL = web.RelativeEndpoint(request, fmt.Sprintf("%s%s/%d", challengePath, authz.ID, challenge.ID)) | ||||||
| 	} | 	} | ||||||
|  | @ -1305,8 +1325,8 @@ func (wfe *WebFrontEndImpl) Authorization(ctx context.Context, logEvent *web.Req | ||||||
| 	id := request.URL.Path | 	id := request.URL.Path | ||||||
| 	var authz core.Authorization | 	var authz core.Authorization | ||||||
| 	var err error | 	var err error | ||||||
| 	if features.Enabled(features.NewAuthorizationSchema) && strings.HasPrefix(id, "/v2/") { | 	if features.Enabled(features.NewAuthorizationSchema) && strings.HasPrefix(id, authz2Prefix) { | ||||||
| 		authzID, err := strconv.ParseInt(id[4:], 10, 64) | 		authzID, err := strconv.ParseInt(strings.TrimPrefix(id, authz2Prefix+"/"), 10, 64) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			wfe.sendError(response, logEvent, probs.NotFound("No such authorization"), nil) | 			wfe.sendError(response, logEvent, probs.NotFound("No such authorization"), nil) | ||||||
| 			return | 			return | ||||||
|  | @ -1700,7 +1720,7 @@ func (wfe *WebFrontEndImpl) orderToOrderJSON(request *http.Request, order *corep | ||||||
| 		respObj.Authorizations = append(respObj.Authorizations, web.RelativeEndpoint(request, fmt.Sprintf("%s%s", authzPath, authzID))) | 		respObj.Authorizations = append(respObj.Authorizations, web.RelativeEndpoint(request, fmt.Sprintf("%s%s", authzPath, authzID))) | ||||||
| 	} | 	} | ||||||
| 	for _, v2ID := range order.V2Authorizations { | 	for _, v2ID := range order.V2Authorizations { | ||||||
| 		respObj.Authorizations = append(respObj.Authorizations, web.RelativeEndpoint(request, fmt.Sprintf("%sv2/%d", authzPath, v2ID))) | 		respObj.Authorizations = append(respObj.Authorizations, web.RelativeEndpoint(request, fmt.Sprintf("%s%s/%d", authzPath, authz2Prefix, v2ID))) | ||||||
| 	} | 	} | ||||||
| 	if respObj.Status == core.StatusValid { | 	if respObj.Status == core.StatusValid { | ||||||
| 		certURL := web.RelativeEndpoint(request, | 		certURL := web.RelativeEndpoint(request, | ||||||
|  |  | ||||||
|  | @ -1539,7 +1539,7 @@ func TestGetAuthorization(t *testing.T) { | ||||||
| 
 | 
 | ||||||
| 	responseWriter = httptest.NewRecorder() | 	responseWriter = httptest.NewRecorder() | ||||||
| 	wfe.Authorization(ctx, newRequestEvent(), responseWriter, &http.Request{ | 	wfe.Authorization(ctx, newRequestEvent(), responseWriter, &http.Request{ | ||||||
| 		URL:    mustParseURL("/v2/1"), | 		URL:    mustParseURL("v2/1"), | ||||||
| 		Method: "GET", | 		Method: "GET", | ||||||
| 	}) | 	}) | ||||||
| 	test.AssertEquals(t, responseWriter.Code, http.StatusOK) | 	test.AssertEquals(t, responseWriter.Code, http.StatusOK) | ||||||
|  | @ -1563,7 +1563,7 @@ func TestGetAuthorization(t *testing.T) { | ||||||
| 
 | 
 | ||||||
| 	responseWriter = httptest.NewRecorder() | 	responseWriter = httptest.NewRecorder() | ||||||
| 	_, _, jwsBody = signRequestKeyID(t, 1, nil, "http://localhost/v2/1", "", wfe.nonceService) | 	_, _, jwsBody = signRequestKeyID(t, 1, nil, "http://localhost/v2/1", "", wfe.nonceService) | ||||||
| 	postAsGet = makePostRequestWithPath("http://localhost/v2/1", jwsBody) | 	postAsGet = makePostRequestWithPath("v2/1", jwsBody) | ||||||
| 	wfe.Authorization(ctx, newRequestEvent(), responseWriter, postAsGet) | 	wfe.Authorization(ctx, newRequestEvent(), responseWriter, postAsGet) | ||||||
| 	test.AssertEquals(t, responseWriter.Code, http.StatusOK) | 	test.AssertEquals(t, responseWriter.Code, http.StatusOK) | ||||||
| 	body = responseWriter.Body.String() | 	body = responseWriter.Body.String() | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue