# vim: set cindent expandtab ts=4 sw=4:
#
# Copyright (c) 1998-2005 Chi-Keung Ho. All rights reserved.
#
# This programe is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# ExtMan - web interface to manage virtual accounts
# $Id$
package Ext::MgrApp::User;
use strict;
use Exporter;
use vars qw(@ISA @EXPORT);
@ISA = qw(Exporter Ext::MgrApp);
use POSIX qw(strftime);
use Ext::Utils; # import url2str
use Ext::MgrApp;
use vars qw($lang_charset %lang_user $default_expire);
use Ext::Lang;
sub init {
my $self = shift;
$self->SUPER::init(@_);
return unless($self->valid||$self->permit);
$self->add_methods(add_user => \&add_user);
$self->add_methods(edit_user => \&edit_user);
$self->add_methods(save_user => \&save_user);
$self->add_methods(delete_user => \&delete_user);
$self->{default_mode} = 'edit_user';
$default_expire = $self->cvt2expire(strftime("%Y-%m-%d %H:%M:%S", localtime));
$self->_initme;
$self;
}
sub _initme {
initlang($_[0]->{sysconfig}->{'SYS_LANG'}, __PACKAGE__);
$_[0]->{tpl}->assign( lang_charset => $lang_charset );
$_[0]->{tpl}->assign( \%lang_user );
}
sub add_user {
my $self = shift;
my $tpl = $self->{tpl};
my $mgr = $self->{backend};
my $q = $self->{query};
my $sys = $self->{sysconfig};
my $domain = lc $q->cgi('domain');
my $domains = [];
if ($ENV{USERTYPE} eq 'admin') {
my $alldomain = $mgr->get_domains_list;
foreach my $d ( @$alldomain ) {
push @$domains, $d->{domain};
}
} else {
my $pm = $mgr->get_manager_info($ENV{USERNAME});
$domains = $pm->{domain};
}
if (!$domain) {
$domain = $domains->[0]; # the first?
}
my $info = $mgr->get_domain_info($domain);
if (keys %$info) {
my $multiplier = $self->{sysconfig}->{SYS_QUOTA_MULTIPLIER} || '1048576';
if ($info->{default_expire}) {
$default_expire = $self->cvt2expire(
strftime("%Y-%m-%d %H:%M:%S", localtime),
$info->{default_expire},
);
}
if ($info->{default_quota}) {
$info->{default_quota} = $self->quota2num($info->{default_quota})/$multiplier;
}
if ($info->{default_ndquota}) {
$info->{default_ndquota} = $self->quota2num($info->{default_ndquota})/$multiplier;
}
}
$tpl->assign(
HAVE_USER => 1,
NEWADD => 1,
EXPIRE => $default_expire,
ACTIVE => 1,
QUOTA => $info->{default_quota} || $sys->{SYS_USER_DEFAULT_QUOTA} || '0',
NDQUOTA => $info->{default_ndquota} || $sys->{SYS_USER_DEFAULT_NDQUOTA} || '0',
UID => $sys->{SYS_DEFAULT_UID},
GID => $sys->{SYS_DEFAULT_GID},
);
for my $s ( split(/,/, $sys->{SYS_USER_ROUTING_LIST}) ) {
$s =~ s/\s+//;
$tpl->assign(
'LOOP_ROUTING_LIST',
MAILHOST => $s,
);
}
if (keys %$info) {
for my $s (qw(smtpd smtp webmail netdisk imap pop3)) {
$tpl->assign( "SERVICES_$s" => $info->{"disable".$s} ? 0 : 1 );
$tpl->assign( "NOCHK_$s" => $info->{"disable".$s} ? 1 : 0 )
if ($ENV{USERTYPE} ne 'admin');
}
} else {
for my $s ( split(/,/, $sys->{SYS_DEFAULT_SERVICES}) ) {
$tpl->assign( "SERVICES_$s" => 1 );
}
}
if ($domains) {
$domains = [$domains] unless (ref $domains);
foreach my $vd ( @$domains ) {
$tpl->assign(
'LOOP_DOMAIN',
DOMAIN => $vd,
DOMAIN_CHK => ($vd eq lc $domain ? 1 : 0),
);
}
} else {
# no permission or not assign domain
$tpl->assign(NOPERM => 1);
$tpl->assign(HAVE_USER => 0);
}
}
sub edit_user {
my $self = shift;
my $tpl = $self->{tpl};
my $mgr = $self->{backend};
my $q = $self->{query};
my $multiplier = $self->{sysconfig}->{SYS_QUOTA_MULTIPLIER} || '1048576';
my $user = $q->cgi('user') || $q->cgi('username').'@'.$q->cgi('domain');
my $ui = $mgr->get_user_info($user);
return 0 unless($ui);
# permission validation
unless ($self->valid_perm($ui->{domain})) {
$self->error('Access denied');
return 0;
}
my ($uname) = ($ui->{mail} =~ m!(.*)@.*!);
$tpl->assign(HAVE_USER => 1);
$tpl->assign(
MAIL => $ui->{mail},
UNAME => $uname,
NAME => $ui->{cn} || $ui->{username},
DOMAIN => $ui->{domain},
MAILHOST => $ui->{mailhost},
UID => $ui->{uidnumber},
GID => $ui->{gidnumber},
EXPIRE => $ui->{expire},
PASSWD => "",
QUOTA => $self->quota2num($ui->{quota})/$multiplier,
NDQUOTA => $self->quota2num($ui->{netdiskquota})/$multiplier,
ACTIVE => $ui->{active},
DISABLEPWDCHANGE => $ui->{disablepwdchange},
);
my $info = $mgr->get_domain_info($ui->{domain});
for my $srv (qw(smtpd smtp webmail netdisk imap pop3)) {
$tpl->assign( 'SERVICES_'.$srv => $ui->{"disable$srv"} ? 0 : 1 );
$tpl->assign( 'NOCHK_'.$srv => $info->{"disable$srv"} ? 1 : 0 )
if ($ENV{USERTYPE} ne 'admin');
}
}
sub save_user {
my $self = shift;
my $tpl = $self->{tpl};
my $mgr = $self->{backend};
my $q = $self->{query};
my $multiplier = $self->{sysconfig}->{SYS_QUOTA_MULTIPLIER} || '1048576';
my ($user, $domain) = (lc $q->cgi('username'), lc $q->cgi('domain'));
# permission validation
unless ($self->valid_perm($domain)) {
$self->error('Access denied');
return 0;
}
if (!$self->sanity_username($user)) {
$self->error('Bad username');
return 0;
}
if ($mgr->get_user_info("$user\@$domain")) {
if ($q->cgi('newadd')) {
$tpl->assign(ERROR => $lang_user{'user_exist'});
$self->add_user;
return 0;
}else {
# save the change
my $pwd1 = $q->cgi('passwd1');
my $pwd2 = $q->cgi('passwd2');
if ($pwd1 && $pwd2) {
if ($pwd1 ne $pwd2) {
# pwd1 != pwd2, password modification fail, abort
$tpl->assign(ERROR => $lang_user{'errinput_passwd'});
return 0;
}
}
if (!$self->valid_time($q->cgi('expire'))) {
$tpl->assign(ERROR => $lang_user{'err_time'});
$self->edit_user;
return;
}
my $old = $mgr->get_user_info("$user\@$domain");
my $oldquota = $self->quota2num($old->{quota});
my $oldndquota = $self->quota2num($old->{netdiskquota});
my $newquota = $multiplier*$q->cgi('quota'); # number
my $newndquota = $multiplier*$q->cgi('netdiskquota'); # number
#die "$newndquota $oldndquota\n";
my $rc = $self->domain_overusage(
domain => $domain,
quota => ($newquota - $oldquota > 0 ? $newquota - $oldquota : 0 ),
ndquota => ($newndquota - $oldndquota > 0 ? $newndquota - $oldndquota : 0 ),
);
$rc = $mgr->modify_user(
user => "$user\@$domain",
domain => $domain,
cn => $q->cgi('cn'),
uidnumber => $q->cgi('uid'),
gidnumber => $q->cgi('gid'),
expire => $q->cgi('expire'),
passwd => $pwd1,
quota => $self->num2quota($multiplier*$q->cgi('quota')),
netdiskquota => $self->num2quota($multiplier*$q->cgi('netdiskquota')),
active => $q->cgi('active'),
disablepwdchange => $q->cgi('disablepwdchange') ? 1 : 0,
disablesmtpd => $q->cgi('SERVICES_smtpd') ? 0 : 1,
disablesmtp => $q->cgi('SERVICES_smtp') ? 0 : 1,
disablewebmail => $q->cgi('SERVICES_webmail') ? 0 : 1,
disablenetdisk => $q->cgi('SERVICES_netdisk') ? 0 : 1,
disablepop3 => $q->cgi('SERVICES_pop3') ? 0 : 1,
disableimap => $q->cgi('SERVICES_imap') ? 0 : 1,
) unless ($rc);
if ($rc) {
$tpl->assign(ERROR => sprintf($lang_user{'modify_fail'}, $q->cgi('username')).$rc);
}else {
$tpl->assign(SUCCESS => sprintf($lang_user{'modify_ok'}, $q->cgi('username')));
}
$self->edit_user;
}
} else {
# no such user
if ($q->cgi('newadd')) {
# new add user
my $pwd1 = $q->cgi('passwd1');
my $pwd2 = $q->cgi('passwd2');
# include all possible state:
# 1) pwd1 null, pwd2 not null
# 2) pwd2 null, pwd1 not null
# 3) pwd2 and pwd1 not null, but not eq
if ($pwd1 ne $pwd2) {
$tpl->assign(ERROR => $lang_user{'errinput_passwd'});
return 0;
}
if (!$self->valid_time($q->cgi('expire'))) {
$tpl->assign(ERROR => $lang_user{'err_time'});
$self->add_user;
return;
}
my $rc = $self->domain_overusage(
domain => $domain,
quota => $multiplier*$q->cgi('quota'),
user => 1, # new add, must exists
ndquota => $multiplier*$q->cgi('netdiskquota'),
);
my $d_hashdir = $self->get_domain_hashdir($domain);
my $u_hashdir = $self->gen_user_hashdir;
my $path;
if ($self->{sysconfig}->{SYS_ISP_MODE} eq 'yes') {
$path = ($d_hashdir ? "$d_hashdir/" : "").
"$domain/" .($u_hashdir? "$u_hashdir/" : "").
$user;
} else {
$path = "$domain/$user";
}
$rc = $mgr->add_user(
mail => "$user\@$domain",
domain => $domain,
uid => $user,
cn => $q->cgi('cn'),
uidnumber => $q->cgi('uid'),
gidnumber => $q->cgi('gid'),
# new user attributes here
create => strftime("%Y-%m-%d %H:%M:%S", localtime),
expire => $q->cgi('expire'),
passwd => $pwd1,
quota => $self->num2quota($multiplier*$q->cgi('quota')),
mailhost => $q->cgi('mailhost'),
maildir => "$path/Maildir/",
homedir => $path,
netdiskquota => $self->num2quota($multiplier*$q->cgi('netdiskquota')),
active => $q->cgi('active'),
disablepwdchange => $q->cgi('disablepwdchange') ? 1 : 0,
disablesmtpd => $q->cgi('SERVICES_smtpd') ? 0 : 1,
disablesmtp => $q->cgi('SERVICES_smtp') ? 0 : 1,
disablewebmail => $q->cgi('SERVICES_webmail') ? 0 : 1,
disablenetdisk => $q->cgi('SERVICES_netdisk') ? 0 : 1,
disablepop3 => $q->cgi('SERVICES_pop3') ? 0 : 1,
disableimap => $q->cgi('SERVICES_imap') ? 0 : 1,
) unless ($rc);
if ($rc) {
$tpl->assign(ERROR => sprintf($lang_user{'add_fail'}, "$user\@$domain").$rc);
} else {
$tpl->assign(SUCCESS => sprintf($lang_user{'add_ok'}, "$user\@$domain"));
my $dir = $self->{sysconfig}->{SYS_CONFIG};
my $base = $self->{sysconfig}->{SYS_MAILDIR_BASE};
system("$dir/tools/maildirmake.pl $base/$path/Maildir/");
}
$self->add_user;
} else {
$tpl->assign(ERROR => $lang_user{'no_such_user'});
}
}
}
sub delete_user {
my $self = shift;
my $tpl = $self->{tpl};
my $q = $self->{query};
my $mgr = $self->{backend};
my $user = lc $q->cgi('user');
my ($domain) = ($user =~ m!.*@(.*)!);
# permission validation
unless ($self->valid_perm($domain)) {
$self->error('Access denied');
return 0;
}
if ($mgr->get_user_info($user)) {
my $rc = $mgr->delete_user($user);
if ($rc) {
$tpl->assign(ERROR => "Delete fail!");
} else {
$tpl->{noprint} = 1;
$self->{redirect} = url2str($q->cgi('url'));
}
} else {
$tpl->assign(ERROR => $lang_user{'no_such_user'});
}
}
sub pre_run { 1 }
sub post_run {
my $template = $_[0]->{query}->cgi('screen') || 'edit_user.html';
$_[0]->{tpl}->process($template);
$_[0]->{tpl}->print;
}
1;
syntax highlighted by Code2HTML, v. 0.9.1