Skip to content

Commit

Permalink
Switch to using not_required_introspection instead of token_version f…
Browse files Browse the repository at this point in the history
…or tokens' exchange
  • Loading branch information
vasayxtx committed Jan 14, 2025
1 parent 552a0de commit 3d836e4
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 62 deletions.
27 changes: 23 additions & 4 deletions idptoken/grpc_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,12 +165,31 @@ func (c *GRPCClient) IntrospectToken(
}, nil
}

type exchangeTokenOptions struct {
notRequiredIntrospection bool
}

// ExchangeTokenOption is an option for the ExchangeToken method.
type ExchangeTokenOption func(*exchangeTokenOptions)

// WithNotRequiredIntrospection specifies that the new issued token will not require introspection.
func WithNotRequiredIntrospection(b bool) ExchangeTokenOption {
return func(opts *exchangeTokenOptions) {
opts.notRequiredIntrospection = b
}
}

// ExchangeToken exchanges the token requesting a new token with the specified version.
func (c *GRPCClient) ExchangeToken(ctx context.Context, token string, tokenVersion uint32) (TokenData, error) {
func (c *GRPCClient) ExchangeToken(ctx context.Context, token string, opts ...ExchangeTokenOption) (TokenData, error) {
var options exchangeTokenOptions
for _, opt := range opts {
opt(&options)
}

req := pb.CreateTokenRequest{
GrantType: idputil.GrantTypeJWTBearer,
Assertion: token,
TokenVersion: tokenVersion,
GrantType: idputil.GrantTypeJWTBearer,
Assertion: token,
NotRequiredIntrospection: options.notRequiredIntrospection,
}

var resp *pb.CreateTokenResponse
Expand Down
61 changes: 22 additions & 39 deletions idptoken/grpc_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,28 +26,22 @@ import (
func TestGRPCClient_ExchangeToken(t *gotesting.T) {
tokenExpiresIn := time.Hour
tokenExpiresAt := time.Now().Add(time.Hour)
tokenV1 := idptest.MustMakeTokenStringSignedWithTestKey(&VersionedClaims{
DefaultClaims: jwt.DefaultClaims{
RegisteredClaims: jwtgo.RegisteredClaims{
Subject: "test-subject",
ExpiresAt: jwtgo.NewNumericDate(tokenExpiresAt),
},
riToken := idptest.MustMakeTokenStringSignedWithTestKey(&jwt.DefaultClaims{
RegisteredClaims: jwtgo.RegisteredClaims{
Subject: "test-subject",
ExpiresAt: jwtgo.NewNumericDate(tokenExpiresAt),
},
Version: 1,
})
tokenV2 := idptest.MustMakeTokenStringSignedWithTestKey(&VersionedClaims{
DefaultClaims: jwt.DefaultClaims{
RegisteredClaims: jwtgo.RegisteredClaims{
Subject: "test-subject",
ExpiresAt: jwtgo.NewNumericDate(tokenExpiresAt),
},
nriToken := idptest.MustMakeTokenStringWithHeader(&jwt.DefaultClaims{
RegisteredClaims: jwtgo.RegisteredClaims{
Subject: "test-subject",
ExpiresAt: jwtgo.NewNumericDate(tokenExpiresAt),
},
Version: 2,
})
}, idptest.TestKeyID, idptest.GetTestRSAPrivateKey(), map[string]interface{}{"nri": true})

grpcServerTokenCreator := testing.NewGRPCServerTokenCreatorMock()
grpcServerTokenCreator.SetResultForToken(tokenV1, &pb.CreateTokenResponse{
AccessToken: tokenV2,
grpcServerTokenCreator.SetResultForToken(riToken, &pb.CreateTokenResponse{
AccessToken: nriToken,
ExpiresIn: int64(tokenExpiresIn.Seconds()),
TokenType: idputil.TokenTypeBearer,
})
Expand Down Expand Up @@ -76,46 +70,35 @@ func TestGRPCClient_ExchangeToken(t *gotesting.T) {
},
},
{
name: "ok",
assertion: tokenV1,
tokenVersion: 2,
name: "ok",
assertion: riToken,
expectedRequest: &pb.CreateTokenRequest{
GrantType: idputil.GrantTypeJWTBearer,
Assertion: tokenV1,
TokenVersion: 2,
GrantType: idputil.GrantTypeJWTBearer,
Assertion: riToken,
NotRequiredIntrospection: true,
},
expectedTokenData: idptoken.TokenData{
AccessToken: tokenV2,
AccessToken: nriToken,
ExpiresIn: tokenExpiresIn,
TokenType: idputil.TokenTypeBearer,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *gotesting.T) {
tokenData, err := grpcClient.ExchangeToken(context.Background(), tt.assertion, tt.tokenVersion)
tokenData, exchangeErr := grpcClient.ExchangeToken(context.Background(), tt.assertion,
idptoken.WithNotRequiredIntrospection(true))
if tt.checkErr != nil {
tt.checkErr(t, err)
tt.checkErr(t, exchangeErr)
} else {
require.Equal(t, tt.expectedTokenData, tokenData)
}
if tt.expectedRequest != nil {
require.Equal(t, tt.expectedRequest.GrantType, grpcServerTokenCreator.LastRequest.GrantType)
require.Equal(t, tt.expectedRequest.Assertion, grpcServerTokenCreator.LastRequest.Assertion)
require.Equal(t, tt.expectedRequest.TokenVersion, grpcServerTokenCreator.LastRequest.TokenVersion)
require.Equal(t, tt.expectedRequest.NotRequiredIntrospection,
grpcServerTokenCreator.LastRequest.NotRequiredIntrospection)
}
})
}
}

type VersionedClaims struct {
jwt.DefaultClaims
Version int `json:"ver"`
}

func (c *VersionedClaims) Clone() jwt.Claims {
return &VersionedClaims{
DefaultClaims: *c.DefaultClaims.Clone().(*jwt.DefaultClaims),
Version: c.Version,
}
}
5 changes: 3 additions & 2 deletions idptoken/idp_token.proto
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ service IDPTokenService {
}

message CreateTokenRequest {
reserved 4 to 50;
reserved 5 to 50;
reserved 3;
string grant_type = 1; // example: urn:ietf:params:oauth:grant-type:jwt-bearer
string assertion = 2;
uint32 token_version = 3;
bool not_required_introspection = 4;
}

message CreateTokenResponse {
Expand Down
34 changes: 18 additions & 16 deletions idptoken/pb/idp_token.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion idptoken/pb/idp_token_grpc.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 3d836e4

Please sign in to comment.