1
0
mirror of https://github.com/unrealircd/unrealircd.git synced 2026-07-08 16:33:14 +02:00

Make user.list() RPC API return a list of all users with details.

This is the 1st RPC API call that actually works :D
This commit is contained in:
Bram Matthys
2022-06-06 16:47:09 +02:00
parent 31fc2843a2
commit 4cd520d327
8 changed files with 104 additions and 24 deletions
+34 -9
View File
@@ -26,7 +26,8 @@ int rpc_handle_request_data(Client *client, WebRequest *web, const char *readbuf
int rpc_packet_in(Client *client, const char *readbuf, int *length);
void rpc_call_text(Client *client, const char *buf, int len);
void rpc_call(Client *client, json_t *request);
void rpc_error(Client *client, json_t *request, const char *msg);
void _rpc_response(Client *client, json_t *request, json_t *result);
void _rpc_error(Client *client, json_t *request, const char *msg);
/* Structs */
typedef struct RPCUser RPCUser;
@@ -43,7 +44,10 @@ ModDataInfo *rpc_md;
MOD_TEST()
{
MARK_AS_OFFICIAL_MODULE(modinfo);
HookAdd(modinfo->handle, HOOKTYPE_CONFIGTEST, 0, rpc_config_test);
EfunctionAddVoid(modinfo->handle, EFUNC_RPC_RESPONSE, _rpc_response);
EfunctionAddVoid(modinfo->handle, EFUNC_RPC_ERROR, _rpc_error);
return MOD_SUCCESS;
}
@@ -243,19 +247,40 @@ void rpc_call_text(Client *client, const char *readbuf, int len)
json_decref(request);
}
const char *json_object_get_string(json_t *j, const char *name)
{
json_t *v = json_object_get(j, name);
return v ? json_string_value(v) : NULL;
}
void rpc_error(Client *client, json_t *request, const char *msg)
void _rpc_error(Client *client, json_t *request, const char *msg)
{
// FIXME
//json_t *response = json_object;
sendto_one(client, NULL, "{ ERROR: %s }", msg);
}
void _rpc_response(Client *client, json_t *request, json_t *result)
{
const char *method = json_object_get_string(request, "method");
json_t *id = json_object_get(request, "id");
const char *json_serialized;
json_t *j = json_object();
json_object_set_new(j, "jsonrpc", json_string_unreal("2.0"));
json_object_set_new(j, "method", json_string_unreal(method));
if (id)
json_object_set_new(j, "id", id); /* 'id' is optional */
json_object_set_new(j, "response", result);
json_serialized = json_dumps(j, 0);
if (!json_serialized)
{
unreal_log(ULOG_WARNING, "rpc", "BUG_RPC_RESPONSE_SERIALIZE_FAILED", NULL,
"[BUG] rpc_response() failed to serialize response "
"for request from $client ($method)",
log_data_string("method", method));
return;
}
dbuf_put(&client->local->sendQ, json_serialized, strlen(json_serialized));
dbuf_put(&client->local->sendQ, "\n", 1);
}
/** Handle the RPC request: request is in JSON */
void rpc_call(Client *client, json_t *request)
{
@@ -292,5 +317,5 @@ void rpc_call(Client *client, json_t *request)
rpc_error(client, request, "Unsupported method");
return;
}
handler->call(client, request);
handler->call(client, request, params);
}
+25 -4
View File
@@ -15,7 +15,7 @@ ModuleHeader MOD_HEADER
};
/* Forward declarations */
int rpc_user_list(Client *client, json_t *request);
void rpc_user_list(Client *client, json_t *request, json_t *params);
MOD_INIT()
{
@@ -45,8 +45,29 @@ MOD_UNLOAD()
return MOD_SUCCESS;
}
int rpc_user_list(Client *client, json_t *request)
#define RPC_USER_LIST_EXPAND_NONE 0
#define RPC_USER_LIST_EXPAND_SELECT 1
#define RPC_USER_LIST_EXPAND_ALL 2
void rpc_user_list(Client *client, json_t *request, json_t *params)
{
config_status("YAY! user.list() called via RPC!");
return 0;
json_t *result, *list, *item;
Client *acptr;
result = json_object();
list = json_array();
json_object_set_new(result, "list", list);
list_for_each_entry(acptr, &client_list, client_node)
{
if (!IsUser(acptr))
continue;
item = json_object();
json_expand_client(item, NULL, acptr, 1);
json_array_append_new(list, item);
}
rpc_response(client, request, result);
json_decref(result);
}
+1
View File
@@ -46,6 +46,7 @@ ModDataInfo *webserver_md;
MOD_TEST()
{
MARK_AS_OFFICIAL_MODULE(modinfo);
EfunctionAddVoid(modinfo->handle, EFUNC_WEBSERVER_SEND_RESPONSE, _webserver_send_response);
EfunctionAddVoid(modinfo->handle, EFUNC_WEBSERVER_CLOSE_CLIENT, _webserver_close_client);
return MOD_SUCCESS;