0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-11-15 22:41:12 +01:00

ircd:Ⓜ️ Reorg filter interface and linkage related.

This commit is contained in:
Jason Volk 2018-05-12 16:00:37 -07:00
parent 3ec5df018a
commit 1d7fce8368
7 changed files with 279 additions and 210 deletions

View file

@ -91,15 +91,8 @@ struct ircd::m::filter
>
{
using super_type::tuple;
using super_type::operator=;
using closure = std::function<void (const json::object &)>;
static bool get(std::nothrow_t, const user &, const string_view &filter_id, const closure &);
static void get(const user &, const string_view &filter_id, const closure &);
static string_view set(const mutable_buffer &id, const user &, const json::object &filter);
filter(const user &, const string_view &filter_id, const mutable_buffer &);
using super_type::operator=;
};
#pragma GCC diagnostic pop

View file

@ -57,6 +57,13 @@ struct ircd::m::user
json::object account_data(const mutable_buffer &out, const string_view &type) const; //nothrow
event::id::buf account_data(const m::user &sender, const string_view &type, const json::object &value);
using filter_closure = std::function<void (const json::object &)>;
bool filter(std::nothrow_t, const string_view &filter_id, const filter_closure &) const;
void filter(const string_view &filter_id, const filter_closure &) const;
std::string filter(std::nothrow_t, const string_view &filter_id) const;
std::string filter(const string_view &filter_id) const;
event::id::buf filter(const json::object &filter, const mutable_buffer &id);
bool is_active() const;
event::id::buf deactivate();
event::id::buf activate();

View file

@ -108,7 +108,6 @@ libircd_la_SOURCES = \
m/dbs.cc \
m/state.cc \
m/room.cc \
m/filter.cc \
m/request.cc \
m/v1.cc \
m/m.cc \

View file

@ -1,199 +0,0 @@
// 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.
//TODO: globular expression
bool
ircd::m::match(const room_event_filter &filter,
const event &event)
{
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
//
ircd::m::filter::filter(const user &user,
const string_view &filter_id,
const mutable_buffer &buf)
{
get(user, filter_id, [this, &buf]
(const json::object &filter)
{
const size_t len
{
copy(buf, string_view{filter})
};
new (this) m::filter
{
json::object
{
data(buf), len
}
};
});
}
ircd::string_view
ircd::m::filter::set(const mutable_buffer &idbuf,
const user &user,
const json::object &filter)
{
const auto user_room_id
{
user.room_id()
};
const m::room room
{
user_room_id
};
const sha256::buf hash
{
sha256{filter}
};
const string_view filter_id
{
b64encode_unpadded(idbuf, hash)
};
send(room, user.user_id, "ircd.filter", filter_id, filter);
return filter_id;
}
void
ircd::m::filter::get(const user &user,
const string_view &filter_id,
const closure &closure)
{
if(!get(std::nothrow, user, filter_id, closure))
throw m::NOT_FOUND
{
"Filter not found"
};
}
bool
ircd::m::filter::get(std::nothrow_t,
const user &user,
const string_view &filter_id,
const closure &closure)
{
const auto user_room_id
{
user.room_id()
};
const m::room room
{
user_room_id
};
return room.get(std::nothrow, "ircd.filter", filter_id, [&closure]
(const m::event &event)
{
const json::object &content
{
at<"content"_>(event)
};
closure(content);
});
}
//
// 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)
}
{
}
//
// 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)
}
{
}

View file

