mirror of
https://github.com/matrix-construct/construct
synced 2024-11-26 08:42:34 +01:00
ircd:Ⓜ️:user: Remove pre-pushrules highlight counter.
This commit is contained in:
parent
014b6e9a9b
commit
f8b99ad26e
8 changed files with 7 additions and 446 deletions
|
@ -1,43 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#define HAVE_IRCD_M_USER_HIGHLIGHT_H
|
|
||||||
|
|
||||||
/// Interface to user highlighting and counting.
|
|
||||||
struct ircd::m::user::highlight
|
|
||||||
{
|
|
||||||
static conf::item<bool> enable_count;
|
|
||||||
static conf::item<bool> match_mxid_full;
|
|
||||||
static conf::item<bool> match_mxid_local_cs;
|
|
||||||
static conf::item<bool> match_mxid_local_ci;
|
|
||||||
static conf::item<bool> match_at_room;
|
|
||||||
|
|
||||||
static bool imatch(const string_view &text, const string_view &arg);
|
|
||||||
static bool match(const string_view &text, const string_view &arg);
|
|
||||||
|
|
||||||
m::user user;
|
|
||||||
|
|
||||||
public:
|
|
||||||
bool match(const string_view &text) const;
|
|
||||||
bool has(const event &) const;
|
|
||||||
bool has(const event::idx &) const;
|
|
||||||
|
|
||||||
bool for_each(const m::room &, const event::idx_range &, const event::closure_idx_bool &) const;
|
|
||||||
size_t count_between(const m::room &, const event::idx_range &) const;
|
|
||||||
size_t count_to(const m::room &, const event::idx &) const;
|
|
||||||
size_t count(const m::room &) const;
|
|
||||||
size_t count() const;
|
|
||||||
|
|
||||||
highlight(const m::user &user)
|
|
||||||
noexcept
|
|
||||||
:user{user}
|
|
||||||
{}
|
|
||||||
};
|
|
|
@ -41,7 +41,6 @@ struct ircd::m::user
|
||||||
struct room_tags;
|
struct room_tags;
|
||||||
struct filter;
|
struct filter;
|
||||||
struct ignores;
|
struct ignores;
|
||||||
struct highlight;
|
|
||||||
struct registar;
|
struct registar;
|
||||||
struct pushrules;
|
struct pushrules;
|
||||||
|
|
||||||
|
@ -91,6 +90,5 @@ const
|
||||||
#include "room_tags.h"
|
#include "room_tags.h"
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "ignores.h"
|
#include "ignores.h"
|
||||||
#include "highlight.h"
|
|
||||||
#include "register.h"
|
#include "register.h"
|
||||||
#include "pushrules.h"
|
#include "pushrules.h"
|
||||||
|
|
|
@ -94,7 +94,6 @@ libircd_matrix_la_SOURCES += user_account_data.cc
|
||||||
libircd_matrix_la_SOURCES += user_events.cc
|
libircd_matrix_la_SOURCES += user_events.cc
|
||||||
libircd_matrix_la_SOURCES += user_rooms.cc
|
libircd_matrix_la_SOURCES += user_rooms.cc
|
||||||
libircd_matrix_la_SOURCES += user_filter.cc
|
libircd_matrix_la_SOURCES += user_filter.cc
|
||||||
libircd_matrix_la_SOURCES += user_highlight.cc
|
|
||||||
libircd_matrix_la_SOURCES += user_mitsein.cc
|
libircd_matrix_la_SOURCES += user_mitsein.cc
|
||||||
libircd_matrix_la_SOURCES += user_profile.cc
|
libircd_matrix_la_SOURCES += user_profile.cc
|
||||||
libircd_matrix_la_SOURCES += user_pushrules.cc
|
libircd_matrix_la_SOURCES += user_pushrules.cc
|
||||||
|
|
|
@ -84,7 +84,6 @@ ircd::m::matrix::module_names
|
||||||
"m_room_redaction",
|
"m_room_redaction",
|
||||||
"m_room_server_acl",
|
"m_room_server_acl",
|
||||||
"m_room_third_party_invite",
|
"m_room_third_party_invite",
|
||||||
"m_user_highlight_auth",
|
|
||||||
"m_vm_fetch",
|
"m_vm_fetch",
|
||||||
|
|
||||||
"federation_backfill_ids",
|
"federation_backfill_ids",
|
||||||
|
|
|
@ -1,293 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
namespace ircd::m
|
|
||||||
{
|
|
||||||
static bool user_highlight_match(const string_view &text, const string_view &arg, const size_t &pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
decltype(ircd::m::user::highlight::enable_count)
|
|
||||||
ircd::m::user::highlight::enable_count
|
|
||||||
{
|
|
||||||
{ "name", "ircd.m.user.highlight.enable.count" },
|
|
||||||
{ "default", true },
|
|
||||||
};
|
|
||||||
|
|
||||||
decltype(ircd::m::user::highlight::match_mxid_full)
|
|
||||||
ircd::m::user::highlight::match_mxid_full
|
|
||||||
{
|
|
||||||
{ "name", "ircd.m.user.highlight.match.mxid.full" },
|
|
||||||
{ "default", true },
|
|
||||||
};
|
|
||||||
|
|
||||||
decltype(ircd::m::user::highlight::match_mxid_local_cs)
|
|
||||||
ircd::m::user::highlight::match_mxid_local_cs
|
|
||||||
{
|
|
||||||
{ "name", "ircd.m.user.highlight.match.mxid.local.cs" },
|
|
||||||
{ "default", true },
|
|
||||||
};
|
|
||||||
|
|
||||||
decltype(ircd::m::user::highlight::match_mxid_local_cs)
|
|
||||||
ircd::m::user::highlight::match_mxid_local_ci
|
|
||||||
{
|
|
||||||
{ "name", "ircd.m.user.highlight.match.mxid.local.ci" },
|
|
||||||
{ "default", false },
|
|
||||||
};
|
|
||||||
|
|
||||||
decltype(ircd::m::user::highlight::match_at_room)
|
|
||||||
ircd::m::user::highlight::match_at_room
|
|
||||||
{
|
|
||||||
{ "name", "ircd.m.user.highlight.match.at.room" },
|
|
||||||
{ "default", true },
|
|
||||||
};
|
|
||||||
|
|
||||||
size_t
|
|
||||||
ircd::m::user::highlight::count()
|
|
||||||
const
|
|
||||||
{
|
|
||||||
const m::user::rooms rooms
|
|
||||||
{
|
|
||||||
user
|
|
||||||
};
|
|
||||||
|
|
||||||
size_t ret(0);
|
|
||||||
rooms.for_each("join", m::user::rooms::closure_bool{[this, &ret]
|
|
||||||
(const m::room &room, const string_view &)
|
|
||||||
{
|
|
||||||
ret += this->count(room);
|
|
||||||
return true;
|
|
||||||
}});
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t
|
|
||||||
ircd::m::user::highlight::count(const m::room &room)
|
|
||||||
const
|
|
||||||
{
|
|
||||||
const auto ¤t
|
|
||||||
{
|
|
||||||
head_idx(room)
|
|
||||||
};
|
|
||||||
|
|
||||||
return count_to(room, current);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t
|
|
||||||
ircd::m::user::highlight::count_to(const m::room &room,
|
|
||||||
const event::idx ¤t)
|
|
||||||
const
|
|
||||||
{
|
|
||||||
event::id::buf last_read_buf;
|
|
||||||
const event::id last_read
|
|
||||||
{
|
|
||||||
receipt::read(last_read_buf, room, user)
|
|
||||||
};
|
|
||||||
|
|
||||||
if(!last_read)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
const auto &a
|
|
||||||
{
|
|
||||||
index(last_read)
|
|
||||||
};
|
|
||||||
|
|
||||||
const event::idx_range range
|
|
||||||
{
|
|
||||||
a, current
|
|
||||||
};
|
|
||||||
|
|
||||||
return count_between(room, range);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t
|
|
||||||
ircd::m::user::highlight::count_between(const m::room &room,
|
|
||||||
const event::idx_range &range)
|
|
||||||
const
|
|
||||||
{
|
|
||||||
size_t ret(0);
|
|
||||||
for_each(room, range, [this, &ret]
|
|
||||||
(const m::event::idx &event_idx)
|
|
||||||
{
|
|
||||||
ret += has(event_idx);
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
ircd::m::user::highlight::for_each(const m::room &room,
|
|
||||||
const event::idx_range &range,
|
|
||||||
const event::closure_idx_bool &closure)
|
|
||||||
const
|
|
||||||
{
|
|
||||||
m::room::events it
|
|
||||||
{
|
|
||||||
room
|
|
||||||
};
|
|
||||||
|
|
||||||
assert(range.first <= range.second);
|
|
||||||
it.seek_idx(range.first);
|
|
||||||
|
|
||||||
if(!it && !exists(room))
|
|
||||||
throw m::NOT_FOUND
|
|
||||||
{
|
|
||||||
"Cannot find room '%s' to count highlights for '%s'",
|
|
||||||
string_view{room.room_id},
|
|
||||||
string_view{user.user_id}
|
|
||||||
};
|
|
||||||
else if(!it)
|
|
||||||
throw m::NOT_FOUND
|
|
||||||
{
|
|
||||||
"Event @ idx:%lu or idx:%lu not found in '%s' to count highlights for '%s'",
|
|
||||||
range.first,
|
|
||||||
range.second,
|
|
||||||
string_view{room.room_id},
|
|
||||||
string_view{user.user_id},
|
|
||||||
};
|
|
||||||
|
|
||||||
for(++it; it && it.event_idx() < range.second; ++it)
|
|
||||||
if(!closure(it.event_idx()))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
ircd::m::user::highlight::has(const event::idx &event_idx)
|
|
||||||
const
|
|
||||||
{
|
|
||||||
char typebuf[event::TYPE_MAX_SIZE];
|
|
||||||
const string_view type
|
|
||||||
{
|
|
||||||
m::get(std::nothrow, event_idx, "type", typebuf)
|
|
||||||
};
|
|
||||||
|
|
||||||
bool ret{false};
|
|
||||||
if(type != "m.room.message")
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
m::get(std::nothrow, event_idx, "content", [this, &type, &ret]
|
|
||||||
(const json::object &content)
|
|
||||||
{
|
|
||||||
m::event event;
|
|
||||||
json::get<"content"_>(event) = content;
|
|
||||||
json::get<"type"_>(event) = type;
|
|
||||||
ret = has(event);
|
|
||||||
});
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
ircd::m::user::highlight::has(const event &event)
|
|
||||||
const
|
|
||||||
{
|
|
||||||
if(json::get<"type"_>(event) != "m.room.message")
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const json::object &content
|
|
||||||
{
|
|
||||||
json::get<"content"_>(event)
|
|
||||||
};
|
|
||||||
|
|
||||||
const json::string &body
|
|
||||||
{
|
|
||||||
content.get("body")
|
|
||||||
};
|
|
||||||
|
|
||||||
return match(body);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
ircd::m::user::highlight::match(const string_view &text)
|
|
||||||
const
|
|
||||||
{
|
|
||||||
if(match_at_room)
|
|
||||||
if(startswith(text, "@room"))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// Case insensitive and case-sensitive are exlusive; if both
|
|
||||||
// are true only one branch is taken.
|
|
||||||
if(match_mxid_local_ci)
|
|
||||||
{
|
|
||||||
if(imatch(text, user.user_id.localname()))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if(match_mxid_local_cs)
|
|
||||||
{
|
|
||||||
if(match(text, user.user_id.localname()))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(match_mxid_full)
|
|
||||||
if(match(text, user.user_id))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
ircd::m::user::highlight::match(const string_view &text,
|
|
||||||
const string_view &arg)
|
|
||||||
{
|
|
||||||
const auto pos
|
|
||||||
{
|
|
||||||
text.find(arg)
|
|
||||||
};
|
|
||||||
|
|
||||||
return user_highlight_match(text, arg, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
ircd::m::user::highlight::imatch(const string_view &text,
|
|
||||||
const string_view &arg)
|
|
||||||
{
|
|
||||||
const auto pos
|
|
||||||
{
|
|
||||||
ifind(text, arg)
|
|
||||||
};
|
|
||||||
|
|
||||||
return user_highlight_match(text, arg, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
ircd::m::user_highlight_match(const string_view &text,
|
|
||||||
const string_view &arg,
|
|
||||||
const size_t &pos)
|
|
||||||
{
|
|
||||||
static constexpr char sp {'\x20'}, colon {':'};
|
|
||||||
|
|
||||||
// no match
|
|
||||||
if(likely(pos == string_view::npos))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if(pos == 0)
|
|
||||||
{
|
|
||||||
// match is at the beginning of the string
|
|
||||||
assert(pos + size(arg) <= size(text));
|
|
||||||
if(pos + size(arg) == size(text))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return text[pos + size(arg)] == sp || text[pos + size(arg)] == colon;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(pos + size(arg) == size(text))
|
|
||||||
{
|
|
||||||
// match is at the end of the string
|
|
||||||
assert(size(arg) < size(text));
|
|
||||||
return text[pos - 1] == sp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// test if match surrounded by spaces
|
|
||||||
assert(size(text) >= size(arg) + 2);
|
|
||||||
return text[pos - 1] == sp && text[pos] == sp;
|
|
||||||
}
|
|
|
@ -114,7 +114,6 @@ m_room_power_levels_la_SOURCES = m_room_power_levels.cc
|
||||||
m_room_redaction_la_SOURCES = m_room_redaction.cc
|
m_room_redaction_la_SOURCES = m_room_redaction.cc
|
||||||
m_room_server_acl_la_SOURCES = m_room_server_acl.cc
|
m_room_server_acl_la_SOURCES = m_room_server_acl.cc
|
||||||
m_room_third_party_invite_la_SOURCES = m_room_third_party_invite.cc
|
m_room_third_party_invite_la_SOURCES = m_room_third_party_invite.cc
|
||||||
m_user_highlight_auth_la_SOURCES = m_user_highlight_auth.cc
|
|
||||||
m_vm_fetch_la_SOURCES = m_vm_fetch.cc
|
m_vm_fetch_la_SOURCES = m_vm_fetch.cc
|
||||||
|
|
||||||
m_module_LTLIBRARIES = \
|
m_module_LTLIBRARIES = \
|
||||||
|
@ -144,7 +143,6 @@ m_module_LTLIBRARIES = \
|
||||||
m_room_redaction.la \
|
m_room_redaction.la \
|
||||||
m_room_server_acl.la \
|
m_room_server_acl.la \
|
||||||
m_room_third_party_invite.la \
|
m_room_third_party_invite.la \
|
||||||
m_user_highlight_auth.la \
|
|
||||||
m_vm_fetch.la \
|
m_vm_fetch.la \
|
||||||
###
|
###
|
||||||
|
|
||||||
|
|
|
@ -185,14 +185,13 @@ ircd::m::sync::room_unread_notifications_polylog(data &data)
|
||||||
};
|
};
|
||||||
|
|
||||||
// highlight_count
|
// highlight_count
|
||||||
if(m::user::highlight::enable_count)
|
json::stack::member
|
||||||
json::stack::member
|
{
|
||||||
|
*data.out, "highlight_count", json::value
|
||||||
{
|
{
|
||||||
*data.out, "highlight_count", json::value
|
_highlight_count(room, data.user, start_idx, data.range.second)
|
||||||
{
|
}
|
||||||
_highlight_count(room, data.user, start_idx, data.range.second)
|
};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -216,15 +215,10 @@ ircd::m::sync::_highlight_count(const room &room,
|
||||||
const event::idx &a,
|
const event::idx &a,
|
||||||
const event::idx &b)
|
const event::idx &b)
|
||||||
{
|
{
|
||||||
const m::user::highlight highlight
|
|
||||||
{
|
|
||||||
user
|
|
||||||
};
|
|
||||||
|
|
||||||
const event::idx_range range
|
const event::idx_range range
|
||||||
{
|
{
|
||||||
std::minmax(a, b)
|
std::minmax(a, b)
|
||||||
};
|
};
|
||||||
|
|
||||||
return highlight.count_between(room, range);
|
return 0L;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,91 +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.
|
|
||||||
|
|
||||||
namespace ircd::m
|
|
||||||
{
|
|
||||||
static void user_highlight_auth(const event &, room::auth::hookdata &);
|
|
||||||
extern hookfn<room::auth::hookdata &> user_highlight_auth_hook;
|
|
||||||
}
|
|
||||||
|
|
||||||
ircd::mapi::header
|
|
||||||
IRCD_MODULE
|
|
||||||
{
|
|
||||||
"Matrix @room highlight authentication"
|
|
||||||
};
|
|
||||||
|
|
||||||
decltype(ircd::m::user_highlight_auth_hook)
|
|
||||||
ircd::m::user_highlight_auth_hook
|
|
||||||
{
|
|
||||||
user_highlight_auth,
|
|
||||||
{
|
|
||||||
{ "_site", "room.auth" },
|
|
||||||
{ "type", "m.room.message" },
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void
|
|
||||||
ircd::m::user_highlight_auth(const event &event,
|
|
||||||
room::auth::hookdata &data)
|
|
||||||
{
|
|
||||||
using FAIL = m::room::auth::FAIL;
|
|
||||||
using conforms = m::event::conforms;
|
|
||||||
assert(json::get<"type"_>(event) == "m.room.message");
|
|
||||||
|
|
||||||
const auto &content
|
|
||||||
{
|
|
||||||
json::get<"content"_>(event)
|
|
||||||
};
|
|
||||||
|
|
||||||
if(!user::highlight::match_at_room)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const json::string &body
|
|
||||||
{
|
|
||||||
content.get("body")
|
|
||||||
};
|
|
||||||
|
|
||||||
if(likely(!startswith(body, "@room")))
|
|
||||||
return;
|
|
||||||
|
|
||||||
const room::power power
|
|
||||||
{
|
|
||||||
data.auth_power?
|
|
||||||
*data.auth_power : m::event{},
|
|
||||||
*data.auth_create
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto &user_level
|
|
||||||
{
|
|
||||||
power.level_user(at<"sender"_>(event))
|
|
||||||
};
|
|
||||||
|
|
||||||
int64_t required_level
|
|
||||||
{
|
|
||||||
room::power::default_power_level
|
|
||||||
};
|
|
||||||
|
|
||||||
power.for_each("notifications", room::power::closure_bool{[&required_level]
|
|
||||||
(const auto &name, const auto &level)
|
|
||||||
{
|
|
||||||
if(name != "room")
|
|
||||||
return true;
|
|
||||||
|
|
||||||
required_level = level;
|
|
||||||
return false;
|
|
||||||
}});
|
|
||||||
|
|
||||||
if(user_level < required_level)
|
|
||||||
throw FAIL
|
|
||||||
{
|
|
||||||
"Insufficient power level to highlight the room (have:%ld require:%ld).",
|
|
||||||
user_level,
|
|
||||||
required_level
|
|
||||||
};
|
|
||||||
}
|
|
Loading…
Reference in a new issue