From 5aafb216fd70cc3f109779f2ebf54793789e3a8d Mon Sep 17 00:00:00 2001 From: destinyoooo <643604012@qq.com> Date: Sat, 1 Nov 2025 15:24:46 +0800 Subject: [PATCH 1/2] feat: add acl support and command test --- acl_commands.go | 22 ++++++++++++++++++++++ acl_commands_test.go | 15 +++++++++++++++ commands_test.go | 19 +++++++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/acl_commands.go b/acl_commands.go index 9cb800bb3b..a7b5dd2483 100644 --- a/acl_commands.go +++ b/acl_commands.go @@ -8,8 +8,12 @@ type ACLCmdable interface { ACLLog(ctx context.Context, count int64) *ACLLogCmd ACLLogReset(ctx context.Context) *StatusCmd + ACLGenPass(ctx context.Context, bit int) *StringCmd + ACLSetUser(ctx context.Context, username string, rules ...string) *StatusCmd ACLDelUser(ctx context.Context, username string) *IntCmd + ACLUsers(ctx context.Context) *StringSliceCmd + ACLWhoAmI(ctx context.Context) *StringCmd ACLList(ctx context.Context) *StringSliceCmd ACLCat(ctx context.Context) *StringSliceCmd @@ -65,6 +69,24 @@ func (c cmdable) ACLSetUser(ctx context.Context, username string, rules ...strin return cmd } +func (c cmdable) ACLGenPass(ctx context.Context, bit int) *StringCmd { + cmd := NewStringCmd(ctx, "acl", "genpass") + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ACLUsers(ctx context.Context) *StringSliceCmd { + cmd := NewStringSliceCmd(ctx, "acl", "users") + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ACLWhoAmI(ctx context.Context) *StringCmd { + cmd := NewStringCmd(ctx, "acl", "whoami") + _ = c(ctx, cmd) + return cmd +} + func (c cmdable) ACLList(ctx context.Context) *StringSliceCmd { cmd := NewStringSliceCmd(ctx, "acl", "list") _ = c(ctx, cmd) diff --git a/acl_commands_test.go b/acl_commands_test.go index a96621dbce..e6a99ec5e3 100644 --- a/acl_commands_test.go +++ b/acl_commands_test.go @@ -92,6 +92,21 @@ var _ = Describe("ACL user commands", Label("NonRedisEnterprise"), func() { Expect(err).NotTo(HaveOccurred()) Expect(res).To(HaveLen(1)) Expect(res[0]).To(ContainSubstring("default")) + + res, err = client.ACLUsers(ctx).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(res).To(HaveLen(1)) + Expect(res[0]).To(Equal("default")) + + res1, err := client.ACLWhoAmI(ctx).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(res1).To(Equal("default")) + }) + + It("gen password", func() { + password, err := client.ACLGenPass(ctx, 0).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(password).NotTo(BeEmpty()) }) It("setuser and deluser", func() { diff --git a/commands_test.go b/commands_test.go index 17b4dd0306..535780c58c 100644 --- a/commands_test.go +++ b/commands_test.go @@ -199,6 +199,25 @@ var _ = Describe("Commands", func() { Expect(r.Val()).To(Equal(int64(0))) }) + It("should ClientKillByFilter with kill myself", func() { + opt := redisOptions() + opt.ClientName = "killmyid" + db := redis.NewClient(opt) + + defer func() { + Expect(db.Close()).NotTo(HaveOccurred()) + }() + + myid := db.ClientID(ctx).Val() + killed := client.ClientKillByFilter(ctx, "ID", strconv.FormatInt(myid, 10)) + Expect(killed.Err()).NotTo(HaveOccurred()) + Expect(killed.Val()).To(BeNumerically("==", 1)) + + val, err := client.ClientList(ctx).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(val).ShouldNot(ContainSubstring("name=killmyid")) + }) + It("should ClientKillByFilter with MAXAGE", Label("NonRedisEnterprise"), func() { SkipBeforeRedisVersion(7.4, "doesn't work with older redis stack images") var s []string From 60f5375b11f594328269ba03f90233f5eb8cff9d Mon Sep 17 00:00:00 2001 From: destinyoooo <643604012@qq.com> Date: Tue, 4 Nov 2025 10:47:41 +0800 Subject: [PATCH 2/2] validate client name before kill it --- commands_test.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/commands_test.go b/commands_test.go index 535780c58c..26e9becca9 100644 --- a/commands_test.go +++ b/commands_test.go @@ -203,17 +203,21 @@ var _ = Describe("Commands", func() { opt := redisOptions() opt.ClientName = "killmyid" db := redis.NewClient(opt) + Expect(db.Ping(ctx).Err()).NotTo(HaveOccurred()) defer func() { Expect(db.Close()).NotTo(HaveOccurred()) }() + val, err := client.ClientList(ctx).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(val).Should(ContainSubstring("name=killmyid")) myid := db.ClientID(ctx).Val() killed := client.ClientKillByFilter(ctx, "ID", strconv.FormatInt(myid, 10)) Expect(killed.Err()).NotTo(HaveOccurred()) Expect(killed.Val()).To(BeNumerically("==", 1)) - val, err := client.ClientList(ctx).Result() + val, err = client.ClientList(ctx).Result() Expect(err).NotTo(HaveOccurred()) Expect(val).ShouldNot(ContainSubstring("name=killmyid")) })