From 35c4ad13a52bdcaab251358e4b7df99dd852c76d Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Sun, 20 Jan 2013 03:04:17 +0100 Subject: New domains. --- lib/Fripost/Panel/Interface.pm | 157 +++++++++++++++++++++++++++++++---------- 1 file changed, 119 insertions(+), 38 deletions(-) (limited to 'lib/Fripost/Panel/Interface.pm') diff --git a/lib/Fripost/Panel/Interface.pm b/lib/Fripost/Panel/Interface.pm index d04fa3a..e4724d1 100644 --- a/lib/Fripost/Panel/Interface.pm +++ b/lib/Fripost/Panel/Interface.pm @@ -18,7 +18,8 @@ use Fripost::Schema::Util 'split_addr'; use Fripost::Password; use HTML::Entities 'encode_entities'; use URI::Escape::XS 'encodeURIComponent'; -use Net::IDN::Encode qw/email_to_unicode email_to_ascii/; +use Net::IDN::Encode qw/email_to_unicode email_to_ascii domain_to_ascii/; +use Encode; # This method is called right before the 'setup' method below. It @@ -38,8 +39,6 @@ sub ListDomains : StartRunmode { my $self = shift; my %CFG = $self->cfg; - my ($ul,$ud) = split_addr( $self->authen->username, -encode => 'unicode' ); - my $fp = Fripost::Schema::->SASLauth( $self->authen->username, %CFG ); my @domains = $fp->domain->search( -concat => "\n", -die => 403); $fp->done; @@ -49,6 +48,7 @@ sub ListDomains : StartRunmode { $template->param( $self->userInfo ); $template->param( domains => [ map { { &mkLink( domain => $_->{domain}) , isactive => $_->{isactive} + , ispending => $_->{ispending} , description => $_->{description} } } @domains ] ); @@ -62,10 +62,16 @@ sub ListLocals : Runmode { my $self = shift; my %CFG = $self->cfg; - my ($ul,$ud) = split_addr( $self->authen->username, -encode => 'unicode' ); my $d = ($self->split_path)[1]; my $fp = Fripost::Schema::->SASLauth( $self->authen->username, %CFG ); + my $q = $self->query; + if (defined $q->param('unlock') and $q->param('unlock') ne '') { + $fp->domain->unlock( $d, $q->param('unlock') ); + $fp->done; + return $self->redirect('../'); + } + # Query *the* matching domain my %domain = $fp->domain->get( $d, -die => 404 ); @@ -156,7 +162,6 @@ sub EditDomain : Runmode { my $self = shift; my %CFG = $self->cfg; - my ($ul,$ud) = split_addr( $self->authen->username, -encode => 'unicode' ); my $d = ($self->split_path)[1]; my $q = $self->query; @@ -169,11 +174,11 @@ sub EditDomain : Runmode { # Changes have been submitted: process them $error = $fp->domain->replace({ domain => $d, - isactive => $q->param('isactive'), - description => $q->param('description'), - catchalls => $q->param('catchalls'), - canAddAlias => $q->param('canAddAlias'), - canAddList => $q->param('canAddList') + isactive => $q->param('isactive') // 1, + description => $q->param('description') // undef, + catchalls => $q->param('catchalls') // undef, + canAddAlias => $q->param('canAddAlias') // undef, + canAddList => $q->param('canAddList') // undef }, -concat => "(\n|\x{0D}\x{0A})"); } my %domain = $fp->domain->get( $d, -die => 404 ); @@ -186,11 +191,11 @@ sub EditDomain : Runmode { , isPostmaster => $domain{permissions} eq 'p'); if ($error) { # Preserve the (incorrect) form - $template->param( isactive => $q->param('isactive') - , description => $q->param('description') - , catchalls => $q->param('catchalls') - , canAddAlias => $q->param('canAddAlias') - , canAddList => $q->param('canAddList') + $template->param( isactive => $q->param('isactive') // 1 + , description => $q->param('description') // undef + , catchalls => $q->param('catchalls') // undef + , canAddAlias => $q->param('canAddAlias') // undef + , canAddList => $q->param('canAddList') // undef , error => encode_entities ($error) ); } else { @@ -241,11 +246,11 @@ sub EditLocal : Runmode { my %entry; if ($t eq 'user') { $entry{user} = $l.'@'.$d; - $entry{forwards} = $q->param('forwards'); + $entry{forwards} = $q->param('forwards') // undef; - if ($q->param('oldpw') ne '' or - $q->param('newpw') ne '' or - $q->param('newpw2') ne '') { + if (($q->param('oldpw') // '') ne '' or + ($q->param('newpw') // '') ne '' or + ($q->param('newpw2') // '') ne '') { # If the user tries to change the password, we make her # bind first, to prevent an attacker from setting a # custom password and accessing the emails. @@ -263,13 +268,13 @@ sub EditLocal : Runmode { my $u = email_to_unicode($self->authen->username); $fp = Fripost::Schema::->auth( $u, - $q->param('oldpw'), + $q->param('oldpw') // '', %CFG, -die => "Wrong password (for ‘".$u."’)." ); }; $error = $@ || $fp->user->passwd( $entry{user}, - Fripost::Password::hash($q->param('newpw')) + Fripost::Password::hash($q->param('newpw') // '') ); $fp->done if defined $fp; } @@ -277,14 +282,14 @@ sub EditLocal : Runmode { } elsif ($t eq 'alias') { $entry{alias} = $l.'@'.$d; - $entry{maildrop} = $q->param('maildrop'); + $entry{maildrop} = $q->param('maildrop') // undef; } elsif ($t eq 'list') { $entry{list} = $l.'@'.$d; - $entry{transport} = $q->param('transport'); + $entry{transport} = $q->param('transport') // undef; } - $entry{isactive} = $q->param('isactive'); - $entry{description} = $q->param('description'); + $entry{isactive} = $q->param('isactive') // 1; + $entry{description} = $q->param('description') // undef; $error = $fp->$t->replace( \%entry, -concat => "(\n|\x{0D}\x{0A})") unless $error; } @@ -297,17 +302,17 @@ sub EditLocal : Runmode { # Preserve the (incorrect) form, except the passwords if ($t eq 'user') { $template->param( user => encode_entities($l) - , forwards => $q->param('forwards') ); + , forwards => $q->param('forwards') // undef ); } elsif ($t eq 'alias') { $template->param( alias => encode_entities($l) - , maildrop => $q->param('maildrop') ); + , maildrop => $q->param('maildrop') // undef ); } elsif ($t eq 'list') { $template->param( list => encode_entities($l) ); } - $template->param( isactive => $q->param('isactive') - , description => $q->param('description') ); + $template->param( isactive => $q->param('isactive') // 1 + , description => $q->param('description') // undef ); } else { %local = $fp->local->get ($l.'@'.$d, -die => 404, @@ -339,6 +344,82 @@ sub EditLocal : Runmode { return $template->output; } +sub AddDomain : Runmode { + my $self = shift; + my %CFG = $self->cfg; + + my $q = $self->query; + return $self->redirect('./') if defined $q->param('cancel'); # Cancellation + + my $fp = Fripost::Schema::->SASLauth( $self->authen->username, %CFG ); + my $domain = $q->param('domain'); + Encode::_utf8_on($domain) if defined $domain; + my $session_param; + $session_param = 'AddDomain-Postmasters-' . domain_to_ascii($domain) + if defined $domain; + + my $error; # Tells whether the change submission has failed. + if (defined $q->param('submit')) { + # Changes have been submitted: process them + + if (defined $q->param('postmaster') and defined $session_param) { + my @postmasters = split /\s*,\s*/, $self->session->param($session_param); + $error = "‘".$q->param('postmaster')."’ was not listed among the domain owners." + unless defined $self->session->param($session_param) + and grep { $q->param('postmaster') eq $_ } @postmasters; + } + + $error = $fp->domain->add({ + domain => $domain, + send_token_to => $q->param('postmaster') // undef, + isactive => $q->param('isactive') // 1, + description => $q->param('description') // undef, + catchalls => $q->param('catchalls') // undef }, + -concat => "(\n|\x{0D}\x{0A})", + '-dry-run' => not (defined $q->param('postmaster')), + -domainurl => $q->url.'/'.encode_entities($domain).'/' # TODO: try that in nginx + ) unless $error; + } + $fp->done; + + return $self->redirect('./') # Confirmation token sent, everything OK + if ($error // '') eq '' and defined $q->param('postmaster'); + + my $tmpl_file; + my @postmasters; + + if (($error // '') ne '' or not (defined $domain)) { + # Something went wrong, or the domain is unknown + $tmpl_file = 'add-domain-1.html'; + } + else { + $tmpl_file = 'add-domain-2.html'; + @postmasters = Fripost::Schema::Domain::->list_postmasters($domain); + } + + my $template = $self->load_tmpl( $tmpl_file, cache => 1, + , loop_context_vars => 1 ); + $template->param( $self->userInfo ); + $template->param( error => encode_entities ($error) ) if $error; + + $template->param( isactive => $q->param('isactive') // 1 + , description => $q->param('description') // undef + , catchalls => $q->param('catchalls') // undef + ); + $template->param( domain => encode_entities($domain) ) + if defined $domain; + + if (@postmasters) { + # Store it, to ensure the user doesn't send back a bogus email + $self->session->param( $session_param, join(',', @postmasters) ); + $self->session->flush; + + $template->param( postmasters => [ map {{postmaster => $_}} @postmasters ] ) + } + + return $template->output; +} + # In this Run Mode authenticated users can add users, aliases and lists # (if they have the permission). @@ -400,8 +481,8 @@ sub AddLocal : Runmode { # Unknown type return $self->redirect('./'); } - $entry{isactive} = $q->param('isactive'); - $entry{description} = $q->param('description'); + $entry{isactive} = $q->param('isactive') // 1; + $entry{description} = $q->param('description') // undef; unless ($error) { my $fp = Fripost::Schema::->SASLauth( $self->authen->username, %CFG ); @@ -417,23 +498,23 @@ sub AddLocal : Runmode { if ($error) { # Preserve the (incorrect) form, except the passwords if ($t eq 'user') { - $template->param( user => $q->param('user') - , forwards => $q->param('forwards') ); + $template->param( user => $q->param('user') // undef + , forwards => $q->param('forwards') // undef ); } elsif ($t eq 'alias') { - $template->param( alias => $q->param('alias') - , maildrop => $q->param('maildrop') ); + $template->param( alias => $q->param('alias') // undef + , maildrop => $q->param('maildrop') // undef ); } elsif ($t eq 'list') { - $template->param( list => $q->param('list') + $template->param( list => $q->param('list') // undef , isenc => $q->param('transport') eq 'schleuder' ); } else { # Unknown type return $self->redirect('./'); } - $template->param( isactive => $q->param('isactive') - , description => $q->param('description') + $template->param( isactive => $q->param('isactive') // 1 + , description => $q->param('description') // undef , error => encode_entities ($error) ); } else { -- cgit v1.2.3