]> jfr.im git - solanum.git/commitdiff
m_invite: Add hooks
authorEd Kellett <redacted>
Sat, 1 Feb 2020 00:08:23 +0000 (00:08 +0000)
committerEd Kellett <redacted>
Thu, 30 Apr 2020 17:16:59 +0000 (18:16 +0100)
can_invite is called on the source server, can override channel access
invite is called on the target

include/hook.h
modules/m_invite.c

index 58a94d4118832330c9e1be3f54ff97fda2065c98..099eeec7e37e93870230049a1b0d4a2ca0422989 100644 (file)
@@ -95,6 +95,7 @@ typedef struct
        int approved;
        int dir;
        const char *modestr;
+       const char *error;
 } hook_data_channel_approval;
 
 typedef struct
index 63645e2b7c5be98227a114cf12f6eebfef013844..044c72f58d1a8d010bdccb93711d228019dff0f1 100644 (file)
@@ -48,14 +48,22 @@ struct Message invite_msgtab = {
        {mg_unreg, {m_invite, 3}, {m_invite, 3}, mg_ignore, mg_ignore, {m_invite, 3}}
 };
 
+static int can_invite_hook;
+static int invite_hook;
+
 mapi_clist_av1 invite_clist[] = { &invite_msgtab, NULL };
+mapi_hlist_av1 invite_hlist[] = {
+       { "can_invite", &can_invite_hook },
+       { "invite",     &invite_hook },
+       { NULL, NULL }
+};
 
 mapi_cap_list_av2 invite_cap_list[] = {
        { MAPI_CAP_CLIENT, "invite-notify", NULL, &CAP_INVITE_NOTIFY },
        { 0, NULL, NULL, NULL }
 };
 
-DECLARE_MODULE_AV2(invite, NULL, NULL, invite_clist, NULL, NULL, invite_cap_list, NULL, invite_desc);
+DECLARE_MODULE_AV2(invite, NULL, NULL, invite_clist, invite_hlist, NULL, invite_cap_list, NULL, invite_desc);
 
 static bool add_invite(struct Channel *, struct Client *);
 
@@ -70,6 +78,7 @@ m_invite(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
        struct Channel *chptr;
        struct membership *msptr;
        int store_invite = 0;
+       hook_data_channel_approval hdata = { 0 };
 
        if(MyClient(source_p) && !IsFloodDone(source_p))
                flood_endgrace(source_p);
@@ -142,14 +151,24 @@ m_invite(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
                return;
        }
 
-       /* unconditionally require ops, unless the channel is +g */
-       /* treat remote clients as chanops */
-       if(MyClient(source_p) && !is_chanop(msptr) &&
-                       !(chptr->mode.mode & MODE_FREEINVITE))
+       if (MyClient(source_p))
        {
-               sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
-                          me.name, source_p->name, parv[2]);
-               return;
+               hdata.chptr = chptr;
+               hdata.msptr = msptr;
+               hdata.client = source_p;
+               hdata.target = target_p;
+               hdata.approved = !(is_chanop(msptr) || (chptr->mode.mode & MODE_FREEINVITE));
+
+               call_hook(can_invite_hook, &hdata);
+               if (hdata.approved)
+               {
+                       if (hdata.error)
+                               sendto_one_numeric(source_p, hdata.approved, "%s", hdata.error);
+                       else
+                               sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
+                                                me.name, source_p->name, parv[2]);
+                       return;
+               }
        }
 
        /* store invites when they could affect the ability to join
@@ -214,6 +233,22 @@ m_invite(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
                                target_p->localClient->last_caller_id_time = rb_current_time();
                        }
                }
+
+               hdata.chptr = chptr;
+               hdata.msptr = msptr;
+               hdata.client = source_p;
+               hdata.target = target_p;
+               hdata.approved = 0;
+
+               call_hook(invite_hook, &hdata);
+
+               if (hdata.approved)
+               {
+                       if (hdata.error)
+                               sendto_one_numeric(source_p, hdata.approved, "%s", hdata.error);
+                       return;
+               }
+
                add_reply_target(target_p, source_p);
                sendto_one(target_p, ":%s!%s@%s INVITE %s :%s",
                           source_p->name, source_p->username, source_p->host,