Skip to content

Commit 9aaae46

Browse files
committed
ircd::m::push: Implement event_property_is. (matrix-org/matrix-spec-proposals#3758)
1 parent d5c2ff0 commit 9aaae46

File tree

4 files changed

+67
-3
lines changed

4 files changed

+67
-3
lines changed

include/ircd/m/name.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ struct ircd::m::name
191191
static constexpr const char *const pattern {"pattern"};
192192
static constexpr const char *const is {"is"};
193193
static constexpr const char *const cond {"cond"};
194+
static constexpr const char *const value {"value"};
194195

195196
static constexpr const char *const actions {"actions"};
196197
static constexpr const char *const default_ {"default"};

include/ircd/m/push.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ struct ircd::m::push::match
6464
struct opts;
6565
using cond_kind_func = bool (*)(const event &, const cond &, const opts &);
6666

67-
static const string_view cond_kind_name[6];
68-
static const cond_kind_func cond_kind[7];
67+
static const string_view cond_kind_name[];
68+
static const cond_kind_func cond_kind[];
6969

7070
explicit match(const event &, const cond &, const opts &);
7171
explicit match(const event &, const rule &, const opts &);
@@ -217,7 +217,11 @@ struct ircd::m::push::cond
217217
/// prefixed by one of, ==, <, >, >= or <=. A prefix of < matches rooms
218218
/// where the member count is strictly less than the given number and so
219219
/// forth. If no prefix is present, this parameter defaults to ==.
220-
json::property<name::is, json::string>
220+
json::property<name::is, json::string>,
221+
222+
/// Required for event_property conditions. The exact case-sensitive string
223+
/// to match.
224+
json::property<name::value, json::string>
221225
>
222226
{
223227
using super_type::tuple;

matrix/name.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ constexpr const char *const ircd::m::name::key;
170170
constexpr const char *const ircd::m::name::pattern;
171171
constexpr const char *const ircd::m::name::is;
172172
constexpr const char *const ircd::m::name::cond;
173+
constexpr const char *const ircd::m::name::value;
173174

174175
constexpr const char *const ircd::m::name::actions;
175176
constexpr const char *const ircd::m::name::default_;

matrix/push.cc

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,15 @@ namespace ircd::m::push
7777
static bool state_key_user_mxid(const event &, const cond &, const match::opts &);
7878
static bool contains_user_mxid(const event &, const cond &, const match::opts &);
7979
static bool room_member_count(const event &, const cond &, const match::opts &);
80+
static bool event_property_is(const event &, const cond &, const match::opts &);
8081
static bool event_match(const event &, const cond &, const match::opts &);
8182
}
8283

8384
decltype(ircd::m::push::match::cond_kind)
8485
ircd::m::push::match::cond_kind
8586
{
8687
event_match,
88+
event_property_is,
8789
room_member_count,
8890
contains_user_mxid,
8991
state_key_user_mxid,
@@ -96,6 +98,7 @@ decltype(ircd::m::push::match::cond_kind_name)
9698
ircd::m::push::match::cond_kind_name
9799
{
98100
"event_match",
101+
"event_property_is",
99102
"room_member_count",
100103
"contains_user_mxid",
101104
"state_key_user_mxid",
@@ -220,6 +223,61 @@ catch(const std::exception &e)
220223
return false;
221224
}
222225

226+
bool
227+
ircd::m::push::event_property_is(const event &event,
228+
const cond &cond,
229+
const match::opts &opts)
230+
try
231+
{
232+
assert(json::get<"kind"_>(cond) == "event_property_is");
233+
234+
const auto &[top, path]
235+
{
236+
split(json::get<"key"_>(cond), '.')
237+
};
238+
239+
string_view value
240+
{
241+
json::get(event, top, json::object{})
242+
};
243+
244+
tokens(path, '.', [&value]
245+
(const string_view &key)
246+
{
247+
if(!json::type(value, json::OBJECT))
248+
return false;
249+
250+
value = json::object(value)[key];
251+
if(likely(!json::type(value, json::STRING)))
252+
return true;
253+
254+
value = json::string(value);
255+
return false;
256+
});
257+
258+
const json::value a{value}, b
259+
{
260+
json::get<"value"_>(cond)
261+
};
262+
263+
return a == b;
264+
}
265+
catch(const ctx::interrupted &)
266+
{
267+
throw;
268+
}
269+
catch(const std::exception &e)
270+
{
271+
log::error
272+
{
273+
log, "Push condition 'event_property_is' %s :%s",
274+
string_view{event.event_id},
275+
e.what(),
276+
};
277+
278+
return false;
279+
}
280+
223281
bool
224282
ircd::m::push::contains_user_mxid(const event &event,
225283
const cond &cond,

0 commit comments

Comments
 (0)