Age | Commit message (Collapse) | Author |
|
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.
|
|
|
|
Previously moc choked on [[attributes]]; deprecated signals, slots etc.
were documented as \deprecated instead. By Qt 5.15, that was fixed.
|
|
TagEvent is only created to immediately extract content JSON from it;
at the same rate content JSON can be generated directly from content.
|
|
Now that StateEvent name is vacated, the naming for event core classes
can be completely unified: Event, RoomEvent, CallEvent, StateEvent.
|
|
These are small enough to comfortably reside in a single translation
unit.
|
|
This gives a more conventional API compared to queryOr() that can be
used for event objects that have content() defined - with the downside
being that content() unpacks the entire object instead of retrieving
one particular piece (but for state events and single key-value content
it's not a problem, and those make for the vast majority of events).
|
|
|
|
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.
|
|
|
|
|
|
|
|
# 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.
|
|
...instead of just the number of them.
|
|
Event type ids don't need a C++ type to be used, and clients might
define those types on their side (NeoChat does that, e.g.).
|
|
Profiling revealed 3 inefficiencies in read receipts code - and given
there are a lot of them coming, these inefficiences quickly add up.
Fixing them allows to slash read receipt processing time by 60%, and
the total time of updating a room by more than a half.
1. Room::lastReadEventChanged() is emitted per receipt. This can be
taxing on initial syncs or in bigger rooms; this commit converts it
to an aggregate signal only emitted once per sync room batch and
carrying the list of all user ids (more on that below) with updated
read receipts.
For that, Room::P::setLastReadEvent() is split into
Room::P::setLocalLastReadEvent() that is called whenever the local
read receipt has to be updated, and setLastReadEvent() proper that is
very fast and only updates the internal data structures, nothing else.
setLocalLastEvent() calls it, as does processEphemeralEvents(); both
take responsibility to emit lastReadEventChanged() depending on the
outcome of setLastReadEvent() invocation(s).
2. Massively aggravating the above point, user id from each read receipt
is turned to a User object - and since most of the users are unknown
at early moments, this causes thousands of allocations. Therefore
the new aggregated lastReadEventChanged() only carries user ids, and
clients will have to resolve them to User objects if they need.
3. Despite fairly tight conditions (note we're talking about thousands
of receipts), Quotient still creates an intermediate C++ structure
(EventsWithReceipts), only for the sake of passing it to
processEphemeralEvent() that immediately disassembles it back again,
converting to a series of calls to set(Local)LastReadEvent(). To fix
this, processEphemeralEvent() now takes the event content JSON
directly and iterates over it instead.
Aside from that, a few extraneous conditions and logging has been
removed and the whole function rewritten with switchOnType() to reduce
cognitive complexity.
|
|
The result of factoring out duplicate code.
|
|
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.
|
|
|
|
Now there's only 1 instead of 5 lookups of the same EncryptionEvent,
and the code is shorter.
|
|
|
|
|
|
Also: build with Qt 6 first, so that it fails sooner.
|
|
|
|
deferring until sending event
|
|
|
|
There was a fairly nasty change where `from` parameter in /messages
became optional and that led to two QString parameters (`from` and `dir)
switching positions. Because they have the same type, the problem only
shows at runtime. This commit fixes Room::getPreviousContent() to pass
the parameters at right positions; client code won't feel anything
(unless it uses GetRoomEventsJob directly).
|
|
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.
|
|
Notably, replace a multi-level hash map with QMultiHash and factor out
Room::P::createOlmSession().
|
|
|
|
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.
|
|
|
|
|
|
|
|
Co-authored-by: Alexey Rusakov <Kitsune-Ral@users.sf.net>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
As mentioned in the commit introducing `Expected`, `QOlmExpected` is
simply an alias for `Expected<T, QOlmError>`. This simplifies quite
a few function signatures in `QOlm*` classes and collapses unwieldy
`std::holds_alternative<>`/`std::get<>` constructs into a neat
contextual bool cast and an invocation of `operator*` or
`value()`/`error()` accessors that don't need to specify the type.
While refactoring the code, I found a couple of cases of mismatching
`uint32_t` and `qint32_t` in return values; a couple of cases where
`decrypt()` returns `QString` which is in fact `QByteArray` (e.g., in
`QOlmSession::decrypt()`); there's a repetitive algorithm in
`Connection::Private::sessionDecryptPrekey()` and
`sessionDecryptGeneral()`
|