Skip to content

Commit a0d9205

Browse files
authored
Merge pull request #859 from ydb-platform/obfuscate-access-token
* Refactored credentials options (from funcs to interfaces and types)
2 parents 184cadd + f88d739 commit a0d9205

File tree

15 files changed

+412
-140
lines changed

15 files changed

+412
-140
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
* Refactored credentials options (from funcs to interfaces and types)
2+
* Fixed stringification of credentials object
3+
14
## v3.53.2
25
* Fixed panic when try to unwrap values with more than 127 columns with custom ydb unmarshaler
36

connection.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,8 @@ func connect(ctx context.Context, c *Driver) error {
465465
c.config = c.config.With(config.WithCredentials(
466466
credentials.NewStaticCredentials(
467467
c.userInfo.User, c.userInfo.Password,
468-
c.config,
468+
c.config.Endpoint(),
469+
credentials.WithGrpcDialOptions(c.config.GrpcDialOptions()...),
469470
),
470471
))
471472
}

credentials/credentials.go

Lines changed: 12 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,7 @@ package credentials
33
import (
44
"context"
55

6-
"google.golang.org/grpc"
7-
86
"github.com/ydb-platform/ydb-go-sdk/v3/internal/credentials"
9-
"github.com/ydb-platform/ydb-go-sdk/v3/internal/stack"
107
)
118

129
// Credentials is an interface of YDB credentials required for connect with YDB
@@ -15,67 +12,25 @@ type Credentials interface {
1512
Token(context.Context) (string, error)
1613
}
1714

