From fc3dc6ed97be51a78995039618ed33e021dad0a5 Mon Sep 17 00:00:00 2001 From: Kyle Wiese Date: Mon, 30 Sep 2024 08:42:36 -0600 Subject: [PATCH] For analytics records, upload a singular product that was used for an authorized operation. This replaces the existing functionality that picked a random matching product from the credential (#412) --- go.mod | 4 ++-- go.sum | 4 ++-- server/authorization.go | 1 + server/authorization_test.go | 5 +++-- server/header_context.go | 2 ++ server/header_context_test.go | 2 ++ server/metadata_context.go | 21 ++++++++++++--------- server/metadata_context_test.go | 3 +++ 8 files changed, 27 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index a96c9b4..d26044b 100644 --- a/go.mod +++ b/go.mod @@ -2,10 +2,10 @@ module github.com/apigee/apigee-remote-service-envoy/v2 go 1.16 -//replace github.com/apigee/apigee-remote-service-golib/v2 => ../apigee-remote-service-golib +// replace github.com/apigee/apigee-remote-service-golib/v2 => ../apigee-remote-service-golib require ( - github.com/apigee/apigee-remote-service-golib/v2 v2.1.2 + github.com/apigee/apigee-remote-service-golib/v2 v2.1.3 github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad github.com/gogo/googleapis v1.4.1 github.com/golang/protobuf v1.5.2 diff --git a/go.sum b/go.sum index 270f763..0798d29 100644 --- a/go.sum +++ b/go.sum @@ -42,8 +42,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/apigee/apigee-remote-service-golib/v2 v2.1.2 h1:9+tdJlIrpWOhGXTvYNysgG2bL4Sta93L2exiW3ChKEc= -github.com/apigee/apigee-remote-service-golib/v2 v2.1.2/go.mod h1:km/iROUzLa13srZgVP0R31sAcsdgYnCJlvZdCW7ud98= +github.com/apigee/apigee-remote-service-golib/v2 v2.1.3 h1:Sh4CD+w4Hgtm8njaFVyM+MMXceFvQC29xIcUHkg73Wg= +github.com/apigee/apigee-remote-service-golib/v2 v2.1.3/go.mod h1:km/iROUzLa13srZgVP0R31sAcsdgYnCJlvZdCW7ud98= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= diff --git a/server/authorization.go b/server/authorization.go index 9be1af2..e349452 100644 --- a/server/authorization.go +++ b/server/authorization.go @@ -144,6 +144,7 @@ func (a *AuthorizationServer) Check(ctx gocontext.Context, req *envoy_auth.Check if len(authorizedOps) == 0 { return a.denied(req, tracker, authContext, api), nil } + authContext.AnalyticsProduct = authorizedOps[0].APIProduct // apply quotas to matched operations var quotaArgs = quota.Args{QuotaAmount: 1} diff --git a/server/authorization_test.go b/server/authorization_test.go index 78b50fc..3905e71 100644 --- a/server/authorization_test.go +++ b/server/authorization_test.go @@ -365,12 +365,13 @@ func TestImmediateAnalytics(t *testing.T) { ClientID: "client id", AccessToken: "token", Application: "app", - APIProducts: []string{"product1"}, + APIProducts: []string{"not-accepted-product", "accepted-product"}, Expires: time.Now(), DeveloperEmail: "email", Scopes: []string{"scope"}, APIKey: "apikey", CustomAttributes: "{\"tier\":\"standard\"}", + AnalyticsProduct: "accepted-product", } testAuthMan.sendAuth(ac, auth.ErrBadAuth) @@ -430,7 +431,7 @@ func TestImmediateAnalytics(t *testing.T) { DeveloperApp: ac.Application, AccessToken: ac.AccessToken, ClientID: ac.ClientID, - APIProduct: ac.APIProducts[0], + APIProduct: ac.AnalyticsProduct, Organization: server.handler.orgName, Environment: server.handler.envName, GatewaySource: gatewaySource, diff --git a/server/header_context.go b/server/header_context.go index d35a3f8..50795bb 100644 --- a/server/header_context.go +++ b/server/header_context.go @@ -38,6 +38,7 @@ func makeMetadataHeaders(api string, ac *auth.Context, authorized bool) []*core. header(headerEnvironment, ac.Environment()), header(headerOrganization, ac.Organization()), header(headerScope, strings.Join(ac.Scopes, " ")), + header(headerAnalyticsProduct, ac.AnalyticsProduct), } if ac.CustomAttributes != "" { headers = append(headers, header(headerCustomAttributes, ac.CustomAttributes)) @@ -87,5 +88,6 @@ func (h *Handler) decodeMetadataHeaders(headers map[string]string) (string, *aut DeveloperEmail: headers[headerDeveloperEmail], Scopes: strings.Split(headers[headerScope], " "), CustomAttributes: headers[headerCustomAttributes], + AnalyticsProduct: headers[headerAnalyticsProduct], } } diff --git a/server/header_context_test.go b/server/header_context_test.go index cec0476..5d08bc5 100644 --- a/server/header_context_test.go +++ b/server/header_context_test.go @@ -42,6 +42,7 @@ func TestMetadataHeaders(t *testing.T) { DeveloperEmail: "dev@google.com", Scopes: []string{"scope1", "scope2"}, CustomAttributes: "{\"tier\":\"standard\"}", + AnalyticsProduct: "prod1", } api := "api" opts = makeMetadataHeaders(api, authContext, true) @@ -66,6 +67,7 @@ func TestMetadataHeaders(t *testing.T) { equal(headerEnvironment, authContext.Environment()) equal(headerOrganization, authContext.Organization()) equal(headerScope, strings.Join(authContext.Scopes, " ")) + equal(headerAnalyticsProduct, authContext.AnalyticsProduct) api2, ac2 := h.decodeMetadataHeaders(headers) if api != api2 { diff --git a/server/metadata_context.go b/server/metadata_context.go index af5cf8d..5411e8c 100644 --- a/server/metadata_context.go +++ b/server/metadata_context.go @@ -37,6 +37,7 @@ const ( headerOrganization = "x-apigee-organization" headerScope = "x-apigee-scope" headerCustomAttributes = "x-apigee-customattributes" + headerAnalyticsProduct = "x-apigee-analytics-product" ) // encodeExtAuthzMetadata encodes given api and auth context into @@ -47,15 +48,16 @@ func encodeExtAuthzMetadata(api string, ac *auth.Context, authorized bool) *stru } fields := map[string]*structpb.Value{ - headerAccessToken: stringValueFrom(ac.AccessToken), - headerAPI: stringValueFrom(api), - headerAPIProducts: stringValueFrom(strings.Join(ac.APIProducts, ",")), - headerApplication: stringValueFrom(ac.Application), - headerClientID: stringValueFrom(ac.ClientID), - headerDeveloperEmail: stringValueFrom(ac.DeveloperEmail), - headerEnvironment: stringValueFrom(ac.Environment()), - headerOrganization: stringValueFrom(ac.Organization()), - headerScope: stringValueFrom(strings.Join(ac.Scopes, " ")), + headerAccessToken: stringValueFrom(ac.AccessToken), + headerAPI: stringValueFrom(api), + headerAPIProducts: stringValueFrom(strings.Join(ac.APIProducts, ",")), + headerApplication: stringValueFrom(ac.Application), + headerClientID: stringValueFrom(ac.ClientID), + headerDeveloperEmail: stringValueFrom(ac.DeveloperEmail), + headerEnvironment: stringValueFrom(ac.Environment()), + headerOrganization: stringValueFrom(ac.Organization()), + headerScope: stringValueFrom(strings.Join(ac.Scopes, " ")), + headerAnalyticsProduct: stringValueFrom(ac.AnalyticsProduct), } if ac.CustomAttributes != "" { @@ -133,5 +135,6 @@ func (h *Handler) decodeExtAuthzMetadata(fields map[string]*structpb.Value) (str DeveloperEmail: fields[headerDeveloperEmail].GetStringValue(), Scopes: strings.Split(fields[headerScope].GetStringValue(), " "), CustomAttributes: fields[headerCustomAttributes].GetStringValue(), + AnalyticsProduct: fields[headerAnalyticsProduct].GetStringValue(), } } diff --git a/server/metadata_context_test.go b/server/metadata_context_test.go index 315e65b..626bc89 100644 --- a/server/metadata_context_test.go +++ b/server/metadata_context_test.go @@ -41,6 +41,7 @@ func TestEncodeMetadata(t *testing.T) { DeveloperEmail: "dev@google.com", Scopes: []string{"scope1", "scope2"}, CustomAttributes: "{\"tier\":\"standard\"}", + AnalyticsProduct: "prod1", } api := "api" metadata := encodeExtAuthzMetadata(api, authContext, true) @@ -65,6 +66,7 @@ func TestEncodeMetadata(t *testing.T) { equal(headerOrganization, authContext.Organization()) equal(headerScope, strings.Join(authContext.Scopes, " ")) equal(headerCustomAttributes, authContext.CustomAttributes) + equal(headerAnalyticsProduct, authContext.AnalyticsProduct) api2, ac2 := h.decodeExtAuthzMetadata(metadata.GetFields()) if api != api2 { @@ -96,6 +98,7 @@ func TestEncodeMetadataAuthorizedField(t *testing.T) { DeveloperEmail: "dev@google.com", Scopes: []string{"scope1", "scope2"}, CustomAttributes: "", + AnalyticsProduct: "prod1", } metadata := encodeExtAuthzMetadata("api", authContext, true)