summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSadie Powell <sadie@witchery.services>2025-02-24 03:39:50 +0000
committerSadie Powell <sadie@witchery.services>2025-02-24 03:59:52 +0000
commit801a748e256cb7c4952969103f2f2eaf5ee36552 (patch)
tree2dae96409362ee42b2591128a1ba42896226ecd2
parenta111b40560bf305653b07d8f7289484793a32588 (diff)
Add the system.listMethods RPC method.
Still to implement: - system.getCapabilities - system.methodHelp - system.methodSignature
-rw-r--r--data/modules.example.conf9
-rw-r--r--include/modules/rpc.h5
-rw-r--r--modules/extra/xmlrpc.cpp7
-rw-r--r--modules/rpc/jsonrpc.cpp7
-rw-r--r--modules/rpc/rpc_system.cpp64
5 files changed, 90 insertions, 2 deletions
diff --git a/data/modules.example.conf b/data/modules.example.conf
index e3fbb4294..ebf2f3527 100644
--- a/data/modules.example.conf
+++ b/data/modules.example.conf
@@ -824,3 +824,12 @@ module { name = "sasl" }
* Requires xmlrpc.
*/
#module { name = "rpc_main" }
+
+/*
+ * rpc_system
+ *
+ * Adds support for the system.listMethods RPC method.
+ *
+ * Requires either the jsonrpc or xmlrpc module.
+ */
+#module { name = "rpc_system" }
diff --git a/include/modules/rpc.h b/include/modules/rpc.h
index 1f136b1e2..640eebda1 100644
--- a/include/modules/rpc.h
+++ b/include/modules/rpc.h
@@ -21,6 +21,9 @@ namespace RPC
class ServiceInterface;
class Value;
+ /** Represents a list of registered events. */
+ using Events = Anope::map<Event *>;
+
/** Represents possible types of RPC value. */
using ValueUnion = std::variant<Array, Map, Anope::string, std::nullptr_t, bool, double, int64_t, uint64_t>;
@@ -194,6 +197,8 @@ public:
{
}
+ virtual const Events &GetEvents() = 0;
+
virtual bool Register(Event *event) = 0;
virtual bool Unregister(Event *event) = 0;
diff --git a/modules/extra/xmlrpc.cpp b/modules/extra/xmlrpc.cpp
index 681b230dc..94beb2088 100644
--- a/modules/extra/xmlrpc.cpp
+++ b/modules/extra/xmlrpc.cpp
@@ -23,7 +23,7 @@ class MyXMLRPCServiceInterface final
, public HTTPPage
{
private:
- Anope::map<RPC::Event *> events;
+ RPC::Events events;
static void SendError(HTTPReply &reply, xmlrpc_env &env)
{
@@ -69,6 +69,11 @@ public:
{
}
+ const RPC::Events &GetEvents() override
+ {
+ return events;
+ }
+
bool Register(RPC::Event *event) override
{
return this->events.emplace(event->GetEvent(), event).second;
diff --git a/modules/rpc/jsonrpc.cpp b/modules/rpc/jsonrpc.cpp
index 22c00b118..fc4c40e83 100644
--- a/modules/rpc/jsonrpc.cpp
+++ b/modules/rpc/jsonrpc.cpp
@@ -26,7 +26,7 @@ class MyJSONRPCServiceInterface final
, public HTTPPage
{
private:
- Anope::map<RPC::Event *> events;
+ RPC::Events events;
static void SendError(HTTPReply &reply, int64_t code, const Anope::string &message, const Anope::string &id)
{
@@ -86,6 +86,11 @@ public:
{
}
+ const RPC::Events &GetEvents() override
+ {
+ return events;
+ }
+
bool Register(RPC::Event *event) override
{
return this->events.emplace(event->GetEvent(), event).second;
diff --git a/modules/rpc/rpc_system.cpp b/modules/rpc/rpc_system.cpp
new file mode 100644
index 000000000..d1f49a1aa
--- /dev/null
+++ b/modules/rpc/rpc_system.cpp
@@ -0,0 +1,64 @@
+/*
+ *
+ * (C) 2010-2025 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ */
+
+#include "module.h"
+#include "modules/rpc.h"
+
+// TODO:
+//
+// * system.getCapabilities
+// * system.methodHelp
+// * system.methodSignature
+
+
+class SystemListMethodsRPCEvent final
+ : public RPC::Event
+{
+public:
+ SystemListMethodsRPCEvent()
+ : RPC::Event("system.listMethods")
+ {
+ }
+
+ bool Run(RPC::ServiceInterface *iface, HTTPClient *client, RPC::Request &request) override
+ {
+ auto &root = request.Root<RPC::Array>();
+ for (const auto &[event, _] : iface->GetEvents())
+ root.Reply(event);
+ return true;
+ }
+};
+
+class ModuleRPCSystem final
+ : public Module
+{
+private:
+ ServiceReference<RPC::ServiceInterface> rpc;
+ SystemListMethodsRPCEvent systemlistmethodsrpcevent;
+
+public:
+ ModuleRPCSystem(const Anope::string &modname, const Anope::string &creator)
+ : Module(modname, creator, EXTRA | VENDOR)
+ , rpc("RPCServiceInterface", "rpc")
+ {
+ if (!rpc)
+ throw ModuleException("Unable to find RPC interface, is jsonrpc/xmlrpc loaded?");
+
+ rpc->Register(&systemlistmethodsrpcevent);
+ }
+
+ ~ModuleRPCSystem() override
+ {
+ if (!rpc)
+ return;
+
+ rpc->Unregister(&systemlistmethodsrpcevent);
+ }
+};
+
+MODULE_INIT(ModuleRPCSystem)