Skip to content

Commit ee96edb

Browse files
committed
Fix subscribe and introduce nonstandard acl login
1 parent 11fba87 commit ee96edb

3 files changed

Lines changed: 32 additions & 17 deletions

File tree

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ This is a redis proxy to make ACL more convenient. It prefixes keys with the ACL
44

55
Your app can connect to this instance listening by default at port `6479`.
66

7+
If your framework doesn't have a way to log in via `AUTH username password`, you can log in using legacy password like `AUTH username:::password` (note the double colon). This nonstandard way of log in only works with this proxy and not with actual redis instance.
8+
79
## What it does do
810

911
Let's assume this software runs on port 6479 while the upstream Redis is on port 6379.
@@ -14,6 +16,8 @@ This is how it works when it executed serially:
1416

1517
```
1618
|GET foo| > |GET default:foo|
19+
|AUTH foo:::bar| > |AUTH foo bar|
20+
|GET baz| > |GET foo:baz|
1721
|AUTH user pass| > |AUTH user pass|
1822
|GET foo| > |GET user:foo|
1923
|SET foo bar| > |GET user:foo bar|

handler.go

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -111,23 +111,25 @@ func (m *Handler) subscriptionLoop(conn redcon.DetachedConn, upConn net.Conn) {
111111
}
112112

113113
go (func() {
114-
cmd, err := conn.ReadCommand()
115-
if err != nil {
116-
log.Printf("Failed to read command: %v", err)
117-
conn.Close()
118-
return
119-
}
120-
command := strings.ToUpper(string(cmd.Args[0]))
121-
newArgs, _ := modSingleCommand(command, context.username, cmd.Args)
122-
cmd.Args = newArgs
123-
124-
// Construct RESP command & send to redis
125-
request := buildRESPCommand(cmd.Args)
126-
_, err = upConn.Write(request)
127-
if err != nil {
128-
log.Printf("Failed to send command: %v", err)
129-
conn.Close()
130-
return
114+
for {
115+
cmd, err := conn.ReadCommand()
116+
if err != nil {
117+
log.Printf("Failed to read command: %v", err)
118+
conn.Close()
119+
return
120+
}
121+
command := strings.ToUpper(string(cmd.Args[0]))
122+
newArgs, _ := modSingleCommand(command, context.username, cmd.Args)
123+
cmd.Args = newArgs
124+
125+
// Construct RESP command & send to redis
126+
request := buildRESPCommand(cmd.Args)
127+
_, err = upConn.Write(request)
128+
if err != nil {
129+
log.Printf("Failed to send command: %v", err)
130+
conn.Close()
131+
return
132+
}
131133
}
132134
})()
133135

mod.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77

88
// Command modification types
99
const (
10+
ModifyAuth = "auth"
1011
ModifyFirst = "first"
1112
ModifyFirstTwo = "first_two"
1213
ModifyAll = "all"
@@ -26,6 +27,7 @@ const (
2627

2728
// Define namespaced command rules (extracted from redis-namespace)
2829
var namespacedCommands = map[string]string{
30+
"AUTH": ModifyAuth,
2931
"APPEND": ModifyFirst, "BITCOUNT": ModifyFirst, "BITFIELD": ModifyFirst,
3032
"BITOP": ModifyExcludeFirst, "BITPOS": ModifyFirst, "BLPOP": ModifyExcludeLast,
3133
"BRPOP": ModifyExcludeLast, "BRPOPLPUSH": ModifyExcludeLast, "BZPOPMIN": ModifyFirst,
@@ -89,6 +91,13 @@ func modSingleCommand(command, username string, args [][]byte) ([][]byte, revive
8991
}
9092

9193
switch modType {
94+
case ModifyAuth:
95+
if len(args) == 2 {
96+
if user, pass, found := strings.Cut(string(args[1]), ":::"); found {
97+
args[1] = []byte(user)
98+
args = append(args, []byte(pass))
99+
}
100+
}
92101
case ModifyFirst:
93102
if len(args) > 1 {
94103
args[1] = appendPrefix(args[1])

0 commit comments

Comments
 (0)