Parsee/src/Routes/UserAck.c
LDA 59cbd8b22d [MOD] Hash-based name conflict resolution
Still basic, but should prevent basic name issues.
2024-08-18 16:11:12 +02:00

159 lines
3.8 KiB
C

#include <Routes.h>
#include <Cytoplasm/Memory.h>
#include <Cytoplasm/Log.h>
#include <Cytoplasm/Str.h>
#include <Matrix.h>
#include <XMPP.h>
#include <AS.h>
RouteHead(RouteUserAck, arr, argp)
{
ParseeHttpArg *args = argp;
HashMap *request = NULL;
HashMap *response = NULL;
char *user = ArrayGet(arr, 0);
response = ASVerifyRequest(args);
if (response)
{
goto end;
}
if (HttpRequestMethodGet(args->ctx) != HTTP_GET)
{
HttpResponseStatus(args->ctx, HTTP_METHOD_NOT_ALLOWED);
response = MatrixCreateError(
"M_UNRECOGNIZED",
"Path /users only accepts GET as a valid method."
);
goto end;
}
Log(LOG_INFO, "user=%s", user);
ASRegisterUser(args->data->config, user);
response = HashMapCreate();
end:
JsonFree(request);
return response;
}
RouteHead(RouteRoomAck, arr, argp)
{
ParseeHttpArg *args = argp;
HashMap *request = NULL;
HashMap *response = NULL;
MUCInfo info = { .exists = false };
char *room = ArrayGet(arr, 0), *muc = NULL, *id = NULL;
char *creator = NULL, *muc_name = NULL, *chatid = NULL;
/* TODO: If an ACK request maps to a MUC that has a chat ID,
* DO NOT create a new one, and instead make a new mapping to
* the previous one. */
response = ASVerifyRequest(args);
if (response)
{
goto end;
}
if (HttpRequestMethodGet(args->ctx) != HTTP_GET)
{
HttpResponseStatus(args->ctx, HTTP_METHOD_NOT_ALLOWED);
response = MatrixCreateError(
"M_UNRECOGNIZED",
"Path /users only accepts GET as a valid method."
);
goto end;
}
muc = ParseeDecodeLocalMUC(args->data->config, room);
if (ParseeManageBan(args->data, muc, NULL))
{
HttpResponseStatus(args->ctx, HTTP_METHOD_NOT_ALLOWED);
response = MatrixCreateError(
"M_NOT_FOUND",
"XMPP MUC is banned from being accessed on this instance"
);
goto end;
}
if (!XMPPQueryMUC(args->data->jabber, muc, &info))
{
HttpResponseStatus(args->ctx, HTTP_METHOD_NOT_ALLOWED);
response = MatrixCreateError(
"M_UNRECOGNIZED",
"Room does not map to a real XMPP MUC"
);
goto end;
}
if ((chatid = ParseeGetFromMUCID(args->data, muc)))
{
/* TODO: Should we map the plumbed MUC? */
Free(chatid);
chatid = NULL;
HttpResponseStatus(args->ctx, HTTP_METHOD_NOT_ALLOWED);
response = MatrixCreateError(
"M_UNRECOGNIZED",
"Room is already plumbed"
);
goto end;
}
creator = ParseeMXID(args->data);
id = ASCreateRoom(
args->data->config,
creator, room
);
if (!id)
{
HttpResponseStatus(args->ctx, HTTP_INTERNAL_SERVER_ERROR);
response = MatrixCreateError(
"M_UNKNOWN",
"Could not create the room."
);
goto end;
}
muc_name = XMPPGetMUCName(info);
if (muc_name)
{
ASSetState(
args->data->config, id, "m.room.name", "", creator,
MatrixCreateNameState(muc_name)
);
Free(muc_name);
}
/* Creates a mapping */
chatid = ParseePushMUC(args->data, id, muc);
/* Invite the Parsee listener, so that we can have some
* events right up */
{
char *rev = StrConcat(2, muc, "/parsee");
Log(LOG_NOTICE, "Sending presence to %s", rev);
XMPPJoinMUC(args->data->jabber, "parsee", rev, false);
Free(rev);
}
response = HashMapCreate();
end:
if (chatid)
{
Free(chatid);
}
if (muc)
{
Free(muc);
}
if (id)
{
Free(id);
}
if (creator)
{
Free(creator);
}
XMPPFreeMUCInfo(info);
JsonFree(request);
return response;
}