18-
type optionsHolder struct {
19-
sourceInfo string
20-
}
21-
22-
type option func(h *optionsHolder)
23-
24-
// WithSourceInfo option append to credentials object the source info for reporting source info details on error case
25-
func WithSourceInfo(sourceInfo string) option {
26-
return func(h *optionsHolder) {
27-
h.sourceInfo = sourceInfo
28-
}
29-
}
30-
3115
// NewAccessTokenCredentials makes access token credentials object
3216
// Passed options redefines default values of credentials object internal fields
33-
func NewAccessTokenCredentials(accessToken string, opts ...option) *credentials.AccessToken {
34-
h := &optionsHolder{
35-
sourceInfo: stack.Record(1),
36-
}
37-
for _, o := range opts {
38-
if o != nil {
39-
o(h)
40-
}
41-
}
42-
return credentials.NewAccessTokenCredentials(accessToken, credentials.WithSourceInfo(h.sourceInfo))
17+
func NewAccessTokenCredentials(
18+
accessToken string, opts ...credentials.AccessTokenCredentialsOption,
19+
) *credentials.AccessToken {
20+
return credentials.NewAccessTokenCredentials(accessToken, opts...)
4321
}
4422

4523
// NewAnonymousCredentials makes anonymous credentials object
4624
// Passed options redefines default values of credentials object internal fields
47-
func NewAnonymousCredentials(opts ...option) *credentials.Anonymous {
48-
h := &optionsHolder{
49-
sourceInfo: stack.Record(1),
50-
}
51-
for _, o := range opts {
52-
if o != nil {
53-
o(h)
54-
}
55-
}
56-
return credentials.NewAnonymousCredentials(credentials.WithSourceInfo(h.sourceInfo))
57-
}
58-
59-
type staticCredentialsConfig struct {
60-
authEndpoint string
61-
opts []grpc.DialOption
62-
}
63-
64-
func (s staticCredentialsConfig) Endpoint() string {
65-
return s.authEndpoint
66-
}
67-
68-
func (s staticCredentialsConfig) GrpcDialOptions() []grpc.DialOption {
69-
return s.opts
25+
func NewAnonymousCredentials(
26+
opts ...credentials.AnonymousCredentialsOption,
27+
) *credentials.Anonymous {
28+
return credentials.NewAnonymousCredentials(opts...)
7029
}
7130

7231
// NewStaticCredentials makes static credentials object
73-
func NewStaticCredentials(user, password, authEndpoint string, opts ...grpc.DialOption) *credentials.Static {
74-
return credentials.NewStaticCredentials(user, password,
75-
staticCredentialsConfig{
76-
authEndpoint: authEndpoint,
77-
opts: opts,
78-
},
79-
credentials.WithSourceInfo(stack.Record(1)),
80-
)
32+
func NewStaticCredentials(
33+
user, password, authEndpoint string, opts ...credentials.StaticCredentialsOption,
34+
) *credentials.Static {
35+
return credentials.NewStaticCredentials(user, password, authEndpoint, opts...)
8136
}

credentials/options.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package credentials
2+
3+
import (
4+
"google.golang.org/grpc"
5+
6+
"github.com/ydb-platform/ydb-go-sdk/v3/internal/credentials"
7+
)
8+
9+
// WithSourceInfo option append to credentials object the source info for reporting source info details on error case
10+
func WithSourceInfo(sourceInfo string) credentials.SourceInfoOption {
11+
return credentials.WithSourceInfo(sourceInfo)
12+
}
13+
14+
// WithGrpcDialOptions option append to static credentials object GRPC dial options
15+
func WithGrpcDialOptions(opts ...grpc.DialOption) credentials.StaticCredentialsOption {
16+
return credentials.WithGrpcDialOptions(opts...)
17+
}

internal/balancer/balancer.go

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
balancerConfig "github.com/ydb-platform/ydb-go-sdk/v3/internal/balancer/config"
1212
"github.com/ydb-platform/ydb-go-sdk/v3/internal/closer"
1313
"github.com/ydb-platform/ydb-go-sdk/v3/internal/conn"
14+
"github.com/ydb-platform/ydb-go-sdk/v3/internal/credentials"
1415
internalDiscovery "github.com/ydb-platform/ydb-go-sdk/v3/internal/discovery"
1516
discoveryConfig "github.com/ydb-platform/ydb-go-sdk/v3/internal/discovery/config"
1617
"github.com/ydb-platform/ydb-go-sdk/v3/internal/endpoint"
@@ -66,14 +67,10 @@ func (b *Balancer) clusterDiscovery(ctx context.Context) (err error) {
6667
if err = retry.Retry(ctx, func(childCtx context.Context) (err error) {
6768
if err = b.clusterDiscoveryAttempt(childCtx); err != nil {
6869
if xerrors.IsTransportError(err, grpcCodes.Unauthenticated) {
69-
return xerrors.WithStackTrace(
70-
fmt.Errorf(
71-
"cluster discovery failed: %w (endpoint: %q, database: %q, credentials: %q)",
72-
err,
73-
b.driverConfig.Endpoint(),
74-
b.driverConfig.Database(),
75-
b.driverConfig.Credentials(),
76-
),
70+
return credentials.UnauthenticatedError("cluster discovery failed", err,
71+
credentials.WithEndpoint(b.driverConfig.Endpoint()),
72+
credentials.WithDatabase(b.driverConfig.Database()),
73+
credentials.WithCredentials(b.driverConfig.Credentials()),
7774
)
7875
}
7976
// if got err but parent context is not done - mark error as retryable
@@ -298,6 +295,13 @@ func (b *Balancer) wrapCall(ctx context.Context, f func(ctx context.Context, cc
298295

299296
if err = f(ctx, cc); err != nil {
300297
if conn.UseWrapping(ctx) {
298+
if xerrors.IsTransportError(err, grpcCodes.Unauthenticated) {
299+
err = credentials.UnauthenticatedError("unauthenticated", err,
300+
credentials.WithAddress(cc.Endpoint().String()),
301+
credentials.WithNodeID(cc.Endpoint().NodeID()),
302+
credentials.WithCredentials(b.driverConfig.Credentials()),
303+
)
304+
}
301305
return xerrors.WithStackTrace(err)
302306
}
303307
return err

internal/conn/middleware.go

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -80,21 +80,3 @@ func WithBeforeFunc(
8080
},
8181
}
8282
}
83-
84-
func WithAfterFunc(
85-
cc grpc.ClientConnInterface,
86-
after func(),
87-
) grpc.ClientConnInterface {
88-
return &middleware{
89-
invoke: func(ctx context.Context, method string, args interface{}, reply interface{}, opts ...grpc.CallOption) error {
90-
defer after()
91-
return cc.Invoke(ctx, method, args, reply, opts...)
92-
},
93-
newStream: func(ctx context.Context, desc *grpc.StreamDesc, method string, opts ...grpc.CallOption) (
94-
grpc.ClientStream, error,
95-
) {
96-
defer after()
97-
return cc.NewStream(ctx, desc, method, opts...)
98-
},
99-
}
100-
}

internal/credentials/access_token.go

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,33 +4,37 @@ import (
44
"context"
55
"fmt"
66

7+
"github.com/ydb-platform/ydb-go-sdk/v3/internal/allocator"
78
"github.com/ydb-platform/ydb-go-sdk/v3/internal/secret"
89
"github.com/ydb-platform/ydb-go-sdk/v3/internal/stack"
910
)
1011

1112
var (
12-
_ Credentials = (*AccessToken)(nil)
13-
_ fmt.Stringer = (*AccessToken)(nil)
13+
_ Credentials = (*AccessToken)(nil)
14+
_ fmt.Stringer = (*AccessToken)(nil)
15+
_ AccessTokenCredentialsOption = SourceInfoOption("")
1416
)
1517

18+
type AccessTokenCredentialsOption interface {
19+
ApplyAccessTokenCredentialsOption(c *AccessToken)
20+
}
21+
1622
// AccessToken implements Credentials interface with static
1723
// authorization parameters.
1824
type AccessToken struct {
1925
token string
2026
sourceInfo string
2127
}
2228

23-
func NewAccessTokenCredentials(token string, opts ...Option) *AccessToken {
24-
options := optionsHolder{
29+
func NewAccessTokenCredentials(token string, opts ...AccessTokenCredentialsOption) *AccessToken {
30+
c := &AccessToken{
31+
token: token,
2532
sourceInfo: stack.Record(1),
2633
}
2734
for _, opt := range opts {
28-
opt(&options)
29-
}
30-
return &AccessToken{
31-
token: token,
32-
sourceInfo: options.sourceInfo,
35+
opt.ApplyAccessTokenCredentialsOption(c)
3336
}
37+
return c
3438
}
3539

3640
// Token implements Credentials.
@@ -40,5 +44,14 @@ func (c AccessToken) Token(_ context.Context) (string, error) {
4044

4145
// Token implements Credentials.
4246
func (c AccessToken) String() string {
43-
return fmt.Sprintf("AccessToken(token:%q,from:%q)", secret.Token(c.token), c.sourceInfo)
47+
buffer := allocator.Buffers.Get()
48+
defer allocator.Buffers.Put(buffer)
49+
buffer.WriteString("AccessToken(token:")
50+
fmt.Fprintf(buffer, "%q", secret.Token(c.token))
51+
if c.sourceInfo != "" {
52+
buffer.WriteString(",from:")
53+
fmt.Fprintf(buffer, "%q", c.sourceInfo)
54+
}
55+
buffer.WriteByte(')')
56+
return buffer.String()
4457
}

internal/credentials/anonymous.go

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,33 @@ import (
44
"context"
55
"fmt"
66

7+
"github.com/ydb-platform/ydb-go-sdk/v3/internal/allocator"
78
"github.com/ydb-platform/ydb-go-sdk/v3/internal/stack"
89
)
910

1011
var (
11-
_ Credentials = (*Anonymous)(nil)
12-
_ fmt.Stringer = (*Anonymous)(nil)
12+
_ Credentials = (*Anonymous)(nil)
13+
_ fmt.Stringer = (*Anonymous)(nil)
14+
_ AnonymousCredentialsOption = SourceInfoOption("")
1315
)
1416

17+
type AnonymousCredentialsOption interface {
18+
ApplyAnonymousCredentialsOption(c *Anonymous)
19+
}
20+
1521
// Anonymous implements Credentials interface with Anonymous access
1622
type Anonymous struct {
1723
sourceInfo string
1824
}
1925

20-
func NewAnonymousCredentials(opts ...Option) *Anonymous {
21-
options := optionsHolder{
26+
func NewAnonymousCredentials(opts ...AnonymousCredentialsOption) *Anonymous {
27+
c := &Anonymous{
2228
sourceInfo: stack.Record(1),
2329
}
2430
for _, opt := range opts {
25-
opt(&options)
26-
}
27-
return &Anonymous{
28-
sourceInfo: options.sourceInfo,
31+
opt.ApplyAnonymousCredentialsOption(c)
2932
}
33+
return c
3034
}
3135

3236
// Token implements Credentials.
@@ -36,5 +40,13 @@ func (c Anonymous) Token(_ context.Context) (string, error) {
3640

3741
// Token implements Credentials.
3842
func (c Anonymous) String() string {
39-
return fmt.Sprintf("Anonymous(from:%q)", c.sourceInfo)
43+
buffer := allocator.Buffers.Get()
44+
defer allocator.Buffers.Put(buffer)
45+
buffer.WriteString("Anonymous(")
46+
if c.sourceInfo != "" {
47+
buffer.WriteString("from:")
48+
fmt.Fprintf(buffer, "%q", c.sourceInfo)
49+
}
50+
buffer.WriteByte(')')
51+
return buffer.String()
4052
}

internal/credentials/options.go

Lines changed: 0 additions & 13 deletions
This file was deleted.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package credentials
2+
3+
type SourceInfoOption string
4+
5+
func (sourceInfo SourceInfoOption) ApplyStaticCredentialsOption(h *Static) {
6+
h.sourceInfo = string(sourceInfo)
7+
}
8+
9+
func (sourceInfo SourceInfoOption) ApplyAnonymousCredentialsOption(h *Anonymous) {
10+
h.sourceInfo = string(sourceInfo)
11+
}
12+
13+
func (sourceInfo SourceInfoOption) ApplyAccessTokenCredentialsOption(h *AccessToken) {
14+
h.sourceInfo = string(sourceInfo)
15+
}
16+
17+
// WithSourceInfo option append to credentials object the source info for reporting source info details on error case
18+
func WithSourceInfo(sourceInfo string) SourceInfoOption {
19+
return SourceInfoOption(sourceInfo)
20+
}

0 commit comments

Comments
 (0)