Skip to content

Commit 68fa3f4

Browse files
authored
feat(AclFamily): add acl whoami command (#1774)
* add acl whoami * add tests
1 parent 6706707 commit 68fa3f4

File tree

3 files changed

+33
-11
lines changed

3 files changed

+33
-11
lines changed

src/server/acl/acl_family.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,10 @@ void AclFamily::DelUser(CmdArgList args, ConnectionContext* cntx) {
215215
cntx->SendOk();
216216
}
217217

218+
void AclFamily::WhoAmI(CmdArgList args, ConnectionContext* cntx) {
219+
cntx->SendSimpleString(absl::StrCat("User is ", cntx->authed_username));
220+
}
221+
218222
using CI = dfly::CommandId;
219223

220224
using MemberFunc = void (AclFamily::*)(CmdArgList args, ConnectionContext* cntx);
@@ -229,6 +233,7 @@ constexpr uint32_t kAcl = acl::CONNECTION;
229233
constexpr uint32_t kList = acl::ADMIN | acl::SLOW | acl::DANGEROUS;
230234
constexpr uint32_t kSetUser = acl::ADMIN | acl::SLOW | acl::DANGEROUS;
231235
constexpr uint32_t kDelUser = acl::ADMIN | acl::SLOW | acl::DANGEROUS;
236+
constexpr uint32_t kWhoAmI = acl::SLOW;
232237

233238
// We can't implement the ACL commands and its respective subcommands LIST, CAT, etc
234239
// the usual way, (that is, one command called ACL which then dispatches to the subcommand
@@ -245,6 +250,8 @@ void AclFamily::Register(dfly::CommandRegistry* registry) {
245250
.HFUNC(SetUser);
246251
*registry << CI{"ACL DELUSER", CO::ADMIN | CO::NOSCRIPT | CO::LOADING, 2, 0, 0, 0, acl::kDelUser}
247252
.HFUNC(DelUser);
253+
*registry << CI{"ACL WHOAMI", CO::ADMIN | CO::NOSCRIPT | CO::LOADING, 1, 0, 0, 0, acl::kWhoAmI}
254+
.HFUNC(WhoAmI);
248255
}
249256

250257
#undef HFUNC

src/server/acl/acl_family.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class AclFamily final {
3131
void List(CmdArgList args, ConnectionContext* cntx);
3232
void SetUser(CmdArgList args, ConnectionContext* cntx);
3333
void DelUser(CmdArgList args, ConnectionContext* cntx);
34+
void WhoAmI(CmdArgList args, ConnectionContext* cntx);
3435

3536
// Helper function that updates all open connections and their
3637
// respective ACL fields on all the available proactor threads

tests/dragonfly/acl_family_test.py

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -196,22 +196,20 @@ async def test_acl_categories_multi_exec_squash(df_local_factory):
196196
async def test_acl_deluser(df_server):
197197
client = aioredis.Redis(port=df_server.port)
198198

199-
try:
200-
res = await client.execute_command("ACL DELUSER adi")
201-
except redis.exceptions.ResponseError as e:
202-
assert e.args[0] == "User adi does not exist"
199+
with pytest.raises(redis.exceptions.ResponseError):
200+
await client.execute_command("ACL DELUSER random")
203201

204-
res = await client.execute_command("ACL SETUSER adi ON >pass +@transaction +@string")
202+
res = await client.execute_command("ACL SETUSER george ON >pass +@transaction +@string")
205203
assert res == b"OK"
206204

207-
res = await client.execute_command("AUTH adi pass")
205+
res = await client.execute_command("AUTH george pass")
208206
assert res == b"OK"
209207

210208
await client.execute_command("MULTI")
211209
await client.execute_command("SET key 44")
212210

213211
admin_client = aioredis.Redis(port=df_server.port)
214-
await admin_client.execute_command("ACL DELUSER adi")
212+
await admin_client.execute_command("ACL DELUSER george")
215213

216214
with pytest.raises(redis.exceptions.ConnectionError):
217215
await client.execute_command("EXEC")
@@ -220,7 +218,7 @@ async def test_acl_deluser(df_server):
220218

221219

222220
script = """
223-
for i = 1, 10000 do
221+
for i = 1, 100000 do
224222
redis.call('SET', 'key', i)
225223
redis.call('SET', 'key1', i)
226224
redis.call('SET', 'key2', i)
@@ -244,7 +242,7 @@ async def test_acl_del_user_while_running_lua_script(df_server):
244242

245243
for i in range(1, 4):
246244
res = await admin_client.get(f"key{i}")
247-
assert res == b"10000"
245+
assert res == b"100000"
248246

249247
await admin_client.close()
250248

@@ -258,12 +256,28 @@ async def test_acl_with_long_running_script(df_server):
258256

259257
await asyncio.gather(
260258
client.eval(script, 4, "key", "key1", "key2", "key3"),
261-
admin_client.execute_command("ACL SETUSER -@string -@scripting"),
259+
admin_client.execute_command("ACL SETUSER roman -@string -@scripting"),
262260
)
263261

264262
for i in range(1, 4):
265263
res = await admin_client.get(f"key{i}")
266-
assert res == b"10000"
264+
assert res == b"100000"
267265

268266
await client.close()
269267
await admin_client.close()
268+
269+
270+
@pytest.mark.asyncio
271+
async def test_acl_whoami(async_client):
272+
await async_client.execute_command("ACL SETUSER kostas >kk +@ALL ON")
273+
274+
with pytest.raises(redis.exceptions.ResponseError):
275+
await async_client.execute_command("ACL WHOAMI WHO")
276+
277+
result = await async_client.execute_command("ACL WHOAMI")
278+
assert result == "User is default"
279+
280+
result = await async_client.execute_command("AUTH kostas kk")
281+
282+
result = await async_client.execute_command("ACL WHOAMI")
283+
assert result == "User is kostas"

0 commit comments

Comments
 (0)