From e138dd0c3b2d1aec363e9ba4751844ed231ebd1d Mon Sep 17 00:00:00 2001 From: Alex Snaps Date: Wed, 4 Sep 2024 10:51:24 -0400 Subject: [PATCH] Tentative at dealing with no Response provided Signed-off-by: Alex Snaps --- controllers/auth_config_controller.go | 223 +++++++++++---------- controllers/auth_config_controller_test.go | 10 +- controllers/auth_config_status_updater.go | 14 +- 3 files changed, 133 insertions(+), 114 deletions(-) diff --git a/controllers/auth_config_controller.go b/controllers/auth_config_controller.go index 78a97be6..03e91261 100644 --- a/controllers/auth_config_controller.go +++ b/controllers/auth_config_controller.go @@ -166,6 +166,9 @@ func (r *AuthConfigReconciler) translateAuthConfig(ctx context.Context, authConf authConfigIdentityConfigs := authConfig.Spec.Authentication if len(authConfigIdentityConfigs) == 0 { + if authConfigIdentityConfigs == nil { + authConfigIdentityConfigs = make(map[string]api.AuthenticationSpec) + } authConfigIdentityConfigs["anonymous"] = api.AuthenticationSpec{ CommonEvaluatorSpec: api.CommonEvaluatorSpec{}, Credentials: api.Credentials{}, @@ -472,129 +475,133 @@ func (r *AuthConfigReconciler) translateAuthConfig(ctx context.Context, authConf interfacedResponseConfigs := make([]auth.AuthConfigEvaluator, 0) - for responseName, headerResponse := range authConfig.Spec.Response.Success.Headers { - translatedResponse := evaluators.NewResponseConfig( - responseName, - headerResponse.Priority, - buildJSONExpression(authConfig, headerResponse.Conditions, jsonexp.All), - "httpHeader", - headerResponse.Key, - headerResponse.Metrics, - ) + if authConfig.Spec.Response != nil { + for responseName, headerResponse := range authConfig.Spec.Response.Success.Headers { + translatedResponse := evaluators.NewResponseConfig( + responseName, + headerResponse.Priority, + buildJSONExpression(authConfig, headerResponse.Conditions, jsonexp.All), + "httpHeader", + headerResponse.Key, + headerResponse.Metrics, + ) - if headerResponse.Cache != nil { - ttl := headerResponse.Cache.TTL - if ttl == 0 { - ttl = api.EvaluatorDefaultCacheTTL + if headerResponse.Cache != nil { + ttl := headerResponse.Cache.TTL + if ttl == 0 { + ttl = api.EvaluatorDefaultCacheTTL + } + translatedResponse.Cache = evaluators.NewEvaluatorCache( + *getJsonFromStaticDynamic(&headerResponse.Cache.Key), + ttl, + ) } - translatedResponse.Cache = evaluators.NewEvaluatorCache( - *getJsonFromStaticDynamic(&headerResponse.Cache.Key), - ttl, - ) + interfacedResponseConfigs = append(interfacedResponseConfigs, translatedResponse) } - interfacedResponseConfigs = append(interfacedResponseConfigs, translatedResponse) } - for responseName, response := range authConfig.Spec.Response.Success.DynamicMetadata { - translatedResponse := evaluators.NewResponseConfig( - responseName, - response.Priority, - buildJSONExpression(authConfig, response.Conditions, jsonexp.All), - "envoyDynamicMetadata", - response.Key, - response.Metrics, - ) + if authConfig.Spec.Response != nil { + for responseName, response := range authConfig.Spec.Response.Success.DynamicMetadata { + translatedResponse := evaluators.NewResponseConfig( + responseName, + response.Priority, + buildJSONExpression(authConfig, response.Conditions, jsonexp.All), + "envoyDynamicMetadata", + response.Key, + response.Metrics, + ) - if response.Cache != nil { - ttl := response.Cache.TTL - if ttl == 0 { - ttl = api.EvaluatorDefaultCacheTTL + if response.Cache != nil { + ttl := response.Cache.TTL + if ttl == 0 { + ttl = api.EvaluatorDefaultCacheTTL + } + translatedResponse.Cache = evaluators.NewEvaluatorCache( + *getJsonFromStaticDynamic(&response.Cache.Key), + ttl, + ) } - translatedResponse.Cache = evaluators.NewEvaluatorCache( - *getJsonFromStaticDynamic(&response.Cache.Key), - ttl, - ) - } - switch response.GetMethod() { - // wristband - case api.WristbandAuthResponse: - wristband := response.Wristband - signingKeys := make([]jose.JSONWebKey, 0) + switch response.GetMethod() { + // wristband + case api.WristbandAuthResponse: + wristband := response.Wristband + signingKeys := make([]jose.JSONWebKey, 0) - for _, signingKeyRef := range wristband.SigningKeyRefs { - secret := &v1.Secret{} - secretName := types.NamespacedName{ - Namespace: authConfig.Namespace, - Name: signingKeyRef.Name, - } - if err := r.Client.Get(ctx, secretName, secret); err != nil { - return nil, err // TODO: Review this error, perhaps we don't need to return an error, just reenqueue. - } else { - if signingKey, err := response_evaluators.NewSigningKey( - signingKeyRef.Name, - string(signingKeyRef.Algorithm), - secret.Data["key.pem"], - ); err != nil { - return nil, err + for _, signingKeyRef := range wristband.SigningKeyRefs { + secret := &v1.Secret{} + secretName := types.NamespacedName{ + Namespace: authConfig.Namespace, + Name: signingKeyRef.Name, + } + if err := r.Client.Get(ctx, secretName, secret); err != nil { + return nil, err // TODO: Review this error, perhaps we don't need to return an error, just reenqueue. } else { - signingKeys = append(signingKeys, *signingKey) + if signingKey, err := response_evaluators.NewSigningKey( + signingKeyRef.Name, + string(signingKeyRef.Algorithm), + secret.Data["key.pem"], + ); err != nil { + return nil, err + } else { + signingKeys = append(signingKeys, *signingKey) + } } } - } - customClaims := make([]json.JSONProperty, 0) - for claimName, claim := range wristband.CustomClaims { - customClaims = append(customClaims, json.JSONProperty{ - Name: claimName, - Value: json.JSONValue{ - Static: claim.Value, - Pattern: claim.Selector, - }, - }) - } + customClaims := make([]json.JSONProperty, 0) + for claimName, claim := range wristband.CustomClaims { + customClaims = append(customClaims, json.JSONProperty{ + Name: claimName, + Value: json.JSONValue{ + Static: claim.Value, + Pattern: claim.Selector, + }, + }) + } - if authorinoWristband, err := response_evaluators.NewWristbandConfig( - wristband.Issuer, - customClaims, - wristband.TokenDuration, - signingKeys, - ); err != nil { - return nil, err - } else { - translatedResponse.Wristband = authorinoWristband - } + if authorinoWristband, err := response_evaluators.NewWristbandConfig( + wristband.Issuer, + customClaims, + wristband.TokenDuration, + signingKeys, + ); err != nil { + return nil, err + } else { + translatedResponse.Wristband = authorinoWristband + } - // dynamic json - case api.JsonAuthResponse: - jsonProperties := make([]json.JSONProperty, 0) + // dynamic json + case api.JsonAuthResponse: + jsonProperties := make([]json.JSONProperty, 0) + + for propertyName, property := range response.Json.Properties { + jsonProperties = append(jsonProperties, json.JSONProperty{ + Name: propertyName, + Value: json.JSONValue{ + Static: property.Value, + Pattern: property.Selector, + }, + }) + } - for propertyName, property := range response.Json.Properties { - jsonProperties = append(jsonProperties, json.JSONProperty{ - Name: propertyName, - Value: json.JSONValue{ - Static: property.Value, - Pattern: property.Selector, - }, - }) - } + translatedResponse.DynamicJSON = response_evaluators.NewDynamicJSONResponse(jsonProperties) - translatedResponse.DynamicJSON = response_evaluators.NewDynamicJSONResponse(jsonProperties) + // plain + case api.PlainAuthResponse: + translatedResponse.Plain = &response_evaluators.Plain{ + JSONValue: json.JSONValue{ + Static: response.Plain.Value, + Pattern: response.Plain.Selector, + }, + } - // plain - case api.PlainAuthResponse: - translatedResponse.Plain = &response_evaluators.Plain{ - JSONValue: json.JSONValue{ - Static: response.Plain.Value, - Pattern: response.Plain.Selector, - }, + case api.UnknownAuthResponseMethod: + return nil, fmt.Errorf("unknown response type %v", response) } - case api.UnknownAuthResponseMethod: - return nil, fmt.Errorf("unknown response type %v", response) + interfacedResponseConfigs = append(interfacedResponseConfigs, translatedResponse) } - - interfacedResponseConfigs = append(interfacedResponseConfigs, translatedResponse) } interfacedCallbackConfigs := make([]auth.AuthConfigEvaluator, 0) @@ -634,11 +641,13 @@ func (r *AuthConfigReconciler) translateAuthConfig(ctx context.Context, authConf } // denyWith - if denyWith := authConfig.Spec.Response.Unauthenticated; denyWith != nil { - translatedAuthConfig.Unauthenticated = buildAuthorinoDenyWithValues(denyWith) - } - if denyWith := authConfig.Spec.Response.Unauthorized; denyWith != nil { - translatedAuthConfig.Unauthorized = buildAuthorinoDenyWithValues(denyWith) + if authConfig.Spec.Response != nil { + if denyWith := authConfig.Spec.Response.Unauthenticated; denyWith != nil { + translatedAuthConfig.Unauthenticated = buildAuthorinoDenyWithValues(denyWith) + } + if denyWith := authConfig.Spec.Response.Unauthorized; denyWith != nil { + translatedAuthConfig.Unauthorized = buildAuthorinoDenyWithValues(denyWith) + } } return translatedAuthConfig, nil diff --git a/controllers/auth_config_controller_test.go b/controllers/auth_config_controller_test.go index f286364f..84e58631 100644 --- a/controllers/auth_config_controller_test.go +++ b/controllers/auth_config_controller_test.go @@ -170,7 +170,7 @@ func TestReconcileAuthConfigOk(t *testing.T) { config := authConfigIndex.Get("echo-api") assert.Check(t, config != nil) idConfig, _ := config.IdentityConfigs[0].(*evaluators.IdentityConfig) - assert.Equal(t, idConfig.ExtendedProperties[0].Name, "source") + assert.Equal(t, idConfig.ExtendedProperties[1].Name, "source") // TODO(@guicassolato): assert other fields of the AuthConfig } @@ -390,6 +390,10 @@ func TestBootstrapIndex(t *testing.T) { indexMock := mock_index.NewMockIndex(mockController) authConfig := newTestAuthConfig(map[string]string{"scope": "in"}) + expectedNumResponseItems := 0 + if authConfig.Spec.Response != nil { + expectedNumResponseItems = len(authConfig.Spec.Response.Success.DynamicMetadata) + len(authConfig.Spec.Response.Success.Headers) + } authConfig.Status.Summary = api.AuthConfigStatusSummary{ Ready: true, HostsReady: authConfig.Spec.Hosts, @@ -397,7 +401,7 @@ func TestBootstrapIndex(t *testing.T) { NumIdentitySources: int64(len(authConfig.Spec.Authentication)), NumMetadataSources: int64(len(authConfig.Spec.Metadata)), NumAuthorizationPolicies: int64(len(authConfig.Spec.Authorization)), - NumResponseItems: int64(len(authConfig.Spec.Response.Success.DynamicMetadata) + len(authConfig.Spec.Response.Success.Headers)), + NumResponseItems: int64(expectedNumResponseItems), FestivalWristbandEnabled: false, } @@ -409,7 +413,7 @@ func TestBootstrapIndex(t *testing.T) { NumIdentitySources: int64(len(authConfig.Spec.Authentication)), NumMetadataSources: int64(len(authConfig.Spec.Metadata)), NumAuthorizationPolicies: int64(len(authConfig.Spec.Authorization)), - NumResponseItems: int64(len(authConfig.Spec.Response.Success.DynamicMetadata) + len(authConfig.Spec.Response.Success.Headers)), + NumResponseItems: int64(expectedNumResponseItems), FestivalWristbandEnabled: false, } diff --git a/controllers/auth_config_status_updater.go b/controllers/auth_config_status_updater.go index 2804d3c7..5793d9bd 100644 --- a/controllers/auth_config_status_updater.go +++ b/controllers/auth_config_status_updater.go @@ -181,6 +181,10 @@ func updateStatusSummary(authConfig *api.AuthConfig, newLinkedHosts []string) (c newLinkedHosts = []string{} } + numResponseItems := 0 + if authConfig.Spec.Response != nil { + numResponseItems = len(authConfig.Spec.Response.Success.DynamicMetadata) + len(authConfig.Spec.Response.Success.Headers) + } new := api.AuthConfigStatusSummary{ Ready: authConfig.Status.Ready(), HostsReady: newLinkedHosts, @@ -188,7 +192,7 @@ func updateStatusSummary(authConfig *api.AuthConfig, newLinkedHosts []string) (c NumIdentitySources: int64(len(authConfig.Spec.Authentication)), NumMetadataSources: int64(len(authConfig.Spec.Metadata)), NumAuthorizationPolicies: int64(len(authConfig.Spec.Authorization)), - NumResponseItems: int64(len(authConfig.Spec.Response.Success.DynamicMetadata) + len(authConfig.Spec.Response.Success.Headers)), + NumResponseItems: int64(numResponseItems), FestivalWristbandEnabled: issuingWristbands(authConfig), } @@ -213,9 +217,11 @@ func updateStatusSummary(authConfig *api.AuthConfig, newLinkedHosts []string) (c } func issuingWristbands(authConfig *api.AuthConfig) bool { - for _, responseConfig := range authConfig.Spec.Response.Success.DynamicMetadata { - if responseConfig.GetMethod() == api.WristbandAuthResponse { - return true + if authConfig.Spec.Response != nil { + for _, responseConfig := range authConfig.Spec.Response.Success.DynamicMetadata { + if responseConfig.GetMethod() == api.WristbandAuthResponse { + return true + } } } return false