Skip to content

Commit

Permalink
Merge pull request #42 from hsshss/username_auth
Browse files Browse the repository at this point in the history
Username and password authentication
  • Loading branch information
yannh authored Sep 17, 2022
2 parents 637df2d + a169cf7 commit 3587bc2
Show file tree
Hide file tree
Showing 12 changed files with 91 additions and 10 deletions.
5 changes: 5 additions & 0 deletions acceptance-tests/acceptance.bats
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@
[ "$status" -eq 0 ]
}

@test "Pass when using a non-default db, and a password with username" {
run tests/select-db-with-username-password.sh
[ "$status" -eq 0 ]
}

@test "Dumping / restoring all databases" {
run tests/multiple-dbs.sh
[ "$status" -eq 0 ]
Expand Down
2 changes: 2 additions & 0 deletions acceptance-tests/redis-confs/users.acl
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
user default on >somepassword allkeys allchannels +@all
user test on >testpassword allkeys allchannels +@all
2 changes: 1 addition & 1 deletion acceptance-tests/redis-confs/with_password.conf
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
port 6380
requirepass somepassword
requirepass somepassword
2 changes: 2 additions & 0 deletions acceptance-tests/redis-confs/with_username_and_password.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
port 6380
aclfile /usr/local/etc/redis/users.acl
4 changes: 2 additions & 2 deletions acceptance-tests/tests/select-db-with-password.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
export DB=2
export REDIS_PORT=6380
export REDISDUMPGO_AUTH=somepassword
export REDISCMD="redis-cli -h redis_secure -p $REDIS_PORT --pass $REDISDUMPGO_AUTH -n 2"
export REDISCMD="redis-cli -h redis_with_password -p $REDIS_PORT --pass $REDISDUMPGO_AUTH -n 2"

echo "-> Filling Redis with Mock Data..."
$REDISCMD FLUSHDB
/generator -output resp -type strings -n 100 | $REDISCMD --pipe
DBSIZE=`$REDISCMD dbsize`

echo "-> Dumping DB..."
time /redis-dump-go -host redis_secure -n 250 -port $REDIS_PORT -db $DB -output resp >backup
time /redis-dump-go -host redis_with_password -n 250 -port $REDIS_PORT -db $DB -output resp >backup

echo "-> Flushing DB and restoring dump..."
$REDISCMD FLUSHDB
Expand Down
29 changes: 29 additions & 0 deletions acceptance-tests/tests/select-db-with-username-password.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/bin/sh -e

export DB=2
export REDIS_PORT=6380
export REDIS_USER=test
export REDISDUMPGO_AUTH=testpassword
export REDISCMD="redis-cli -h redis_with_username_and_password -p $REDIS_PORT --user $REDIS_USER --pass $REDISDUMPGO_AUTH -n 2"
echo $REDISCMD
echo "-> Filling Redis with Mock Data..."
$REDISCMD FLUSHDB
/generator -output resp -type strings -n 100 | $REDISCMD --pipe
DBSIZE=`$REDISCMD dbsize`

echo "-> Dumping DB..."
time /redis-dump-go -host redis_with_username_and_password -n 250 -port $REDIS_PORT -db $DB -user $REDIS_USER -output resp >backup

echo "-> Flushing DB and restoring dump..."
$REDISCMD FLUSHDB
$REDISCMD --pipe <backup
NEWDBSIZE=`$REDISCMD dbsize`
echo "Redis has $DBSIZE entries"
echo "-> Comparing DB sizes..."
if [ $DBSIZE -ne $NEWDBSIZE ]; then
echo "ERROR - restored DB has $NEWDBSIZE elements, expected $DBSIZE"
exit 1
else
echo "OK - $NEWDBSIZE elements"
exit 0
fi
17 changes: 14 additions & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ services:
image: "redis:alpine"
ports:
- "6379:6379"
redis_secure:
redis_with_password:
image: "redis:alpine"
volumes:
- ./acceptance-tests/redis-confs:/usr/local/etc/redis
Expand All @@ -15,6 +15,16 @@ services:
protocol: tcp
mode: host
entrypoint: ["/usr/local/bin/redis-server", "/usr/local/etc/redis/with_password.conf"]
redis_with_username_and_password:
image: "redis:alpine"
volumes:
- ./acceptance-tests/redis-confs:/usr/local/etc/redis
ports:
- target: 6381
published: 6381
protocol: tcp
mode: host
entrypoint: ["/usr/local/bin/redis-server", "/usr/local/etc/redis/with_username_and_password.conf"]
tests:
image: "alpine:latest"
volumes:
Expand All @@ -23,6 +33,7 @@ services:
- ./bin/redis-dump-go:/redis-dump-go
depends_on:
- "redis"
- "redis_secure"
- "redis_with_password"
- "redis_with_username_and_password"
working_dir: /acceptance-tests
entrypoint: ["/acceptance-tests/entrypoint.sh"]
entrypoint: ["/acceptance-tests/entrypoint.sh"]
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ func realMain() int {
s := redisdump.Host{
Host: c.Host,
Port: c.Port,
Username: c.Username,
Password: redisPassword,
TlsHandler: tlshandler,
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ type Config struct {
Host string
Port int
Db int
Username string
Filter string
Noscan bool
BatchSize int
Expand Down Expand Up @@ -44,6 +45,7 @@ func FromFlags(progName string, args []string) (Config, string, error) {
flags.StringVar(&c.Host, "host", "127.0.0.1", "Server host")
flags.IntVar(&c.Port, "port", 6379, "Server port")
flags.IntVar(&c.Db, "db", -1, "only dump this database (default: all databases)")
flags.StringVar(&c.Username, "user", "", "Username")
flags.StringVar(&c.Filter, "filter", "*", "Key filter to use")
flags.BoolVar(&c.Noscan, "noscan", false, "Use KEYS * instead of SCAN - for Redis <=2.8")
flags.IntVar(&c.BatchSize, "batchSize", 1000, "HSET/RPUSH/SADD/ZADD only add 'batchSize' items at a time")
Expand Down
14 changes: 14 additions & 0 deletions pkg/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,20 @@ func TestFromFlags(t *testing.T) {
Output: "commands",
},
},
{
[]string{"-host", "redis", "-port", "1234", "-batchSize", "10", "-user", "test"},
Config{
Db: -1,
Host: "redis",
Port: 1234,
Filter: "*",
BatchSize: 10,
NWorkers: 10,
WithTTL: true,
Output: "resp",
Username: "test",
},
},
{
[]string{"-db", "1"},
Config{
Expand Down
11 changes: 8 additions & 3 deletions pkg/redisdump/redisdump.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,12 +327,16 @@ func RedisURL(redisHost string, redisPort string) string {
return fmt.Sprintf("redis://%s:%s", redisHost, redisPort)
}

func redisDialOpts(redisPassword string, tlsHandler *TlsHandler, db *uint8) ([]radix.DialOpt, error) {
func redisDialOpts(redisUsername string, redisPassword string, tlsHandler *TlsHandler, db *uint8) ([]radix.DialOpt, error) {
dialOpts := []radix.DialOpt{
radix.DialTimeout(5 * time.Minute),
}
if redisPassword != "" {
dialOpts = append(dialOpts, radix.DialAuthPass(redisPassword))
if redisUsername != "" {
dialOpts = append(dialOpts, radix.DialAuthUser(redisUsername, redisPassword))
} else {
dialOpts = append(dialOpts, radix.DialAuthPass(redisPassword))
}
}
if tlsHandler != nil {
tlsCfg, err := tlsConfig(tlsHandler)
Expand Down Expand Up @@ -385,6 +389,7 @@ func dumpDB(client radix.Client, db *uint8, filter string, nWorkers int, withTTL
type Host struct {
Host string
Port int
Username string
Password string
TlsHandler *TlsHandler
}
Expand All @@ -396,7 +401,7 @@ func DumpServer(s Host, db *uint8, filter string, nWorkers int, withTTL bool, ba
redisURL := RedisURL(s.Host, fmt.Sprint(s.Port))
getConnFunc := func(db *uint8) func(network, addr string) (radix.Conn, error) {
return func(network, addr string) (radix.Conn, error) {
dialOpts, err := redisDialOpts(s.Password, s.TlsHandler, db)
dialOpts, err := redisDialOpts(s.Username, s.Password, s.TlsHandler, db)
if err != nil {
return nil, err
}
Expand Down
12 changes: 11 additions & 1 deletion pkg/redisdump/redisdump_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,27 +241,37 @@ func TestParseKeyspaceInfo(t *testing.T) {

func TestRedisDialOpts(t *testing.T) {
for i, testCase := range []struct {
redisUsername string
redisPassword string
tlsHandler *TlsHandler
db uint8
nDialOpts int
err error
}{
{
"",
"",
nil,
1,
2,
nil,
}, {
"",
"test",
&TlsHandler{},
1,
4,
nil,
}, {
"test",
"test",
&TlsHandler{},
1,
4,
nil,
},
} {
dOpts, err := redisDialOpts(testCase.redisPassword, testCase.tlsHandler, &testCase.db)
dOpts, err := redisDialOpts(testCase.redisUsername, testCase.redisPassword, testCase.tlsHandler, &testCase.db)
if err != testCase.err {
t.Errorf("expected error to be %+v, got %+v", testCase.err, err)
}
Expand Down

0 comments on commit 3587bc2

Please sign in to comment.