aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--css/style.css16
-rw-r--r--lib/FPanel/Interface.pm130
-rw-r--r--template/edit-domain.html3
-rw-r--r--template/error.html18
-rw-r--r--template/list-domains.html8
-rw-r--r--template/list-locals.html125
6 files changed, 280 insertions, 20 deletions
diff --git a/css/style.css b/css/style.css
index 390a634..465a7b1 100644
--- a/css/style.css
+++ b/css/style.css
@@ -160,3 +160,19 @@ div.editform {
font-weight: bold;
color: #32CD32;
}
+.description {
+ text-align: justify;
+ font-style: italic;
+ margin: auto;
+ width: 600px;
+}
+.edit {
+ font-weight: normal;
+ font-size: 11pt;
+ margin: 10pt;
+}
+.add {
+ font-weight: normal;
+ font-size: 11pt;
+ margin: 10pt;
+}
diff --git a/lib/FPanel/Interface.pm b/lib/FPanel/Interface.pm
index b1b7fe5..f73b5de 100644
--- a/lib/FPanel/Interface.pm
+++ b/lib/FPanel/Interface.pm
@@ -35,6 +35,9 @@ sub ListDomains : StartRunmode {
, scope => 'one'
, filter => 'objectClass=FripostVirtualDomain'
, deref => 'never'
+ , attrs => [ qw/fvd description fripostIsStatusActive
+ fripostCanCreateAlias fripostCanCreateList
+ fripostOwner fripostPostmaster/ ]
);
die $domains->error if $domains->code;
$ldap->unbind;
@@ -57,6 +60,120 @@ sub ListDomains : StartRunmode {
return $template->output;
}
+
+# This Run Mode lists the known aliases, users and lists in the current
+# domain.
+sub ListLocals : 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 $domainname = (split /\//, $ENV{PATH_INFO}, 3)[1];
+
+ my $answer = $ldap->search( base => "fvd=$domainname,$suffix"
+ , scope => 'base'
+ , filter => 'objectClass=FripostVirtualDomain'
+ , deref => 'never'
+ , attrs => [ qw/fvd description fripostIsStatusActive
+ fripostOptionalMaildrop
+ fripostOwner fripostPostmaster/ ]
+ );
+ die $answer->error if $answer->code;
+ my $domain = $answer->entry('0');
+
+ my $canedit = 0;
+ foreach (qw/fripostOwner fripostPostmaster/) {
+ my $x = $domain->get_value($_, asref=>1);
+ if (defined $x and grep { $_ eq $authzDN} @$x) {
+ $canedit = 1;
+ last;
+ }
+ }
+
+
+ my $mailboxes = $ldap->search( base => "fvd=$domainname,$suffix"
+ , scope => 'one'
+ , filter => 'objectClass=FripostVirtualMailbox'
+ , deref => 'never'
+ , attrs => [ qw/fvu description
+ fripostIsStatusActive
+ fripostOptionalMaildrop
+ fripostMailboxQuota/ ]
+ );
+ die $mailboxes->error if $mailboxes->code;
+
+ my $aliases = $ldap->search( base => "fvd=$domainname,$suffix"
+ , scope => 'one'
+ , filter => 'objectClass=FripostVirtualAlias'
+ , deref => 'never'
+ , attrs => [ qw/fva description
+ fripostIsStatusActive
+ fripostOwner
+ fripostMaildrop/ ]
+ );
+ die $aliases->error if $aliases->code;
+
+ my $lists = $ldap->search( base => "fvd=$domainname,$suffix"
+ , scope => 'one'
+ , filter => 'objectClass=FripostVirtualList'
+ , deref => 'never'
+ , attrs => [ qw/fvl description
+ fripostIsStatusActive
+ fripostOwner
+ fripostListManager/ ]
+ );
+ die $lists->error if $lists->code;
+
+ $ldap->unbind;
+
+ my $template = $self->load_tmpl( 'list-locals.html', cache => 1, utf8 => 1
+ , loop_context_vars => 1
+ , global_vars => 1 );
+ $template->param( URL => $self->query->url );
+ $template->param( DOMAIN => $domainname );
+ $template->param( USER_LOCALPART => $l, USER_DOMAINPART => $d);
+ $template->param( DESCRIPTION => join ("\n", $domain->get_value('description')) );
+ $template->param( ISACTIVE => $domain->get_value('fripostIsStatusActive') eq 'TRUE' ? 1 : 0 );
+ $template->param( CANEDIT => $canedit );
+ $template->param( MAILBOXES => [
+ map { { USER => $_->get_value('fvu')
+ , DESCRIPTION => join ("\n", $_->get_value('description'))
+ , ISACTIVE => $_->get_value('fripostIsStatusActive') eq 'TRUE' ? 1 : 0
+ , FORWARDS => [ map { {FORWARD => $_} } $_->get_value('fripostOptionalMaildrop') ]
+ , QUOTA => $_->get_value('fripostMailboxQuota') // ''
+ };
+ }
+ $mailboxes->sorted('fvu')
+ ]);
+ $template->param( ALIASES => [
+ map { { ALIAS => $_->get_value('fva')
+ , DESCRIPTION => join ("\n", $_->get_value('description'))
+ , ISACTIVE => $_->get_value('fripostIsStatusActive') eq 'TRUE' ? 1 : 0
+ , OWNERS => [ map { {OWNER => &dn2email($_)} } $_->get_value('fripostOwner') ]
+ , DESTINATIONS => [ map { {DESTINATION => $_} } $_->get_value('fripostMaildrop') ]
+ };
+ }
+ $aliases->sorted('fva')
+ ]);
+ $template->param( CATCHALLS => [ map { {CATCHALL => $_} } $domain->get_value('fripostOptionalMaildrop') ] );
+ $template->param( LISTS => [
+ map { { LIST => $_->get_value('fvl')
+ , DESCRIPTION => join ("\n", $_->get_value('description'))
+ , ISACTIVE => $_->get_value('fripostIsStatusActive') eq 'TRUE' ? 1 : 0
+ , OWNERS => [ map { {OWNER => &dn2email($_)} } $_->get_value('fripostOwner') ]
+ , TRANSPORT => $_->get_value('fripostListManager')
+ };
+ }
+ $lists->sorted('fvl')
+ ]);
+ return $template->output;
+}
+
+
# This is the page used to edit domains.
sub EditDomain : Runmode {
my $self = shift;
@@ -67,7 +184,7 @@ sub EditDomain : Runmode {
my $authzDN = "fvu=$l,fvd=$d,". $suffix;
my $ldap = $self->ldap_from_auth_user($authzDN);
- my $domain = (split /\//, $ENV{PATH_INFO}, 3)[1];
+ my $domainname = (split /\//, $ENV{PATH_INFO}, 3)[1];
if (defined $self->query->param('submit') or
defined $self->query->param('active')) {
@@ -92,11 +209,11 @@ sub EditDomain : Runmode {
$changes{fripostOptionalMaildrop} = [ @maildrop ];
}
- my $mesg = $ldap->modify( "fvd=$domain,$suffix", replace => \%changes );
+ my $mesg = $ldap->modify( "fvd=$domainname,$suffix", replace => \%changes );
die $mesg->error if $mesg->code;
}
- my $answer = $ldap->search( base => 'fvd='.$domain .','. $suffix
+ my $answer = $ldap->search( base => "fvd=$domainname,$suffix"
, scope => 'base'
, filter => 'objectClass=FripostVirtualDomain'
, deref => 'never'
@@ -110,7 +227,7 @@ sub EditDomain : Runmode {
, global_vars => 1 );
$template->param( URL => $self->query->url );
$template->param( USER_LOCALPART => $l, USER_DOMAINPART => $d);
- $template->param( DOMAIN => $domain );
+ $template->param( DOMAIN => $domainname );
$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 );
@@ -184,5 +301,10 @@ sub ldap_from_auth_user {
return $ldap;
}
+sub dn2email {
+ my $dn = shift;
+ $dn =~ /^fv[ual]=([^,]+),fvd=([^,]+),/ or return '';
+ return "$1\@$2";
+}
1;
diff --git a/template/edit-domain.html b/template/edit-domain.html
index 38abc62..5be62dd 100644
--- a/template/edit-domain.html
+++ b/template/edit-domain.html
@@ -8,7 +8,8 @@
<body>
<div id="header">
<div class="left column">
- <a href="<TMPL_VAR NAME=URL>/">Root</a> / <TMPL_VAR NAME=DOMAIN> /
+ <a href="<TMPL_VAR NAME=URL>/">Root</a> /
+ <a href="<TMPL_VAR NAME=URL>/<TMPL_VAR NAME=DOMAIN>/"><TMPL_VAR NAME=DOMAIN></a> /
</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"
diff --git a/template/error.html b/template/error.html
index ef454ab..b7f8930 100644
--- a/template/error.html
+++ b/template/error.html
@@ -2,20 +2,18 @@
<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=NAME> <TMPL_VAR NAME=NAME> </TMPL_IF></title>
+ <title>Error</title>
<link href="/css/style.css" media="all" rel="stylesheet" type="text/css" />
</head>
<body>
- <TMPL_IF NAME=NAME>
- <p>This is the <span class="error"><TMPL_VAR NAME=NAME></span> page.
- <TMPL_IF NAME=EMAIL>
- You are not suppose to see this. If you think it is a bug, please
- report it to <a href="mailto:<TMPL_VAR NAME=EMAIL>"><TMPL_VAR NAME=EMAIL></a>.
- </TMPL_IF>
- </p>
- </TMPL_IF>
-
<TMPL_IF NAME=MESSAGE><p class="error"><b><TMPL_VAR NAME=MESSAGE></b></p></TMPL_IF>
+
+ <p>
+ <TMPL_IF NAME=EMAIL>
+ If you think it is a bug, please report it to
+ <a href="mailto:<TMPL_VAR NAME=EMAIL>"><TMPL_VAR NAME=EMAIL></a>.
+ </TMPL_IF>
+ </p>
<hr/>
<TMPL_IF NAME=URL><p><a href="<TMPL_VAR NAME=URL>">Back</a></p></TMPL_IF>
diff --git a/template/list-domains.html b/template/list-domains.html
index 9b8cf0e..b933167 100644
--- a/template/list-domains.html
+++ b/template/list-domains.html
@@ -19,16 +19,15 @@
</div>
<hr/>
- <h1>Manage domains</h1>
+ <h1>Manage domains<span class="add">[<a href="<TMPL_VAR NAME=URL>/?a=AddDomain">add domain</a>]<span></h1>
<table class="list">
<thead>
<tr class="odd">
- <th>Domain (<a href="<TMPL_VAR NAME=URL>/?a=AddDomain">add</a>)</th>
+ <th>Domain</th>
<th>Permissions</th>
<th>Description</th>
- <th>Active?</th>
- <th>Action</th>
+ <th>Active</th>
</tr>
</thead>
<tbody>
@@ -38,7 +37,6 @@
<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="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/list-locals.html b/template/list-locals.html
new file mode 100644
index 0000000..76b86ca
--- /dev/null
+++ b/template/list-locals.html
@@ -0,0 +1,125 @@
+<!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>Manage domain <tt><TMPL_VAR NAME=DOMAIN></tt
+ ><TMPL_IF NAME=CANEDIT><span class="edit">[<a href="<TMPL_VAR NAME=URL>/<TMPL_VAR NAME=DOMAIN>/?a=edit">edit domain</a>]<span></TMPL_IF></h1>
+
+ <TMPL_IF NAME=DESCRIPTION><p class="description"><TMPL_VAR NAME=DESCRIPTION></p></TMPL_IF>
+
+ <p>Domain status: <b><TMPL_IF NAME=ISACTIVE><span class="active">Active</span><TMPL_ELSE><span class="inactive">Inactive</span></TMPL_IF></b><p>
+
+
+ <h3>Mailboxes<span class="add">[<a href="<TMPL_VAR NAME=URL>/<TMPL_VAR NAME=DOMAIN>/?a=AddUser">add</a>]</span></h3>
+
+ <table class="list">
+ <thead>
+ <tr class="odd">
+ <th>Account</th>
+ <th>Description</th>
+ <th>Active</th>
+ <th>Forwards</th>
+ <th>Quota</th>
+ </tr>
+ </thead>
+ <tbody>
+ <TMPL_LOOP NAME=MAILBOXES>
+ <TMPL_IF NAME=__even__><tr class="odd"><TMPL_ELSE><tr></TMPL_IF>
+ <td><tt><a href="<TMPL_VAR NAME=URL>/<TMPL_VAR NAME=DOMAIN>/<TMPL_VAR NAME=USER>/"><TMPL_VAR NAME=USER></a></tt></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_UNLESS NAME=FORWARDS><span class="none">(none)</span></TMPL_UNLESS>
+ <TMPL_LOOP NAME=FORWARDS><tt><TMPL_VAR NAME=FORWARD></tt><TMPL_UNLESS NAME=__last__>, </TMPL_UNLESS></TMPL_LOOP></td>
+
+ <td><TMPL_IF NAME=QUOTA><TMPL_VAR NAME=QUOTA><TMPL_ELSE><span class="none">(none)</span></TMPL_IF></td>
+ </tr>
+ </TMPL_LOOP>
+ </tbody>
+ </table>
+
+
+ <br/>
+
+ <h3>Aliases<span class="add">[<a href="<TMPL_VAR NAME=URL>/<TMPL_VAR NAME=DOMAIN>/?a=Addlias">add</a>]</span></h3>
+
+ <table class="list">
+ <thead>
+ <tr class="odd">
+ <th>Alias</th>
+ <th>Description</th>
+ <th>Active</th>
+ <th>Owner(s)</th>
+ <th>Destination</th>
+ </tr>
+ </thead>
+ <tbody>
+ <TMPL_LOOP NAME=ALIASES>
+ <TMPL_IF NAME=__even__><tr class="odd"><TMPL_ELSE><tr></TMPL_IF>
+ <td><tt><a href="<TMPL_VAR NAME=URL>/<TMPL_VAR NAME=DOMAIN>/<TMPL_VAR NAME=ALIAS>/"><TMPL_VAR NAME=ALIAS></a></tt></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_UNLESS NAME=OWNERS><span class="none">(none)</span></TMPL_UNLESS>
+ <TMPL_LOOP NAME=OWNERS><tt><TMPL_VAR NAME=OWNER></tt><TMPL_UNLESS NAME=__last__>, </TMPL_UNLESS></TMPL_LOOP></td>
+ <td><TMPL_UNLESS NAME=DESTINATIONS><span class="none">(none)</span></TMPL_UNLESS>
+ <TMPL_LOOP NAME=DESTINATIONS><tt><TMPL_VAR NAME=DESTINATION></tt><TMPL_UNLESS NAME=__last__>, </TMPL_UNLESS></TMPL_LOOP></td>
+ </tr>
+ </TMPL_LOOP>
+ <TMPL_IF NAME=CATCHALLS>
+ <td>*</td>
+ <td>Catch-all alias(es) for domain <tt><TMPL_VAR NAME=DOMAIN></tt>.</td>
+ <td><TMPL_IF NAME=ISACTIVE><span class="active">&#x2714;</span><TMPL_ELSE><span class="inactive">&#x2718;</span></TMPL_IF></td>
+ <td></td>
+ <td><TMPL_LOOP NAME=CATCHALLS><tt><TMPL_VAR NAME=CATCHALL></tt><TMPL_UNLESS NAME=__last__>, </TMPL_UNLESS></TMPL_LOOP></td>
+ </TMPL_IF>
+ </tbody>
+ </table>
+
+
+ <br/>
+
+ <h3>Lists<span class="add">[<a href="<TMPL_VAR NAME=URL>/<TMPL_VAR NAME=DOMAIN>/?a=Addlist">add</a>]</span></h3>
+
+ <table class="list">
+ <thead>
+ <tr class="odd">
+ <th>List</th>
+ <th>Description</th>
+ <th>Active</th>
+ <th>Owner(s)</th>
+ <th>Tranport</th>
+ </tr>
+ </thead>
+ <tbody>
+ <TMPL_LOOP NAME=LISTS>
+ <TMPL_IF NAME=__even__><tr class="odd"><TMPL_ELSE><tr></TMPL_IF>
+ <td><tt><a href="<TMPL_VAR NAME=URL>/<TMPL_VAR NAME=DOMAIN>/<TMPL_VAR NAME=LIST>/"><TMPL_VAR NAME=LIST></a></tt></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_UNLESS NAME=OWNERS><span class="none">(none)</span></TMPL_UNLESS>
+ <TMPL_LOOP NAME=OWNERS><tt><TMPL_VAR NAME=OWNER></tt><TMPL_UNLESS NAME=__last__>, </TMPL_UNLESS></TMPL_LOOP></td>
+ <td><TMPL_VAR NAME=TRANSPORT></td>
+ </tr>
+ </TMPL_LOOP>
+ </tbody>
+ </table>
+
+
+ </body>
+</html>