2019-08-12 04:23:38 +02:00
|
|
|
// Matrix Construct
|
|
|
|
//
|
|
|
|
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
|
|
|
// Copyright (C) 2016-2019 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.
|
|
|
|
|
2019-08-12 05:55:58 +02:00
|
|
|
namespace ircd::m::users
|
|
|
|
{
|
|
|
|
static bool for_each_host(const opts &, const user::closure_bool &);
|
|
|
|
static bool for_each_in_host(const opts &, const user::closure_bool &);
|
|
|
|
}
|
|
|
|
|
2019-08-13 12:00:08 +02:00
|
|
|
decltype(ircd::m::users::opts_default)
|
|
|
|
ircd::m::users::opts_default;
|
2019-08-12 05:55:58 +02:00
|
|
|
|
|
|
|
bool
|
|
|
|
ircd::m::users::exists(const opts &opts)
|
2019-08-12 04:23:38 +02:00
|
|
|
{
|
2019-08-12 05:55:58 +02:00
|
|
|
return !for_each(opts, []
|
2022-07-04 22:15:53 +02:00
|
|
|
(const auto &) noexcept
|
2019-08-12 04:23:38 +02:00
|
|
|
{
|
2019-08-12 05:55:58 +02:00
|
|
|
// return false to break and have for_each() returns false
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t
|
|
|
|
ircd::m::users::count(const opts &opts)
|
|
|
|
{
|
|
|
|
size_t ret(0);
|
2022-07-04 22:15:53 +02:00
|
|
|
for_each(opts, [&ret]
|
|
|
|
(const auto &) noexcept
|
2019-08-12 05:55:58 +02:00
|
|
|
{
|
|
|
|
++ret;
|
2019-08-12 04:23:38 +02:00
|
|
|
return true;
|
2019-08-12 05:55:58 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
return ret;
|
2019-08-12 04:23:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ircd::m::users::for_each(const user::closure_bool &closure)
|
|
|
|
{
|
2019-08-13 12:00:08 +02:00
|
|
|
return for_each(opts_default, closure);
|
2019-08-12 04:23:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2019-08-12 05:55:58 +02:00
|
|
|
ircd::m::users::for_each(const opts &opts,
|
2019-08-12 04:23:38 +02:00
|
|
|
const user::closure_bool &closure)
|
|
|
|
{
|
2019-08-20 04:06:14 +02:00
|
|
|
// Branch to a better query for hosts when there's no localpart given.
|
|
|
|
if(opts.hostpart && (!opts.localpart || opts.localpart == "@"))
|
|
|
|
return for_each_host(opts, closure);
|
|
|
|
|
|
|
|
bool ret{true};
|
2019-08-21 03:44:58 +02:00
|
|
|
events::sender::for_each(opts.localpart, [&opts, &ret, &closure]
|
2019-08-20 04:06:14 +02:00
|
|
|
(const id::user &sender)
|
|
|
|
{
|
|
|
|
if(opts.localpart && !opts.localpart_prefix)
|
|
|
|
if(sender.local() != opts.localpart)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if(opts.localpart && opts.localpart_prefix)
|
|
|
|
if(!startswith(sender.local(), opts.localpart))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if(opts.hostpart && !opts.hostpart_prefix)
|
|
|
|
if(sender.host() != opts.hostpart)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if(opts.hostpart && opts.hostpart_prefix)
|
|
|
|
if(!startswith(sender.host(), opts.hostpart))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// Call the user with match.a
|
|
|
|
ret = closure(sender);
|
|
|
|
return ret;
|
|
|
|
});
|
|
|
|
|
|
|
|
return ret;
|
2019-08-12 05:55:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ircd::m::users::for_each_host(const opts &opts,
|
|
|
|
const user::closure_bool &closure)
|
|
|
|
{
|
|
|
|
bool ret{true};
|
2019-08-21 03:44:58 +02:00
|
|
|
events::origin::for_each(opts.hostpart, [&ret, &opts, &closure]
|
2019-08-12 05:55:58 +02:00
|
|
|
(const string_view &origin)
|
|
|
|
{
|
|
|
|
if(opts.hostpart && !opts.hostpart_prefix)
|
|
|
|
if(origin != opts.hostpart)
|
|
|
|
return false;
|
|
|
|
|
2019-08-20 04:06:14 +02:00
|
|
|
if(opts.hostpart && opts.hostpart_prefix)
|
|
|
|
if(!startswith(origin, opts.hostpart))
|
|
|
|
return false;
|
|
|
|
|
2019-08-12 05:55:58 +02:00
|
|
|
auto _opts(opts);
|
|
|
|
_opts.hostpart = origin;
|
2019-08-20 04:06:14 +02:00
|
|
|
_opts.hostpart_prefix = false;
|
2019-08-12 05:55:58 +02:00
|
|
|
ret = for_each_in_host(_opts, closure);
|
|
|
|
return ret;
|
|
|
|
});
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ircd::m::users::for_each_in_host(const opts &opts,
|
|
|
|
const user::closure_bool &closure)
|
|
|
|
{
|
|
|
|
bool ret{true};
|
2019-08-20 04:06:14 +02:00
|
|
|
m::user::id::buf last;
|
2019-08-21 03:44:58 +02:00
|
|
|
events::origin::for_each_in(opts.hostpart, [&opts, &ret, &closure, &last]
|
2019-08-20 04:06:14 +02:00
|
|
|
(const id::user &sender, const auto &event_idx)
|
2019-08-12 05:55:58 +02:00
|
|
|
{
|
2019-08-20 04:06:14 +02:00
|
|
|
if(sender == last)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if(opts.hostpart && !opts.hostpart_prefix)
|
|
|
|
if(sender.host() != opts.hostpart)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if(opts.hostpart && opts.hostpart_prefix)
|
|
|
|
if(!startswith(sender.host(), opts.hostpart))
|
|
|
|
return false;
|
|
|
|
|
2019-08-12 05:55:58 +02:00
|
|
|
if(opts.localpart && opts.localpart_prefix)
|
|
|
|
if(!startswith(sender.local(), opts.localpart))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if(opts.localpart && !opts.localpart_prefix)
|
|
|
|
if(sender.local() != opts.localpart)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// Call the user with match.
|
|
|
|
ret = closure(sender);
|
2019-08-20 04:06:14 +02:00
|
|
|
last = sender;
|
2019-08-12 05:55:58 +02:00
|
|
|
return ret;
|
|
|
|
});
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
ircd::m::users::opts::opts(const string_view &query)
|
|
|
|
{
|
|
|
|
if(startswith(query, '@') && has(query, ':'))
|
|
|
|
{
|
|
|
|
localpart = split(query, ':').first;
|
|
|
|
hostpart = split(query, ':').second;
|
2019-08-20 04:06:14 +02:00
|
|
|
hostpart_prefix = !has(hostpart, '.');
|
2019-08-12 05:55:58 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(startswith(query, '@'))
|
2019-08-12 04:23:38 +02:00
|
|
|
{
|
2019-08-12 05:55:58 +02:00
|
|
|
localpart = query;
|
|
|
|
localpart_prefix = true;
|
|
|
|
return;
|
|
|
|
}
|
2019-08-12 04:23:38 +02:00
|
|
|
|
2019-08-12 05:55:58 +02:00
|
|
|
if(startswith(query, ':'))
|
2019-08-12 04:23:38 +02:00
|
|
|
{
|
2019-08-12 05:55:58 +02:00
|
|
|
hostpart = lstrip(query, ':');
|
2019-08-20 04:06:14 +02:00
|
|
|
hostpart_prefix = !has(hostpart, '.');
|
2019-08-12 05:55:58 +02:00
|
|
|
return;
|
|
|
|
}
|
2019-08-12 04:23:38 +02:00
|
|
|
|
2019-08-20 04:06:14 +02:00
|
|
|
localpart = query;
|
|
|
|
localpart_prefix = true;
|
2019-08-12 04:23:38 +02:00
|
|
|
}
|