package FPanel::Interface; use strict; use warnings; use utf8; use lib 'lib'; use base 'FPanel::Login'; # This method is called right before the 'setup' method below. It # inherits the configuration from the super class. sub cgiapp_init { my $self = shift; $self->SUPER::cgiapp_init; # Every single Run Mode here is protected $self->authen->protected_runmodes( ':all' ); } # This is the first page seen by authenticated users. It lists the known # domains. sub ListDomains : StartRunmode { 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 $domains = $ldap->search( base => $suffix , scope => 'one' , filter => 'objectClass=FripostVirtualDomain' , deref => 'never' ); die $domains->error if $domains->code; $ldap->unbind; 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 ); $template->param( USER_LOCALPART => $l, USER_DOMAINPART => $d); $template->param( DOMAINS => [ map { { DOMAIN => $_->get_value('fvd') , PERMS => &list_perms($_, $authzDN) , DESCRIPTION => join ("\n", $_->get_value('description')) , ISACTIVE => $_->get_value('fripostIsStatusActive') eq 'TRUE' ? 1 : 0 }; } $domains->sorted('fvd') ]); 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 : # - "can create aliases" (a) # - "can create lists" (l) # - "can create aliases & lists" (al) # - "owner" (o) # - "postmaster" (p) sub list_perms { my ($entry, $dn) = @_; my $perms = ''; my $canCreateAlias = $entry->get_value ('fripostCanCreateAlias', asref => 1); $perms .= 'a' if defined $canCreateAlias and grep { $dn eq $_ or (split /,/,$dn,2)[1] eq $_ } @{$canCreateAlias}; my $canCreateList = $entry->get_value ('fripostCanCreateList', asref => 1); $perms .= 'l' if defined $canCreateList and grep { $dn eq $_ or (split /,/,$dn,2)[1] eq $_ } @{$canCreateList}; my $owner = $entry->get_value ('fripostOwner', asref => 1); $perms = 'o' if defined $owner and grep { $dn eq $_ } @{$owner}; my $postmaster = $entry->get_value ('fripostPostmaster', asref => 1); $perms = 'p' if defined $postmaster and grep { $dn eq $_ } @{$postmaster}; if ( $perms =~ /a/) { return 'can create aliases & lists' if ( $perms =~ /l/); return 'can create aliases'; } elsif ( $perms eq 'l' ) { return 'can create lists'; } elsif ( $perms eq 'o' ) { return 'owner'; } elsif ( $perms eq 'p' ) { return 'postmaster'; } } # This method SASL binds the web application and uses the provided # authorization DN. sub ldap_from_auth_user { my $self = shift; my $authzDN = shift; my $ldap = Net::LDAP->new( $self->cfg('ldap_uri'), async => 1, onerror => 'die' ); my $sasl = Authen::SASL->new( mechanism => 'DIGEST-MD5' , callback => { user => $self->cfg('ldap_authcID') , pass => $self->cfg('ldap_authcPW') , authname => "dn:$authzDN" } ); my $mesg = $ldap->bind( sasl => $sasl ) ; die $mesg->error if $mesg->code; return $ldap; } 1;