/* * Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net> with * other valuable contributors. See CONTRIBUTORS.txt for the full list. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #ifndef TELODENDRIA_ROOM_H #define TELODENDRIA_ROOM_H /*** * @Nm Room * @Nd API for creating and manipulating Rooms. * @Dd July 6 2023 * @Xr Event * * The core component of the Matrix specification is the Room, * which holds a directed acyclic graph (DAG) of Events. * .Nm * provides a way of working with persistent rooms. */ #include <Cytoplasm/HashMap.h> #include <Cytoplasm/Db.h> #include <Schema/RoomCreateRequest.h> #include <Schema/PduV1.h> #include <Parser.h> #include <User.h> /** * The functions in this API operate on an opaque structure. */ typedef struct Room Room; #include <State.h> /** * Create a new room in the given database using the given * RoomCreateRequest. */ extern Room * RoomCreate(Db *, User *, RoomCreateRequest *, ServerPart); /** * Lock the existing room in the specified database, * identified by the specified ID, which is expected * to include the server name and room ID sigil. * .Pp * this function returns NULL if there was an error * locking the room, such as the room not existing. */ extern Room * RoomLock(Db *, char *); /** * Returns the database structure a room is tied to. */ extern Db * RoomGetDB(Room *); /** * Unlock a room handle, returning it to the database. * This function returns the result of calling * .Fn DbUnlock() on the internal room reference. */ extern int RoomUnlock(Room *); /** * Get the full ID of the specified room, including * the sigil and server name. This function returns * NULL if there was an error getting the room ID. */ extern char * RoomIdGet(Room *); /** * Get the numeric room version for the specified * room. The room version is determined by and stored * in the m.room.create event as a string, but since this * is expected to be a relatively frequent operation, * the integer representation is stored in the room * information so it can be accessed without having * to lock the room state and m.room.create event. */ extern int RoomVersionGet(Room *); /** * Resolve the state for the latest events in the * room. This function uses the appropriate state * resolution algorithm to compute the latest state, * which is used to select auth events on incoming * client events. */ extern State * RoomStateGet(Room *); /** * Resolves the room's state before a specific point, * (with the event hashmap taking priority), * like * .Fn RoomStateGet . */ extern State * RoomStateGetID(Room *, char *); /** * Get a list of the most recent events in the * room. When ingressing client events, these events * should be copied to the incoming event's prev_events. * Note that this function returns an array of actual * events themselves, not just IDs, even though that's * what's stored in the database. */ extern Array * RoomPrevEventsGet(Room *); /** * Set the list of most recent events in the room. * When ingressing client events, this list will be * manipulated. Unfortunately it can't be manipulated * in place with the current design, so this function * is responsible for copying the modified list into * place. */ extern int RoomPrevEventsSet(Room *, Array *); /** * Send a single event to the specified room. This * function can take either a client event or a * federation PDU. Depending on which is supplied, * the appropriate logic is applied. Client events * are converted into their federation format for * the room version, which includes setting the * prev_events and auth_events fields correctly. */ extern HashMap * RoomEventSend(Room *, HashMap *); /** * Sends an invite to a user in a room, and tries * to notify such user of it. */ extern void RoomSendInvite(User *, bool, char *, Room *); /** * Fetch a single event's PDU in a room into an * hashmap, given an event ID, from the database * if possible, or otherwise fetched from a remote * homeserver participating in the room. */ extern HashMap * RoomEventFetch(Room *, char *); /** * Strips all the fields not required in a * Matrix ClientEvent from a PDU object. */ extern HashMap * RoomEventClientify(HashMap *); /** * Verifies whenever an event(as a PDUv1) is * authorised by a room. */ extern bool RoomAuthoriseEventV1(Room *, PduV1, State *); /** * Gets the room's creator as a ServerPart. This value should * not be freed, as it lives alongside the room itself */ extern ServerPart RoomGetCreator(Room *); /** * Puts a PDUv1 into the event list, while updating the leaf * list. */ extern bool RoomAddEventV1(Room *, PduV1); /** * Creates a barebones JSON object to be sent to * .Fn RoomEventFetch . */ extern HashMap * RoomEventCreate(char *, char *, char *, HashMap *); /** * Computes an approximation of the PDU depth by looking at * the leaves stored in the room data. */ extern uint64_t RoomGetDepth(Room *); /** * Tries to find an alias from room alias to an ID stored * on the heap, or NULL if it does not exist. */ extern char * RoomResolveAlias(Db *, char *); /** * Tries to resolve a list of aliases from a room ID into * an array of strings stored on the heap. */ extern Array * RoomReverseAlias(Db *, char *); /** * Frees the array returned by * .Fn RoomReverseAlias . */ extern void RoomFreeReverse(Array *); /** * Checks whenever a room contains a specific user. */ extern bool RoomContainsUser(Room *, char *); /** * Checks whenever an user can join a specific room, * given it's permissions. */ extern bool RoomCanJoin(Room *, char *); /** * Makes a local user join a room, and returns true if * the room was joined. */ extern bool RoomJoin(Room *, User *); /** * Adds or overwrites a room alias. */ extern void RoomAddAlias(Db *, char *, char *, char *, char *); #endif /* TELODENDRIA_ROOM_H */