From 58cbd4e5307aa583a99530d258b69b9bc778f422 Mon Sep 17 00:00:00 2001 From: Johan Stokking Date: Fri, 30 Jun 2023 18:36:45 +0200 Subject: [PATCH] pba: Support address with gRPC dialer scheme --- CHANGELOG.md | 1 + pkg/packetbroker/token.go | 7 ++++++- pkg/packetbroker/token_test.go | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 23777d223f..c93cb232ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ For details about compatibility between different releases, see the **Commitment - HTTP API routes for parsing QR codes for the QR Generator service. We exercise our right to break compatibility with third party HTTP clients since this is a bug. - `/qr-code/end-devices/parse` is changed to `/qr-codes/end-devices/parse`. - `/qr-code/end-devices/{format_id}/parse` is changed to `/qr-codes/end-devices/{format_id}/parse`. +- Fixed authenticating with Packet Broker when gRPC dialer schemes are used in the address. ### Security diff --git a/pkg/packetbroker/token.go b/pkg/packetbroker/token.go index d4c3c14744..278c319602 100644 --- a/pkg/packetbroker/token.go +++ b/pkg/packetbroker/token.go @@ -72,6 +72,11 @@ func WithAudienceFromAddresses(addresses ...string) TokenOption { if addr == "" { continue } + // If the address is a URL with a scheme, check if it's a gRPC dialer scheme and remove it. + // gRPC dialer schemes in the target address look like passthrough:///host:port. + if u, err := url.Parse(addr); err == nil && u.Scheme != "" && strings.HasPrefix(addr, u.Scheme+":///") { + addr = addr[len(u.Scheme)+4:] + } if h, _, err := net.SplitHostPort(addr); err == nil { addr = h } @@ -110,7 +115,7 @@ func TokenSource(ctx context.Context, clientID, clientSecret string, opts ...Tok return config.TokenSource(ctx) } -// TokenNetworkClaims defines a Packet Broker network identifier. +// TokenNetworkClaim defines a Packet Broker network identifier. type TokenNetworkClaim struct { NetID uint32 `json:"nid"` TenantID string `json:"tid"` diff --git a/pkg/packetbroker/token_test.go b/pkg/packetbroker/token_test.go index 49cea9b3ef..44fb25531f 100644 --- a/pkg/packetbroker/token_test.go +++ b/pkg/packetbroker/token_test.go @@ -85,6 +85,39 @@ func TestToken(t *testing.T) { return a.So(claims.PacketBroker.Cluster, should.BeFalse) }, }, + { + name: "SuccessWithDialerScheme", + clientID: "test", + clientSecret: "secret", + opts: []packetbroker.TokenOption{ + packetbroker.WithScope(packetbroker.ScopeNetworks), + packetbroker.WithAudienceFromAddresses("passthrough:///iam.packetbroker.net:443"), + }, + tokenRequestAssertion: func(a *assertions.Assertion, vars url.Values) bool { + return a.So(vars["scope"], should.Resemble, []string{"networks"}) && + a.So(vars["audience"], should.Resemble, []string{"iam.packetbroker.net"}) + }, + tokenClaims: func() packetbroker.IAMTokenClaims { + return packetbroker.IAMTokenClaims{ + Networks: []packetbroker.TokenNetworkClaim{ + { + NetID: 0x000013, + TenantID: "ttn", + }, + }, + } + }, + audience: "iam.packetbroker.net", + tokenAssertion: func(a *assertions.Assertion, token string) bool { + id, err := packetbroker.UnverifiedNetworkIdentifier(token) + return a.So(err, should.BeNil) && + a.So(id.NetId, should.Equal, 0x000013) && + a.So(id.TenantId, should.Equal, "ttn") + }, + tokenClaimsAssertion: func(a *assertions.Assertion, claims packetbroker.TokenClaims) bool { + return a.So(claims.PacketBroker.Cluster, should.BeFalse) + }, + }, { name: "BadRequest", clientID: "test",