0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-11-16 15:00:51 +01:00
construct/modules/m_room_aliases.cc

169 lines
3.5 KiB
C++

// Matrix Construct
//
// Copyright (C) Matrix Construct Developers, Authors & Contributors
// Copyright (C) 2016-2018 Jason Volk <jason@zemos.net>
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice is present in all copies. The
// full license for this software is available in the LICENSE file.
namespace ircd::m
{
extern const room::id::buf alias_room_id;
extern const room alias_room;
static void auth_room_aliases(const event &, room::auth::hookdata &);
extern hookfn<room::auth::hookdata &> auth_room_aliases_hookfn;
static void changed_room_aliases(const event &, vm::eval &);
extern hookfn<vm::eval &> changed_room_aliases_hookfn;
extern hookfn<m::vm::eval &> create_alias_room_hookfn;
}
ircd::mapi::header
IRCD_MODULE
{
"Matrix m.room.aliases"
};
//
// create the alias room as an effect of !ircd created on bootstrap
//
decltype(ircd::m::create_alias_room_hookfn)
ircd::m::create_alias_room_hookfn
{
{
{ "_site", "vm.effect" },
{ "room_id", "!ircd" },
{ "type", "m.room.create" },
},
[](const m::event &event, m::vm::eval &)
{
auto &my
{
m::my(at<"origin"_>(event))
};
const m::room::id::buf alias_room_id
{
"alias", origin(my)
};
create(alias_room_id, my.self);
}
};
//
// an effect of room aliases changed
//
decltype(ircd::m::changed_room_aliases_hookfn)
ircd::m::changed_room_aliases_hookfn
{
changed_room_aliases,
{
{ "_site", "vm.effect" },
{ "type", "m.room.aliases" },
}
};
void
ircd::m::changed_room_aliases(const m::event &event,
m::vm::eval &)
try
{
const m::room::id &room_id
{
at<"room_id"_>(event)
};
const json::array &aliases
{
at<"content"_>(event).get("aliases")
};
for(const json::string &alias : aliases) try
{
m::room::aliases::cache::set(alias, room_id);
log::info
{
m::log, "Updated aliases of %s by %s in %s with %s",
string_view{room_id},
json::get<"sender"_>(event),
string_view{event.event_id},
string_view{alias},
};
}
catch(const std::exception &e)
{
log::error
{
m::log, "Updating aliases of %s by %s in %s with %s :%s",
string_view{room_id},
json::get<"sender"_>(event),
string_view{event.event_id},
string_view{alias},
e.what(),
};
}
if(m::join_rule(room_id, "public"))
rooms::summary::set(room_id);
}
catch(const std::exception &e)
{
log::error
{
m::log, "Updating aliases of %s by %s in %s :%s",
json::get<"room_id"_>(event),
json::get<"sender"_>(event),
string_view{event.event_id},
e.what(),
};
}
//
// auth handler
//
decltype(ircd::m::auth_room_aliases_hookfn)
ircd::m::auth_room_aliases_hookfn
{
auth_room_aliases,
{
{ "_site", "room.auth" },
{ "type", "m.room.aliases" },
}
};
void
ircd::m::auth_room_aliases(const event &event,
room::auth::hookdata &data)
{
using FAIL = m::room::auth::FAIL;
using conforms = m::event::conforms;
// 4. If type is m.room.aliases:
assert(json::get<"type"_>(event) == "m.room.aliases");
// a. If event has no state_key, reject.
if(empty(json::get<"state_key"_>(event)))
throw FAIL
{
"m.room.aliases event is missing a state_key."
};
// b. If sender's domain doesn't matches state_key, reject.
if(json::get<"state_key"_>(event) != m::user::id(json::get<"sender"_>(event)).host())
throw FAIL
{
"m.room.aliases event state_key is not the sender's domain."
};
// c. Otherwise, allow
data.allow = true;
}