0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-12-27 07:54:05 +01:00

ircd:Ⓜ️:user::rooms: Use _event_state to eliminate the ircd.member type.

This commit is contained in:
Jason Volk 2020-03-01 17:13:15 -08:00
parent 48a8af4252
commit f471093d3e
5 changed files with 29 additions and 144 deletions

View file

@ -19,7 +19,7 @@ struct ircd::m::user::rooms
using closure = std::function<void (const m::room &, const string_view &)>; using closure = std::function<void (const m::room &, const string_view &)>;
using closure_bool = std::function<bool (const m::room &, const string_view &)>; using closure_bool = std::function<bool (const m::room &, const string_view &)>;
m::user::room user_room; m::user user;
public: public:
// All rooms with specific membership // All rooms with specific membership
@ -34,6 +34,6 @@ struct ircd::m::user::rooms
size_t count() const; size_t count() const;
rooms(const m::user &user) rooms(const m::user &user)
:user_room{user} :user{user}
{} {}
}; };

View file

@ -79,28 +79,38 @@ ircd::m::user::rooms::for_each(const string_view &membership,
const closure_bool &closure) const closure_bool &closure)
const const
{ {
const m::room::state state m::events::state::tuple query;
{ std::get<0>(query) = user;
user_room std::get<1>(query) = "m.room.member";
};
return state.for_each("ircd.member", [&membership, &closure] m::room::id::buf room_id_;
(const string_view &, const string_view &state_key, const m::event::idx &event_idx) return m::events::state::for_each(query, [&]
(const auto &tuple)
{ {
bool ret{true}; bool ret{true};
m::get(std::nothrow, event_idx, "content", [&state_key, &membership, &closure, &ret] const auto &[state_key, type, room_id, depth, event_idx]
(const json::object &content)
{ {
const json::string &membership_ tuple
{
content.get("membership")
}; };
if(!membership || membership_ == membership) assert(type == "m.room.member");
assert(state_key == user);
if(room_id != room_id_)
room_id_ = room_id;
else
return ret;
const auto &_room_id(room_id);
m::get(std::nothrow, event_idx, "content", [&]
(const json::object &content)
{ {
const m::room::id &room_id{state_key}; const json::string &_membership
ret = closure(room_id, membership_); {
} content["membership"]
};
if(!membership || _membership == membership)
ret = closure(_room_id, _membership);
}); });
return ret; return ret;

View file

@ -27,34 +27,9 @@ post__forget(client &client,
request.user_id request.user_id
}; };
const auto event_idx //
{ //TODO: XXX
user_room.get(std::nothrow, "ircd.member", room_id) //
};
if(!event_idx)
throw m::NOT_FOUND
{
"No user membership found for room %s.",
string_view{room_id}
};
if(m::membership(event_idx, m::membership_positive))
throw m::error
{
http::UNPROCESSABLE_ENTITY, "M_MEMBERSHIP_POSITIVE",
"You must leave or be banned from the room to forget it."
};
const auto event_id
{
m::event_id(event_idx)
};
const auto redact_id
{
redact(user_room, request.user_id, event_id, "forget")
};
return m::resource::response return m::resource::response
{ {

View file

@ -22,41 +22,6 @@ post__leave(client &client,
room_id room_id
}; };
if(!room.has("m.room.member", request.user_id))
{
const m::user::room user_room
{
request.user_id
};
// In case the user's user room falls out of sync with the real room
// state; we directly set the user's user room state.
if(!user_room.has("ircd.member", room_id))
throw m::error
{
http::NOT_MODIFIED, "M_TARGET_NOT_IN_ROOM",
"The user %s has no membership state in %s",
string_view{request.user_id},
string_view{room_id},
};
const auto event_id
{
send(user_room, request.user_id, "ircd.member", room_id, json::members
{
{ "membership", "leave" }
})
};
return m::resource::response
{
client, http::OK, json::members
{
{ "event_id", event_id }
}
};
}
const auto event_id const auto event_id
{ {
m::leave(room, request.user_id) m::leave(room, request.user_id)

View file

@ -35,71 +35,6 @@ IRCD_MODULE
"Matrix m.room.member" "Matrix m.room.member"
}; };
decltype(ircd::m::affect_user_room_hookfn)
ircd::m::affect_user_room_hookfn
{
affect_user_room,
{
{ "_site", "vm.effect" },
{ "type", "m.room.member" },
}
};
void
ircd::m::affect_user_room(const m::event &event,
m::vm::eval &eval)
try
{
const auto &room_id
{
at<"room_id"_>(event)
};
const auto &sender
{
at<"sender"_>(event)
};
const m::user::id &subject
{
at<"state_key"_>(event)
};
//TODO: ABA / TXN
if(!exists(subject))
create(subject);
m::user::room user_room
{
subject
};
//TODO: ABA / TXN
assert(exists(user_room));
const auto &prev_idx
{
user_room.get(std::nothrow, "ircd.member", room_id)
};
int64_t prev_depth;
if(m::get(prev_idx, "depth", prev_depth))
if(at<"depth"_>(event) < prev_depth)
return;
send(user_room, sender, "ircd.member", room_id, at<"content"_>(event));
}
catch(const std::exception &e)
{
log::error
{
log, "Failed to update user %s room for membership change in %s by %s :%s",
json::get<"state_key"_>(event),
json::get<"room_id"_>(event),
json::get<"sender"_>(event),
e.what()
};
}
decltype(ircd::m::auth_room_member_hookfn) decltype(ircd::m::auth_room_member_hookfn)
ircd::m::auth_room_member_hookfn ircd::m::auth_room_member_hookfn
{ {