aboutsummaryrefslogtreecommitdiff
path: root/lib/events
AgeCommit message (Collapse)Author
2022-09-26RandomBufferAlexey Rusakov
A convenient abstraction swallowing all the type casts and, more importantly, cleanup on destruction (previous code only cleaned up the buffer upon a successful call to Olm API but not upon an error).
2022-09-26Cleanup across E2EE codeAlexey Rusakov
Notably: - simplified unnecessarily verbose constructs; - formally aligned (no re-numeration was necessary) QOlmMessage::Type with corresponding OLM_ constants; - dropped QOlmSession::encryptMessageType() because it's very sensitive to the order of calling with QOlmSession::encrypt() (and encrypt() itself already calls it and returns the message type); - simplify the return type of pickle() calls that can only fail due to an internal error; - replace const QString& with QStringView or const QByteArray& where appropriate; - use '\0' where it was meant to be instead of '0'.
2022-09-26Replace QOlmError with OlmErrorCodeAlexey Rusakov
QOlmError represents a subset of OlmErrorCode, and the associated fromString() function uses undocumented strings produced inside Olm; meanwhile OlmErrorCode is documented in its own header file. Each QOlm* class now has lastErrorCode() next to lastError() (that, from now, returns a textual representation straight from Olm, not QOlmError enum). Also: including olm/error.h in e2ee/e2ee.h required some rearrangement of the code to make sure non-E2EE configuration still builds.
2022-09-11KeyVerificationEvent; KeyVerificationSession::handleEvent()Alexey Rusakov
Key verification events gain their own base type and KeyVerificationSession gets a single point of entry for all kinds of incoming events. This allows to drop a pile of `incoming*` signals in Connection and a stack of options inside switchOnType in processIfVerification(). KVS::handleEvent() also makes (some) allowed state transitions a bit clearer.
2022-09-04SingleKeyValue: use reference for template parameterAlexey Rusakov
I guess it was simply overlooked originally; in any case, currently used compilers deal with the reference just as fine as with the pointer.
2022-09-04StateEventBase -> StateEventAlexey Rusakov
Now that StateEvent name is vacated, the naming for event core classes can be completely unified: Event, RoomEvent, CallEvent, StateEvent.
2022-09-04concept EventClassAlexey Rusakov
Constrain types to derive from Event (or the chosen class), where applicable.
2022-09-04Disallow direct events construction from JSONAlexey Rusakov
Direct construction (using makeEvent() or explicitly constructing an event) from JSON may create an event that has a type conflicting with that stored in JSON. There's no such problem with loadEvent(), even though it's considerably slower. Driven by the fact that almost nowhere in the code direct construction is used on checked JSON (one test is the only valid case), this commit moves all JSON-loading constructors to the protected section, thereby disabling usage of makeEvent() in JSON-loading capacity, and switches such cases across the library to loadEvent().
2022-09-04CallEventBase -> CallEvent; pack up all call eventsAlexey Rusakov
These are small enough to comfortably reside in a single translation unit.
2022-09-04More cleanupAlexey Rusakov
2022-09-04Remove #include "logging.h" from event.hAlexey Rusakov
We don't expose logging internals to the outside world.
2022-09-04Streamline event typesAlexey Rusakov
This commit introduces a few things to further reduce the boilerplate across event type definitions: - Event type is no more separately stored in Event and therefore no more passed to base event constructors. Until the previous commit, it was used by is() to quickly match the event type; with the new event metatype class, the same is achieved even quicker by comparing metatype pointers. - EventTemplate is a generalisation of StateEvent for all event types providing common constructor signatures and content() for (most) leaf event types. StateEvent therefore has become a partial specialisation of EventTemplate for types derived from StateEventBase; as the known client code base does not use it directly, a compatibility alias is not provided. Also, DEFINE_SIMPLE_EVENT now expands into a class deriving from EventTemplate. - On top of StateEvent->EventTemplate specialisation, KeyedStateEventBase and KeylessStateEventBase types are introduced with appropriate constructor signatures (with or without state_key, respectively) to allow `using` of them from derived event types. To facilitate writing of constraints, concepts for keyed and keyless state event types are also introduced; RoomStateView, e.g., makes use of those to provide appropriate method signatures. - typeId(), unknownEventTypeId(), UnknownEventTypeId are no more provided - they weren't used throughout the known code base (Quaternion, NeoChat), and the concept of "unknown event types" is hereby eliminated entirely. - RoomKeyEvent no more accepts senderId as a parameter; it has never been a good practice as the sender is assigned by Connection anyway.
2022-09-04EventMetaType, QUO_EVENT, QUO_BASE_EVENTAlexey Rusakov
The new metatype framework replaces EventFactory/DEFINE_EVENT_TYPEID/REGISTER_EVENT_TYPE; it is faster, more functional and extensible. Of note: - EventMetaType mostly reproduces the logic of EventFactory but supports custom base event types not just for loading (that part EventFactory also supported) but also for matching - previously you had to have Event::is*Event() for base type matching. Now Quotient::is() can match against both base and leaf types. - Instead of DEFINE_EVENT_TYPEID and REGISTER_EVENT_TYPE there's now a single macro, QUO_EVENT, intended for use in the way similar to Q_OBJECT. Actually, the entire framework borrows heavily from QMetaObject and Q_OBJECT. Making event types full-fledged QObjects is still not considered because half of QObject functions would not be applicable (e.g. signals/slots) while another half (in particular, using Matrix type ids to select event types) would still have to be done on top of QObject. And QML can just access events as const QJsonObjects which is arguably more lightweight as well. - QUO_BASE_EVENT is a new macro replacing EventFactory object definitions. This was necessary for the same reason why Q_OBJECT is a macro: aside from a static object definition, this macro introduces a virtual function override to resolve the metatype at runtime. This very mechanism is used to make event type matching/casting as quick as possible - QUO_BASE_EVENT and QUO_EVENT use the C++20 __VA_OPT__ feature that is only available with the new MSVC preprocessor (see https://docs.microsoft.com/en-us/cpp/preprocessor/preprocessor-experimental-overview); the respective switch was added to CMakeLists.txt.
2022-09-04DEFINE_SIMPLE_EVENT: support custom JSON keysAlexey Rusakov
2022-09-04SingleKeyValue: allow seamless construction from the underlying typeAlexey Rusakov
SingleKeyValue is a tiny wrapper and supposed to be discreet. Having to explicitly (even if only with braces) construct its objects stands in the way of readability on the consuming side of the code and sometimes prevents direct initialisation of event objects without constructors getting some kind of ContentParamTs parameter pack where a single content_type argument would suffice otherwise.
2022-09-03KeyVerificationDoneEvent: fix copy-pasta in DEFINE_EVENT_TYPEIDAlexey Rusakov
2022-08-25More code reorganisationAlexey Rusakov
- Common switchOnType() piece for key verification events is factored out into processIfVerificationEvent() - Bare event JSON removed from KeyVerificationSession into constructors of respective events - Connection::sendToDevice() uses assembleEncryptedContent() introduced in the previous commit - commonSupportedMethods() moved out to .cpp; error/string converters made static
2022-08-25Connection::Private::assembleEncryptedContent()Alexey Rusakov
What was partially factored out before into encryptSessionKeyEvent() is now the complete algorithm converting any event json into encrypted content.
2022-08-24Merge branch 'dev' into device-verificationAlexey Rusakov
# Conflicts: # autotests/testfilecrypto.cpp # lib/connection.cpp # lib/connection.h # lib/database.cpp # lib/database.h # lib/e2ee/qolmoutboundsession.cpp # lib/e2ee/qolmoutboundsession.h # lib/eventitem.h # lib/events/encryptedevent.cpp # lib/events/encryptedevent.h # lib/events/encryptedfile.cpp # lib/events/encryptedfile.h # lib/events/keyverificationevent.cpp # lib/events/keyverificationevent.h # lib/events/roomkeyevent.h # lib/room.cpp # lib/room.h
2022-08-05eventloader.h: use basicJson() in a uniform wayAlexey Rusakov
There's no particular reason the order of parameters in StateEventBase::basicJson() should be as it was, and (the only) loadStateEvent() usage in room.cpp suggests the unified order is more convenient. Besides, this order is aligned with that in the StateEventBase constructor.
2022-08-01Fix FTBFSAlexey Rusakov
2022-08-01Pull out common JsonConverter code to JsonObjectUnpackerAlexey Rusakov
2022-07-30moving eventCast(): disallow passing nullptrAlexey Rusakov
This is aligned with the non-moving version.
2022-07-29Moving eventCast()Alexey Rusakov
In a situation where you have an EventPtr that you want to place somewhere as an `event_ptr_tt<SomeMoreSpecificEventType>` you have to carefully check that the stored event is actually of SomeMoreSpecificType and if it is, release() that event pointer, downcast, and re-wrap it into that new event_ptr_tt - or, as can be seen from the diff here, re-loadEvent() from JSON, which is simpler but inefficient. To help clients, and the library, eventCast() can now accept an rvalue smart pointer and do all the necessary things with it.
2022-07-26...and the definitive fixAlexey Rusakov
2022-07-26Another fix attemptAlexey Rusakov
2022-07-26Hopefully fix building with GCCAlexey Rusakov
The last commit broke it.
2022-07-26Add missing QUOTIENT_API piecesAlexey Rusakov
The upcoming event type infrastructure finally helps to detect those omissions more or less reliably (for event types only though).
2022-07-13eventcontent.h: Use C++17 nested namespaces notationAlexey Rusakov
2022-07-12converters.*: facilities to convert enumsAlexey Rusakov
This introduces enumTo/FromJsonString() and flagTo/FromJsonString(), four facility functions to simplify conversion between C++ enums and JSON, and refactors a couple of places where it's useful.
2022-07-12Make AliasesEventContent a simple structureAlexey Rusakov
JSON conversions are moved out of the class, obviating the need to define the plain data constructor and gaining default-constructibility along the way - previously the default constructor was preempted by user-defined ones.
2022-07-12Refactor things around EncryptionEvent[Content]Alexey Rusakov
EncryptionEvent was marked as Q_GADGET only for the sake of defining EncryptionType inside of it as Q_ENUM, with aliases also available under Quotient:: and EncryptionEventContent. This is a legacy from pre-Q_ENUM_NS times. However, event types are not really made to be proper Q_GADGETs: Q_GADGET implies access by value or reference but event types are uncopyable for the former and QML is ill-equipped for the latter. This commit moves EncryptionType definition to where other such enumerations reside - on the namespace level in quotient_common.h; and the other two places are now deprecated; and EncryptionEvent is no more Q_GADGET. With fromJson/toJson refactored in the previous commit there's no more need to specialise JsonConverter<>: specialising fromJson() is just enough. Moving EncryptionType to quotient_common.h exposed the clash of two Undefined enumerators (in RoomType and EncryptionType), warranting both enumerations to become scoped (which they ought to be, anyway). And while we're at it, the base type of enumerations is specified explicitly, as MSVC apparently uses a signed base type (int?) by default, unlike other compilers, and the upcoming enum converters will assume an unsigned base type. Finally, using fillFromJson() instead of fromJson() in the EncryptionEventContent constructor allowed to make default values explicit in the header file, rather than buried in the initialisation code.
2022-07-12fromJson()/toJson() refactoringAlexey Rusakov
fromJson() is generalised to accept any JSON-like type while passing QJsonObject to JsonConverter<>::load (instead of doLoad). This allows to (still) rely on JsonConverter<> as a customisation point while providing an opportunity to overload fromJson for custom types in a pointed way (specifically, by providing the overload for `fromJson(const QJsonObject&)`), instead of having to go with full-blown JsonConverter<> specialisation. This will be used in a further commit to simplify ReceiptEvent definition. Using if constexpr in combination with constraints (`requires()`) - the first such case in Quotient codebase - allowed to put the entire logic in a single JsonConverter<>::load() body instead of having a facility JsonExporter<> class for SFINAE. Aside from that, fromJson<QJsonValue, QJsonValue> is entirely dropped because it's not supposed to be used that way (it's no-op after all); reflecting that, Event::unsignedPart() and Event::contentPart() no more default to QJsonValue as the expected return type, you have to explicitly provide the type instead (and as one can see from the changes in the commit, it's actually better that way since it's better to validate the value inside JSON - e.g. check QString or QJsonObject for emptiness - than the QJsonValue envelope which may still wrap an empty value). toJson() is also generalised, replacing 3 functions with one that has a constexpr if to discern between two kinds of types.
2022-07-12Fix deprecation messagesAlexey Rusakov
[skip ci]
2022-07-12Pack up StickerEvent in the header fileAlexey Rusakov
Dropping yet another translation unit.
2022-07-07Avoid std::derived_from and std::bind_frontAlexey Rusakov
Apple Clang doesn't have those yet.
2022-07-03Shorten switchOnType, function_traits and connect*Alexey Rusakov
...thanks to C++20 awesomeness. A notable change is that wrap_in_function() (and respectively function_traits<>::function_type) and fn_return_t alias are gone. The former are no more needed because connectUntil/connectSingleShot no more use std::function. The latter has been relatively underused and with the optimisation of switchOnType hereby, could be completely replaced with std::invoke_result_t. Rewriting connect* functions using constexpr and auto parameters made the implementation 30% more compact and much easier to understand (though still with a couple of - now thoroughly commented - tricky places). Dropping std::function<> from it may also bring some (quite modest, likely) performance benefits.
2022-06-24Make EventContent::Base() move constructor noexceptAlexey Rusakov
2022-06-23Streamline Room::P::shouldRotateMegolmSession()Alexey Rusakov
Now there's only 1 instead of 5 lookups of the same EncryptionEvent, and the code is shorter.
2022-06-23Use QUO_CONTENT_GETTERAlexey Rusakov
In keyverificationevent.*, this massively shortens repetitive getter definitions; the remaining few non-trivial ones are moved to keyverificationevent.h, dropping the respective .cpp file and therefore the dedicated translation unit. In roomkeyevent.h, it's just shorter.
2022-06-22Streamline RoomPowerLevelsEvent backoffice codeAlexey Rusakov
Also: leave a link at the place in the spec with power level defaults to make it clear they are not invented out of thin air.
2022-06-22Address a few more Sonar warningsAlexey Rusakov
2022-06-21Fix a few clang-tidy/GCC warningsAlexey Rusakov
2022-06-21Move out Overloads to util.hAlexey Rusakov
...instead of tucking the template in filesourceinfo.cpp where it surely will be forgotten.
2022-06-18Move C++-only macros to util.hAlexey Rusakov
This pertains to QUO_IMPLICIT and DECL_DEPRECATED_ENUMERATOR - both can be used with no connection to Qt meta-type system (which is what quotient_common.h is for).
2022-06-18Drop make_array(); use std::to_array() where neededAlexey Rusakov
make_array() has been introduced to cover for shortcomings on macOS and Windows. These shortcomings are no more there, so we can just use the standardrlibrary.
2022-05-29Move some Meg/Olm session logic from Room::Private to Connection::PrivateAlexey Rusakov
Functions (Room::Private::)createOlmSession, payloadForUserDevice and sendRoomKeyToDevices don't have a lot to do with the given Room object but deal with quite a few things stored in Connection. This commit moves them to Connection::Private, exposing sendSessionKeyToDevices (the new name for sendRoomKeyToDevices) in Connection so that Room could call it from Room::P::sendMegolmSession(). While moving these over, a few additional things were adjusted: - more functions marked as const - a few functions could be moved now from Connection to Connection::Private - false slots in Connection (such as picklingMode) are moved out of the slots block - keys.yml in Matrix CS API definitions has been adjusted to match the real structure of `/claim` response (see quotient-im/matrix-spec repo); csapi/keys.h has been regenerated accordingly.
2022-05-29Cleanup and address Sonar warningsAlexey Rusakov
2022-05-29Move encryptFile/decryptFile out of EncryptedFileMetadataAlexey Rusakov
These are not operations on EncryptedFileMetadata but rather on a combination of EncryptedFileMetadata and ciphertext. If C++ had multimethods these could be bound to such a combination.
2022-05-29Refactor EncryptedFile and EC::FileInfo::fileAlexey Rusakov
Besides having a misleading name (and it goes back to the spec), EncryptedFile under `file` key preempts the `url` (or `thumbnail_url`) string value so only one of the two should exist. This is a case for using std::variant<> - despite its clumsy syntax, it can actually simplify and streamline code when all the necessary bits are in place (such as conversion to JSON and getting the common piece - the URL - out of it). This commit replaces `FileInfo::url` and `FileInfo::file` with a common field `source` of type `FileSourceInfo` that is an alias for a variant type covering both underlying types; and `url()` is reintroduced as a function instead, to allow simplified access to whichever URL is available inside the variant. Oh, and EncryptedFile is EncryptedFileMetadata now, to clarify that it does not represent the file payload itself but rather the data necessary to obtain that payload.