0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-11-27 09:12:36 +01:00
construct/matrix/filter.cc
2019-09-27 19:35:26 -07:00

191 lines
4.1 KiB
C++

// 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.
///////////////////////////////////////////////////////////////////////////////
//
// m/filter.h
//
//TODO: globular expression
//TODO: tribool for contains_url; we currently ignore the false value.
bool
ircd::m::match(const room_event_filter &filter,
const event &event)
{
if(json::get<"contains_url"_>(filter) == true)
if(!at<"content"_>(event).has("url"))
return false;
for(const auto &room_id : json::get<"not_rooms"_>(filter))
if(at<"room_id"_>(event) == unquote(room_id))
return false;
if(empty(json::get<"rooms"_>(filter)))
return match(event_filter{filter}, event);
for(const auto &room_id : json::get<"rooms"_>(filter))
if(at<"room_id"_>(event) == unquote(room_id))
return match(event_filter{filter}, event);
return false;
}
//TODO: globular expression
bool
ircd::m::match(const event_filter &filter,
const event &event)
{
for(const auto &type : json::get<"not_types"_>(filter))
if(at<"type"_>(event) == unquote(type))
return false;
for(const auto &sender : json::get<"not_senders"_>(filter))
if(at<"sender"_>(event) == unquote(sender))
return false;
if(empty(json::get<"senders"_>(filter)) && empty(json::get<"types"_>(filter)))
return true;
if(empty(json::get<"senders"_>(filter)))
{
for(const auto &type : json::get<"types"_>(filter))
if(at<"type"_>(event) == unquote(type))
return true;
return false;
}
if(empty(json::get<"types"_>(filter)))
{
for(const auto &sender : json::get<"senders"_>(filter))
if(at<"sender"_>(event) == unquote(sender))
return true;
return false;
}
return true;
}
//
// filter
//
/// Convenience interface for filters out of common `?filter=` query string
/// arguments. This function expects a raw urlencoded value of the filter
/// query parameter. It detects if the value is an "inline" filter by being
/// a valid JSON object; otherwise it considers the value an ID and fetches
/// the filter stored previously by the user.
std::string
ircd::m::filter::get(const string_view &val,
const m::user &user)
{
if(!val)
return {};
const bool is_inline
{
startswith(val, "{") || startswith(val, "%7B")
};
if(is_inline)
return util::string(val.size(), [&val]
(const mutable_buffer &buf)
{
return url::decode(buf, val);
});
if(!user.user_id)
return {};
char idbuf[m::event::STATE_KEY_MAX_SIZE];
const string_view &id
{
url::decode(idbuf, val)
};
const m::user::filter filter
{
user
};
return filter.get(id);
}
//
// filter::filter
//
ircd::m::filter::filter(const user &user,
const string_view &filter_id,
const mutable_buffer &buf)
{
const json::object &obj
{
user::filter(user).get(buf, filter_id)
};
new (this) m::filter
{
obj
};
}
//
// room_filter
//
ircd::m::room_filter::room_filter(const mutable_buffer &buf,
const json::members &members)
:super_type::tuple
{
json::stringify(mutable_buffer{buf}, members)
}
{
}
//
// state_filter
//
ircd::m::state_filter::state_filter(const mutable_buffer &buf,
const json::members &members)
:super_type::tuple
{
json::stringify(mutable_buffer{buf}, members)
}
{
}
//
// room_event_filter
//
ircd::m::room_event_filter::room_event_filter(const mutable_buffer &buf,
const json::members &members)
:super_type::tuple
{
json::stringify(mutable_buffer{buf}, members)
}
{
}
//
// event_filter
//
ircd::m::event_filter::event_filter(const mutable_buffer &buf,
const json::members &members)
:super_type::tuple
{
json::stringify(mutable_buffer{buf}, members)
}
{
}