From eaacbeb2d5fece7fe9cab570f262a8f29be96863 Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Mon, 10 Sep 2012 20:01:06 +0200 Subject: Internationalization. --- lib/Fripost/Panel/Interface.pm | 128 +++++++++++++++++++++-------------------- lib/Fripost/Panel/Login.pm | 25 ++++---- 2 files changed, 81 insertions(+), 72 deletions(-) (limited to 'lib/Fripost/Panel') diff --git a/lib/Fripost/Panel/Interface.pm b/lib/Fripost/Panel/Interface.pm index 6859e57..0b7860e 100644 --- a/lib/Fripost/Panel/Interface.pm +++ b/lib/Fripost/Panel/Interface.pm @@ -15,6 +15,7 @@ use parent 'Fripost::Panel::Login'; use Fripost::Schema; use Fripost::Password; use HTML::Entities; +use Net::IDN::Encode qw/email_to_unicode/; # This method is called right before the 'setup' method below. It @@ -34,7 +35,7 @@ sub ListDomains : StartRunmode { my $self = shift; my %CFG = $self->cfg; - my ($ul,$ud) = split /\@/, $self->authen->username, 2; + my ($ul,$ud) = split /\@/, email_to_unicode($self->authen->username), 2; my $fp = Fripost::Schema->SASLauth( $self->authen->username, %CFG ); my @domains = $fp->domain->search( -concat => "\n", -die => 403); @@ -44,9 +45,12 @@ sub ListDomains : StartRunmode { , loop_context_vars => 1 , global_vars => 1 ); $template->param( url => $self->query->url - , user_localpart => $ul - , user_domainpart => $ud - , domains => [ @domains ] + , user_localpart => encode_entities($ul) + , user_domainpart => encode_entities($ud) + , domains => [ map { { domain => encode_entities($_->{domain}) + , isactive => $_->{isactive} + , description => $_->{description} } } + @domains ] ); return $template->output; } @@ -58,8 +62,9 @@ sub ListLocals : Runmode { my $self = shift; my %CFG = $self->cfg; - my ($ul,$ud) = split /\@/, $self->authen->username, 2; - my $d = (split /\//, $ENV{PATH_INFO}, 3)[1]; + my ($ul,$ud) = split /\@/, email_to_unicode($self->authen->username), 2; + my $d = decode_entities ((split /\//, $ENV{PATH_INFO}, 3)[1]); + Encode::_utf8_on($d); my $fp = Fripost::Schema::->SASLauth( $self->authen->username, %CFG ); # Query *the* matching domain @@ -79,10 +84,10 @@ sub ListLocals : Runmode { , global_vars => 1 ); $template->param( url => $self->query->url - , user_localpart => $ul - , user_domainpart => $ud + , user_localpart => encode_entities($ul) + , user_domainpart => encode_entities($ud) ); - $template->param( domain => $domain{domain} + $template->param( domain => encode_entities($domain{domain}) , isactive => $domain{isactive} , description => join ("\n", @{$domain{description}}) ); # Can the user edit the domain (change description, toggle @@ -95,10 +100,11 @@ sub ListLocals : Runmode { $template->param( listMailboxes => $#mailboxes >= 0 || $domain{permissions} =~ /p/ ); $template->param( mailboxes => [ - map { { user => $_->{user} + map { { user => encode_entities($_->{user}) , description => join ("\n", @{$_->{description}}) , isactive => $_->{isactive} - , forwards => [ map { {forward => $_} } @{$_->{forwards}} ] + , forwards => [ map { {forward => encode_entities($_)} } + @{$_->{forwards}} ] , quota => $_->{quota} }; } @@ -111,16 +117,16 @@ sub ListLocals : Runmode { $template->param( listAliases => $#aliases >= 0 || $domain{permissions} =~ /[aop]/ ); $template->param( aliases => [ - map { { alias => $_->{alias} + map { { alias => encode_entities($_->{alias}) , description => join ("\n", @{$_->{description}}) , isactive => $_->{isactive} - , destinations => [ map { {destination => $_} } + , destinations => [ map { {destination => encode_entities($_)} } @{$_->{maildrop}} ] }; } @aliases ]); - $template->param( catchalls => [ map { {catchall => $_} } + $template->param( catchalls => [ map { {catchall => encode_entities($_)} } @{$domain{catchalls}} ] , CAodd => not $#aliases % 2); @@ -129,7 +135,7 @@ sub ListLocals : Runmode { # Should we list lists? $template->param( listLists => $#lists >= 0 || $domain{permissions} =~ /[lop]/ ); $template->param( lists => [ - map { { list => $_->{list} + map { { list => encode_entities($_->{list}) , description => join ("\n", @{$_->{description}}) , isactive => $_->{isactive} , transport => $_->{transport} @@ -147,8 +153,9 @@ sub EditDomain : Runmode { my $self = shift; my %CFG = $self->cfg; - my ($ul,$ud) = split /\@/, $self->authen->username, 2; - my $d = (split /\//, $ENV{PATH_INFO}, 3)[1]; + my ($ul,$ud) = split /\@/, email_to_unicode($self->authen->username), 2; + my $d = decode_entities ((split /\//, $ENV{PATH_INFO}, 3)[1]); + Encode::_utf8_on($d); my $q = $self->query; return $self->redirect($q->url .'/') if defined $q->param('cancel'); @@ -172,9 +179,9 @@ sub EditDomain : Runmode { , loop_context_vars => 1 , global_vars => 1 ); $template->param( url => $q->url - , user_localpart => $ul - , user_domainpart => $ud - , domain => $d + , user_localpart => encode_entities($ul) + , user_domainpart => encode_entities($ud) + , domain => encode_entities($d) ); if ($error) { # Preserve the (incorrect) form @@ -188,7 +195,8 @@ sub EditDomain : Runmode { , description => join ("\x{0D}\x{0A}", @{$domain{description}}) , catchalls => join ("\x{0D}\x{0A}", - @{$domain{catchalls}}) ); + map { encode_entities ($_) } + @{$domain{catchalls}}) ); } $template->param( newChanges => defined $q->param('submit') ); return $template->output; @@ -201,8 +209,10 @@ sub EditLocal : Runmode { my $self = shift; my %CFG = $self->cfg; - my ($ul,$ud) = split /\@/, $self->authen->username, 2; + my ($ul,$ud) = split /\@/, email_to_unicode($self->authen->username), 2; my ($null,$d,$l,$crap) = split /\//, $ENV{PATH_INFO}, 4; + my $du = decode_entities ($d); Encode::_utf8_on($du); + my $lu = decode_entities ($l); Encode::_utf8_on($lu); my $q = $self->query; return $self->redirect($q->url.'/'.$d.'/') if defined $q->param('cancel'); @@ -210,8 +220,8 @@ sub EditLocal : Runmode { my $fp = Fripost::Schema::->SASLauth( $self->authen->username, %CFG ); # Search for *the* matching mailbox, alias or list. - my %local = $fp->local->get ($l, $d, -die => 404, - -concat => "\x{0D}\x{0A}"); + my %local = $fp->local->get ($lu.'@'.$du, -die => 404, + -concat => "\x{0D}\x{0A}"); die "Unknown type" unless grep { $local{type} eq $_ } qw/mailbox alias list/; @@ -220,17 +230,17 @@ sub EditLocal : Runmode { if (defined $q->param('a') and $q->param('a') eq 'delete') { # Delete the entry - $error = $fp->$t->delete($l, $d, -die => 0); + $error = $fp->$t->delete($lu.'@'.$du, -die => 0); unless ($error) { $fp->done; return $self->redirect($q->url .'/'. $d .'/'); } } - elsif (defined $q->param('submit')) { + if (defined $q->param('submit')) { # Changes have been submitted: process them my %entry; if ($t eq 'mailbox') { - $entry{user} = $l.'@'.$d; + $entry{user} = $lu.'@'.$du; $entry{forwards} = $q->param('forwards'); if ($q->param('oldpw') ne '' or @@ -250,13 +260,14 @@ sub EditLocal : Runmode { else { my $fp; eval { + my $u = email_to_unicode($self->authen->username); $fp = Fripost::Schema::->auth( - $self->authen->username, + $u, $q->param('oldpw'), ldap_uri => $CFG{ldap_uri}, ldap_suffix => $CFG{ldap_suffix}, -die => "Wrong password (for ‘" - .$self->authen->username."‘)." ); + .encode_entities($u)."‘)." ); }; $error = $@ || $fp->mailbox->passwd( $entry{user}, @@ -267,66 +278,60 @@ sub EditLocal : Runmode { } } elsif ($t eq 'alias') { - $entry{alias} = $l.'@'.$d; + $entry{alias} = $lu.'@'.$du; $entry{maildrop} = $q->param('maildrop'); } elsif ($t eq 'list') { - $entry{list} = $l.'@'.$d; + $entry{list} = $lu.'@'.$du; $entry{transport} = $q->param('transport'); } - else { - # Unknown type - return $self->redirect($q->url .'/'. $d .'/'); - } $entry{isactive} = $q->param('isactive'); $entry{description} = $q->param('description'); $error = $fp->$t->replace( \%entry, -concat => "(\n|\x{0D}\x{0A})") unless $error; } - $fp->done; - my $template = $self->load_tmpl( "edit-$t.html", cache => 1, utf8 => 1 ); $template->param( url => $q->url - , user_localpart => $ul - , user_domainpart => $ud - , domain => $d + , user_localpart => encode_entities($ul) + , user_domainpart => encode_entities($ud) + , domain => encode_entities($du) ); if ($error and defined $q->param('submit')) { # Preserve the (incorrect) form, except the passwords - if ($local{type} eq 'mailbox') { - $template->param( user => $l + if ($t eq 'mailbox') { + $template->param( user => encode_entities($l) , forwards => $q->param('forwards') ); } - elsif ($local{type} eq 'alias') { - $template->param( alias => $l + elsif ($t eq 'alias') { + $template->param( alias => encode_entities($l) , maildrop => $q->param('maildrop') ); } - elsif ($local{type} eq 'list') { - $template->param( list => $l ); - } - else { - die "Unknown type"; + elsif ($t eq 'list') { + $template->param( list => encode_entities($l) ); } $template->param( isactive => $q->param('isactive') , description => $q->param('description') ); } else { + %local = $fp->local->get ($lu.'@'.$du, -die => 404, + -concat => "\x{0D}\x{0A}"); if ($t eq 'mailbox') { - $template->param( user => $local{user} - , forwards => $local{forwards} ); + $template->param( user => encode_entities($local{user}) + , forwards => encode_entities($local{forwards}) ); } elsif ($t eq 'alias') { - $template->param( alias => $local{alias} - , maildrop => $local{maildrop} ); + $template->param( alias => encode_entities($local{alias}) + , maildrop => encode_entities($local{maildrop}) ); } elsif ($t eq 'list') { - $template->param( list => $local{list} ); + $template->param( list => encode_entities($local{list}) ); } $template->param( isactive => $local{isactive} , description => $local{description} ); } + $fp->done; my $news = (defined $q->param('submit') or (defined $q->param('a') and $q->param('a') eq 'delete')); $template->param( newChanges => $news ); @@ -343,8 +348,9 @@ sub AddLocal : Runmode { my $self = shift; my %CFG = $self->cfg; - my ($ul,$ud) = split /\@/, $self->authen->username, 2; + my ($ul,$ud) = split /\@/, email_to_unicode($self->authen->username), 2; my $d = (split /\//, $ENV{PATH_INFO}, 3)[1]; + my $du = decode_entities ($d); Encode::_utf8_on($du); my $q = $self->query; return $self->redirect($q->url.'/'.$d.'/') if defined $q->param('cancel'); @@ -355,7 +361,7 @@ sub AddLocal : Runmode { # Changes have been submitted: process them my %entry; if ($t eq 'mailbox') { - $entry{user} = $q->param('user').'@'.$d; + $entry{user} = $q->param('user').'@'.$du; $entry{forwards} = $q->param('forwards'); if ($q->param('password') ne $q->param('password2')) { $error = "Passwords do not match"; @@ -371,11 +377,11 @@ sub AddLocal : Runmode { # TODO: inherit the quota from the postmaster's? } elsif ($t eq 'alias') { - $entry{alias} = $q->param('alias').'@'.$d; + $entry{alias} = $q->param('alias').'@'.$du; $entry{maildrop} = $q->param('maildrop'); } elsif ($t eq 'list') { - $entry{list} = $q->param('list').'@'.$d; + $entry{list} = $q->param('list').'@'.$du; $entry{transport} = $q->param('transport'); } else { @@ -395,9 +401,9 @@ sub AddLocal : Runmode { my $template = $self->load_tmpl( "add-$t.html", cache => 1, utf8 => 1 ); $template->param( url => $q->url - , user_localpart => $ul - , user_domainpart => $ud - , domain => $d + , user_localpart => encode_entities($ul) + , user_domainpart => encode_entities($ud) + , domain => encode_entities($du) ); if ($error) { # Preserve the (incorrect) form, except the passwords diff --git a/lib/Fripost/Panel/Login.pm b/lib/Fripost/Panel/Login.pm index 8dcfd2b..a147371 100644 --- a/lib/Fripost/Panel/Login.pm +++ b/lib/Fripost/Panel/Login.pm @@ -19,10 +19,10 @@ use CGI::Application::Plugin::Authentication; use CGI::Application::Plugin::Redirect; use CGI::Application::Plugin::ConfigAuto 'cfg'; -use Net::LDAP; -use Authen::SASL; +use Fripost::Schema; use File::Spec::Functions qw/catfile catdir/; use HTML::Entities; +use Net::IDN::Encode qw/email_to_ascii/; # This method is called right before the 'setup' method below. It @@ -56,19 +56,22 @@ sub cgiapp_init { $self->authen->config( DRIVER => [ 'Generic', sub { my ($u,$p) = @_; - my ($l,$d) = split /\@/, $u, 2; + my $d = (split /\@/, $u, 2)[1]; unless (defined $d) { $CFG{default_realm} // return 0; - $d = $CFG{default_realm}; - $u .= '@'.$d; + $u .= '@'.$CFG{default_realm}; } - my $bind_dn = "fvu=$l,fvd=$d,". join (',', @{$CFG{ldap_suffix}}); - - my $ldap = Net::LDAP->new( $CFG{ldap_uri} ); - my $mesg = $ldap->bind ( $bind_dn, password => $p ); - $ldap->unbind; - $mesg->code ? 0 : $u; + Encode::_utf8_on($u); + $u = Net::IDN::Encode::email_to_ascii($u); + my $fp = Fripost::Schema::->auth($u, $p, + ldap_uri => $CFG{ldap_uri}, + ldap_suffix => $CFG{ldap_suffix}, + -die => 0 + ); + return 0 unless defined $fp; + $fp->done; + return $u; } ], STORE => 'Session', LOGIN_RUNMODE => 'login', -- cgit v1.2.3