diff options
author | Guilhem Moulin <guilhem.moulin@fripost.org> | 2012-09-03 00:05:22 +0200 |
---|---|---|
committer | Guilhem Moulin <guilhem.moulin@fripost.org> | 2012-09-03 00:05:22 +0200 |
commit | 3c8b9dba04da6d66f7e592c3c1367a2367e1c5a5 (patch) | |
tree | 57739942759a34ba245f076c2bde0a596adf5e9c | |
parent | 742c9938af740b9ba758f4b03909f30106b285a5 (diff) |
Domain edition.
-rw-r--r-- | css/style.css | 67 | ||||
-rw-r--r-- | lib/FPanel/Interface.pm | 69 | ||||
-rw-r--r-- | lib/FPanel/Login.pm | 24 | ||||
-rw-r--r-- | template/edit-domain.html | 75 | ||||
-rw-r--r-- | template/list-domains.html (renamed from template/domain-list.html) | 9 | ||||
-rw-r--r-- | template/login.html | 6 |
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">✔</span><TMPL_ELSE><span class="nonactive">✘</span></TMPL_IF></td> + <td><TMPL_IF NAME=ISACTIVE><span class="active">✔</span><TMPL_ELSE><span class="inactive">✘</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> |