diff --git a/ql-web/trunk/lang/de.hdf b/ql-web/trunk/lang/de.hdf index 046b4e8..13236cd 100644 --- a/ql-web/trunk/lang/de.hdf +++ b/ql-web/trunk/lang/de.hdf @@ -25,21 +25,14 @@ Lang { Buttons { Password = Passwort aendern AddForward = Weiterleitung hinzufuegen - DelForward = Weiterleitung entfernen + DelForward = Weiterleitung(en) entfernen Filter = Einstellung speichern Vacation = Einstellung speichern } - Options { - filter_on = Aktiviere den Spam-Filter - spam_move = Verschiebe Spam in ein eigenes Verzeichnis - vacation_on = Aktivieren Abwesenheits-Benachrichtigung - } - - Misc { - NewForwardAddress = Neue Weiterleitungsadresse + NewForward = Neue Weiterleitungsadresse VacationText = Benachrichtigungstext Password = Mailaccount-Passwort OldPassword = Altes Passwort @@ -52,6 +45,12 @@ Lang { StatusSpamNone = eingehende Nachrichten werden nicht auf Spam geprueft StatusSpamMark = Spam wird markiert StatusSpamMove = Spam wird in das Spam-Verzeichnis verschoben + Vacation = Abwesenheitsbenachrichtigung versenden + VacationText = Inhalt der automatischen Abwesenheitsnachricht + ForwardCount = Anzahl der Mail-Weiterleitungen + NoForward = Keine Weiterleitungen + VacationEnabled = Abwesenheitsnachrichten werden versandt + VacationDisabled = Keine Abwesenhitsnachrichten } ErrorMessage { @@ -61,8 +60,18 @@ Lang { WarningMessage { - FilterConnfig = Die Filterungseinstellungen konnten nicht gespeichert werden! + LdapConnect = Fehler beim Zugriff auf den LDAP-Server! + FilterConfig = Die Filterungseinstellungen konnten nicht gespeichert werden! + AddForward = Die Weiterleitung konnte nicht aktiviert werden! + DelForward = Mindestens eine Weiterleitung konnte nicht entfernt werden! + ExistingForward = Diese Weiterleitung existiert bereits! WrongPassword = Das angegebene Passwort war nicht korrekt! + InvalidAddress = Die angegebene Mailadresse ist ungueltig! + EmptyAddress = Es wurde keine Mailadresse angegeben! + ForwardNotFound = Die Weiterleitung war nicht vorhanden! + EmptyVacationText = Der Abwesenheitstext darf nicht leer sein! + ToggleVacation = Das Aendern des Abwesenheitsmodus schlug fehl! + SetVacationText = Das Speichern der Abwesenheitsnachricht schlug fehl! } @@ -84,7 +93,8 @@ Lang { StatusForward = Weiterleitungen StatusVacation = Abwesenheitsbenachrichtigungen Password = Passwort aendern - Forward = Weiterleitungen verwalten + DelForward = Weiterleitung(en) entfernen + AddForward = Weiterleitungen hinzufuegen Filter = Spam-Filterung einrichten Vacation = Abwesenheitsbenachrichtigung einrichten } diff --git a/ql-web/trunk/ql-web.conf b/ql-web/trunk/ql-web.conf index dbe1eaa..bda9f34 100644 --- a/ql-web/trunk/ql-web.conf +++ b/ql-web/trunk/ql-web.conf @@ -13,6 +13,13 @@ $LDAP_HOST = 'ldap.sao'; # the string '_USERNAME_' will be replaced by the real username $LDAP_USER_DN = "cn=_USERNAME_,sc=mailAccount,ou=People,o=neofaxe,dc=systemausfall,dc=org"; -$LDAP_SPAM_MOVE = "/usr/local/bin/ifspamh spam-_USERNAME_\@systemausfall.org"; -$LDAP_SPAM_MARK = "/usr/local/bin/ifspamh spam-_USERNAME_\@systemausfall.org || /bin/true"; +#$LDAP_SPAM_MOVE = "/usr/local/bin/ifspamh spam-_USERNAME_\@systemausfall.org"; + +# spam filtering disables forwarding and local delivery (for spam) +# dot-qmail files will be used, if there +$LDAP_SPAM_MOVE = [ "deliveryProgramPath" => "/data/scripts/spam_moving.sh" ]; + +# for tagging spam, you need to turn off local delivery (no dot-qmail files, no maildir) +$LDAP_SPAM_MARK = [ "deliveryProgramPath" => "/data/scripts/spam_tagging.sh", + "deliveryMode" => "nolocal" ]; diff --git a/ql-web/trunk/ql-web.pl b/ql-web/trunk/ql-web.pl index f3b8af4..5f77760 100755 --- a/ql-web/trunk/ql-web.pl +++ b/ql-web/trunk/ql-web.pl @@ -13,6 +13,9 @@ use CGI; use IO::File; use Net::LDAP; +# Net::LDAP will care about base64 encoding for multiline ldap entries +#use MIME::Base64; + my $q = new CGI; $q->import_names('Q'); @@ -77,7 +80,7 @@ if ($action eq '' || $action eq 'overview') { $pagename = 'forward_form'; } elsif ($action eq 'forward_add') { # add a forwarding address - if (defined($q->param('options_forward_add_address'))) { + if (defined($q->param('fw_address'))) { $success = 'AddForward' if (&add_forward()); $pagename = 'forward_form'; } else { @@ -87,7 +90,7 @@ if ($action eq '' || $action eq 'overview') { } elsif ($action eq 'forward_del') { # remove a forwarding address # no selected address -> no error - if (defined($q->param('options_forward_del_address'))) { + if (defined($q->param('fw_delete'))) { $success = 'DelForward' if (&del_forward()); $pagename = 'forward_form'; } else { @@ -125,45 +128,201 @@ sub set_pagedata { $pagedata->setValue('Data.isSpamMove', &is_spam_move()? 1 : 0); $pagedata->setValue('Data.isSpamMark', &is_spam_mark()? 1 : 0); $pagedata->setValue('Data.UserName', $mail_user); + + # retrieve frowarding addresses + my $one_forward; + my $i = 0; + foreach $one_forward (&get_ldap_values('mailForwardingAddress')) { + $pagedata->setValue("Data.ForwardAddresses.$i", $one_forward); + $i++; + } + + my $vacation_text = &get_ldap_values('mailReplyText'); + # encoding is not necessary -> automatically done by Net::LDAP + #$vacation_text = MIME::Base64::decode_base64($vacation_text); + my $vacation_state = &compare_ldap_attr('deliveryMode', 'reply'); + $pagedata->setValue('Data.VacationText', $vacation_text); + $pagedata->setValue('Data.isVacation', $vacation_state? 1 : 0); } # --------------------------------------------------------------------------- -sub update_filter { - - my $ldif; - my $password = $q->param('pw'); - my $result; - my $ldap; +sub add_forward { my $user_dn = $LDAP_USER_DN; $user_dn =~ s/_USERNAME_/$mail_user/g; + my $password = $q->param('pw'); + my $new_forward = $q->param('fw_address'); + + if ($new_forward eq '') { + $warning = 'EmptyAddress'; + return (0==1); + } - $ldap = Net::LDAP->new($LDAP_HOST); - $result = $ldap->bind($user_dn, password => $password); + $new_forward =~ /^([\w\_\-\.]*\@[\w\_\-\.]*)/; + $new_forward = $1; + + if ($new_forward eq '') { + $warning = 'InvalidAddress'; + return (0==1); + } + + my $ldap = Net::LDAP->new($LDAP_HOST); + my $result = $ldap->bind($user_dn, password => $password); if ($result->is_error) { $warning = 'WrongPassword'; return (0==1); } - if ($q->param('filter_type') eq 'none') { - if (&is_spam_mark() || &is_spam_move()) { - $result = $ldap->modify($user_dn, delete => ['deliveryProgramPath']); + if (&compare_ldap_attr('mailForwardingAddress', $new_forward)) { + $warning = 'ExistingForward'; + $ldap->unbind; + return (0==1); + } + + $result = $ldap->modify($user_dn, add => { mailForwardingAddress => $new_forward }); + $ldap->unbind; + + if ($result->is_error) { + $warning = 'AddForward'; + return (0==1); + } else { + return (0==0); + } +} + +# --------------------------------------------------------------------------- + +sub del_forward { + my $user_dn = $LDAP_USER_DN; + $user_dn =~ s/_USERNAME_/$mail_user/g; + my $password = $q->param('pw'); + if ($q->param('fw_delete') eq '') { + $warning = 'EmptyAddress'; + return (0==1); + } + + my $ldap = Net::LDAP->new($LDAP_HOST); + my $result = $ldap->bind($user_dn, password => $password); + if ($result->is_error) { + $warning = 'WrongPassword'; + return (0==1); + } + + my $address; + my $successes = 0; + foreach $address ($q->param('fw_delete')) { + $address =~ /^([\w\_\-\.]*\@[\w\_\-\.]*)/; + $address = $1; + if ($address eq '') { + $warning = 'InvalidAddress' unless ($warning); + } else { + if (&compare_ldap_attr('mailForwardingAddress', $address)) { + $result = $ldap->modify($user_dn, + delete => { mailForwardingAddress => $address }); + if ($result->is_error) { + $warning = 'DelForward'; + } else { + $successes++; + } + return (0==1); + } else { + $warning = 'ForwardNotFound'; + } } + } + + $ldap->unbind; + return ($successes > 0); +} + +# --------------------------------------------------------------------------- + +sub update_vacation { + my $failure = 0; + my $user_dn = $LDAP_USER_DN; + $user_dn =~ s/_USERNAME_/$mail_user/g; + my $password = $q->param('pw'); + if (defined($q->param('vacation_enabled')) && ($q->param('vacation_text') eq '')) { + $warning = 'EmptyVacationText'; + return (0==1); + } + + my $ldap = Net::LDAP->new($LDAP_HOST); + my $result = $ldap->bind($user_dn, password => $password); + if ($result->is_error) { + $warning = 'WrongPassword'; + return (0==1); + } + + # set vacation state + $result = undef; + if (defined($q->param('vacation_enabled'))) { + $result = $ldap->modify($user_dn, add => [ deliveryMode => 'reply' ]) + unless (&compare_ldap_attr("deliveryMode", "reply")); + } else { + $result = $ldap->modify($user_dn, delete => { deliveryMode => 'reply' }) + if (&compare_ldap_attr("deliveryMode", "reply")); + } + if (defined($result) && ($result->is_error)) { + $warning = 'ToggleVacation'; + warn $result->error_text; + $failure = 1; + } + + # set vacation text + $result = undef; + # a multiline vacation text has to be base64 encoded + # we encode it without a trailing line feed + my $vacation_text = $q->param('vacation_text'); + # encoding is not necessary -> automatically done by Net::LDAP + #$vacation_text = MIME::Base64::encode_base64($vacation_text); + $ldap->modify($user_dn, delete => [ 'mailReplyText' ]); # may return an error + $result = $ldap->modify($user_dn, add => [ mailReplyText => $vacation_text ]) + unless ($vacation_text eq ''); + if (defined($result) && ($result->is_error)) { + $warning = 'SetVacationText'; + $failure = 1; + } + + $ldap->unbind; + return ($failure == 0); +} + +# --------------------------------------------------------------------------- + +sub update_filter { + my $ldif_move; + my $ldif_mark; + my $password = $q->param('pw'); + my $user_dn = $LDAP_USER_DN; + $user_dn =~ s/_USERNAME_/$mail_user/g; + + my $ldap = Net::LDAP->new($LDAP_HOST); + my $result = $ldap->bind($user_dn, password => $password); + if ($result->is_error) { + $warning = 'WrongPassword'; + return (0==1); + } + + $ldif_move = &substitute_username($LDAP_SPAM_MOVE); + $ldif_mark = &substitute_username($LDAP_SPAM_MARK); + + if ($q->param('filter_type') eq 'none') { + $result = $ldap->modify($user_dn, delete => { @$ldif_move }) + if (&is_spam_move()); + $result = $ldap->modify($user_dn, delete => { @$ldif_mark }) + if (&is_spam_mark()); } elsif ($q->param('filter_type') eq 'move') { if (!&is_spam_move()) { - $ldif = $LDAP_SPAM_MOVE; - $ldif =~ s/_USERNAME_/$mail_user/g; - $ldap->modify($user_dn, delete => [ 'deliveryProgramPath' ]) + $ldap->modify($user_dn, delete => { @$ldif_mark }) if (&is_spam_mark()); - $result = $ldap->modify($user_dn, add => { deliveryProgramPath => $ldif }); + $result = $ldap->modify($user_dn, add => $ldif_move); } } elsif ($q->param('filter_type') eq 'mark') { if (!&is_spam_mark()) { - $ldif = $LDAP_SPAM_MARK; - $ldif =~ s/_USERNAME_/$mail_user/g; - $ldap->modify($user_dn, delete => [ 'deliveryProgramPath' ]) + $ldap->modify($user_dn, delete => { @$ldif_move }) if (&is_spam_move()); - $result = $ldap->modify($user_dn, add => { deliveryProgramPath => $ldif }); + $result = $ldap->modify($user_dn, add => $ldif_mark); } } else { $error = 'ParameterMissing'; @@ -173,6 +332,7 @@ sub update_filter { if ($result->is_error) { $warning = 'FilterConfig'; + warn $result->error_text; return (0==1); } else { return (0==0); @@ -181,18 +341,71 @@ sub update_filter { # --------------------------------------------------------------------------- +sub update_password { + # TODO +} + +# --------------------------------------------------------------------------- + +sub substitute_username { + my ($input) = @_; + my $value; + my @array; + my $count = 0; + foreach $value (@$input) { + # substitute only values - not keys + if ($count == 0) { + $count++; + } else { + $value =~ s/_USERNAME_/$mail_user/g; + $count = 0; + } + push @array, $value; + } + return \@array; +} + +# --------------------------------------------------------------------------- + sub is_spam_move { - return &compare_ldap_attr('deliveryProgramPath', $LDAP_SPAM_MOVE); + my $key; + my $value; + my $count = 0; + my $failed = 0; + foreach $value (@$LDAP_SPAM_MOVE) { + if ($count == 0) { + $key = $value; + $count++; + } else { + $failed++ unless &compare_ldap_attr($key, $value); + $count = 0; + } + } + return ($failed == 0); } # --------------------------------------------------------------------------- sub is_spam_mark { - return &compare_ldap_attr('deliveryProgramPath', $LDAP_SPAM_MARK); + my $key; + my $value; + my $count = 0; + my $failed = 0; + foreach $value (@$LDAP_SPAM_MARK) { + if ($count == 0) { + $key = $value; + $count++; + } else { + $failed++ unless &compare_ldap_attr($key, $value); + $count = 0; + } + } + return ($failed == 0); } # --------------------------------------------------------------------------- +# values will get substituted (e.g. _USERNAME_ ...) sub compare_ldap_attr { my ($attr, $value) = @_; my $ldap = Net::LDAP->new($LDAP_HOST); @@ -203,7 +416,11 @@ sub compare_ldap_attr { $value =~ s/_USERNAME_/$mail_user/g; - $ldap->bind; + $result = $ldap->bind; + if ($result->is_error) { + $warning = 'LdapConnect' unless ($warning); + return (0==1); + } $result = $ldap->compare($user_dn, attr => $attr, value => $value); @@ -213,6 +430,40 @@ sub compare_ldap_attr { # --------------------------------------------------------------------------- +sub get_ldap_values { + my $attr = shift; + my $user_dn = $LDAP_USER_DN; + $user_dn =~ s/_USERNAME_/$mail_user/g; + + my $ldap = Net::LDAP->new($LDAP_HOST); + my $result = $ldap->bind; + if ($result->is_error) { + $warning = 'LdapConnect' if ($warning eq ''); + return (0==1); + } + + $result = $ldap->search( base => $user_dn, + scope => 'base', + filter => "($attr=*)", + attrs => [$attr]); + my $entry; + my @values; + # there will be only one entry + foreach $entry ($result->entries) { + @values = $entry->get_value($attr); + } + + $ldap->unbind; + + if (wantarray) { + return @values; + } else { + return $values[0]; + } +} + +# --------------------------------------------------------------------------- + sub load_hdf { # initialize the data for clearsilver my $hdf = ClearSilver::HDF->new(); diff --git a/ql-web/trunk/template/forward_form.cs b/ql-web/trunk/template/forward_form.cs index 996ba72..e30197f 100644 --- a/ql-web/trunk/template/forward_form.cs +++ b/ql-web/trunk/template/forward_form.cs @@ -2,20 +2,42 @@

+ 0 ?>
- +
- + + +
+ +
+ + +
+ + +
+ + +
diff --git a/ql-web/trunk/template/overview.cs b/ql-web/trunk/template/overview.cs index 59346f6..b64fa59 100644 --- a/ql-web/trunk/template/overview.cs +++ b/ql-web/trunk/template/overview.cs @@ -4,7 +4,13 @@
-

noch nicht implementiert

+

+ 0 ?> + : + + + +

@@ -17,5 +23,11 @@
-

noch nicht implementiert

+

+ + + + + +

diff --git a/ql-web/trunk/template/vacation_form.cs b/ql-web/trunk/template/vacation_form.cs index 3e02b41..59ac74d 100644 --- a/ql-web/trunk/template/vacation_form.cs +++ b/ql-web/trunk/template/vacation_form.cs @@ -7,11 +7,17 @@
    -
  • noch nicht implementiert
  • - +
  • checked="checked" /> +
  • +
  • +
    • + +
  • +
  • +