Age | Commit message (Collapse) | Author |
|
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).
|
|
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'.
|
|
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.
|
|
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.
|
|
I guess it was simply overlooked originally; in any case, currently
used compilers deal with the reference just as fine as with the pointer.
|
|
Now that StateEvent name is vacated, the naming for event core classes
can be completely unified: Event, RoomEvent, CallEvent, StateEvent.
|
|
Constrain types to derive from Event (or the chosen class), where
applicable.
|
|
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().
|
|
These are small enough to comfortably reside in a single translation
unit.
|
|
|
|
We don't expose logging internals to the outside world.
|
|
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.
|
|
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.
|
|
|
|
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.
|
|
|
|
- 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
|
|
What was partially factored out before into encryptSessionKeyEvent()
is now the complete algorithm converting any event json into encrypted
content.
|
|
# 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
|
|
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.
|
|
|
|
|
|
This is aligned with the non-moving version.
|
|
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.
|
|
|
|
|
|
The last commit broke it.
|
|
The upcoming event type infrastructure finally helps to detect those
omissions more or less reliably (for event types only though).
|
|
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
[skip ci]
|
|
Dropping yet another translation unit.
|
|
Apple Clang doesn't have those yet.
|
|
...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.
|
|
|
|
Now there's only 1 instead of 5 lookups of the same EncryptionEvent,
and the code is shorter.
|
|
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.
|
|
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.
|
|
|
|
|
|
...instead of tucking the template in filesourceinfo.cpp where it surely
will be forgotten.
|
|
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).
|
|
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.
|
|
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.
|
|
|
|
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.
|
|
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.
|