aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuilhem Moulin <guilhem.moulin@fripost.org>2012-09-23 20:57:43 +0200
committerGuilhem Moulin <guilhem.moulin@fripost.org>2012-09-23 20:57:43 +0200
commit06a4de26e05b74e3ed5493cef205af91462678a1 (patch)
treea6d6f009b3792f838fb4d9a2ff24d3d866cbf201
parent0a4b5d24845fb86bade3ab3c38a6202862d6caad (diff)
Making the list creation method.
-rw-r--r--INSTALL27
-rw-r--r--README20
-rw-r--r--TODO.org8
-rw-r--r--css/style.css14
-rw-r--r--lib/Fripost/Panel/Interface.pm22
-rw-r--r--lib/Fripost/Panel/Login.pm16
-rw-r--r--lib/Fripost/Schema/List.pm27
-rw-r--r--lib/Fripost/Schema/Misc.pm1
-rw-r--r--template/add-list.html26
-rw-r--r--template/error_http.html4
-rw-r--r--template/list-locals.html3
-rw-r--r--template/login.html4
12 files changed, 140 insertions, 32 deletions
diff --git a/INSTALL b/INSTALL
index 0ffeb21..c4bc314 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,5 +1,6 @@
# You need several CPAN modules to use the administrator panel.
-# If you use Debian GNU/Linux, you can install them like so:
+# If you use Debian GNU/Linux, you can install them like so (tested on
+# Debian 7.0):
# Web panel
apt-get install libcgi-application-perl \
@@ -7,13 +8,35 @@ apt-get install libcgi-application-perl \
libcgi-application-plugin-autorunmode-perl \
libcgi-application-plugin-configauto-perl \
libcgi-application-plugin-session-perl \
+ libcgi-fast-perl \
libfreezethaw-perl \
libhtml-template-perl
+
# Fripost Schema
apt-get install libnet-ldap-perl \
libauthen-sasl-perl \
libemail-valid-perl \
libdigest-perl \
libstring-mkpasswd-perl \
- libnet-idn-encode-perl
+ libnet-idn-encode-perl \
+ libmail-gnupg-perl
+
+
+# Configuration
+mkdir -p /etc/fripost-panel/gnupg
+chown www-data:www-data /etc/fripost-panel/gnupg && chmod 0700 /etc/fripost-panel/gnupg
+cp ./config.in /etc/fripost-panel/
+chown www-data:www-data /etc/fripost-panel/config.in && chmod 0600 /etc/fripost-panel/config.in
+# Edit /etc/fripost-panel/config.in
+
+
+# Create a GPG key
+sudo -u www-data gpg --homedir /etc/fripost-panel/gnupg/ --gen-key
+# (1) RSA and RSA (default)
+# What keysize do you want? (2048) 4096
+# Real name: Fripost Admin Panel
+# Email address: AdminWebPanel@fripost.org
+# Comment:
+# You selected this USER-ID:
+# "Fripost Admin Panel <AdminWebPanel@fripost.org>"
diff --git a/README b/README
index 892fdf4..35d1689 100644
--- a/README
+++ b/README
@@ -14,7 +14,7 @@ Read installation file INSTALL and follow those instructions.
** LDAP
The panel, or rather the Fripost::Schema library itself, requires
-Fripost's LDAP schema, and base directory. See our other repository
+Fripost's LDAP schema, and base directory. See our other repository
git clone gitolite@git.fripost.org:fripost-admin.git
@@ -28,15 +28,27 @@ custom modifications.
Both files are equal separated (e.g., key=value) configuration file.
Comments (prefixed with a hash #) and blank/empty lines are ignored.
-** Web server
+** Web server (nginx)
-TODO: instructions for Apache and Nginx.
+ location = / {
+ rewrite ^ /cgi-bin/ permanent;
+ }
+ location ^~ /cgi-bin/ {
+ fastcgi_split_path_info ^(/cgi-bin)(/.*)$;
+ include fastcgi/params;
+ fastcgi_pass unix:/var/run/fcgi/fripost-panel.socket;
+ }
+ location ^~ /img/ { }
+ location ^~ /css/ { }
+ location ^~ / { return 404; }
+
+Start the FastCGI process with './bin/fripost-panel start'.
** Development
For testing purposes, the developers may want to install
HTTP::Server::Simple and use our custom clone of
-CGI::Application::Server.
+CGI::Application::Server.
./dev/server.pl will start a server listening to localhost:8080.
Visit http://127.0.0.1:8080/cgi-bin/ to log in and browse the panel.
diff --git a/TODO.org b/TODO.org
index a8b3f0f..49c1154 100644
--- a/TODO.org
+++ b/TODO.org
@@ -12,14 +12,14 @@ domains/emails to Punycode internally?
* TODO Check for cycles when creating new aliases?
(It is impossible since the authenticated user may not have full read access on the graph)
-Actually Postfix checks it and warns the administrator with a
+Actually Postfix checks it and warns the administrator with a
"unreasonable virtual_alias_maps map nesting for test-loop1@fripost.org"
in the logs. So it's fine to do a partial check here.
* TODO Write a script to check every runmode against the W3 validator.
-
-* TODO Use FastCGI. References
-- http://search.cpan.org/~naoya/CGI-Application-FastCGI-0.02/lib/CGI/Application/FastCGI.pm
+
+* DONE Use FastCGI. References
+- http://www.cgi-app.org/index.cgi?FastCGI
- http://stackoverflow.com/questions/11771564/nginx-fastcgi-configuration-for-cgiapplication-app
* TODO Use HTML::Template::Pro. Not sure it's really worth it, though.
diff --git a/css/style.css b/css/style.css
index 277ff52..fa2f407 100644
--- a/css/style.css
+++ b/css/style.css
@@ -21,6 +21,13 @@ h1, h2, h3 {
span.domain, span.email, span.alias, span.mailbox, span.list {
font-family: Inconsolata, "Lucida Console", "Droid Sans Mono", Cousine, monospace;
}
+.errorhttp {
+ font-family: serif, times;
+ margin: 25pt auto;
+ text-align: center;
+ font-size: 25pt;
+ font-weight: bold;
+}
/* Login form */
@@ -128,11 +135,16 @@ table.list thead th {
font-size: 11pt;
margin: 10pt;
}
+a.external {
+ text-decoration: none;
+ color:#ff0000;
+ color: #1a1a1a;
+}
/* Edit modes */
.help {
- font-size: 8pt;
+ font-size: 8pt;
text-align: justify;
color: #6A6A6A;
padding: 0 50pt;
diff --git a/lib/Fripost/Panel/Interface.pm b/lib/Fripost/Panel/Interface.pm
index 46d4058..e253ca0 100644
--- a/lib/Fripost/Panel/Interface.pm
+++ b/lib/Fripost/Panel/Interface.pm
@@ -37,7 +37,7 @@ sub ListDomains : StartRunmode {
my ($ul,$ud) = split /\@/, email_to_unicode($self->authen->username), 2;
- my $fp = Fripost::Schema->SASLauth( $self->authen->username, %CFG );
+ my $fp = Fripost::Schema::->SASLauth( $self->authen->username, %CFG );
my @domains = $fp->domain->search( -concat => "\n", -die => 403);
$fp->done;
@@ -139,6 +139,7 @@ sub ListLocals : Runmode {
, description => join ("\n", @{$_->{description}})
, isactive => $_->{isactive}
, transport => $_->{transport}
+ , listurl => $CFG{'listurl_'.$_->{transport}}.$_->{list}.'@'.$d
};
}
@lists
@@ -360,6 +361,7 @@ sub AddLocal : Runmode {
if (defined $q->param('submit')) {
# Changes have been submitted: process them
my %entry;
+ my %rest;
if ($t eq 'mailbox') {
$entry{user} = $q->param('user').'@'.$du;
$entry{forwards} = $q->param('forwards');
@@ -383,6 +385,22 @@ sub AddLocal : Runmode {
elsif ($t eq 'list') {
$entry{list} = $q->param('list').'@'.$du;
$entry{transport} = $q->param('transport');
+ if ($q->param('password') ne $q->param('password2')) {
+ $error = "Passwords do not match";
+ }
+ elsif (length $q->param('password') < $CFG{password_min_length}) {
+ $error = "Password should be at least "
+ .$CFG{password_min_length}
+ ." characters long.";
+ }
+ else {
+ $rest{gpg} = { use_agent => 0
+ , keydir => $CFG{gpghome}
+ , key => $CFG{gpg_private_key_id}
+ , passphrase => $CFG{gpg_private_key_passphrase}
+ };
+ $entry{password} = $q->param('password');
+ }
}
else {
# Unknown type
@@ -393,7 +411,7 @@ sub AddLocal : Runmode {
unless ($error) {
my $fp = Fripost::Schema::->SASLauth( $self->authen->username, %CFG );
- $error = $fp->$t->add( \%entry, -concat => "(\n|\x{0D}\x{0A})");
+ $error = $fp->$t->add( \%entry, -concat => "(\n|\x{0D}\x{0A})", %rest);
$fp->done;
return $self->redirect($q->url.'/'.$d.'/') unless $error;
}
diff --git a/lib/Fripost/Panel/Login.pm b/lib/Fripost/Panel/Login.pm
index a147371..1483e06 100644
--- a/lib/Fripost/Panel/Login.pm
+++ b/lib/Fripost/Panel/Login.pm
@@ -20,7 +20,6 @@ use CGI::Application::Plugin::Redirect;
use CGI::Application::Plugin::ConfigAuto 'cfg';
use Fripost::Schema;
-use File::Spec::Functions qw/catfile catdir/;
use HTML::Entities;
use Net::IDN::Encode qw/email_to_ascii/;
@@ -92,12 +91,11 @@ sub setup {
my $self = shift;
$self->header_props( -charset=>'utf-8' );
- $self->tmpl_path( catdir ( $self->cfg('pwd'), $self->cfg('tmpl_path') ) );
+ $self->tmpl_path( $self->cfg('tmpl_path') );
$self->mode_param( sub {
my $self = shift;
my $q = $self->query;
- print STDERR $ENV{PATH_INFO} . '?' . $q->query_string, "\n";
# The user just logged in
return 'okay' if defined $q->param('login');
@@ -135,9 +133,9 @@ sub setup {
# wanted to visit.
sub okay : Runmode {
my $self = shift;
- my $destination = $self->query->param('destination') //
- $self->query->url;
- return $self->redirect($destination);
+ my $redirect = $self->query->param('redirect') //
+ $self->query->url;
+ return $self->redirect($redirect);
}
@@ -154,8 +152,8 @@ sub login : Runmode {
$self->query->param('a') eq 'login';
# Where the users wants to go
- $self->query->param( destination => $self->query->self_url)
- unless defined $self->query->param('destination');
+ $self->query->param( redirect => $self->query->self_url)
+ unless defined $self->query->param('redirect');
return $self->login_box;
}
@@ -167,7 +165,7 @@ sub login_box {
my $template = $self->load_tmpl( 'login.html', cache => 1, utf8 => 1 );
$template->param( error => $self->authen->login_attempts );
- $template->param( destination => $self->query->param('destination') );
+ $template->param( redirect => $self->query->param('redirect') );
return $template->output;
}
diff --git a/lib/Fripost/Schema/List.pm b/lib/Fripost/Schema/List.pm
index 69317b1..edf9d24 100644
--- a/lib/Fripost/Schema/List.pm
+++ b/lib/Fripost/Schema/List.pm
@@ -20,6 +20,8 @@ use parent 'Fripost::Schema';
use Fripost::Schema::Misc qw/concat explode must_attrs email_valid/;
use Net::IDN::Encode qw/domain_to_ascii
email_to_ascii email_to_unicode/;
+use Mail::GnuPG;
+use MIME::Entity;
=head1 METHODS
@@ -105,6 +107,7 @@ sub add {
my $l = shift;
my %options = @_;
+ my $lname = $l->{list};
$l->{description} = explode ($options{'-concat'}, $l->{description})
if defined $l->{description};
@@ -114,7 +117,7 @@ sub add {
die "Missing list name\n" if $l eq '';
must_attrs( $l, 'transport' );
&_is_valid($l);
- die "‘".$l->{list}."‘ alread exists\n"
+ die "‘".$l->{list}."‘ already exists\n"
if $self->local->exists($l->{list},%options);
my %attrs = ( objectClass => 'FripostVirtualList'
@@ -134,8 +137,24 @@ sub add {
die $mesg->error."\n";
}
};
- return $@;
- # TODO: send email to mklist-$transport to finalize
+ return $@ if $@;
+
+ # Ask the list manager to create the list now.
+ my $member = $self->whoami;
+ $member =~ s/^fvu=([^,]+),fvd=([^,]+),.*$/$1\@$2/;
+ my $mail = MIME::Entity::->build(
+ From => 'Fripost Admin Panel <AdminWebPanel@fripost.org>',
+ To => 'mklist+'.$l->{transport}.'@fripost.org',
+ Subject => "New ".$l->{transport}." list",
+ Encoding => 'quoted-printable',
+ Charset => 'utf-8',
+ Data => [ map { $_ . "\n"} ($lname, $member, $l->{password}) ]
+ );
+ my $gpg = Mail::GnuPG::->new( %{$options{gpg}} );
+ my $ret = $gpg->mime_sign( $mail );
+ return join ("\n", @{$gpg->{last_message}}) if $ret;
+ $mail->send;
+ return 0;
}
@@ -166,7 +185,7 @@ sub is_pending {
die "Error: Multiple matching entries found." if $mesg->count > 1;
my $list = $mesg->pop_entry;
-
+
die "Error: No matching entry found." unless defined $list;
my $r = $list->get_value('fripostIsStatusPending');
return (defined $r and $r eq 'TRUE');
diff --git a/lib/Fripost/Schema/Misc.pm b/lib/Fripost/Schema/Misc.pm
index 39fa3b7..745a20b 100644
--- a/lib/Fripost/Schema/Misc.pm
+++ b/lib/Fripost/Schema/Misc.pm
@@ -10,7 +10,6 @@ use 5.010_000;
use strict;
use warnings;
use utf8;
-use feature "unicode_strings";
use Exporter 'import';
our @EXPORT_OK = qw /concat get_perms explode
diff --git a/template/add-list.html b/template/add-list.html
index 00c94ac..ef99497 100644
--- a/template/add-list.html
+++ b/template/add-list.html
@@ -52,6 +52,26 @@
<hr/>
+ <h4 class="label">Password</h4>
+
+ <table class="loginform">
+ <tr>
+ <td class="label">Password</td>
+ <td><input type="password" name="password" size="20" /></td>
+ </tr>
+ <tr>
+ <td class="label">Repeat password</td>
+ <td><input type="password" name="password2" size="20" /></td>
+ </tr>
+ </table>
+ <div class="help">
+ This is the admin password for the web interface of the chosen list manager.
+ (The user name being yourself
+ <span class="email"><TMPL_VAR NAME=user_localpart>@<TMPL_VAR NAME=user_domainpart></span>.)
+ </div>
+
+ <hr/>
+
<h4 class="label">Description</h4>
<textarea name="description" cols="50" rows="3" ><TMPL_VAR NAME=description></textarea>
<div class="help">
@@ -79,6 +99,12 @@
<input type="submit" name="cancel" value="Cancel" />
<input type="submit" name="submit" value="Submit" />
+ <div class="help">
+ <i>Note</i>: No confirmation email will be sent. It may take a while for the list to be created (especially
+ for the Schleuder list manager, as it requires a GPG key creation); Once the list has succefully been created,
+ it will be visible under the
+ <a href="<TMPL_VAR NAME=url>/<TMPL_VAR NAME=domain>/">management page for <span class="domain"><TMPL_VAR NAME=domain></span></a>.
+ </div>
</div>
</form>
</div>
diff --git a/template/error_http.html b/template/error_http.html
index 7cf4f50..c6ab50a 100644
--- a/template/error_http.html
+++ b/template/error_http.html
@@ -2,10 +2,10 @@
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
- <title><TMPL_IF NAME=message><TMPL_VAR NAME=message><TMPL_ELSE>Error</TMPL_IF></title>
+ <title><TMPL_VAR NAME=code> <TMPL_IF NAME=message><TMPL_VAR NAME=message><TMPL_ELSE>Error</TMPL_IF></title>
<link href="/css/style.css" media="all" rel="stylesheet" type="text/css" />
</head>
<body>
- <h1><TMPL_VAR NAME=code> <TMPL_VAR NAME=message></h1>
+ <div class="errorhttp"><TMPL_VAR NAME=code> <TMPL_VAR NAME=message></div>
</body>
</html>
diff --git a/template/list-locals.html b/template/list-locals.html
index 1e3a799..f9d8535 100644
--- a/template/list-locals.html
+++ b/template/list-locals.html
@@ -122,7 +122,8 @@
<tbody>
<TMPL_LOOP NAME=lists>
<TMPL_IF NAME=__even__><tr class="odd"><TMPL_ELSE><tr></TMPL_IF>
- <td><span class="list"><a href="<TMPL_VAR NAME=url>/<TMPL_VAR NAME=domain>/<TMPL_VAR NAME=list>/"><TMPL_VAR NAME=list></a></span></td>
+ <td><span class="list"><a href="<TMPL_VAR NAME=url>/<TMPL_VAR NAME=domain>/<TMPL_VAR NAME=list>/"><TMPL_VAR NAME=list></a></span
+ > <a class="external" target="_blank" href="<TMPL_VAR NAME=listurl>">➠</a></td>
<td><TMPL_IF NAME=description><TMPL_VAR NAME=description><TMPL_ELSE><span class="none">(none)</span></TMPL_IF></td>
<td><TMPL_IF NAME=isactive><span class="active">&#x2714;</span><TMPL_ELSE><span class="inactive">&#x2718;</span></TMPL_IF></td>
<td><TMPL_VAR NAME=transport></td>
diff --git a/template/login.html b/template/login.html
index 766dd7d..ed10d20 100644
--- a/template/login.html
+++ b/template/login.html
@@ -2,7 +2,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
- <title>Log In | Fripost's Administrator panel</title>
+ <title>Log In | Fripost Administrator Panel</title>
<link href="/css/style.css" media="all" rel="stylesheet" type="text/css" />
</head>
<body class="loginform" onload="document.loginform.authen_username.focus();">
@@ -30,7 +30,7 @@
</tr>
</table>
<div>
- <input type="hidden" name="destination" value="<TMPL_VAR NAME=destination>" />
+ <input type="hidden" name="redirect" value="<TMPL_VAR NAME=redirect>" />
<input type="submit" name="login" value="Log in" />
</div>
</form>