vexim / vexim2

Virtual Exim 2
Other
71 stars 47 forks source link

"Writer" for private groups #281

Open VVD opened 7 months ago

VVD commented 7 months ago

Private groups: only who have Writer bit can write emails to group. Public groups: not affected. checked.png: checked unchecked.png: unchecked

diff -ur vexim.orig/admingroupchange.php vexim/admingroupchange.php
--- vexim.orig/admingroupchange.php
+++ vexim/admingroupchange.php
@@ -76,7 +76,7 @@
         <tr>
           <td colspan="2">
             <?php
-              $query = "SELECT u.realname, u.localpart, u.enabled, c.member_id
+              $query = "SELECT u.realname, u.localpart, u.enabled, c.member_id, c.writer
                 FROM users u, group_contents c
                 WHERE u.user_id=c.member_id and c.group_id=:group_id
                 ORDER BY u.enabled desc, u.realname asc";
@@ -86,6 +86,7 @@
             ?>
             <table align="center">
               <tr>
+                <th><?php echo _('Writer'); ?></th>
                 <th>&nbsp;</th>
                 <th><?php echo _('Real name'); ?></th>
                 <th><?php echo _('Email Address'); ?></th>
@@ -95,11 +96,42 @@
                 while ($row = $sth->fetch()) {
               ?>
               <tr>
+                <td>
+                  <div align="center">
+                  <?php
+                    if($row['writer']=='1') {
+                  ?>
+                  <a href="admingroupwritersubmit.php?group_id=<?php echo htmlspecialchars($_GET['group_id']);
+                                        ?>&member_id=<?php echo $row['member_id'];
+                                        ?>&localpart=<?php echo $grouplocalpart;
+                                        ?>&writer=0">
+                    <img
+                      title="Disable writer permissions <?php echo $row['realname']
+                      . ' from group ' . $grouplocalpart; ?>"
+                      src="images/checked.png" alt="disable">
+                  </a>
+                  <?php
+                    } else {
+                  ?>
+                  <a href="admingroupwritersubmit.php?group_id=<?php echo htmlspecialchars($_GET['group_id']);
+                                        ?>&member_id=<?php echo $row['member_id'];
+                                        ?>&localpart=<?php echo $grouplocalpart;
+                                        ?>&writer=1">
+                    <img
+                      title="Enable writer permissions <?php echo $row['realname']
+                      . ' from group ' . $grouplocalpart; ?>"
+                      src="images/unchecked.png" alt="enable">
+                  </a>
+                  <?php
+                    }
+                  ?>
+                  </div>
+                </td>
                 <td class="trash">
                   <a href="admingroupcontentdeletesubmit.php?group_id=<?php echo htmlspecialchars($_GET['group_id']);
-                                       ?>&member_id=<?php echo $row['member_id'];
-                                       ?>&localpart=<?php echo $grouplocalpart;
-                                       ?>">
+                                        ?>&member_id=<?php echo $row['member_id'];
+                                        ?>&localpart=<?php echo $grouplocalpart;
+                                        ?>">
                     <img class="trash"
                       title="Remove member <?php echo $row['realname']
                       . ' from group ' . $grouplocalpart; ?>"
@@ -112,7 +144,7 @@
                   <?php
                     if($row['enabled']=='1') {
                   ?>
-                  <img class="check" src="images/check.gif">
+                  <div align="center"><img class="check" src="images/check.gif"></div>
                   <?php
                     }
                   ?>
@@ -135,7 +167,7 @@
           <form method="post" action="admingroupcontentaddsubmit.php"
             name="groupcontentadd">
           <tr>
-            <td><?php echo _('Add Member'); ?></td>
+            <td><?php echo _('Add Member'); ?><br/>&nbsp;</td>
             <td>
               <input name="group_id" type="hidden"
                 value="<?php echo htmlspecialchars($_GET['group_id']); ?>" class="textfield">
@@ -158,6 +190,7 @@
                   }
                 ?>
               </select>
+              <br><?php echo _('Writer'); ?>: <input name="writer" type="checkbox" class="textfield" />
             </td>
           </tr>
           <tr>
diff -ur vexim.orig/admingroupcontentaddsubmit.php vexim/admingroupcontentaddsubmit.php
--- vexim.orig/admingroupcontentaddsubmit.php
+++ vexim/admingroupcontentaddsubmit.php
@@ -17,9 +17,13 @@
     header("Location: admingroup.php?badname={$_POST['usertoadd']}");
     die;
   }
