aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuilhem Moulin <guilhem.moulin@fripost.org>2012-09-03 00:05:22 +0200
committerGuilhem Moulin <guilhem.moulin@fripost.org>2012-09-03 00:05:22 +0200
commit3c8b9dba04da6d66f7e592c3c1367a2367e1c5a5 (patch)
tree57739942759a34ba245f076c2bde0a596adf5e9c
parent742c9938af740b9ba758f4b03909f30106b285a5 (diff)
Domain edition.
-rw-r--r--css/style.css67
-rw-r--r--lib/FPanel/Interface.pm69
-rw-r--r--lib/FPanel/Login.pm24
-rw-r--r--template/edit-domain.html75
-rw-r--r--template/list-domains.html (renamed from template/domain-list.html)9
-rw-r--r--template/login.html6
6 files changed, 230 insertions, 20 deletions
diff --git a/css/style.css b/css/style.css
index 87b0275..390a634 100644
--- a/css/style.css
+++ b/css/style.css
@@ -1,6 +1,6 @@
/* Global */
body {
- font-family: "DejaVu Sans", Helvetica, Arial, sans-serif;
+ font-family: Helvetica, Arial, sans-serif;
font-size: 11pt;
line-height: 140%;
color: #1a1a1a;
@@ -8,6 +8,10 @@ body {
.error {
color: #FF0040;
}
+tt {
+ font-family: Inconsolata, "Lucida Console", "Droid Sans Mono", Cousine, monospace;
+}
+
/* Login form */
@@ -30,8 +34,9 @@ table.loginform td {
text-align: center;
font-size: 12pt;
}
-.label {
+td.label {
text-align: right;
+ vertical-align: top;
}
@@ -56,6 +61,27 @@ table.loginform td {
text-align: right;
}
+#columns {
+ width: 100%;
+}
+#columns .column {
+ position: relative;
+ padding: 0pt;
+ border: 0pt;
+}
+#columns .left {
+ width: 50%;
+ padding: 0 0 0 30pt;
+ float: left;
+ text-align: left;
+}
+#columns .right {
+ width: 50%;
+ padding: 0 0 0 30pt;
+ float: right;
+ text-align: right;
+}
+
/* Listing table */
table.list {
@@ -89,7 +115,7 @@ table.list thead th {
font-weight:bold;
color:#66a3d3
}
-.nonactive {
+.inactive {
color: #FF0040;
}
.active {
@@ -99,3 +125,38 @@ table.list thead th {
font-size: 6pt;
color: lightgray;
}
+.help {
+ font-size: 8pt;
+ text-align: justify;
+ color: #6A6A6A;
+ padding: 0 50pt;
+}
+h4.label {
+ font-weight: bold;
+ text-align: center;
+ font-size: 12pt;
+}
+
+/* Edit forms */
+form.editform {
+ margin: 0px auto;
+ border: 1px solid #cccccc;
+ padding: 10pt;
+ position: relative;
+ width: 80ex;
+ background:#E7EFF7;
+}
+table.editform {
+ margin:0 auto 5pt auto;
+ border-collapse:collapse;
+}
+table.editform td {
+ padding:0 5pt 0 0;
+}
+div.editform {
+ text-align: center;
+}
+.ack {
+ font-weight: bold;
+ color: #32CD32;
+}
diff --git a/lib/FPanel/Interface.pm b/lib/FPanel/Interface.pm
index 6781ae5..b1b7fe5 100644
--- a/lib/FPanel/Interface.pm
+++ b/lib/FPanel/Interface.pm
@@ -20,9 +20,9 @@ sub cgiapp_init {
}
-# This is the first page an authenticated user sees. It lists the known
+# This is the first page seen by authenticated users. It lists the known
# domains.
-sub DomainList : StartRunmode {
+sub ListDomains : StartRunmode {
my $self = shift;
my %CFG = $self->cfg;
my $suffix = join ',', @{$CFG{ldap_suffix}};
@@ -37,9 +37,10 @@ sub DomainList : StartRunmode {
, deref => 'never'
);
die $domains->error if $domains->code;
+ $ldap->unbind;
- my $template = $self->load_tmpl( 'domain-list.html', cache => 1, utf8 => 1
+ my $template = $self->load_tmpl( 'list-domains.html', cache => 1, utf8 => 1
, loop_context_vars => 1
, global_vars => 1 );
$template->param( URL => $self->query->url );
@@ -56,6 +57,67 @@ sub DomainList : StartRunmode {
return $template->output;
}
+# This is the page used to edit domains.
+sub EditDomain : Runmode {
+ my $self = shift;
+ my %CFG = $self->cfg;
+ my $suffix = join ',', @{$CFG{ldap_suffix}};
+
+ my ($l,$d) = split /@/, $self->authen->username, 2;
+ my $authzDN = "fvu=$l,fvd=$d,". $suffix;
+ my $ldap = $self->ldap_from_auth_user($authzDN);
+
+ my $domain = (split /\//, $ENV{PATH_INFO}, 3)[1];
+
+ if (defined $self->query->param('submit') or
+ defined $self->query->param('active')) {
+ # Changes have been submitted: process them
+ my %changes;
+ if (defined $self->query->param('active')) {
+ $changes{fripostIsStatusActive} = $self->query->param('active');
+ }
+ if (defined $self->query->param('description')) {
+ my @desc;
+ foreach my $d (split /\n/, $self->query->param('description')) {
+ push @desc, $d;
+ }
+ $changes{description} = [ @desc ];
+ }
+ if (defined $self->query->param('maildrop')) {
+ my @maildrop;
+ foreach my $d (split /\n/, $self->query->param('maildrop')) {
+ $d =~ s/\s//g;
+ push @maildrop, (lc $d) unless $d =~ /^$/;
+ }
+ $changes{fripostOptionalMaildrop} = [ @maildrop ];
+ }
+
+ my $mesg = $ldap->modify( "fvd=$domain,$suffix", replace => \%changes );
+ die $mesg->error if $mesg->code;
+ }
+
+ my $answer = $ldap->search( base => 'fvd='.$domain .','. $suffix
+ , scope => 'base'
+ , filter => 'objectClass=FripostVirtualDomain'
+ , deref => 'never'
+ );
+ die $answer->error if $answer->code;
+ $answer = $answer->entry('0');
+ $ldap->unbind;
+
+ my $template = $self->load_tmpl( 'edit-domain.html', cache => 1, utf8 => 1
+ , loop_context_vars => 1
+ , global_vars => 1 );
+ $template->param( URL => $self->query->url );
+ $template->param( USER_LOCALPART => $l, USER_DOMAINPART => $d);
+ $template->param( DOMAIN => $domain );
+ $template->param( DESCRIPTION => join ("\n",$answer->get_value('description')) );
+ $template->param( MAILDROP => join ("\n",$answer->get_value('fripostOptionalMaildrop')) );
+ $template->param( ISACTIVE => $answer->get_value('fripostIsStatusActive') eq 'TRUE' ? 1 : 0 );
+ $template->param( NEWCHANGES => defined $self->query->param('submit') );
+ return $template->output;
+}
+
# This subroutine displays the access that the given DN has on the entry.
# Possible values are :
@@ -124,4 +186,3 @@ sub ldap_from_auth_user {
1;
-
diff --git a/lib/FPanel/Login.pm b/lib/FPanel/Login.pm
index 506a7b8..173a34f 100644
--- a/lib/FPanel/Login.pm
+++ b/lib/FPanel/Login.pm
@@ -59,6 +59,7 @@ sub cgiapp_init {
my $ldap = Net::LDAP->new( $CFG{ldap_uri} );
my $mesg = $ldap->bind ( $bind_dn, password => $p );
+ $ldap->unbind;
$mesg->code ? 0 : $u;
} ],
STORE => 'Session',
@@ -87,23 +88,22 @@ sub setup {
print STDERR $ENV{PATH_INFO} . '?' . $q->query_string, "\n";
# The user just logged in
- return 'okay' if (defined $q->param('authen_username')) and
- (defined $q->param('authen_password'));
+ return 'okay' if defined $q->param('login');
my $a = $q->param('a');
return 'login' if defined $a and $a eq 'login';
return 'logout' if defined $a and $a eq 'logout';
- # /domain/{user,alias,list}/?requests
+ # /domain/{user,alias,list}/?query_url
my ($null,$domain,$local,$crap) = split /\//, $ENV{PATH_INFO};
- return 'DomainList' unless (defined $null) and $null eq '';
+ return 'ListDomains' unless (defined $null) and $null eq '';
unless (defined $domain and $domain ne '') {
if (defined $a) {
return 'AddDomain' if $a eq 'AddDomain';
}
- return 'DomainList';
+ return 'ListDomains';
}
unless (defined $local and $local ne '') {
@@ -111,15 +111,16 @@ sub setup {
return 'EditDomain' if $a eq 'edit';
return 'AddAccount' if $a eq 'AddAccount';
return 'AddAlias' if $a eq 'AddAlias';
+ return 'AddList' if $a eq 'AddList';
}
- return 'LocalList';
+ return 'ListLocals';
}
unless (defined $crap and $crap ne '') {
- return 'LocalEdit';
+ return 'EditLocal';
}
- return 'DomainList';
+ return 'error_404';
});
}
@@ -193,11 +194,16 @@ sub error_rm : ErrorRunmode {
my $template = $self->load_tmpl( 'error.html', cache => 1, utf8 => 1 );
$template->param( EMAIL => $self->cfg('report_email') );
$template->param( MESSAGE => $error );
- $template->param( URL => $self->query->url );
+ $template->param( URL => $self->query->url . '/');
return $template->output;
}
+sub error_404 : Runmode {
+ my $self = shift;
+ $self->header_props ( -status => '404 Not found' );
+ return '';
+}
1;
diff --git a/template/edit-domain.html b/template/edit-domain.html
new file mode 100644
index 0000000..38abc62
--- /dev/null
+++ b/template/edit-domain.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<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>Domain names for <TMPL_VAR NAME=USER></title>
+ <link href="/css/style.css" media="all" rel="stylesheet" type="text/css" />
+ </head>
+ <body>
+ <div id="header">
+ <div class="left column">
+ <a href="<TMPL_VAR NAME=URL>/">Root</a> / <TMPL_VAR NAME=DOMAIN> /
+ </div>
+ <div class="right column">
+ Logged as <a href="<TMPL_VAR NAME=URL>/<TMPL_VAR NAME=USER_DOMAINPART>/<TMPL_VAR NAME=USER_LOCALPART>/?a=edit"
+ ><TMPL_VAR NAME=USER_LOCALPART>@<TMPL_VAR NAME=USER_DOMAINPART></a>
+ | <a href="<TMPL_VAR NAME=URL>/?a=logout">Log out</a>
+ </div>
+ <br/>
+ </div>
+ <hr/>
+
+ <h1>Edit domain <tt><TMPL_VAR NAME=DOMAIN></tt></h1>
+
+
+ <table width=90% align=center>
+ <tr>
+ <td width=30%>
+ Status: <b><TMPL_IF NAME=ISACTIVE><span class="active">Active</span><TMPL_ELSE><span class="inactive">Inactive</span></TMPL_IF></b>
+ (<a href="./?a=edit&active=<TMPL_IF NAME=ISACTIVE>FALSE<TMPL_ELSE>TRUE</TMPL_IF>">toggle</a>)
+ </td>
+ <td width=70% align=right>
+ <span class="ack">
+ <TMPL_IF NAME=NEWCHANGES>Your changes have succesfully been submitted.</TMPL_IF>
+ </span>
+ </td>
+ </tr>
+ </table>
+
+ <br/>
+
+ <form class="editform" name="editform" method="post">
+ <div class="editform">
+ <input type="hidden" name="a" value="edit" />
+
+ <p>
+ <h4 class="label">Description</h4>
+ <textarea type="text" name="description" cols="50" rows="3" wrap="soft"><TMPL_VAR NAME=DESCRIPTION></textarea>
+ <div class="help">
+ An optional description of your domain.
+ </div>
+ </p>
+
+ <hr/>
+
+ <p>
+ <h4 class="label">Catch-All aliases</h4>
+ <textarea type="text" name="maildrop" cols="50" rows="10" wrap="hard" ><TMPL_VAR NAME=MAILDROP></textarea>
+ <div class="help">
+ An optional list of destinations (one e-mail address per line) that
+ will receive mail sent to <i>non existing</i> recipients.
+ Domain aliases can be defined by leaving the local part of
+ the destination empty, like in <tt>@example.org</tt>: email
+ to <tt>inexisting@<TMPL_VAR NAME=DOMAIN></tt>
+ will then be sent to <tt>inexisting@example.org</tt>.
+ </div>
+ </p>
+
+ <hr/>
+
+ <input type="hidden" name="destination" value="<TMPL_VAR NAME=DESTINATION>" />
+ <input type="submit" name="submit" value="Submit Changes" />
+ </div>
+ </form>
+ </body>
+</html>
diff --git a/template/domain-list.html b/template/list-domains.html
index fcc7b23..9b8cf0e 100644
--- a/template/domain-list.html
+++ b/template/list-domains.html
@@ -17,7 +17,10 @@
</div>
<br/>
</div>
+ <hr/>
+
<h1>Manage domains</h1>
+
<table class="list">
<thead>
<tr class="odd">
@@ -25,15 +28,17 @@
<th>Permissions</th>
<th>Description</th>
<th>Active?</th>
+ <th>Action</th>
</tr>
</thead>
<tbody>
<TMPL_LOOP NAME=DOMAINS>
<TMPL_IF NAME=__even__><tr class="odd"><TMPL_ELSE><tr></TMPL_IF>
- <td><a href="<TMPL_VAR NAME=URL>/<TMPL_VAR NAME=DOMAIN>/"><TMPL_VAR NAME=DOMAIN></a></td>
+ <td><tt><a href="<TMPL_VAR NAME=URL>/<TMPL_VAR NAME=DOMAIN>/"><TMPL_VAR NAME=DOMAIN></a></tt></td>
<td><TMPL_IF NAME=PERMS><TMPL_VAR NAME=PERMS><TMPL_ELSE><span class="none">(none)</span></TMPL_IF></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="nonactive">&#x2718;</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><a href="<TMPL_VAR NAME=URL>/<TMPL_VAR NAME=DOMAIN>/?a=edit">edit</a></td>
</tr>
</TMPL_LOOP>
</tbody>
diff --git a/template/login.html b/template/login.html
index 6ed2a7e..293f20f 100644
--- a/template/login.html
+++ b/template/login.html
@@ -13,10 +13,12 @@
src="/img/fripost_logo.png"
title="fripost.org|demokratisk e-post"
/></a>
+
<h2>Administrator Panel</h2>
<br/>
<br/>
- <form class="loginform" name="loginform" method="post" >
+
+ <form class="loginform" name="loginform" method="post">
<table class="loginform">
<tr>
<td class="label">Username</td>
@@ -28,7 +30,7 @@
</tr>
</table>
<div>
- <input type="hidden" name="destination" value="<TMPL_VAR DESTINATION>" />
+ <input type="hidden" name="destination" value="<TMPL_VAR NAME=DESTINATION>" />
<input type="submit" name="login" value="Log in" />
</div>
</form>