2018-10-24 23:01:21 +02:00
|
|
|
// 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.
|
|
|
|
|
|
|
|
ircd::mapi::header
|
|
|
|
IRCD_MODULE
|
|
|
|
{
|
|
|
|
"Matrix rooms interface; modular components"
|
|
|
|
};
|
|
|
|
|
2019-08-13 07:59:27 +02:00
|
|
|
decltype(ircd::m::rooms::opts_default)
|
|
|
|
ircd::m::rooms::opts_default;
|
2018-10-24 23:01:21 +02:00
|
|
|
|
2018-10-24 23:08:14 +02:00
|
|
|
bool
|
2019-04-08 05:15:00 +02:00
|
|
|
IRCD_MODULE_EXPORT
|
2019-08-13 07:59:27 +02:00
|
|
|
ircd::m::rooms::has(const opts &opts)
|
2018-10-24 23:08:14 +02:00
|
|
|
{
|
2019-08-13 07:59:27 +02:00
|
|
|
return !for_each(opts, []
|
|
|
|
(const m::room::id &)
|
2018-10-24 23:08:14 +02:00
|
|
|
{
|
2019-08-13 07:59:27 +02:00
|
|
|
// false to break; for_each() returns false
|
|
|
|
return false;
|
|
|
|
});
|
2019-03-01 23:51:30 +01:00
|
|
|
}
|
|
|
|
|
2018-10-24 23:22:10 +02:00
|
|
|
size_t
|
2019-05-06 20:46:05 +02:00
|
|
|
IRCD_MODULE_EXPORT
|
2019-08-13 07:59:27 +02:00
|
|
|
ircd::m::rooms::count(const opts &opts)
|
2018-10-24 23:22:10 +02:00
|
|
|
{
|
2018-10-25 01:50:54 +02:00
|
|
|
size_t ret{0};
|
2019-08-13 07:59:27 +02:00
|
|
|
for_each(opts, [&ret]
|
|
|
|
(const m::room::id &)
|
2018-10-24 23:22:10 +02:00
|
|
|
{
|
2018-10-25 01:50:54 +02:00
|
|
|
++ret;
|
|
|
|
return true;
|
2019-08-13 07:59:27 +02:00
|
|
|
});
|
2018-10-24 23:22:10 +02:00
|
|
|
|
2018-10-25 01:50:54 +02:00
|
|
|
return ret;
|
2018-10-24 23:22:10 +02:00
|
|
|
}
|
|
|
|
|
2018-10-24 23:15:36 +02:00
|
|
|
bool
|
2019-05-06 20:46:05 +02:00
|
|
|
IRCD_MODULE_EXPORT
|
2019-08-13 07:59:27 +02:00
|
|
|
ircd::m::rooms::for_each(const room::id::closure_bool &closure)
|
2018-10-24 23:01:21 +02:00
|
|
|
{
|
2019-08-13 07:59:27 +02:00
|
|
|
return for_each(opts_default, closure);
|
2018-10-25 01:50:54 +02:00
|
|
|
}
|
|
|
|
|
2019-08-13 07:59:27 +02:00
|
|
|
bool
|
|
|
|
IRCD_MODULE_EXPORT
|
|
|
|
ircd::m::rooms::for_each(const opts &opts,
|
|
|
|
const room::id::closure_bool &closure)
|
2018-10-25 01:50:54 +02:00
|
|
|
{
|
2019-08-13 07:59:27 +02:00
|
|
|
bool ret{true};
|
2019-09-06 06:15:06 +02:00
|
|
|
const auto proffer{[&opts, &closure, &ret]
|
2019-08-13 07:59:27 +02:00
|
|
|
(const m::room::id &room_id)
|
2018-10-25 01:50:54 +02:00
|
|
|
{
|
2019-08-13 07:59:27 +02:00
|
|
|
if(opts.room_id && !opts.lower_bound)
|
2018-10-25 01:50:54 +02:00
|
|
|
{
|
2019-08-13 07:59:27 +02:00
|
|
|
ret = false;
|
|
|
|
return;
|
|
|
|
}
|
2018-10-25 00:18:07 +02:00
|
|
|
|
2019-09-08 01:33:24 +02:00
|
|
|
const m::room room
|
|
|
|
{
|
|
|
|
room_id
|
|
|
|
};
|
|
|
|
|
2019-08-13 07:59:27 +02:00
|
|
|
if(opts.room_id)
|
|
|
|
if(room_id < opts.room_id)
|
|
|
|
return;
|
2018-10-25 01:50:54 +02:00
|
|
|
|
2019-09-08 01:33:24 +02:00
|
|
|
if(opts.local_joined_only)
|
|
|
|
if(!local_joined(room))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if(opts.remote_joined_only)
|
|
|
|
if(!remote_joined(room))
|
2019-08-13 13:43:04 +02:00
|
|
|
return;
|
|
|
|
|
2019-09-08 07:03:02 +02:00
|
|
|
if(opts.local_only)
|
|
|
|
if(!local_only(room))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if(opts.remote_only)
|
|
|
|
if(local_only(room))
|
|
|
|
return;
|
|
|
|
|
2019-08-13 07:59:27 +02:00
|
|
|
if(opts.server && !opts.summary)
|
|
|
|
if(opts.server != room_id.host())
|
|
|
|
return;
|
2018-10-24 23:01:21 +02:00
|
|
|
|
2019-08-13 07:59:27 +02:00
|
|
|
if(opts.summary)
|
2019-09-08 01:33:24 +02:00
|
|
|
if(!summary::has(room))
|
2019-08-13 07:59:27 +02:00
|
|
|
return;
|
2018-10-24 23:01:21 +02:00
|
|
|
|
2019-08-13 07:59:27 +02:00
|
|
|
if(opts.server && opts.summary)
|
2019-09-08 01:33:24 +02:00
|
|
|
if(!room::aliases(room).count(opts.server))
|
2019-08-13 07:59:27 +02:00
|
|
|
return;
|
2018-10-24 23:01:21 +02:00
|
|
|
|
2019-09-14 02:26:28 +02:00
|
|
|
if(opts.join_rule && !opts.summary)
|
2019-09-08 01:33:24 +02:00
|
|
|
if(!join_rule(room, opts.join_rule))
|
2019-08-13 07:59:27 +02:00
|
|
|
return;
|
2018-10-24 23:01:21 +02:00
|
|
|
|
2019-09-06 06:15:06 +02:00
|
|
|
if(opts.room_alias)
|
|
|
|
{
|
|
|
|
const auto match_alias_prefix{[&opts](const auto &alias)
|
|
|
|
{
|
|
|
|
return !startswith(alias, opts.room_alias);
|
|
|
|
}};
|
|
|
|
|
2019-09-08 01:33:24 +02:00
|
|
|
if(room::aliases(room).for_each(match_alias_prefix))
|
2019-09-06 05:28:43 +02:00
|
|
|
return; // no match
|
2019-09-06 06:15:06 +02:00
|
|
|
}
|
2019-09-06 05:28:43 +02:00
|
|
|
|
2019-09-08 01:33:24 +02:00
|
|
|
ret = closure(room);
|
2019-08-13 07:59:27 +02:00
|
|
|
}};
|
2018-10-24 23:01:21 +02:00
|
|
|
|
2019-09-06 06:15:06 +02:00
|
|
|
// branch for public rooms of a specific user
|
|
|
|
if(opts.user_id)
|
|
|
|
{
|
|
|
|
const user::rooms user_rooms
|
|
|
|
{
|
|
|
|
opts.user_id
|
|
|
|
};
|
|
|
|
|
|
|
|
return user_rooms.for_each(user::rooms::closure_bool{[&proffer, &ret]
|
|
|
|
(const room::id &room_id, const string_view &membership)
|
|
|
|
{
|
|
|
|
proffer(room_id);
|
|
|
|
return ret;
|
|
|
|
}});
|
|
|
|
}
|
|
|
|
|
2019-09-14 02:48:35 +02:00
|
|
|
// branch for optimized public rooms searches.
|
|
|
|
if(opts.summary && opts.server)
|
|
|
|
{
|
|
|
|
m::room::aliases::cache::for_each(opts.server, [&proffer, &ret]
|
|
|
|
(const auto &alias, const auto &room_id)
|
|
|
|
{
|
|
|
|
if(!m::rooms::summary::has(room_id))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
proffer(room_id);
|
|
|
|
return ret;
|
|
|
|
});
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2019-08-13 07:59:27 +02:00
|
|
|
// branch for optimized public rooms searches.
|
|
|
|
if(opts.summary)
|
2018-10-24 23:01:21 +02:00
|
|
|
{
|
2019-08-13 07:59:27 +02:00
|
|
|
const room::id::buf public_room_id
|
2018-10-24 23:01:21 +02:00
|
|
|
{
|
2019-08-13 07:59:27 +02:00
|
|
|
"!public", my_host()
|
2018-10-24 23:01:21 +02:00
|
|
|
};
|
|
|
|
|
2019-09-06 05:29:17 +02:00
|
|
|
const room::state state
|
|
|
|
{
|
|
|
|
public_room_id
|
|
|
|
};
|
|
|
|
|
2019-09-14 02:41:26 +02:00
|
|
|
const auto proffer_state{[&opts, &proffer, &ret]
|
2019-08-13 07:59:27 +02:00
|
|
|
(const string_view &type, const string_view &state_key, const event::idx &event_idx)
|
2018-10-24 23:01:21 +02:00
|
|
|
{
|
2019-09-15 01:03:38 +02:00
|
|
|
const auto room_id
|
2019-09-14 02:41:26 +02:00
|
|
|
{
|
2019-09-15 01:03:38 +02:00
|
|
|
rooms::summary::unmake_state_key(state_key)
|
2019-09-14 02:41:26 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
proffer(room_id);
|
2019-08-13 07:59:27 +02:00
|
|
|
return ret;
|
2019-09-06 05:29:17 +02:00
|
|
|
}};
|
|
|
|
|
2019-09-14 02:41:26 +02:00
|
|
|
state.for_each("ircd.rooms", proffer_state);
|
|
|
|
return ret;
|
2018-10-24 23:01:21 +02:00
|
|
|
}
|
|
|
|
|
2019-08-21 03:44:58 +02:00
|
|
|
return events::type::for_each_in("m.room.create", [&proffer, &ret]
|
2019-08-13 07:59:27 +02:00
|
|
|
(const string_view &type, const event::idx &event_idx)
|
2018-10-24 23:01:21 +02:00
|
|
|
{
|
2019-08-13 07:59:27 +02:00
|
|
|
assert(type == "m.room.create");
|
|
|
|
m::get(std::nothrow, event_idx, "room_id", proffer);
|
|
|
|
return ret;
|
2018-10-24 23:01:21 +02:00
|
|
|
});
|
2018-10-25 00:18:07 +02:00
|
|
|
}
|
2019-09-08 04:54:15 +02:00
|
|
|
|
|
|
|
//
|
|
|
|
// ircd::m::rooms::opts::opts
|
|
|
|
//
|
|
|
|
|
|
|
|
IRCD_MODULE_EXPORT
|
|
|
|
ircd::m::rooms::opts::opts(const string_view &input)
|
|
|
|
noexcept
|
|
|
|
:room_id
|
|
|
|
{
|
|
|
|
valid(m::id::ROOM, input)?
|
|
|
|
m::id::room{input}:
|
|
|
|
m::id::room{}
|
|
|
|
}
|
|
|
|
,server
|
|
|
|
{
|
|
|
|
startswith(input, ':')?
|
|
|
|
lstrip(input, ':'):
|
|
|
|
string_view{}
|
|
|
|
}
|
|
|
|
,room_alias
|
|
|
|
{
|
|
|
|
valid(m::id::ROOM_ALIAS, input)?
|
|
|
|
m::id::room_alias{input}:
|
|
|
|
m::id::room_alias{}
|
|
|
|
}
|
|
|
|
,user_id
|
|
|
|
{
|
|
|
|
valid(m::id::USER, input)?
|
|
|
|
m::id::user{input}:
|
|
|
|
m::id::user{}
|
|
|
|
}
|
|
|
|
,local_only
|
|
|
|
{
|
|
|
|
has(input, "local_only")
|
|
|
|
}
|
|
|
|
,remote_only
|
|
|
|
{
|
|
|
|
has(input, "remote_only")
|
|
|
|
}
|
|
|
|
,local_joined_only
|
|
|
|
{
|
|
|
|
has(input, "local_joined_only")
|
|
|
|
}
|
|
|
|
,remote_joined_only
|
|
|
|
{
|
|
|
|
has(input, "remote_joined_only")
|
|
|
|
}
|
|
|
|
,search_term
|
|
|
|
{
|
|
|
|
!room_id && !server && !room_alias && !user_id
|
|
|
|
&& !local_only && !remote_only
|
|
|
|
&& !local_joined_only && !remote_joined_only?
|
|
|
|
input:
|
|
|
|
string_view{}
|
|
|
|
}
|
|
|
|
{
|
|
|
|
}
|