Skip to content

Commit cf6cf7f

Browse files
filipecosta90vmihailenco
authored andcommitted
Add AuthACL
1 parent 64bb0b7 commit cf6cf7f

File tree

7 files changed

+70
-2
lines changed

7 files changed

+70
-2
lines changed

cluster.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ type ClusterOptions struct {
5757

5858
OnConnect func(*Conn) error
5959

60+
Username string
6061
Password string
6162

6263
MaxRetries int
@@ -130,6 +131,7 @@ func (opt *ClusterOptions) clientOptions() *Options {
130131
MaxRetries: opt.MaxRetries,
131132
MinRetryBackoff: opt.MinRetryBackoff,
132133
MaxRetryBackoff: opt.MaxRetryBackoff,
134+
Username: opt.Username,
133135
Password: opt.Password,
134136
readOnly: opt.ReadOnly,
135137

commands.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ type Cmdable interface {
302302
type StatefulCmdable interface {
303303
Cmdable
304304
Auth(password string) *StatusCmd
305+
AuthACL(username, password string) *StatusCmd
305306
Select(index int) *StatusCmd
306307
SwapDB(index1, index2 int) *StatusCmd
307308
ClientSetName(name string) *BoolCmd
@@ -324,6 +325,15 @@ func (c statefulCmdable) Auth(password string) *StatusCmd {
324325
return cmd
325326
}
326327

328+
// Perform an AUTH command, using the given user and pass.
329+
// Should be used to authenticate the current connection with one of the connections defined in the ACL list
330+
// when connecting to a Redis 6.0 instance, or greater, that is using the Redis ACL system.
331+
func (c statefulCmdable) AuthACL(username, password string) *StatusCmd {
332+
cmd := NewStatusCmd("auth", username, password)
333+
_ = c(cmd)
334+
return cmd
335+
}
336+
327337
func (c cmdable) Echo(message interface{}) *StringCmd {
328338
cmd := NewStringCmd("echo", message)
329339
_ = c(cmd)

options.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,13 @@ type Options struct {
4040
// Hook that is called when new connection is established.
4141
OnConnect func(*Conn) error
4242

43+
// Use the specified Username to authenticate the current connection with one of the connections defined in the ACL
44+
// list when connecting to a Redis 6.0 instance, or greater, that is using the Redis ACL system.
45+
Username string
46+
4347
// Optional password. Must match the password specified in the
44-
// requirepass server configuration option.
48+
// requirepass server configuration option (if connecting to a Redis 5.0 instance, or lower),
49+
// or the User Password when connecting to a Redis 6.0 instance, or greater, that is using the Redis ACL system.
4550
Password string
4651
// Database to be selected after connecting to the server.
4752
DB int
@@ -187,6 +192,7 @@ func ParseURL(redisURL string) (*Options, error) {
187192
}
188193

189194
if u.User != nil {
195+
o.Username = u.User.Username()
190196
if p, ok := u.User.Password(); ok {
191197
o.Password = p
192198
}

options_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,56 +15,86 @@ func TestParseURL(t *testing.T) {
1515
db int
1616
tls bool
1717
err error
18+
user string
19+
pass string
1820
}{
1921
{
2022
"redis://localhost:123/1",
2123
"localhost:123",
2224
1, false, nil,
25+
"", "",
2326
},
2427
{
2528
"redis://localhost:123",
2629
"localhost:123",
2730
0, false, nil,
31+
"", "",
2832
},
2933
{
3034
"redis://localhost/1",
3135
"localhost:6379",
3236
1, false, nil,
37+
"", "",
3338
},
3439
{
3540
"redis://12345",
3641
"12345:6379",
3742
0, false, nil,
43+
"", "",
3844
},
3945
{
4046
"rediss://localhost:123",
4147
"localhost:123",
4248
0, true, nil,
49+
"", "",
50+
},
51+
{
52+
"redis://:bar@localhost:123",
53+
"localhost:123",
54+
0, false, nil,
55+
"", "bar",
56+
},
57+
{
58+
"redis://foo@localhost:123",
59+
"localhost:123",
60+
0, false, nil,
61+
"foo", "",
62+
},
63+
{
64+
"redis://foo:bar@localhost:123",
65+
"localhost:123",
66+
0, false, nil,
67+
"foo", "bar",
4368
},
4469
{
4570
"redis://localhost/?abc=123",
4671
"",
4772
0, false, errors.New("no options supported"),
73+
"", "",
4874
},
4975
{
5076
"http://google.com",
5177
"",
5278
0, false, errors.New("invalid redis URL scheme: http"),
79+
"", "",
5380
},
5481
{
5582
"redis://localhost/1/2/3/4",
5683
"",
5784
0, false, errors.New("invalid redis URL path: /1/2/3/4"),
85+
"", "",
5886
},
5987
{
6088
"12345",
6189
"",
6290
0, false, errors.New("invalid redis URL scheme: "),
91+
"", "",
6392
},
6493
{
6594
"redis://localhost/iamadatabase",
6695
"",
6796
0, false, errors.New(`invalid redis database number: "iamadatabase"`),
97+
"", "",
6898
},
6999
}
70100

@@ -90,6 +120,12 @@ func TestParseURL(t *testing.T) {
90120
if c.tls && o.TLSConfig == nil {
91121
t.Errorf("got nil TLSConfig, expected a TLSConfig")
92122
}
123+
if o.Username != c.user {
124+
t.Errorf("got %q, expected %q", o.Username, c.user)
125+
}
126+
if o.Password != c.pass {
127+
t.Errorf("got %q, expected %q", o.Password, c.pass)
128+
}
93129
})
94130
}
95131
}

redis.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,11 @@ func (c *baseClient) initConn(ctx context.Context, cn *pool.Conn) error {
241241

242242
_, err := conn.Pipelined(func(pipe Pipeliner) error {
243243
if c.opt.Password != "" {
244-
pipe.Auth(c.opt.Password)
244+
if c.opt.Username != "" {
245+
pipe.AuthACL(c.opt.Username, c.opt.Password)
246+
} else {
247+
pipe.Auth(c.opt.Password)
248+
}
245249
}
246250

247251
if c.opt.DB > 0 {

sentinel.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,15 @@ type FailoverOptions struct {
2222
MasterName string
2323
// A seed list of host:port addresses of sentinel nodes.
2424
SentinelAddrs []string
25+
SentinelUsername string
2526
SentinelPassword string
2627

2728
// Following options are copied from Options struct.
2829

2930
Dialer func(ctx context.Context, network, addr string) (net.Conn, error)
3031
OnConnect func(*Conn) error
3132

33+
Username string
3234
Password string
3335
DB int
3436

@@ -57,6 +59,7 @@ func (opt *FailoverOptions) options() *Options {
5759
OnConnect: opt.OnConnect,
5860

5961
DB: opt.DB,
62+
Username: opt.Username,
6063
Password: opt.Password,
6164

6265
MaxRetries: opt.MaxRetries,
@@ -88,6 +91,7 @@ func NewFailoverClient(failoverOpt *FailoverOptions) *Client {
8891
failover := &sentinelFailover{
8992
masterName: failoverOpt.MasterName,
9093
sentinelAddrs: failoverOpt.SentinelAddrs,
94+
username: failoverOpt.SentinelUsername,
9195
password: failoverOpt.SentinelPassword,
9296

9397
opt: opt,
@@ -281,6 +285,7 @@ type sentinelFailover struct {
281285
sentinelAddrs []string
282286

283287
opt *Options
288+
username string
284289
password string
285290

286291
pool *pool.ConnPool
@@ -372,6 +377,7 @@ func (c *sentinelFailover) masterAddr() (string, error) {
372377
Addr: sentinelAddr,
373378
Dialer: c.opt.Dialer,
374379

380+
Username: c.username,
375381
Password: c.password,
376382

377383
MaxRetries: c.opt.MaxRetries,

universal.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ type UniversalOptions struct {
2222

2323
Dialer func(ctx context.Context, network, addr string) (net.Conn, error)
2424
OnConnect func(*Conn) error
25+
Username string
2526
Password string
2627
MaxRetries int
2728
MinRetryBackoff time.Duration
@@ -60,6 +61,7 @@ func (o *UniversalOptions) Cluster() *ClusterOptions {
6061
Dialer: o.Dialer,
6162
OnConnect: o.OnConnect,
6263

64+
Username: o.Username,
6365
Password: o.Password,
6466

6567
MaxRedirects: o.MaxRedirects,
@@ -99,6 +101,7 @@ func (o *UniversalOptions) Failover() *FailoverOptions {
99101
OnConnect: o.OnConnect,
100102

101103
DB: o.DB,
104+
Username: o.Username,
102105
Password: o.Password,
103106

104107
MaxRetries: o.MaxRetries,
@@ -133,6 +136,7 @@ func (o *UniversalOptions) Simple() *Options {
133136
OnConnect: o.OnConnect,
134137

135138
DB: o.DB,
139+
Username: o.Username,
136140
Password: o.Password,
137141

138142
MaxRetries: o.MaxRetries,

0 commit comments

Comments
 (0)