mirror of
https://github.com/dragonflydb/dragonfly.git
synced 2025-05-11 18:35:46 +02:00
feat(server): allow AUTH and SETNAME options in the HELLO command (#1156)
Signed-off-by: Rueian <rueiancsie@gmail.com>
This commit is contained in:
parent
494ca14e4e
commit
688f8f51a3
3 changed files with 59 additions and 8 deletions
|
@ -235,11 +235,17 @@ TEST_F(DflyEngineTest, Hello) {
|
|||
ArgType(RespExpr::STRING), "proto", IntArg(3), "id",
|
||||
ArgType(RespExpr::INT64), "mode", "standalone", "role", "master"));
|
||||
|
||||
// These are valid arguments to HELLO, however as they are not yet supported the implementation
|
||||
// is degraded to 'unknown command'.
|
||||
EXPECT_THAT(
|
||||
Run({"hello", "2", "AUTH", "uname", "pwd"}),
|
||||
ErrArg("ERR unknown command 'HELLO' with args beginning with: `2`, `AUTH`, `uname`, `pwd`"));
|
||||
EXPECT_THAT(Run({"hello", "2", "AUTH", "uname", "pwd"}),
|
||||
ErrArg("WRONGPASS invalid username-password pair or user is disabled."));
|
||||
|
||||
EXPECT_THAT(Run({"hello", "2", "AUTH", "default", "pwd"}),
|
||||
ErrArg("WRONGPASS invalid username-password pair or user is disabled."));
|
||||
|
||||
resp = Run({"hello", "3", "AUTH", "default", ""});
|
||||
ASSERT_THAT(resp, ArrLen(14));
|
||||
|
||||
resp = Run({"hello", "3", "AUTH", "default", "", "SETNAME", "myname"});
|
||||
ASSERT_THAT(resp, ArrLen(14));
|
||||
}
|
||||
|
||||
TEST_F(DflyEngineTest, Memcache) {
|
||||
|
|
|
@ -625,7 +625,7 @@ bool Service::VerifyCommand(const CommandId* cid, CmdArgList args,
|
|||
string_view cmd_name{cid->name()};
|
||||
|
||||
if (cntx->req_auth && !cntx->authenticated) {
|
||||
if (cmd_name != "AUTH" && cmd_name != "QUIT") {
|
||||
if (cmd_name != "AUTH" && cmd_name != "QUIT" && cmd_name != "HELLO") {
|
||||
(*cntx)->SendError("-NOAUTH Authentication required.");
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1757,16 +1757,61 @@ void ServerFamily::Info(CmdArgList args, ConnectionContext* cntx) {
|
|||
|
||||
void ServerFamily::Hello(CmdArgList args, ConnectionContext* cntx) {
|
||||
// If no arguments are provided default to RESP2.
|
||||
// AUTH and SETNAME options are not supported.
|
||||
bool is_resp3 = false;
|
||||
bool has_auth = false;
|
||||
bool has_setname = false;
|
||||
string_view username;
|
||||
string_view password;
|
||||
string_view clientname;
|
||||
|
||||
if (args.size() > 0) {
|
||||
string_view proto_version = ArgS(args, 0);
|
||||
is_resp3 = proto_version == "3";
|
||||
bool valid_proto_version = proto_version == "2" || is_resp3;
|
||||
if (!valid_proto_version || args.size() > 1) {
|
||||
if (!valid_proto_version) {
|
||||
(*cntx)->SendError(UnknownCmd("HELLO", args));
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32_t i = 1; i < args.size(); i++) {
|
||||
auto sub_cmd = ArgS(args, i);
|
||||
auto moreargs = args.size() - 1 - i;
|
||||
if (absl::EqualsIgnoreCase(sub_cmd, "AUTH") && moreargs >= 2) {
|
||||
has_auth = true;
|
||||
username = ArgS(args, i + 1);
|
||||
password = ArgS(args, i + 2);
|
||||
i += 2;
|
||||
} else if (absl::EqualsIgnoreCase(sub_cmd, "SETNAME") && moreargs > 0) {
|
||||
has_setname = true;
|
||||
clientname = ArgS(args, i + 1);
|
||||
i += 1;
|
||||
} else {
|
||||
(*cntx)->SendError(kSyntaxErr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (has_auth) {
|
||||
if (username == "default" && password == GetPassword()) {
|
||||
cntx->authenticated = true;
|
||||
} else {
|
||||
(*cntx)->SendError(facade::kAuthRejected);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (cntx->req_auth && !cntx->authenticated) {
|
||||
(*cntx)->SendError(
|
||||
"-NOAUTH HELLO must be called with the client already "
|
||||
"authenticated, otherwise the HELLO <proto> AUTH <user> <pass> "
|
||||
"option can be used to authenticate the client and "
|
||||
"select the RESP protocol version at the same time");
|
||||
return;
|
||||
}
|
||||
|
||||
if (has_setname) {
|
||||
cntx->owner()->SetName(string{clientname});
|
||||
}
|
||||
|
||||
int proto_version = 2;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue