ircd:Ⓜ️:user::devices: Complete the m.device_list_update broadcast w/ keys; reinterface.

This commit is contained in:
Jason Volk 2023-04-27 11:58:37 -07:00
parent e7ad503f8c
commit ca80d66e85
3 changed files with 100 additions and 57 deletions

View File

@ -13,6 +13,8 @@
struct ircd::m::user::devices
{
struct send;
using closure = std::function<void (const event::idx &, const string_view &)>;
using closure_bool = std::function<bool (const event::idx &, const string_view &)>;
@ -36,9 +38,17 @@ struct ircd::m::user::devices
///TODO: XXX junk
static std::map<std::string, long> count_one_time_keys(const m::user &, const string_view &);
static bool update(const device_list_update &);
static bool send(json::iov &content);
devices(const m::user &user)
:user{user}
{}
};
/// Broadcast m.device_list_update.
///
struct ircd::m::user::devices::send
{
send(const m::user::devices &,
const m::id::device &,
const string_view = {});
};

View File

@ -8,26 +8,81 @@
// copyright notice and this permission notice is present in all copies. The
// full license for this software is available in the LICENSE file.
bool
ircd::m::user::devices::send(json::iov &content)
ircd::m::user::devices::send::send(const m::user::devices &devices,
const m::id::device &device_id,
const string_view room_id)
try
{
assert(content.has("user_id"));
assert(content.has("device_id"));
assert(device_id);
const auto &user_id
{
devices.user.user_id
};
const bool deleted
{
devices.has(device_id)
};
const m::user::keys user_keys
{
user_id
};
const bool has_keys
{
!deleted && user_keys.has_device(device_id)
};
const unique_mutable_buffer keys_buf
{
has_keys? 4_KiB: 0_KiB
};
json::stack keys{keys_buf};
if(has_keys)
{
json::stack::object top{keys};
user_keys.device(top, device_id);
}
// Triggers a devices request from the remote; also see
// modules/federation/user_devices.cc
const long &stream_id
{
1L
};
static const auto stream_id{1L};
json::iov event;
json::iov event, content;
const json::iov::push push[]
{
{ event, { "type", "m.device_list_update" } },
{ event, { "sender", content.at("user_id") } },
{ event, { "sender", user_id } },
{ content, { "deleted", deleted } },
{ content, { "device_id", device_id } },
{ content, { "stream_id", stream_id } },
{ content, { "user_id", user_id } },
};
const json::iov::push push_keys
{
content, has_keys,
{
"keys", [&keys]
{
return keys.completed();
}
}
};
// For diagnostic purposes; usually not defined.
const json::iov::push push_room_id
{
event, m::valid(m::id::ROOM, room_id),
{
"room_id", [&room_id]
{
return room_id;
}
}
};
m::vm::copts opts;
@ -39,8 +94,6 @@ try
{
event, content, opts
};
return true;
}
catch(const ctx::interrupted &)
{
@ -51,12 +104,10 @@ catch(const std::exception &e)
log::error
{
m::log, "Send m.device_list_update for '%s' belonging to %s :%s",
content.at("device_id"),
content.at("user_id"),
string_view{device_id},
string_view{devices.user.user_id},
e.what(),
};
return false;
}
bool
@ -185,21 +236,11 @@ const
m::redact(user_room, user_room.user, event_id, "deleted")
};
if(!my(user))
return true;
json::iov content;
const json::iov::push push[]
{
{ content, { "user_id", user.user_id } },
{ content, { "device_id", id } },
{ content, { "deleted", true } },
};
const bool broadcasted
{
user::devices::send(content)
};
if(my(user))
user::devices::send
{
*this, id
};
return true;
}

View File

@ -14449,7 +14449,7 @@ console_cmd__user__devices__update(opt &out, const string_view &line)
{
const params param{line, " ",
{
"user_id", "device_id", "deleted"
"user_id", "device_id", "room_id"
}};
const m::user::id &user_id
@ -14457,14 +14457,16 @@ console_cmd__user__devices__update(opt &out, const string_view &line)
param.at("user_id")
};
const string_view &device_id_
const string_view &device_id
{
param.at("device_id", "*"_sv)
};
const bool deleted
const m::room::id::buf room_id
{
param["deleted"] == "deleted"
m::valid(m::id::ROOM, param["room_id"])?
m::room_id(param["room_id"]):
m::room::id::buf{}
};
const m::user::devices devices
@ -14472,45 +14474,35 @@ console_cmd__user__devices__update(opt &out, const string_view &line)
user_id
};
const auto update{[&out, &user_id, &deleted]
const auto update{[&out, &devices, &user_id, &room_id]
(const auto &device_id)
{
json::iov content;
const json::iov::push push[]
m::user::devices::send
{
{ content, { "user_id", user_id } },
{ content, { "device_id", device_id } },
{ content, { "deleted", deleted } },
};
const bool broadcasted
{
m::user::devices::send(content)
devices, device_id, room_id
};
out
<< "broadcast:"
<< broadcasted
<< ' '
<< "broadcast: "
<< device_id
<< std::endl;
}};
const bool found
{
!devices.for_each([&update, &device_id_]
(const auto &, const string_view &device_id)
!devices.for_each([&update, &device_id]
(const auto &, const string_view &_device_id)
{
if(device_id_ != "*" && device_id != device_id_)
if(device_id != "*" && _device_id != device_id)
return true;
update(device_id);
return device_id != device_id_; // false to break
update(_device_id);
return _device_id != device_id; // false to break
})
};
if(!found && deleted)
update(device_id_);
if(device_id != "*" && !found)
update(device_id);
return true;
}