mirror of
https://github.com/anope/anope.git
synced 2026-07-05 02:53:12 +02:00
Use RPC error responses correctly.
This commit is contained in:
+1
-1
@@ -85,7 +85,7 @@ class AnopeXMLRPC
|
||||
{
|
||||
$ret = $this->run("checkAuthentication", [$account, $pass]);
|
||||
|
||||
if ($ret && $ret["result"] == "Success") {
|
||||
if ($ret && array_key_exists("account", $ret)) {
|
||||
return $ret["account"];
|
||||
}
|
||||
|
||||
|
||||
+19
-3
@@ -13,16 +13,32 @@
|
||||
class RPCRequest final
|
||||
{
|
||||
private:
|
||||
std::optional<std::pair<int64_t, Anope::string>> error;
|
||||
std::map<Anope::string, Anope::string> replies;
|
||||
|
||||
public:
|
||||
Anope::string name;
|
||||
Anope::string id;
|
||||
std::deque<Anope::string> data;
|
||||
HTTPReply &r;
|
||||
HTTPReply &reply;
|
||||
|
||||
RPCRequest(HTTPReply &r)
|
||||
: reply(r)
|
||||
{
|
||||
}
|
||||
|
||||
inline void Error(uint64_t errcode, const Anope::string &errstr)
|
||||
{
|
||||
this->error.emplace(errcode, errstr);
|
||||
}
|
||||
|
||||
inline void Reply(const Anope::string &dname, const Anope::string &ddata)
|
||||
{
|
||||
this->replies.emplace(dname, ddata);
|
||||
}
|
||||
|
||||
inline const auto &GetError() { return this->error; }
|
||||
|
||||
RPCRequest(HTTPReply &_r) : r(_r) { }
|
||||
inline void Reply(const Anope::string &dname, const Anope::string &ddata) { this->replies.emplace(dname, ddata); }
|
||||
inline const auto &GetReplies() { return this->replies; }
|
||||
};
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ class MyJSONRPCServiceInterface final
|
||||
private:
|
||||
std::deque<RPCEvent *> events;
|
||||
|
||||
void SendError(HTTPReply &reply, int64_t code, const char *message, const Anope::string &id)
|
||||
void SendError(HTTPReply &reply, int64_t code, const Anope::string &message, const Anope::string &id)
|
||||
{
|
||||
Log(LOG_DEBUG) << "JSON-RPC error " << code << ": " << message;
|
||||
|
||||
@@ -37,7 +37,7 @@ private:
|
||||
|
||||
auto *error = yyjson_mut_obj(doc);
|
||||
yyjson_mut_obj_add_sint(doc, error, "code", code);
|
||||
yyjson_mut_obj_add_str(doc, error, "message", message);
|
||||
yyjson_mut_obj_add_strn(doc, error, "message", message.c_str(), message.length());
|
||||
|
||||
yyjson_mut_obj_add_val(doc, root, "error", error);
|
||||
yyjson_mut_obj_add_str(doc, root, "jsonrpc", "2.0");
|
||||
@@ -122,6 +122,12 @@ public:
|
||||
if (!e->Run(this, client, request))
|
||||
return false;
|
||||
|
||||
else if (request.GetError())
|
||||
{
|
||||
SendError(reply, request.GetError()->first, request.GetError()->second, id);
|
||||
return true;
|
||||
}
|
||||
|
||||
else if (!request.GetReplies().empty())
|
||||
{
|
||||
this->Reply(request);
|
||||
@@ -160,7 +166,7 @@ public:
|
||||
auto *json = yyjson_mut_write(doc, YYJSON_WRITE_ALLOW_INVALID_UNICODE | YYJSON_WRITE_NEWLINE_AT_END, nullptr);
|
||||
if (json)
|
||||
{
|
||||
request.r.Write(json);
|
||||
request.reply.Write(json);
|
||||
free(json);
|
||||
}
|
||||
yyjson_mut_doc_free(doc);
|
||||
|
||||
+16
-14
@@ -21,20 +21,26 @@ class RPCIdentifyRequest final
|
||||
Reference<RPCServiceInterface> xinterface;
|
||||
|
||||
public:
|
||||
RPCIdentifyRequest(Module *m, RPCRequest &req, HTTPClient *c, RPCServiceInterface *iface, const Anope::string &acc, const Anope::string &pass) : IdentifyRequest(m, acc, pass), request(req), repl(request.r), client(c), xinterface(iface) { }
|
||||
RPCIdentifyRequest(Module *m, RPCRequest &req, HTTPClient *c, RPCServiceInterface *iface, const Anope::string &acc, const Anope::string &pass)
|
||||
: IdentifyRequest(m, acc, pass)
|
||||
, request(req)
|
||||
, repl(request.reply)
|
||||
, client(c)
|
||||
, xinterface(iface)
|
||||
{
|
||||
}
|
||||
|
||||
void OnSuccess() override
|
||||
{
|
||||
if (!xinterface || !client)
|
||||
return;
|
||||
|
||||
request.r = this->repl;
|
||||
request.reply = this->repl;
|
||||
|
||||
request.Reply("result", "Success");
|
||||
request.Reply("account", GetAccount());
|
||||
|
||||
xinterface->Reply(request);
|
||||
client->SendReply(&request.r);
|
||||
client->SendReply(&request.reply);
|
||||
}
|
||||
|
||||
void OnFail() override
|
||||
@@ -42,12 +48,12 @@ public:
|
||||
if (!xinterface || !client)
|
||||
return;
|
||||
|
||||
request.r = this->repl;
|
||||
request.reply = this->repl;
|
||||
|
||||
request.Reply("error", "Invalid password");
|
||||
request.Error(-32000, "Invalid password");
|
||||
|
||||
xinterface->Reply(request);
|
||||
client->SendReply(&request.r);
|
||||
client->SendReply(&request.reply);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -83,16 +89,14 @@ private:
|
||||
Anope::string command = request.data.size() > 2 ? request.data[2] : "";
|
||||
|
||||
if (service.empty() || user.empty() || command.empty())
|
||||
request.Reply("error", "Invalid parameters");
|
||||
request.Error(-32602, "Invalid parameters");
|
||||
else
|
||||
{
|
||||
BotInfo *bi = BotInfo::Find(service, true);
|
||||
if (!bi)
|
||||
request.Reply("error", "Invalid service");
|
||||
request.Error(-32000, "Invalid service");
|
||||
else
|
||||
{
|
||||
request.Reply("result", "Success");
|
||||
|
||||
NickAlias *na = NickAlias::Find(user);
|
||||
|
||||
Anope::string out;
|
||||
@@ -127,7 +131,7 @@ private:
|
||||
Anope::string password = request.data.size() > 1 ? request.data[1] : "";
|
||||
|
||||
if (username.empty() || password.empty())
|
||||
request.Reply("error", "Invalid parameters");
|
||||
request.Error(-32602, "Invalid parameters");
|
||||
else
|
||||
{
|
||||
auto *req = new RPCIdentifyRequest(me, request, client, iface, username, password);
|
||||
@@ -273,8 +277,6 @@ private:
|
||||
return;
|
||||
|
||||
u->SendMessage(bi, message);
|
||||
|
||||
request.Reply("result", "Success");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+51
-5
@@ -187,12 +187,58 @@ public:
|
||||
if (!request.id.empty())
|
||||
request.Reply("id", request.id);
|
||||
|
||||
Anope::string r = "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<methodResponse>\n<params>\n<param>\n<value>\n<struct>\n";
|
||||
for (const auto &[name, value] : request.GetReplies())
|
||||
r += "<member>\n<name>" + this->Sanitize(name) + "</name>\n<value>\n<string>" + this->Sanitize(value) + "</string>\n</value>\n</member>\n";
|
||||
r += "</struct>\n</value>\n</param>\n</params>\n</methodResponse>";
|
||||
Anope::string xml =
|
||||
"<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"
|
||||
"<methodResponse>\n";
|
||||
|
||||
request.r.Write(r);
|
||||
if (request.GetError())
|
||||
{
|
||||
xml +=
|
||||
"<fault>\n"
|
||||
" <value>\n"
|
||||
" <struct>\n"
|
||||
" <member>\n"
|
||||
" <name>faultCode</name>\n"
|
||||
" <value>\n"
|
||||
" <int>" + Anope::ToString(request.GetError()->first) + "</int>\n"
|
||||
" </value>\n"
|
||||
" </member>\n"
|
||||
" <member>\n"
|
||||
" <name>faultString</name>\n"
|
||||
" <value>\n"
|
||||
" <string>" + this->Sanitize(request.GetError()->second) + "</string>\n"
|
||||
" </value>\n"
|
||||
" </member>\n"
|
||||
" </struct>\n"
|
||||
" </value>\n"
|
||||
"</fault>\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
xml +=
|
||||
"<params>\n"
|
||||
" <param>\n"
|
||||
" <value>\n"
|
||||
" <struct>\n";
|
||||
for (const auto &[name, value] : request.GetReplies())
|
||||
{
|
||||
xml +=
|
||||
"<member>\n"
|
||||
" <name>" + this->Sanitize(name) + "</name>\n"
|
||||
" <value>\n"
|
||||
" <string>" + this->Sanitize(value) + "</string>\n"
|
||||
" </value>\n"
|
||||
"</member>\n";
|
||||
}
|
||||
xml +=
|
||||
" </struct>\n"
|
||||
" </value>\n"
|
||||
" </param>\n"
|
||||
"</params>\n";
|
||||
}
|
||||
xml += "</methodResponse>";
|
||||
|
||||
request.reply.Write(xml);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user