Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ linters:
- errcheck
- ineffassign
settings:
errorlint:
# Check whether fmt.Errorf uses the %w verb for formatting errors.
# See the https://github.com/polyfloyd/go-errorlint for caveats.
# Default: true
errorf: false
misspell:
locale: US
exclusions:
Expand Down
25 changes: 13 additions & 12 deletions WRPAccessControl.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// SPDX-FileCopyrightText: 2019 Comcast Cable Communications Management, LLC
// SPDX-License-Identifier: Apache-2.0

package main

import (
Expand All @@ -10,18 +9,19 @@ import (
"github.com/go-kit/kit/metrics"
"github.com/spf13/cast"
"github.com/xmidt-org/bascule"
"github.com/xmidt-org/bascule/basculehttp"
"github.com/xmidt-org/bascule/basculejwt"
"github.com/xmidt-org/webpa-common/v2/xhttp"
"github.com/xmidt-org/wrp-go/v3"
)

// partnerAuthority errors
var (
ErrTokenMissing = &xhttp.Error{Code: http.StatusInternalServerError, Text: "No JWT Token was found in context"}
ErrTokenTypeMismatch = &xhttp.Error{Code: http.StatusInternalServerError, Text: "Token must be a JWT"}
ErrPIDMissing = &xhttp.Error{Code: http.StatusBadRequest, Text: "WRP PartnerIDs field must not be empty"}
ErrAllowedPartnersNotFound = &xhttp.Error{Code: http.StatusForbidden, Text: "AllowedPartners JWT claim not found"}
ErrInvalidAllowedPartners = &xhttp.Error{Code: http.StatusForbidden, Text: "AllowedPartners JWT claim must be a non-empty list of strings"}
ErrPIDMismatch = &xhttp.Error{Code: http.StatusForbidden, Text: "Unauthorized partners credentials in WRP message"}
ErrTokenMissing = &xhttp.Error{Code: http.StatusInternalServerError, Text: "No JWT Token was found in context"}
ErrTokenTypeMismatch = &xhttp.Error{Code: http.StatusInternalServerError, Text: "Token must be a JWT"}
ErrPIDMissing = &xhttp.Error{Code: http.StatusBadRequest, Text: "WRP PartnerIDs field must not be empty"}
ErrInvalidAllowedPartners = &xhttp.Error{Code: http.StatusForbidden, Text: "AllowedPartners JWT claim was either not found or an empty list"}
ErrPIDMismatch = &xhttp.Error{Code: http.StatusForbidden, Text: "Unauthorized partners credentials in WRP message"}
)

// WRPCheckConfig drives the WRP Access control configuration when enabled
Expand Down Expand Up @@ -76,13 +76,14 @@ func (p *wrpPartnersAccess) authorizeWRP(ctx context.Context, message *wrp.Messa
return false, nil
}

tt, isTyped := token.(tokenType)
if !isTyped || tt.TokenType() != jwtTokenType {
switch token.(type) {
case basculejwt.Claims, basculehttp.BasicToken:
default:
p.withFailure(ClientIDLabel, satClientID, ReasonLabel, TokenTypeMismatch).Add(1)

if p.strict {
return false, ErrTokenTypeMismatch
}

return false, nil
}

Expand All @@ -95,7 +96,7 @@ func (p *wrpPartnersAccess) authorizeWRP(ctx context.Context, message *wrp.Messa
p.withFailure(ClientIDLabel, satClientID, ReasonLabel, JWTPIDInvalid).Add(1)

if p.strict {
return false, ErrAllowedPartnersNotFound
return false, ErrInvalidAllowedPartners
}

return false, nil
Expand All @@ -106,7 +107,7 @@ func (p *wrpPartnersAccess) authorizeWRP(ctx context.Context, message *wrp.Messa
p.withFailure(ClientIDLabel, satClientID, ReasonLabel, JWTPIDInvalid).Add(1)

if p.strict {
return false, ErrAllowedPartnersNotFound
return false, ErrInvalidAllowedPartners
}

return false, nil
Expand Down
61 changes: 25 additions & 36 deletions WRPAccessControl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ package main

import (
"context"
"fmt"
"testing"

"github.com/go-kit/kit/metrics"
"github.com/lestrrat-go/jwx/v2/jwt"
"github.com/stretchr/testify/assert"
"github.com/xmidt-org/bascule"
"github.com/xmidt-org/wrp-go/v3"
Expand All @@ -18,7 +20,7 @@ func TestAuthorizeWRP(t *testing.T) {
Name string
PartnerIDs []string
AllowedPartners []string
TokenType string
IsBearer bool
InjectSecurityToken bool
ExpectAutocorrect bool
Error error
Expand All @@ -28,19 +30,18 @@ func TestAuthorizeWRP(t *testing.T) {
{
Name: "Bascule token Missing",
Error: ErrTokenMissing,
// nolint: goconst
TokenType: "jwt",

IsBearer: true,
BaseLabelPairs: map[string]string{
ReasonLabel: TokenMissing,
// nolint: goconst

ClientIDLabel: "none",
},
},
{
Name: "Bad bascule token type",
Error: ErrTokenTypeMismatch,
InjectSecurityToken: true,
TokenType: "basic",
// nolint: goconst
AllowedPartners: []string{"partner0"},
BaseLabelPairs: map[string]string{
Expand All @@ -53,7 +54,7 @@ func TestAuthorizeWRP(t *testing.T) {
Name: "Invalid AllowedPartners",
Error: ErrInvalidAllowedPartners,
InjectSecurityToken: true,
TokenType: "jwt",
IsBearer: true,
AllowedPartners: []string{},
BaseLabelPairs: map[string]string{
ReasonLabel: JWTPIDInvalid,
Expand All @@ -64,9 +65,9 @@ func TestAuthorizeWRP(t *testing.T) {

{
Name: "No AllowedPartners",
Error: ErrAllowedPartnersNotFound,
Error: ErrInvalidAllowedPartners,
InjectSecurityToken: true,
TokenType: "jwt",
IsBearer: true,
AllowedPartners: nil,
BaseLabelPairs: map[string]string{
ReasonLabel: JWTPIDInvalid,
Expand All @@ -78,7 +79,7 @@ func TestAuthorizeWRP(t *testing.T) {
Name: "PartnerIDs missing from WRP",
Error: ErrPIDMissing,
InjectSecurityToken: true,
TokenType: "jwt",
IsBearer: true,
AllowedPartners: []string{"p0", "p1"},
ExpectAutocorrect: true,
BaseLabelPairs: map[string]string{
Expand All @@ -91,7 +92,7 @@ func TestAuthorizeWRP(t *testing.T) {
{
Name: "PartnerIDs is not subset of allowerPartners",
InjectSecurityToken: true,
TokenType: "jwt",
IsBearer: true,
PartnerIDs: []string{"p2"},
AllowedPartners: []string{"p0", "p1"},
Error: ErrPIDMismatch,
Expand All @@ -106,7 +107,7 @@ func TestAuthorizeWRP(t *testing.T) {
{
Name: "Wildcard in allowedPartners",
InjectSecurityToken: true,
TokenType: "jwt",
IsBearer: true,
PartnerIDs: []string{"p2"}, //TODO: is this the behavior we actually want? '*' giving user superpowers!
AllowedPartners: []string{"p0", "p1", "*"},
BaseLabelPairs: map[string]string{
Expand All @@ -119,7 +120,7 @@ func TestAuthorizeWRP(t *testing.T) {
{
Name: "Non-empty partnerIDs is subset of allowerPartners",
InjectSecurityToken: true,
TokenType: "jwt",
IsBearer: true,
PartnerIDs: []string{"p0"},
AllowedPartners: []string{"p0", "p1"},
BaseLabelPairs: map[string]string{
Expand All @@ -136,7 +137,7 @@ func TestAuthorizeWRP(t *testing.T) {

ctx := context.Background()
if testCase.InjectSecurityToken {
ctx = enrichWithBasculeToken(context.Background(), testCase.TokenType, testCase.AllowedPartners)
ctx = enrichWithBasculeToken(context.Background(), testCase.IsBearer, testCase.AllowedPartners)
}

wrpMsg := &wrp.Message{
Expand Down Expand Up @@ -196,33 +197,21 @@ func createLabelMaps(rejected bool, baseLabelPairs map[string]string) (strict ma
return
}

func enrichWithBasculeToken(ctx context.Context, tokenType string, allowedPartners []string) context.Context {
if tokenType == jwtTokenType {
attrs := map[string]interface{}{
// nolint: goconst
"allowedResources": map[string]interface{}{"allowedPartners": allowedPartners},
}
if allowedPartners == nil {
attrs = map[string]interface{}{"allowedResources": map[string]interface{}{}}
func enrichWithBasculeToken(ctx context.Context, isBearer bool, partners []string) context.Context {
if isBearer {
token, err := jwt.NewBuilder().
Claim(allowedResources, map[string]any{allowedPartners: partners}).
Subject("tester").
Issuer("https://example.com").
Build()
if err != nil {
panic(fmt.Errorf("failed to build test JWT: %v", err))
}

return bascule.WithToken(ctx, &jwtToken{principal: "tester", claims: attrs})
return bascule.WithToken(ctx, &testJWT{token})
}

return bascule.WithToken(ctx, &testToken{principal: "tester", tokenType: tokenType})
}

type testToken struct {
principal string
tokenType string
}

func (t *testToken) Principal() string {
return t.principal
}

func (t *testToken) TokenType() string {
return t.tokenType
return bascule.WithToken(ctx, bascule.StubToken("tester"))
}

type testCounter struct {
Expand Down
Loading
Loading