Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2700101
device-ops-test.cpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
10 KB
Referenced Files
None
Subscribers
None
device-ops-test.cpp
View Options
/*
* This file is part of libkazv.
* SPDX-FileCopyrightText: 2023 tusooa <tusooa@kazv.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
#include
<libkazv-config.hpp>
#include
<catch2/catch_test_macros.hpp>
#include
<catch2/matchers/catch_matchers_predicate.hpp>
#include
<catch2/matchers/catch_matchers_contains.hpp>
#include
<boost/asio.hpp>
#include
<asio-promise-handler.hpp>
#include
<cursorutil.hpp>
#include
<sdk-model.hpp>
#include
<client/client.hpp>
#include
"client-test-util.hpp"
static
void
addDeviceToModel
(
ClientModel
&
model
,
std
::
string
userId
,
std
::
string
deviceId
,
std
::
string
displayName
,
DeviceTrustLevel
trustLevel
=
DeviceTrustLevel
::
Unseen
)
{
DeviceKeyInfo
info
{
deviceId
,
deviceId
+
"ed25519"
,
deviceId
+
"curve25519"
,
displayName
,
trustLevel
,
};
model
.
deviceLists
.
deviceLists
=
std
::
move
(
model
.
deviceLists
.
deviceLists
)
.
update
(
userId
,
[
=
](
auto
deviceMap
)
{
return
std
::
move
(
deviceMap
).
set
(
deviceId
,
info
);
});
}
static
void
addRoomToModel
(
ClientModel
&
model
,
std
::
string
roomId
)
{
RoomModel
room
;
room
.
encrypted
=
true
;
room
.
roomId
=
roomId
;
room
.
shouldRotateSessionKey
=
false
;
model
.
roomList
.
rooms
=
model
.
roomList
.
rooms
.
set
(
roomId
,
room
);
}
static
void
addRoomMemberToModel
(
ClientModel
&
model
,
std
::
string
roomId
,
std
::
string
userId
)
{
model
.
roomList
.
rooms
=
model
.
roomList
.
rooms
.
update
(
roomId
,
[
userId
,
roomId
](
auto
room
)
{
auto
memberEvent
=
Event
{
json
{
{
"type"
,
"m.room.member"
},
{
"state_key"
,
userId
},
{
"event_id"
,
"$roommember"
+
userId
},
{
"room_id"
,
roomId
},
{
"content"
,
{{
"displayname"
,
userId
+
"name"
},
{
"membership"
,
"join"
}}},
{
"sender"
,
userId
},
}};
room
.
stateEvents
=
room
.
stateEvents
.
set
(
KeyOfState
{
"m.room.member"
,
userId
},
memberEvent
);
return
room
;
});
}
static
auto
getModel
()
{
auto
model
=
createTestClientModel
();
addDeviceToModel
(
model
,
"@test1:test1.org"
,
"device1"
,
"test1-device1"
);
addDeviceToModel
(
model
,
"@test1:test1.org"
,
"device2"
,
"test1-device2"
);
return
model
;
}
static
auto
getModelWithEncryptedRooms
()
{
auto
model
=
createTestClientModel
();
addDeviceToModel
(
model
,
"@test1:test1.org"
,
"device1"
,
"test1-device1"
,
Unseen
);
addDeviceToModel
(
model
,
"@test1:test1.org"
,
"device2"
,
"test1-device2"
,
Verified
);
addDeviceToModel
(
model
,
"@test1:test1.org"
,
"device3"
,
"test1-device3"
,
Seen
);
addDeviceToModel
(
model
,
"@test2:test2.org"
,
"device1"
,
"test2-device1"
,
Unseen
);
addDeviceToModel
(
model
,
"@test2:test2.org"
,
"device2"
,
"test2-device2"
,
Blocked
);
addDeviceToModel
(
model
,
"@test2:test2.org"
,
"device3"
,
"test2-device3"
,
Seen
);
addRoomToModel
(
model
,
"!room1:tusooa.xyz"
);
addRoomMemberToModel
(
model
,
"!room1:tusooa.xyz"
,
"@test1:test1.org"
);
addRoomToModel
(
model
,
"!room2:tusooa.xyz"
);
addRoomMemberToModel
(
model
,
"!room2:tusooa.xyz"
,
"@test2:test2.org"
);
addRoomToModel
(
model
,
"!room3:tusooa.xyz"
);
addRoomMemberToModel
(
model
,
"!room3:tusooa.xyz"
,
"@test1:test1.org"
);
addRoomMemberToModel
(
model
,
"!room3:tusooa.xyz"
,
"@test2:test2.org"
);
return
model
;
}
using
namespace
Kazv
::
CursorOp
;
using
namespace
Catch
::
Matchers
;
TEST_CASE
(
"devicesOfUser()"
,
"[client][device-list-tracker]"
)
{
boost
::
asio
::
io_context
io
;
AsioPromiseHandler
ph
{
io
.
get_executor
()};
auto
model
=
getModel
();
auto
store
=
createTestClientStoreFrom
(
model
,
ph
);
auto
client
=
Client
(
store
.
reader
().
map
([](
auto
c
)
{
return
SdkModel
{
c
};
}),
store
,
std
::
nullopt
);
auto
devices
=
+
client
.
devicesOfUser
(
"@test1:test1.org"
);
REQUIRE
(
devices
.
size
()
==
2
);
REQUIRE_THAT
(
devices
,
Contains
(
Predicate
<
DeviceKeyInfo
>
([](
auto
d
)
{
return
d
.
deviceId
==
"device1"
;
})));
REQUIRE_THAT
(
devices
,
Contains
(
Predicate
<
DeviceKeyInfo
>
([](
auto
d
)
{
return
d
.
deviceId
==
"device2"
;
})));
}
TEST_CASE
(
"setTrustLevel()"
,
"[client][device-list-tracker]"
)
{
boost
::
asio
::
io_context
io
;
AsioPromiseHandler
ph
{
io
.
get_executor
()};
auto
model
=
getModel
();
auto
store
=
createTestClientStoreFrom
(
model
,
ph
);
auto
client
=
Client
(
store
.
reader
().
map
([](
auto
c
)
{
return
SdkModel
{
c
};
}),
store
,
std
::
nullopt
);
client
.
setDeviceTrustLevel
(
"@test1:test1.org"
,
"device1"
,
Seen
)
.
then
([
client
](
auto
s
)
{
REQUIRE
(
s
.
success
());
REQUIRE_THAT
((
+
client
.
devicesOfUser
(
"@test1:test1.org"
)),
Contains
(
Predicate
<
DeviceKeyInfo
>
([](
auto
d
)
{
return
d
.
deviceId
==
"device1"
&&
d
.
trustLevel
==
Seen
;
})));
});
io
.
run
();
}
TEST_CASE
(
"setTrustLevelNeededToSendKeys()"
,
"[client][device-list-tracker]"
)
{
boost
::
asio
::
io_context
io
;
AsioPromiseHandler
ph
{
io
.
get_executor
()};
auto
model
=
getModel
();
auto
store
=
createTestClientStoreFrom
(
model
,
ph
);
auto
client
=
Client
(
store
.
reader
().
map
([](
auto
c
)
{
return
SdkModel
{
c
};
}),
store
,
std
::
nullopt
);
REQUIRE
((
+
client
.
trustLevelNeededToSendKeys
())
==
Unseen
);
client
.
setTrustLevelNeededToSendKeys
(
Verified
)
.
then
([
client
](
auto
s
)
{
REQUIRE
(
s
.
success
());
REQUIRE
((
+
client
.
trustLevelNeededToSendKeys
())
==
Verified
);
});
io
.
run
();
}
TEST_CASE
(
"maybeRotateSessions()"
,
"[client][device-list-tracker]"
)
{
auto
oldModel
=
getModelWithEncryptedRooms
();
oldModel
.
trustLevelNeededToSendKeys
=
Seen
;
WHEN
(
"change a device display name"
)
{
auto
newModel
=
oldModel
;
addDeviceToModel
(
newModel
,
"@test1:test1.org"
,
"device1"
,
"some other things"
,
Unseen
);
newModel
.
maybeRotateSessions
(
oldModel
);
REQUIRE
(
!
newModel
.
roomList
.
rooms
[
"!room1:tusooa.xyz"
].
shouldRotateSessionKey
);
REQUIRE
(
!
newModel
.
roomList
.
rooms
[
"!room2:tusooa.xyz"
].
shouldRotateSessionKey
);
REQUIRE
(
!
newModel
.
roomList
.
rooms
[
"!room3:tusooa.xyz"
].
shouldRotateSessionKey
);
}
WHEN
(
"change from unseen to blocked"
)
{
auto
[
newModel
,
dontCareEffect
]
=
ClientModel
::
update
(
oldModel
,
SetDeviceTrustLevelAction
{
"@test1:test1.org"
,
"device1"
,
Blocked
});
REQUIRE
(
!
newModel
.
roomList
.
rooms
[
"!room1:tusooa.xyz"
].
shouldRotateSessionKey
);
REQUIRE
(
!
newModel
.
roomList
.
rooms
[
"!room2:tusooa.xyz"
].
shouldRotateSessionKey
);
REQUIRE
(
!
newModel
.
roomList
.
rooms
[
"!room3:tusooa.xyz"
].
shouldRotateSessionKey
);
}
WHEN
(
"change from verified to unseen"
)
{
auto
[
newModel
,
dontCareEffect
]
=
ClientModel
::
update
(
oldModel
,
SetDeviceTrustLevelAction
{
"@test1:test1.org"
,
"device2"
,
Unseen
});
REQUIRE
(
newModel
.
roomList
.
rooms
[
"!room1:tusooa.xyz"
].
shouldRotateSessionKey
);
REQUIRE
(
!
newModel
.
roomList
.
rooms
[
"!room2:tusooa.xyz"
].
shouldRotateSessionKey
);
REQUIRE
(
newModel
.
roomList
.
rooms
[
"!room3:tusooa.xyz"
].
shouldRotateSessionKey
);
}
WHEN
(
"change from verified to seen"
)
{
auto
[
newModel
,
dontCareEffect
]
=
ClientModel
::
update
(
oldModel
,
SetDeviceTrustLevelAction
{
"@test1:test1.org"
,
"device2"
,
Seen
});
REQUIRE
(
!
newModel
.
roomList
.
rooms
[
"!room1:tusooa.xyz"
].
shouldRotateSessionKey
);
REQUIRE
(
!
newModel
.
roomList
.
rooms
[
"!room2:tusooa.xyz"
].
shouldRotateSessionKey
);
REQUIRE
(
!
newModel
.
roomList
.
rooms
[
"!room3:tusooa.xyz"
].
shouldRotateSessionKey
);
}
WHEN
(
"change from verified to blocked"
)
{
auto
[
newModel
,
dontCareEffect
]
=
ClientModel
::
update
(
oldModel
,
SetDeviceTrustLevelAction
{
"@test1:test1.org"
,
"device2"
,
Blocked
});
REQUIRE
(
newModel
.
roomList
.
rooms
[
"!room1:tusooa.xyz"
].
shouldRotateSessionKey
);
REQUIRE
(
!
newModel
.
roomList
.
rooms
[
"!room2:tusooa.xyz"
].
shouldRotateSessionKey
);
REQUIRE
(
newModel
.
roomList
.
rooms
[
"!room3:tusooa.xyz"
].
shouldRotateSessionKey
);
}
WHEN
(
"change from unseen to verified"
)
{
auto
[
newModel
,
dontCareEffect
]
=
ClientModel
::
update
(
oldModel
,
SetDeviceTrustLevelAction
{
"@test2:test2.org"
,
"device1"
,
Verified
});
REQUIRE
(
!
newModel
.
roomList
.
rooms
[
"!room1:tusooa.xyz"
].
shouldRotateSessionKey
);
REQUIRE
(
newModel
.
roomList
.
rooms
[
"!room2:tusooa.xyz"
].
shouldRotateSessionKey
);
REQUIRE
(
newModel
.
roomList
.
rooms
[
"!room3:tusooa.xyz"
].
shouldRotateSessionKey
);
}
}
TEST_CASE
(
"maybeRotateSessions() when trustLevelNeededToSendKeys changed"
,
"[client][device-list-tracker]"
)
{
auto
oldModel
=
getModelWithEncryptedRooms
();
oldModel
.
trustLevelNeededToSendKeys
=
Unseen
;
WHEN
(
"threshold didn't change"
)
{
auto
newModel
=
oldModel
;
newModel
.
maybeRotateSessions
(
oldModel
);
REQUIRE
(
!
newModel
.
roomList
.
rooms
[
"!room1:tusooa.xyz"
].
shouldRotateSessionKey
);
REQUIRE
(
!
newModel
.
roomList
.
rooms
[
"!room2:tusooa.xyz"
].
shouldRotateSessionKey
);
REQUIRE
(
!
newModel
.
roomList
.
rooms
[
"!room3:tusooa.xyz"
].
shouldRotateSessionKey
);
}
WHEN
(
"threshold changed from unseen to blocked"
)
{
auto
newModel
=
oldModel
;
newModel
.
trustLevelNeededToSendKeys
=
Blocked
;
newModel
.
maybeRotateSessions
(
oldModel
);
REQUIRE
(
!
newModel
.
roomList
.
rooms
[
"!room1:tusooa.xyz"
].
shouldRotateSessionKey
);
REQUIRE
(
newModel
.
roomList
.
rooms
[
"!room2:tusooa.xyz"
].
shouldRotateSessionKey
);
REQUIRE
(
newModel
.
roomList
.
rooms
[
"!room3:tusooa.xyz"
].
shouldRotateSessionKey
);
}
WHEN
(
"threshold changed from unseen to seen"
)
{
auto
newModel
=
oldModel
;
newModel
.
trustLevelNeededToSendKeys
=
Seen
;
newModel
.
maybeRotateSessions
(
oldModel
);
REQUIRE
(
newModel
.
roomList
.
rooms
[
"!room1:tusooa.xyz"
].
shouldRotateSessionKey
);
REQUIRE
(
newModel
.
roomList
.
rooms
[
"!room2:tusooa.xyz"
].
shouldRotateSessionKey
);
REQUIRE
(
newModel
.
roomList
.
rooms
[
"!room3:tusooa.xyz"
].
shouldRotateSessionKey
);
}
WHEN
(
"threshold changed from seen to verified"
)
{
oldModel
.
trustLevelNeededToSendKeys
=
Seen
;
auto
newModel
=
oldModel
;
newModel
.
trustLevelNeededToSendKeys
=
Verified
;
newModel
.
maybeRotateSessions
(
oldModel
);
REQUIRE
(
newModel
.
roomList
.
rooms
[
"!room1:tusooa.xyz"
].
shouldRotateSessionKey
);
REQUIRE
(
newModel
.
roomList
.
rooms
[
"!room2:tusooa.xyz"
].
shouldRotateSessionKey
);
REQUIRE
(
newModel
.
roomList
.
rooms
[
"!room3:tusooa.xyz"
].
shouldRotateSessionKey
);
}
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Fri, Jul 18, 12:17 PM (1 d, 9 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
261697
Default Alt Text
device-ops-test.cpp (10 KB)
Attached To
Mode
rL libkazv
Attached
Detach File
Event Timeline
Log In to Comment