-  $query = "INSERT INTO group_contents (group_id, member_id) VALUES (:group_id, :usertoadd)";
+  $query = "INSERT INTO group_contents (group_id, member_id, writer) VALUES (:group_id, :usertoadd, :writer)";
   $sth = $dbh->prepare($query);
-  $success = $sth->execute(array(':group_id'=>$_POST['group_id'], ':usertoadd'=>$_POST['usertoadd']));
+  try {
+    $success = $sth->execute(array(':group_id'=>$_POST['group_id'], ':usertoadd'=>$_POST['usertoadd'], ':writer'=>isset($_POST['writer']) ? 1 : 0));
+  } catch (PDOException $e) {
+    $success = 0;
+  }
   if ($success) {
     header ("Location: admingroupchange.php?group_id={$_POST['group_id']}&group_updated={$_POST['localpart']}");
   } else {
Only in vexim/images: checked.png
Only in vexim/images: unchecked.png
diff -ur vexim.orig/locale/ru/LC_MESSAGES/ru.po vexim/locale/ru/LC_MESSAGES/ru.po
--- vexim.orig/locale/ru/LC_MESSAGES/ru.po
+++ vexim/locale/ru/LC_MESSAGES/ru.po
@@ -357,11 +357,15 @@
 msgid "Edit group"
 msgstr "Редактировать группу"

-#: admingroupchange.php:89
+#: admingroupchange.php:89 admingroupchange.php:193
+msgid "Writer"
+msgstr "Писатель"
+
+#: admingroupchange.php:91
 msgid "Real name"
 msgstr "Настоящее имя"

-#: admingroupchange.php:90 adminuserchange.php:79 userchange.php:40
+#: admingroupchange.php:92 adminuserchange.php:79 userchange.php:40
 msgid "Email Address"
 msgstr "Почтвый адрес"

diff -ur vexim.orig/locale/template.pot vexim/locale/template.pot
--- vexim.orig/locale/template.pot
+++ vexim/locale/template.pot
@@ -346,11 +346,15 @@
 msgid "Edit group"
 msgstr ""

-#: admingroupchange.php:89
+#: admingroupchange.php:89 admingroupchange.php:193
+msgid "Writer"
+msgstr ""
+
+#: admingroupchange.php:91
 msgid "Real name"
 msgstr ""

-#: admingroupchange.php:90 adminuserchange.php:79 userchange.php:40
+#: admingroupchange.php:92 adminuserchange.php:79 userchange.php:40
 msgid "Email Address"
 msgstr ""

diff -ur docs.orig/debian-conf.d/router/250_vexim_virtual_domains docs/debian-conf.d/router/250_vexim_virtual_domains
--- docs.orig/debian-conf.d/router/250_vexim_virtual_domains
+++ docs/debian-conf.d/router/250_vexim_virtual_domains
@@ -82,20 +82,30 @@
   allow_fail
   senders = ${if eq{Y}{${lookup mysql{select g.is_public \
                                       from groups g, domains d \
-                                      where d.enabled = '1' and d.domain = '${quote_mysql:$domain}' and \
-                                            d.domain_id = g.domain_id and g.enabled = '1' and \
+                                      where d.enabled = 1 and d.domain = '${quote_mysql:$domain}' and \
+                                            d.domain_id = g.domain_id and g.enabled = 1 and \
                                             g.name = '${quote_mysql:$local_part}'}}} \
                  {$sender_address} \
-                 {${lookup mysql{select concat_ws('@', u.localpart, d.domain) \
+                 {${lookup mysql{select u.username \
                                  from domains d, groups g, group_contents c, users u \
-                                 where d.enabled = '1' and d.domain = '${quote_mysql:$domain}' and \
+                                 where d.enabled = 1 and d.domain = '${quote_mysql:$domain}' and \
                                        d.domain_id = g.domain_id and g.name = '${quote_mysql:$local_part}' and \
-                                       g.enabled = '1' and \
-                                       g.is_public = 'N' and c.member_id = u.user_id and \
-                                       d.domain_id = u.domain_id and u.enabled = '1' \
-                                       and u.username = '${quote_mysql:$sender_address}' limit 1}}}}
+                                       g.enabled = 1 and g.id = c.group_id and \
+                                       g.is_public = 'N' and c.writer = 1 and c.member_id = u.user_id and \
+                                       d.domain_id = u.domain_id and u.enabled = 1 and \
+                                       u.username = '${quote_mysql:$sender_address}' \
+                                 union \
+                                 select a.username \
+                                 from domains d, groups g, group_contents c, users u, users a \
+                                 where d.enabled = 1 and d.domain = '${quote_mysql:$domain}' and \
+                                       d.domain_id = g.domain_id and g.name = '${quote_mysql:$local_part}' and \
+                                       g.enabled = 1 and g.id = c.group_id and \
+                                       g.is_public = 'N' and c.writer = 1 and c.member_id = u.user_id and \
+                                       d.domain_id = u.domain_id and u.enabled = 1 and a.enabled = 1 and \
+                                       a.type = 'alias' and a.username = '${quote_mysql:$sender_address}' and \
+                                       a.smtp = u.username }}}}
   data = ${lookup mysql{ \
-            select concat_ws('@', u.localpart, d.domain) \
+            select u.username \
             from domains d, groups g, group_contents c, users u \
             where d.enabled     = '1'           and \
                   d.domain      = '${quote_mysql:$domain}'   and \
diff -urN setup.orig/migrations/vexim_2.3_to_2.3.1_mysql.sql setup/migrations/vexim_2.3_to_2.3.1_mysql.sql
--- setup.orig/migrations/vexim_2.3_to_2.3.1_mysql.sql
+++ setup/migrations/vexim_2.3_to_2.3.1_mysql.sql
@@ -0,0 +1,5 @@
+--
+-- MySQL script to upgrade Vexim database schema from Vexim 2.3 to Vexim 2.3.1
+--
+
+ALTER TABLE `group_contents` ADD COLUMN `writer` tinyint(1) NOT NULL DEFAULT '1';
diff -urN setup.orig/mysql.sql setup/mysql.sql
--- setup.orig/mysql.sql
+++ setup/mysql.sql
@@ -177,6 +177,7 @@
 CREATE TABLE `group_contents` (
   `group_id` int(10) unsigned NOT NULL,
   `member_id` int(10) unsigned NOT NULL,
+  `writer` tinyint(1) NOT NULL DEFAULT '1',
   PRIMARY KEY (`group_id`, `member_id`),
   INDEX `fk_group_contents_group_id_idx` (`group_id`),
   INDEX `fk_group_contents_member_id_idx` (`member_id`),
diff -urN setup.orig/pgsql.sql setup/pgsql.sql
--- setup.orig/pgsql.sql
+++ setup/pgsql.sql
@@ -189,6 +189,7 @@
 CREATE TABLE "group_contents" (
   "group_id" int NOT NULL,
   "member_id" int NOT NULL,
+  "writer" smallint NOT NULL DEFAULT '1' CHECK("smallint" BETWEEN 0 AND 1),
   PRIMARY KEY ("group_id","member_id"));
 CREATE INDEX "fk_group_contents_group_id_idx" ON "group_contents" ("group_id");
 CREATE INDEX "fk_group_contents_member_id_idx" ON "group_contents" ("member_id");
Udera commented 6 months ago

Not sure about this feature, why not using a mailinglist (we have all the transports for mailman). It has much more options and integrates error handling (user gets a response about message status), ...

VVD commented 6 months ago

why not using a mailinglist

What "mailinglist"? Integration with mailman?

rimas-kudelis commented 6 months ago

why not using a mailinglist

What "mailinglist"? Integration with mailman?

That's what Udera's comment says, no?

VVD commented 6 months ago

I didn't understand his comment. My english is poor.

runout-at commented 6 months ago

Actually I did never use the group feature of vexim.

Mailman is a full blown real Mailing List System, not just a feature to address some mail addresses which are in a grouping.

Mailman2 was a good choice for mailing lists and not quite small. This has changed a lot in Mailman3 which needs a lot more resources and is overblown for my needs. When I tested it some years ago there were no easy migration path from MM2 to MM3 for existing lists.

Another good piece of software is mlmmj which is minimalistic and good choice if you don't need too many features. It integrates easily with Exim. Since I switched from MM2 to mlmmj I wrote a small API to manage mlmmj as I had the need to feed it automatically from a database: https://gitlab.com/runout/mlmmjapi

VVD commented 6 months ago

For more than a decade, the built-in group capabilities of vexim were enough for me. But a year ago I needed groups in which most of the participants were read-only. I don't need anything else from groups.