From 3a9e4f98aca0a9db5a0571a7e5673a75182dd0a1 Mon Sep 17 00:00:00 2001 From: k4be Date: Sat, 17 Jul 2021 18:07:02 +0200 Subject: [PATCH] Add option for notifying chanops about invitations by normal users. Normally, channel operators are only notified when another chanop invites someone to their channel - as this would allow the user to join the channel later if it becomes invite-only. This is still the default behaviour. But now, it can be configured to notify operators about any invitation done to their channel, eitner by another op or by normal user. This will allow them to see whether someone floods others with invitations to their channels. Enable the option with set::normal-user-invite-notification yes; --- include/h.h | 5 +++++ src/conf.c | 2 -- src/modulemanager.c | 1 + src/modules/invite.c | 51 +++++++++++++++++++++++++++++++++++++++----- 4 files changed, 52 insertions(+), 7 deletions(-) diff --git a/include/h.h b/include/h.h index e636d7062..69d88a1e8 100644 --- a/include/h.h +++ b/include/h.h @@ -582,6 +582,11 @@ extern uint16_t getrandom16(); extern uint32_t getrandom32(); extern void gen_random_alnum(char *buf, int numbytes); +/* Check config entry for empty/missing parameter */ +#define CheckNull(x) if ((!(x)->ce_vardata) || (!(*((x)->ce_vardata)))) { config_error("%s:%i: missing parameter", (x)->ce_fileptr->cf_filename, (x)->ce_varlinenum); errors++; continue; } +/* as above, but accepting empty string */ +#define CheckNullAllowEmpty(x) if ((!(x)->ce_vardata)) { config_error("%s:%i: missing parameter", (x)->ce_fileptr->cf_filename, (x)->ce_varlinenum); errors++; continue; } + extern MODVAR char extchmstr[4][64]; extern int extcmode_default_requirechop(Client *, Channel *, char, char *, int, int); diff --git a/src/conf.c b/src/conf.c index 4013fcd92..b988b23ab 100644 --- a/src/conf.c +++ b/src/conf.c @@ -6959,8 +6959,6 @@ int _test_require(ConfigFile *conf, ConfigEntry *ce) return errors; } -#define CheckNull(x) if ((!(x)->ce_vardata) || (!(*((x)->ce_vardata)))) { config_error("%s:%i: missing parameter", (x)->ce_fileptr->cf_filename, (x)->ce_varlinenum); errors++; continue; } -#define CheckNullAllowEmpty(x) if ((!(x)->ce_vardata)) { config_error("%s:%i: missing parameter", (x)->ce_fileptr->cf_filename, (x)->ce_varlinenum); errors++; continue; } #define CheckDuplicate(cep, name, display) if (settings.has_##name) { config_warn_duplicate((cep)->ce_fileptr->cf_filename, cep->ce_varlinenum, "set::" display); continue; } else settings.has_##name = 1 void test_tlsblock(ConfigFile *conf, ConfigEntry *cep, int *totalerrors) diff --git a/src/modulemanager.c b/src/modulemanager.c index 1165df01a..d503e9101 100644 --- a/src/modulemanager.c +++ b/src/modulemanager.c @@ -339,6 +339,7 @@ int parse_quoted_string(char *buf, char *dest, size_t destlen) return 1; } +#undef CheckNull #define CheckNull(x) if ((!(x)->ce_vardata) || (!(*((x)->ce_vardata)))) { config_error("%s:%i: missing parameter", m->name, (x)->ce_varlinenum); return 0; } /** Parse a module { } line from a module (not repo!!) */ diff --git a/src/modules/invite.c b/src/modules/invite.c index 38b94f92a..49c9ef2e8 100644 --- a/src/modules/invite.c +++ b/src/modules/invite.c @@ -27,16 +27,16 @@ #define CLIENT_INVITES(client) (moddata_local_client(client, userInvitesMD).ptr) #define CHANNEL_INVITES(channel) (moddata_channel(channel, channelInvitesMD).ptr) -/* TODO make it configurable */ -#define INVITE_ALWAYS_NOTIFY 1 - ModDataInfo *userInvitesMD; ModDataInfo *channelInvitesMD; long CAP_INVITE_NOTIFY = 0L; +int invite_always_notify = 0; CMD_FUNC(cmd_invite); void invite_free(ModData *md); +int invite_config_test(ConfigFile *cf, ConfigEntry *ce, int type, int *errs); +int invite_config_run(ConfigFile *cf, ConfigEntry *ce, int type); void add_invite(Client *from, Client *to, Channel *channel, MessageTag *mtags); void del_invite(Client *client, Channel *channel); static int invite_channel_destroy(Channel *channel, int *should_destroy); @@ -53,6 +53,12 @@ ModuleHeader MOD_HEADER "unrealircd-5", }; +MOD_TEST() +{ + HookAdd(modinfo->handle, HOOKTYPE_CONFIGTEST, 0, invite_config_test); + return MOD_SUCCESS; +} + MOD_INIT() { ClientCapabilityInfo cap; @@ -93,7 +99,9 @@ MOD_INIT() config_error("[%s] Failed to request channel invite moddata: %s", MOD_HEADER.name, ModuleGetErrorStr(modinfo->handle)); return MOD_FAILED; } - + + invite_always_notify = 0; /* the default */ + HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, invite_config_run); HookAdd(modinfo->handle, HOOKTYPE_CHANNEL_DESTROY, 1000000, invite_channel_destroy); HookAdd(modinfo->handle, HOOKTYPE_LOCAL_QUIT, 0, invite_user_quit); HookAdd(modinfo->handle, HOOKTYPE_LOCAL_JOIN, 0, invite_user_join); @@ -126,6 +134,39 @@ void invite_free(ModData *md) } } +int invite_config_test(ConfigFile *cf, ConfigEntry *ce, int type, int *errs) +{ + int errors = 0; + + if (type != CONFIG_SET) + return 0; + + if (!ce || !ce->ce_varname || strcmp(ce->ce_varname, "normal-user-invite-notification")) + return 0; + + do + CheckNull(ce) + while (0); + + *errs = errors; + return errors ? -1 : 1; +} + +int invite_config_run(ConfigFile *cf, ConfigEntry *ce, int type) +{ + ConfigEntry *cep; + + if (type != CONFIG_SET) + return 0; + + if (!ce || !ce->ce_varname || strcmp(ce->ce_varname, "normal-user-invite-notification")) + return 0; + + invite_always_notify = config_checkval(ce->ce_vardata, CFG_YESNO); + + return 1; +} + static int invite_channel_destroy(Channel *channel, int *should_destroy) { Link *lp; @@ -191,7 +232,7 @@ void invite_process(Client *client, Client *target, Channel *channel, MessageTag if (IsUser(client) && (is_chan_op(client, channel) || IsULine(client) || ValidatePermissionsForPath("channel:override:invite:self",client,NULL,channel,NULL) - || INVITE_ALWAYS_NOTIFY + || invite_always_notify )) { if (override == 1)