407 lines
9.9 KiB
Perl
407 lines
9.9 KiB
Perl
|
package SrvMngr::Controller::Pseudonyms;
|
||
|
|
||
|
#----------------------------------------------------------------------
|
||
|
# heading : User management
|
||
|
# description : Pseudonyms
|
||
|
# navigation : 2000 210
|
||
|
#----------------------------------------------------------------------
|
||
|
#
|
||
|
# routes : end
|
||
|
#----------------------------------------------------------------------
|
||
|
use strict;
|
||
|
use warnings;
|
||
|
use Mojo::Base 'Mojolicious::Controller';
|
||
|
|
||
|
use Locale::gettext;
|
||
|
use SrvMngr::I18N;
|
||
|
|
||
|
use SrvMngr qw(theme_list init_session);
|
||
|
|
||
|
#use Data::Dumper;
|
||
|
|
||
|
#use esmith::FormMagick::Panel::pseudonyms;
|
||
|
use esmith::AccountsDB;
|
||
|
#use URI::Escape;
|
||
|
|
||
|
|
||
|
our $cdb = esmith::ConfigDB->open || die "Couldn't open configuration db";
|
||
|
our $adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
|
||
|
|
||
|
sub main {
|
||
|
|
||
|
my $c = shift;
|
||
|
$c->app->log->info($c->log_req);
|
||
|
|
||
|
my %pse_datas = ();
|
||
|
my $title = $c->l('pse_FORM_TITLE');
|
||
|
my $notif = '';
|
||
|
|
||
|
$pse_datas{trt} = 'LST';
|
||
|
|
||
|
my @pseudonyms;
|
||
|
if ($adb)
|
||
|
{
|
||
|
@pseudonyms = $adb->pseudonyms();
|
||
|
}
|
||
|
|
||
|
$c->stash( title => $title, notif => $notif, pse_datas => \%pse_datas, pseudonyms => \@pseudonyms );
|
||
|
$c->render(template => 'pseudonyms');
|
||
|
|
||
|
};
|
||
|
|
||
|
|
||
|
sub do_display {
|
||
|
|
||
|
my $c = shift;
|
||
|
$c->app->log->info($c->log_req);
|
||
|
|
||
|
my $rt = $c->current_route;
|
||
|
my $trt = ($c->param('trt') || 'LST');
|
||
|
my $pseudonym = $c->param('pseudonym') || '';
|
||
|
|
||
|
my $title = $c->l('pse_FORM_TITLE');
|
||
|
my %pse_datas = ();
|
||
|
$pse_datas{'trt'} = $trt;
|
||
|
|
||
|
if ( $trt eq 'ADD' ) {
|
||
|
#nothing
|
||
|
}
|
||
|
|
||
|
if ( $trt eq 'UPD' ) {
|
||
|
|
||
|
my $rec = $adb->get($pseudonym);
|
||
|
if ($rec and $rec->prop('type') eq 'pseudonym') {
|
||
|
|
||
|
$pse_datas{pseudonym} = $pseudonym;
|
||
|
$pse_datas{account} = $rec->prop('Account') || '';
|
||
|
$pse_datas{internal} = is_pseudonym_internal($pseudonym);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( $trt eq 'DEL' ) {
|
||
|
|
||
|
my $rec = $adb->get($pseudonym);
|
||
|
if ($rec and $rec->prop('type') eq 'pseudonym') {
|
||
|
|
||
|
$pse_datas{pseudonym} = $pseudonym;
|
||
|
$pse_datas{account} = $rec->prop('Account') || '';
|
||
|
$pse_datas{internal} = is_pseudonym_internal($pseudonym);
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( $trt eq 'LST' ) {
|
||
|
my @pseudonyms;
|
||
|
if ($adb) {
|
||
|
@pseudonyms = $adb->pseudonyms();
|
||
|
}
|
||
|
$c->stash( pseudonyms => \@pseudonyms );
|
||
|
|
||
|
}
|
||
|
|
||
|
$c->stash( title => $title, pse_datas => \%pse_datas );
|
||
|
$c->render( template => 'pseudonyms' );
|
||
|
|
||
|
};
|
||
|
|
||
|
|
||
|
sub do_update {
|
||
|
|
||
|
my $c = shift;
|
||
|
$c->app->log->info($c->log_req);
|
||
|
|
||
|
my $rt = $c->current_route;
|
||
|
my $trt = ($c->param('trt') || 'LST');
|
||
|
|
||
|
my $title = $c->l('pse_FORM_TITLE');
|
||
|
my %pse_datas = ();
|
||
|
$pse_datas{'trt'} = $trt;
|
||
|
|
||
|
my ($res, $result) = '';
|
||
|
|
||
|
#my $pseudonym = uri_unescape($c->param('Pseudonym'));
|
||
|
my $pseudonym = $c->param('Pseudonym');
|
||
|
$pse_datas{'pseudonym'} = $pseudonym;
|
||
|
|
||
|
if ( $trt eq 'ADD' ) {
|
||
|
|
||
|
my $account = $c->param('Account');
|
||
|
|
||
|
# controls
|
||
|
$res = $c->validate_new_pseudonym_name( $pseudonym, $account );
|
||
|
$result .= $res unless $res eq 'OK';
|
||
|
|
||
|
#$result .= ' blocked';
|
||
|
|
||
|
$res = '';
|
||
|
if ( ! $result ) {
|
||
|
$adb->new_record( $pseudonym, { type => 'pseudonym',
|
||
|
Account => $account} )
|
||
|
or $result .= "Error occurred while creating pseudonym in database.";
|
||
|
# Untaint $pseudonym before use in system()
|
||
|
($pseudonym) = ($pseudonym =~ /(.+)/);
|
||
|
system( "/sbin/e-smith/signal-event", "pseudonym-create", "$pseudonym",)
|
||
|
== 0 or $result .= 'pse_CREATE_ERROR.';
|
||
|
}
|
||
|
if ( ! $result ) {
|
||
|
$res = 'OK';
|
||
|
$result = $c->l('pse_CREATE_SUCCEEDED') . ' ' . $pseudonym;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( $trt eq 'UPD' ) {
|
||
|
|
||
|
my $account = $c->param('Account');
|
||
|
my $internal = $c->param ('Internal') || 'NO';
|
||
|
my $removable = $adb->get($pseudonym)->prop('Removable') || 'yes';
|
||
|
|
||
|
my %props = ('Account' => $account);
|
||
|
|
||
|
if ($removable eq 'yes') {
|
||
|
if ($internal eq "YES") { $props{'Visible'} = 'internal'; }
|
||
|
else { $adb->get($pseudonym)->delete_prop('Visible'); }
|
||
|
}
|
||
|
|
||
|
# controls
|
||
|
#$res = '';
|
||
|
#$res = validate_description( $c, $account );
|
||
|
#$result .= $res unless $res eq 'OK';
|
||
|
|
||
|
#$result .= 'blocked';
|
||
|
|
||
|
$res = '';
|
||
|
if ( ! $result ) {
|
||
|
$adb->get($pseudonym)->merge_props(%props)
|
||
|
or $result .= "Error occurred while modifying pseudonym in database.";
|
||
|
# Untaint $pseudonym before use in system()
|
||
|
($pseudonym) = ($pseudonym =~ /(.+)/);
|
||
|
system( "/sbin/e-smith/signal-event", "pseudonym-modify", "$pseudonym",)
|
||
|
== 0 or $result .= "Error occurred while modifying pseudonym.";
|
||
|
}
|
||
|
if ( ! $result ) {
|
||
|
$res = 'OK';
|
||
|
$result = $c->l('pse_MODIFY_SUCCEEDED') . ' ' . $pseudonym;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( $trt eq 'DEL' ) {
|
||
|
|
||
|
# controls
|
||
|
$res = '';
|
||
|
$res = validate_is_pseudonym($c, $pseudonym);
|
||
|
$result .= $res unless $res eq 'OK';
|
||
|
|
||
|
#$result .= 'blocked';
|
||
|
|
||
|
$res = '';
|
||
|
if ( ! $result ) {
|
||
|
$res = $c->delete_pseudonym( $pseudonym );
|
||
|
$result .= $res unless $res eq 'OK';
|
||
|
if ( ! $result ) {
|
||
|
$res = 'OK';
|
||
|
$result = $c->l('pse_REMOVE_SUCCEEDED') . ' ' . $pseudonym;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
# common parts
|
||
|
|
||
|
if ( $res ne 'OK' ) {
|
||
|
$c->stash( error => $result);
|
||
|
$c->stash( title => $title, pse_datas => \%pse_datas );
|
||
|
return $c->render('pseudonyms');
|
||
|
}
|
||
|
|
||
|
my $message = "'Pseudonyms' updates $trt DONE";
|
||
|
$c->app->log->info($message);
|
||
|
$c->flash( success => $result );
|
||
|
|
||
|
$c->redirect_to('/pseudonyms');
|
||
|
|
||
|
};
|
||
|
|
||
|
|
||
|
sub delete_pseudonym {
|
||
|
|
||
|
my ($c, $pseudonym) = @_;
|
||
|
|
||
|
my $msg = '';
|
||
|
#------------------------------------------------------------
|
||
|
# Make the pseudonym inactive, signal pseudonym-delete event
|
||
|
# and then delete it
|
||
|
#------------------------------------------------------------
|
||
|
|
||
|
my @pseudonyms = $adb->pseudonyms();
|
||
|
|
||
|
foreach my $p_rec (@pseudonyms) {
|
||
|
if ($p_rec->prop("Account") eq $pseudonym) {
|
||
|
$adb->get($p_rec->key)->set_prop('type','pseudonym-deleted')
|
||
|
or $msg .= "Error occurred while changing pseudonym type.";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$adb->get($pseudonym)->set_prop('type','pseudonym-deleted')
|
||
|
or $msg .= "Error occurred while changing pseudonym type.";
|
||
|
|
||
|
# Untaint $pseudonym before use in system()
|
||
|
($pseudonym) = ($pseudonym =~ /(.+)/);
|
||
|
system( "/sbin/e-smith/signal-event", "pseudonym-delete", "$pseudonym") == 0
|
||
|
or $msg .= "Error occurred while removing pseudonym.";
|
||
|
|
||
|
#TODO: is it ->delete or get()->delete
|
||
|
foreach my $p_rec (@pseudonyms) {
|
||
|
if ($p_rec->prop("Account") eq $pseudonym) {
|
||
|
$adb->get($p_rec->key)->delete()
|
||
|
or $msg .= "Error occurred while deleting pseudonym from database.";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$adb->get($pseudonym)->delete()
|
||
|
or $msg .= "Error occurred while deleting pseudonym from database.";
|
||
|
|
||
|
return $msg unless $msg;
|
||
|
|
||
|
return 'OK';
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
sub existing_accounts_list {
|
||
|
my $c = shift;
|
||
|
|
||
|
my @existingAccounts = ( ['Administrator' => 'admin']);
|
||
|
|
||
|
foreach my $a ($adb->get_all) {
|
||
|
if ($a->prop('type') =~ /(user|group)/) {
|
||
|
push @existingAccounts, [ $a->key => $a->key ];
|
||
|
}
|
||
|
if ($a->prop('type') eq "pseudonym") {
|
||
|
my $target = $adb->get($a->prop('Account'));
|
||
|
|
||
|
unless ($target)
|
||
|
{
|
||
|
warn "WARNING: pseudonym (" . $a->key . ") => missing Account("
|
||
|
. $a->prop('Account') . ")\n";
|
||
|
next;
|
||
|
}
|
||
|
|
||
|
push @existingAccounts, [ $a->key, $a->key ]
|
||
|
unless ($target->prop('type') eq "pseudonym");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return(\@existingAccounts);
|
||
|
}
|
||
|
|
||
|
|
||
|
=head2 get_pseudonym_account
|
||
|
|
||
|
Returns the current Account property for this pseudonym
|
||
|
|
||
|
=cut
|
||
|
|
||
|
sub get_pseudonym_account {
|
||
|
my $c = shift;
|
||
|
my $pseudonym = shift;
|
||
|
|
||
|
my $a = $adb->get($pseudonym)->prop('Account');
|
||
|
if ($a eq "admin") {
|
||
|
$a = "Administrator";
|
||
|
} elsif ($a eq "shared") {
|
||
|
$a = $c->l("EVERYONE");
|
||
|
}
|
||
|
return($a);
|
||
|
}
|
||
|
|
||
|
=head2 is_pseudonym_not_removable
|
||
|
|
||
|
Returns 1 if the current Account is not removable, 0 otherwise
|
||
|
|
||
|
=cut
|
||
|
|
||
|
sub is_pseudonym_not_removable {
|
||
|
my $c = shift;
|
||
|
my $pseudonym = shift;
|
||
|
|
||
|
my $removable = $adb->get($pseudonym)->prop('Removable') || 'yes';
|
||
|
return 1 if ($removable eq 'yes');
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
=head2 is_pseudonym_internal
|
||
|
|
||
|
Returns YES if the current Account property Visible is 'internal'
|
||
|
|
||
|
=cut
|
||
|
|
||
|
sub is_pseudonym_internal {
|
||
|
# my $c = shift;
|
||
|
my $pseudonym = shift;
|
||
|
|
||
|
my $visible = $adb->get($pseudonym)->prop('Visible') || '';
|
||
|
return 'YES' if ($visible eq 'internal');
|
||
|
return 'NO';
|
||
|
}
|
||
|
|
||
|
=head2 validate_new_pseudonym_name FM PSEUDONYM
|
||
|
|
||
|
Returns "OK" if the pseudonym starts with a letter or number and
|
||
|
contains only letters, numbers, . - and _ and isn't taken
|
||
|
|
||
|
Returns "VALID_PSEUDONYM_NAMES" if the name contains invalid chars
|
||
|
|
||
|
Returns "NAME_IN_USE" if this pseudonym is taken.
|
||
|
|
||
|
=cut
|
||
|
|
||
|
sub validate_new_pseudonym_name {
|
||
|
|
||
|
my ($c, $pseudonym, $account) = @_;
|
||
|
|
||
|
my $acct = $adb->get($pseudonym);
|
||
|
|
||
|
if (defined $acct) {
|
||
|
return($c->l('pse_NAME_IN_USE'));
|
||
|
|
||
|
} elsif ($pseudonym =~ /@/) {
|
||
|
use esmith::DomainsDB;
|
||
|
my $ddb = esmith::DomainsDB->open_ro
|
||
|
or die "Couldn't open DomainsDB\n";
|
||
|
my ($lhs, $rhs) = split /@/, $pseudonym;
|
||
|
return ($c->l('pse_PSEUDONYM_INVALID_DOMAIN')) unless ($ddb->get($rhs));
|
||
|
return ($c->l('pse_PSEUDONYM_INVALID_SAMEACCT')) if ($lhs eq $account);
|
||
|
return ('OK'); # p:' . $pseudonym . ' a:' . $account);
|
||
|
|
||
|
} elsif ( $pseudonym !~ /^([a-z0-9][a-z0-9\.\-_!#\?~\$\^\+&`%\/\*]*)$/ ) {
|
||
|
return($c->l('pse_VALID_PSEUDONYM_NAMES'));
|
||
|
} else {
|
||
|
return('OK');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
=head2 validate_is_pseudonym FM NAME
|
||
|
|
||
|
returns "OK" if it is.
|
||
|
returns "NOT_A_PSEUDONYM" if the name in question isn't an existing pseudonym
|
||
|
|
||
|
=cut
|
||
|
|
||
|
sub validate_is_pseudonym {
|
||
|
my $c = shift;
|
||
|
my $pseudonym = shift;
|
||
|
|
||
|
$pseudonym = $adb->get($pseudonym);
|
||
|
return($c->l('pse_NOT_A_PSEUDONYM')) unless $pseudonym;
|
||
|
|
||
|
my $type = $pseudonym->prop('type');
|
||
|
unless (defined $type && ($type eq 'pseudonym') ) {
|
||
|
return($c->l('NOT_A_PSEUDONYM'));
|
||
|
}
|
||
|
|
||
|
return ('OK');
|
||
|
}
|
||
|
|
||
|
|
||
|
1;
|