diff --git a/idptoken/grpc_client.go b/idptoken/grpc_client.go index d68263b..d590418 100644 --- a/idptoken/grpc_client.go +++ b/idptoken/grpc_client.go @@ -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 diff --git a/idptoken/grpc_client_test.go b/idptoken/grpc_client_test.go index 9687266..06a17a8 100644 --- a/idptoken/grpc_client_test.go +++ b/idptoken/grpc_client_test.go @@ -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, }) @@ -76,16 +70,15 @@ 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, }, @@ -93,29 +86,19 @@ func TestGRPCClient_ExchangeToken(t *gotesting.T) { } 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, - } -} diff --git a/idptoken/idp_token.proto b/idptoken/idp_token.proto index d34723e..94fd344 100644 --- a/idptoken/idp_token.proto +++ b/idptoken/idp_token.proto @@ -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 { diff --git a/idptoken/pb/idp_token.pb.go b/idptoken/pb/idp_token.pb.go index 23d1cf9..986d222 100644 --- a/idptoken/pb/idp_token.pb.go +++ b/idptoken/pb/idp_token.pb.go @@ -6,7 +6,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.33.0 -// protoc v5.26.1 +// protoc v5.29.2 // source: idp_token.proto package pb @@ -30,9 +30,9 @@ type CreateTokenRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - GrantType string `protobuf:"bytes,1,opt,name=grant_type,json=grantType,proto3" json:"grant_type,omitempty"` // example: urn:ietf:params:oauth:grant-type:jwt-bearer - Assertion string `protobuf:"bytes,2,opt,name=assertion,proto3" json:"assertion,omitempty"` - TokenVersion uint32 `protobuf:"varint,3,opt,name=token_version,json=tokenVersion,proto3" json:"token_version,omitempty"` + GrantType string `protobuf:"bytes,1,opt,name=grant_type,json=grantType,proto3" json:"grant_type,omitempty"` // example: urn:ietf:params:oauth:grant-type:jwt-bearer + Assertion string `protobuf:"bytes,2,opt,name=assertion,proto3" json:"assertion,omitempty"` + NotRequiredIntrospection bool `protobuf:"varint,4,opt,name=not_required_introspection,json=notRequiredIntrospection,proto3" json:"not_required_introspection,omitempty"` } func (x *CreateTokenRequest) Reset() { @@ -81,11 +81,11 @@ func (x *CreateTokenRequest) GetAssertion() string { return "" } -func (x *CreateTokenRequest) GetTokenVersion() uint32 { +func (x *CreateTokenRequest) GetNotRequiredIntrospection() bool { if x != nil { - return x.TokenVersion + return x.NotRequiredIntrospection } - return 0 + return false } type CreateTokenResponse struct { @@ -463,15 +463,17 @@ var File_idp_token_proto protoreflect.FileDescriptor var file_idp_token_proto_rawDesc = []byte{ 0x0a, 0x0f, 0x69, 0x64, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x12, 0x09, 0x69, 0x64, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x7c, 0x0a, 0x12, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x23, 0x0a, 0x0d, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x33, 0x22, 0x7c, 0x0a, 0x13, 0x43, 0x72, + 0x6f, 0x12, 0x09, 0x69, 0x64, 0x70, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x9b, 0x01, 0x0a, + 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x3c, 0x0a, 0x1a, 0x6e, 0x6f, 0x74, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, + 0x5f, 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x6e, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, + 0x64, 0x49, 0x6e, 0x74, 0x72, 0x6f, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4a, 0x04, + 0x08, 0x05, 0x10, 0x33, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x22, 0x7c, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, diff --git a/idptoken/pb/idp_token_grpc.pb.go b/idptoken/pb/idp_token_grpc.pb.go index e8b2732..b851f25 100644 --- a/idptoken/pb/idp_token_grpc.pb.go +++ b/idptoken/pb/idp_token_grpc.pb.go @@ -6,7 +6,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.3.0 -// - protoc v5.26.1 +// - protoc v5.29.2 // source: idp_token.proto package pb