@ -1430,6 +1430,132 @@ ircd::m::events::for_each(const uint64_t &start,
return true;
}
///////////////////////////////////////////////////////////////////////////////
//
// m/filter.h
//
//TODO: globular expression
bool
ircd::m::match(const room_event_filter &filter,
const event &event)
{
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
//
ircd::m::filter::filter(const user &user,
const string_view &filter_id,
const mutable_buffer &buf)
{
get(user, filter_id, [this, &buf]
(const json::object &filter)
{
const size_t len
{
copy(buf, string_view{filter})
};
new (this) m::filter
{
json::object
{
data(buf), len
}
};
});
}
//
// 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)
}
{
}
//
// 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)
}
{
}
///////////////////////////////////////////////////////////////////////////////
//
// m/rooms.h
@ -1679,6 +1805,77 @@ const
return function(*this);
}
ircd::m::event::id::buf
ircd::m::user::filter(const json::object &filter,
const mutable_buffer &idbuf)
{
using prototype = event::id::buf (const m::user &, const json::object &, const mutable_buffer &);
static import<prototype> function
{
"client_user", "filter_set"
};
return function(*this, filter, idbuf);
}
std::string
ircd::m::user::filter(const string_view &filter_id)
const
{
std::string ret;
filter(filter_id, [&ret]
(const json::object &filter)
{
ret.assign(data(filter), size(filter));
});
return ret;
}
std::string
ircd::m::user::filter(std::nothrow_t,
const string_view &filter_id)
const
{
std::string ret;
filter(std::nothrow, filter_id, [&ret]
(const json::object &filter)
{
ret.assign(data(filter), size(filter));
});
return ret;
}
void
ircd::m::user::filter(const string_view &filter_id,
const filter_closure &closure)
const
{
if(!filter(std::nothrow, filter_id, closure))
throw m::NOT_FOUND
{
"Filter '%s' not found", filter_id
};
}
bool
ircd::m::user::filter(std::nothrow_t,
const string_view &filter_id,
const filter_closure &closure)
const
{
using prototype = bool (std::nothrow_t, const m::user &, const string_view &, const filter_closure &);
static import<prototype> function
{
"client_user", "filter_get"
};
return function(std::nothrow, *this, filter_id, closure);
}
ircd::m::event::id::buf
ircd::m::user::account_data(const m::user &sender,
const string_view &type,

View file

@ -23,7 +23,12 @@ get__filter(client &client,
url::decode(request.parv[2], filter_id_buf)
};
m::filter::get(user_id, filter_id, [&client]
const m::user user
{
user_id
};
user.filter(filter_id, [&client]
(const json::object &filter)
{
resource::response
@ -94,10 +99,15 @@ post__filter(client &client,
json::get<"presence"_>(request)
};
m::user user
{
user_id
};
char filter_id_buf[64];
const auto filter_id
{
m::filter::set(filter_id_buf, user_id, request.body)
user.filter(request.body, filter_id_buf)
};
return resource::response
@ -108,3 +118,54 @@ post__filter(client &client,
}
};
}
m::event::id::buf
filter_set(const m::user &user,
const json::object &filter,
const mutable_buffer &idbuf)
{
const m::user::room user_room
{
user
};
const sha256::buf hash
{
sha256{filter}
};
const string_view filter_id
{
b64encode_unpadded(idbuf, hash)
};
//TODO: ABA
if(user_room.has("ircd.filter", filter_id))
return {};
//TODO: ABA
return send(user_room, user.user_id, "ircd.filter", filter_id, filter);
}
bool
filter_get(std::nothrow_t,
const m::user &user,
const string_view &filter_id,
const m::user::filter_closure &closure)
{
const m::user::room user_room
{
user
};
return user_room.get(std::nothrow, "ircd.filter", filter_id, [&closure]
(const m::event &event)
{
const json::object &content
{
at<"content"_>(event)
};
closure(content);
});
}

View file

@ -15,6 +15,17 @@ extern ircd::resource user_resource;
// filter.cc
//
extern "C" bool
filter_get(std::nothrow_t,
const ircd::m::user &,
const ircd::string_view &filter_id,
const ircd::m::user::filter_closure &);
extern "C" ircd::m::event::id::buf
filter_set(const ircd::m::user &,
const ircd::json::object &filter,
const ircd::mutable_buffer &idbuf);
ircd::resource::response
get__filter(ircd::client &,
const ircd::resource::request &,