diff --git a/TODO b/TODO index f342e42..9b672c8 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,5 @@ Reply-To-Option -Listen-Auswahl fuer Einsende/Mod/...-Modi (moderiert & offen / newsletter / ...) - Infos fuer Massen-Hosting: http://www.fbis.ch/index-de.php?page=14&frameset=4 diff --git a/changelog b/changelog index 228f4cf..9911d58 100644 --- a/changelog +++ b/changelog @@ -7,6 +7,7 @@ Version 3.2 - 04/14/02006 * support for listing of subscription log * a prefix for the local part of mailing list addresses is now configurable * user-specific interface selection (easy/default/expert) + * simplified rules for subscribing, posting and archive access * support for more ezmlm-idx: 'headerkeep', 'mimekeep' and 'copylines' * script for creating binary suid wrappers added * handling of empty settings for ezmlm-idx 5.0 fixed (closes #21) diff --git a/ezmlm-web.cgi b/ezmlm-web.cgi index a269187..1bbc38f 100755 --- a/ezmlm-web.cgi +++ b/ezmlm-web.cgi @@ -842,8 +842,12 @@ sub set_pagedata_misc_configfiles { # Get the contents of some important files $item = $list->getpart('prefix'); $pagedata->setValue("Data.List.Prefix", "$item"); + + # check reply_to setting $item = $list->getpart('headeradd'); $pagedata->setValue("Data.List.HeaderAdd", "$item"); + $pagedata->setValue("Data.List.Options.special_replytoself", 1) + if (&is_reply_to_self("$item")); # 'headerremove' is ignored if 'headerkeep' exists (since ezmlm-idx v5) if ((Mail::Ezmlm->get_version() >= 5.1) &&(-e $list->thislist() . "/headerkeep")) { @@ -1003,7 +1007,10 @@ sub set_pagedata4options { while ($key =~ m/\w/) { # scan the first part of the options string for lower case letters $state = ($options =~ /^\w*$key\w*\s*/); + # set the lower case option $pagedata->setValue("Data.List.Options." . $key , ($state)? 1 : 0); + # also set the reverse value - see cs macro "check_active_selection" + $pagedata->setValue("Data.List.Options." . uc($key) , ($state)? 0 : 1); $i++; $key = lc(substr($options,$i,1)); } @@ -1609,6 +1616,8 @@ sub extract_options_from_params { ################ options ################ $i = 0; $old_key = substr($old_options,$i,1); + # some special selections + my @avail_selections = ('archive', 'subscribe', 'posting'); # parse the first part of the options string while ($old_key =~ m/\w/) { # scan the first part of the options string for lower case letters @@ -1624,7 +1633,17 @@ sub extract_options_from_params { } else { $options .= 'X'; } + } elsif (defined($q->param('available_option_' . uc($old_key)))) { + # inverted checkbox + my $form_var_name = "option_" . uc($old_key); + # this option was visible for the user + if (defined($q->param($form_var_name))) { + $options .= uc($old_key); + } else { + $options .= lc($old_key); + } } elsif (defined($q->param('available_option_' . lc($old_key)))) { + # non inverted checkbox my $form_var_name = "option_" . lc($old_key); # this option was visible for the user if (defined($q->param($form_var_name))) { @@ -1632,6 +1651,12 @@ sub extract_options_from_params { } else { $options .= uc($old_key); } + } elsif (&is_option_in_selections(lc($old_key))) { + # enabled due to some special selection + $options .= lc($old_key); + } elsif (&is_option_in_selections(uc($old_key))) { + # disabled due to some special selection + $options .= uc($old_key); } elsif ("cevz" =~ m/$old_key/i) { # ignore invalid settings (the output of "getconfig" is really weird!) } else { @@ -1914,6 +1939,7 @@ sub update_config { # update trailing text if (defined($q->param('trailing_text'))) { if (defined($q->param('option_t'))) { + # TODO: the trailer _must_ be followed by a newline $list->set_text_content('trailer', $q->param('trailing_text')); } else { # ezmlm-make automatically removes this file @@ -1948,8 +1974,30 @@ sub update_config { if (defined($q->param('mimereject'))); # Update headeradd if this option is visible - $list->setpart('headeradd', $q->param('headeradd')) - if (defined($q->param('headeradd'))); + # afterwards we will care about a single 'options_special_replytoself' + if (defined($q->param('headeradd')) + || defined($q->param('available_option_special_replytoself'))) { + my $headers; + if (defined($q->param('headeradd'))) { + $headers = $q->param('headeradd'); + } else { + $headers = $list->getpart('headeradd'); + } + chomp($headers); + if (defined($q->param('available_option_special_replytoself'))) { + if (!defined($q->param('option_special_replytoself')) + && (&is_reply_to_self("$headers"))) { + # remove the header line + $headers =~ s/^Reply-To:\s+.*$//m; + } elsif (defined($q->param('option_special_replytoself')) + && (!&is_reply_to_self("$headers"))) { + # add the header line + chomp($headers); + $headers .= "\nReply-To: <#l#>@<#h#>"; + } + } + $list->setpart('headeradd', "$headers"); + } # update headerremove/keep if ($q->param('headerfilter_action') eq "remove") { @@ -2025,6 +2073,34 @@ sub update_config { # ------------------------------------------------------------------------ +sub is_reply_to_self { + # check if the header lines of the list contain a reply-to-self line + + my ($header_lines) = @_; + return (0==0) if ($header_lines =~ m/^Reply-To:\s+<#l#>@<#h#>/m); + return (1==0); +} + +# ------------------------------------------------------------------------ + +sub is_option_in_selections { + # check if the given 'key' is defined in any of the special selection + # form fields ('archive', 'subscribe', 'posting'). Case for key matters! + + my $key = shift; + my @avail_selections = ('archive', 'subscribe', 'posting'); + my $one_selection; + + foreach $one_selection (@avail_selections) { + my $form_name = "selection_$one_selection"; + return (0==0) if (defined($q->param($form_name)) + && ($q->param($form_name) =~ m/$key/)); + } + return (1==0); +} + +# ------------------------------------------------------------------------ + sub update_webusers { # replace existing webusers-line or add a new one diff --git a/lang/de.hdf b/lang/de.hdf index 62251a5..f3517ea 100644 --- a/lang/de.hdf +++ b/lang/de.hdf @@ -25,10 +25,10 @@ Lang { ListSelect = Auswahl einer Liste Properties = Eigenschaften von Language = Sprache - Interface = Interface + Interface = Oberfläche Help = Hilfe (extern) SubscribeLog = Einschreibungen - DomainSelect = Choose a domain + DomainSelect = Auswahl einer Domain } Title { ConfigMain = Listeneinstellungen @@ -52,9 +52,9 @@ Lang { GnupgConvert = Verschlüsselung GnupgPublic = Öffentliche Schlüssel GnupgSecret = Private Schlüssel - GnupgGenerate = Erzeugen eines Schlüssels + GnupgGenerateKey = Erzeugen eines Schlüssels GnupgOptions = Verschlüsselungseinstellungen - DomainSelect = Choose a domain + DomainSelect = Auswahl einer Domain } Buttons { Create = Erzeuge die Liste @@ -148,7 +148,7 @@ Lang { d = Aktiviere die Zusammenfassungsliste f = Füge ein Präfix zum Betreff der ausgehenden Mails hinzu g = Verweigere unbekannten NutzerInnen den Zugriff auf das Archiv - h = Bei der Einschreibung in die Liste ist keine Bestätigungsmail + h = Bei der Einschreibung in die Liste ist keine Bestätigungsmail erforderlich. i = Indiziere die Nachrichten zur Veröffentlichung im Internet (z.B. mit ezmlm-www) j = Beim Austragen aus der Liste ist keine Bestätigungsmail erforderlich k = Beachte die Ablehnungsliste bei der Verarbeitung von Mails @@ -163,11 +163,39 @@ Lang { t = Hänge eine Signatur an jede versandte Nachricht u = Nur Einsendungen von AbonnentInnen werden akzeptiert (für moderierte Listen: akzeptiere alle Einsendungen von AbonnentInnen) w = Entferne den Aufruf von ezmlm-warn aus den Verarbeitungsregeln (für sehr spezielle Konfigurationen) - x = Reset the list of to be stripped mime types to its default value + x = Setze die Liste der zu entfernenden MIME-Typen auf den Startwert zurück y = Fordere eine Bestätigung für jede eingesandte Nachricht an gnupg_plain_without_key = Sende Nachrichten im Klartext an Empfänger ohne Schlüssel gnupg_sign_messages = Signiere ausgehende Nachrichten mit dem Listenschlüssel } + Selections { + archive = Das Archiv ist zugänglich für + archive { + bg = AdministratorInnen + Bg = AbonnentInnen und AdministratorInnen + BG = jede/r + } + subscribe = Öffentliche Einschreibung ist + subscribe { + pS = offen + ps = moderiert + P = nicht erlaubt + } + posting = Einsendungen sind + posting { + MOU = offen für jede/n + mOU = moderiert für jede/n + mOu = offen für AbonnentInnen und moderiert für alle anderen + MOu = offen für AbonnentInnen + moU = offen nur für ModeratorInnen + } + confirmation = Bestätigungsmails werden benötigt für + confirmation { + H = Einschreibung + J = Austragung + y = Einsendung + } + } Settings { 0 = Diese Liste ist die Unterliste einer anderen 3 = Definiere die Absender-Adresse ausgehender Mails @@ -186,15 +214,15 @@ Lang { ListName = Name der Liste ListAddress = Addresse der Liste ListOptions = Grundlegende Einstellungen - AllowedToEdit = Users allowed to edit this list via web interface - HeaderFiltering = Header filtering - HeaderRemove = strip these header lines - HeaderKeep = keep only these header lines + AllowedToEdit = Nutzer, die diese Liste per Web-Interface konfigurieren dürfen + HeaderFiltering = Kopfzeilen-Filterung + HeaderRemove = entferne die folgenden Kopfzeilen + HeaderKeep = behalte nur die folgenden Kopfzeilen HeaderAdd = hinzuzufügende Kopfzeilen - MimeTypeExamples = Show some example mime types - MimeFiltering = Mime type filtering (for multipart mails) - MimeRemove = strip these from all messages - MimeKeep = keep only these in messages + MimeTypeExamples = Zeige einige Beispiel-MIME-Typen + MimeFiltering = MIME-Typ-Filterung (für mehrteilige Mails) + MimeRemove = entferne diese von allen Nachrichten + MimeKeep = erhalte nur diese in den Nachrichten MimeReject = Nachrichten, die einen der folgenden Datentypen enthalten, werden abgewiesen EditFileInfo { CommonTags = allgemeine Platzhalter @@ -234,13 +262,13 @@ Lang { GnupgKeySize = Schlüssellänge (in Bytes) GnupgKeyExpires = Verfallsdatum (in Jahren) Never = nie - NoDomainsAvailable = No domains are available. - CopyLinesEnabled = Add some lines of every original message to automatic replies - CopyLinesNumber = number of lines + NoDomainsAvailable = Es sind keine Domains vorhanden. + CopyLinesEnabled = Hänge ein paar Zeilen der Original-Nachricht an jede automatische Antwort + CopyLinesNumber = Anzahl von Zeilen Interfaces { - easy = basic - normal = default - expert = expert + easy = einfach + normal = normal + expert = erweitert } } Introduction { @@ -263,6 +291,8 @@ Lang { GnupgConvert = Du kannst eine normale Mailingliste in eine verschlüsselte umwandeln und umgekehrt. GnupgGenerateKey = Um eine verschlüsselte Mailingliste verwenden zu können, ist es erforderlich, einen Schlüssel für die Liste zu erzeugen (oder zu importieren). Nachdem du das folgende Formular ausgefüllt und abgeschickt hast, wird es eine Weile (bis zu mehreren Minuten) dauern, bis der Schlüssel fertig ist. Sei also bitte geduldig. GnupgOptions = Konfiguriere die Einstellungen der verschlüsselten Mailingliste. + GnupgSecret = Every every mailing list needs a secret key to decrypt incoming. You should take care that the secret key is kept safe. Otherwise the security of your mailing list is broken. + GnupgPublic = There should be a public key for every subscriber of the mailing list. Additionally there is the key of the mailing list, which should be distributed to all subscribers. It is safe to openly publish public keys. } Legend { ConfigAdmin = Fern-Administrations-Rechte @@ -292,6 +322,6 @@ Lang { GnupgKeyImport = Schlüssel importieren GnupgGenerateKey = Schlüssel der Liste erzeugen GnupgOptions = Verschlüsselungseinstellungen - AvailableDomains = Available domains + AvailableDomains = Verfügbare Domains } } diff --git a/lang/en.hdf b/lang/en.hdf index d4e2816..91fec5a 100644 --- a/lang/en.hdf +++ b/lang/en.hdf @@ -56,7 +56,7 @@ Lang { GnupgConvert = Encryption GnupgPublic = Public keys GnupgSecret = Secret keys - GnupgGenerate = Generate a new keypair + GnupgGenerateKey = Generate a new keypair GnupgOptions = Encryption settings DomainSelect = Choose a domain } @@ -179,9 +179,32 @@ Lang { w = Remove the ezmlm-warn invocations from the list setup (rarely useful) x = Reset the list of to be stripped mime types to its default value y = Request a confirmation mail for every posted message + special_replytoself = Redirect replies to the list gnupg_plain_without_key = Send plaintext to the subscribers which have no key gnupg_sign_messages = Sign outgoing messages with the list's key } + + + Selections { + archive = Access to the archive is granted for + archive.bg = administrators + archive.Bg = subscribers and administrators + archive.BG = everyone + subscribe = Public subscription is + subscribe.pS = open + subscribe.ps = moderated + subscribe.P = not allowed + posting = Posting is + posting.MOU = allowed for everyone + posting.mOU = moderated for everyone + posting.mOu = allowed for subscribers and moderated for others + posting.MOu = allowed for subscribers + posting.moU = allowed only for moderators + confirmation = Confirmation mails are required for + confirmation.H = subscription + confirmation.J = unsubscription + confirmation.y = posting + } Settings { @@ -282,6 +305,8 @@ Lang { GnupgConvert = You can convert a normal mailinglist to an encrypted list and vice versa. GnupgGenerateKey = Every encrypted mailing list needs a secret key. You can import this key or create it using the form below. After submitting the form, you have to be patient, as it takes some time (up to several minutes) to create a key. GnupgOptions = Configure some useful settings of the encrypted mailing list. + GnupgSecret = Every every mailing list needs a secret key to decrypt incoming. You should take care that the secret key is kept safe. Otherwise the security of your mailing list is broken. + GnupgPublic = There should be a public key for every subscriber of the mailing list. Additionally there is the key of the mailing list, which should be distributed to all subscribers. It is safe to openly publish public keys. } Legend { diff --git a/scripts/update_language_files.py b/scripts/update_language_files.py index 71fc191..3c76999 100755 --- a/scripts/update_language_files.py +++ b/scripts/update_language_files.py @@ -1,3 +1,7 @@ +#!/bin/sh +# TODO: remove this header as soon as the demo-uml has python +exit + #!/usr/bin/env python #-*- coding: utf-8 -*- # diff --git a/template/config_options/archive_access.cs b/template/config_options/archive_access.cs new file mode 100644 index 0000000..a98d373 --- /dev/null +++ b/template/config_options/archive_access.cs @@ -0,0 +1,3 @@ + + + diff --git a/template/config_options/confirm_selection.cs b/template/config_options/confirm_selection.cs new file mode 100644 index 0000000..bf0df87 --- /dev/null +++ b/template/config_options/confirm_selection.cs @@ -0,0 +1,3 @@ + + + diff --git a/template/config_options/lang_select.cs b/template/config_options/lang_select.cs index eec83d1..79147cc 100644 --- a/template/config_options/lang_select.cs +++ b/template/config_options/lang_select.cs @@ -8,8 +8,8 @@ 0 ?> @@ -18,8 +18,8 @@ diff --git a/template/config_options/posting_selection.cs b/template/config_options/posting_selection.cs new file mode 100644 index 0000000..1b86b9c --- /dev/null +++ b/template/config_options/posting_selection.cs @@ -0,0 +1,3 @@ + + + diff --git a/template/config_options/reply_to_self.cs b/template/config_options/reply_to_self.cs new file mode 100644 index 0000000..ed880f7 --- /dev/null +++ b/template/config_options/reply_to_self.cs @@ -0,0 +1,3 @@ + + + diff --git a/template/config_options/subscribe_selection.cs b/template/config_options/subscribe_selection.cs new file mode 100644 index 0000000..fde8920 --- /dev/null +++ b/template/config_options/subscribe_selection.cs @@ -0,0 +1,3 @@ + + + diff --git a/template/interface_select.cs b/template/interface_select.cs index dd309e4..6b02c7c 100644 --- a/template/interface_select.cs +++ b/template/interface_select.cs @@ -1,4 +1,4 @@ - + 0 ?> diff --git a/template/macros.cs b/template/macros.cs index 4f961af..f3f26b2 100644 --- a/template/macros.cs +++ b/template/macros.cs @@ -1,9 +1,10 @@ checked="checked" />