2670 lines
70 KiB
Plaintext
2670 lines
70 KiB
Plaintext
=====Maacom 0.01 code=====
|
|
|
|
====maacom.pl====
|
|
|
|
<code perl maacom.pl>
|
|
#!@perl@
|
|
|
|
#----------
|
|
#--- DB ---
|
|
#----------
|
|
|
|
package aDB;
|
|
|
|
use strict;
|
|
use warnings;
|
|
use DBI;
|
|
use DBD::Pg;
|
|
|
|
sub new {
|
|
my ($class, %args) = @_;
|
|
my $self = {
|
|
hostname => $args{hostname} || '',
|
|
username => $args{username} || '',
|
|
password => $args{password} || '',
|
|
database => $args{database} || '',
|
|
engine => $args{engine} || 'SQLite',
|
|
error => ''
|
|
};
|
|
bless $self, $class;
|
|
return $self;
|
|
}
|
|
|
|
sub username {
|
|
my ($self, $username) = @_;
|
|
return $self->{username} unless $username;
|
|
$self->{username} = $username;
|
|
$self;
|
|
}
|
|
|
|
sub password {
|
|
my ($self, $password) = @_;
|
|
return $self->{password} unless $password;
|
|
$self->{password} = $password;
|
|
$self;
|
|
}
|
|
|
|
sub hostname {
|
|
my ($self, $hostname) = @_;
|
|
return $self->{hostname} unless $hostname;
|
|
$self->{hostname} = $hostname;
|
|
$self;
|
|
}
|
|
|
|
sub database {
|
|
my ($self, $database) = @_;
|
|
return $self->{database} unless $database;
|
|
$self->{database} = $database;
|
|
$self;
|
|
}
|
|
|
|
sub error {
|
|
my ($self, $error) = @_;
|
|
return $self->{error} unless $error;
|
|
$self->{error} = $error;
|
|
$self;
|
|
}
|
|
|
|
sub engine {
|
|
my ($self, $engine) = @_;
|
|
return $self->{engine} unless $engine;
|
|
$self->{engine} = $engine;
|
|
$self;
|
|
}
|
|
|
|
sub exec {
|
|
my ($self, $query) = @_;
|
|
return undef unless $query;
|
|
|
|
my $dsn = 'dbi:'.$self->engine.
|
|
':dbname='.$self->database.
|
|
';host='.$self->hostname;
|
|
my $dbi;
|
|
eval {
|
|
$dbi = DBI->connect($dsn, $self->username, $self->password, {
|
|
RaiseError => 1,
|
|
PrintError => 0,
|
|
AutoCommit => 1
|
|
});
|
|
};
|
|
$self->error($@);
|
|
return undef if $@;
|
|
|
|
my $sth;
|
|
# eval {
|
|
$sth = $dbi->prepare($query);
|
|
# };
|
|
$self->error($@);
|
|
return undef if $@;
|
|
|
|
my $rows = $sth->execute;
|
|
my @list;
|
|
|
|
while (my $row = $sth->fetchrow_hashref) {
|
|
push @list, $row;
|
|
}
|
|
$sth->finish;
|
|
$dbi->disconnect;
|
|
\@list;
|
|
}
|
|
|
|
sub exec1 {
|
|
my ($self, $query) = @_;
|
|
return undef unless $query;
|
|
|
|
my $dsn = 'dbi:'.$self->engine.
|
|
':dbname='.$self->database.
|
|
';host='.$self->hostname;
|
|
my $dbi;
|
|
# eval {
|
|
$dbi = DBI->connect($dsn, $self->username, $self->password, {
|
|
RaiseError => 1,
|
|
PrintError => 0,
|
|
AutoCommit => 1
|
|
});
|
|
# };
|
|
$self->error($@);
|
|
return undef if $@;
|
|
|
|
my $sth;
|
|
eval {
|
|
$sth = $dbi->prepare($query);
|
|
};
|
|
$self->error($@);
|
|
return undef if $@;
|
|
|
|
my $rows = $sth->execute;
|
|
my $row = $sth->fetchrow_hashref;
|
|
|
|
$sth->finish;
|
|
$dbi->disconnect;
|
|
$row;
|
|
}
|
|
|
|
sub do {
|
|
my ($self, $query) = @_;
|
|
return undef unless $query;
|
|
my $dsn = 'dbi:'.$self->engine.
|
|
':dbname='.$self->database.
|
|
';host='.$self->hostname;
|
|
my $dbi;
|
|
eval {
|
|
$dbi = DBI->connect($dsn, $self->username, $self->password, {
|
|
RaiseError => 1,
|
|
PrintError => 0,
|
|
AutoCommit => 1
|
|
});
|
|
};
|
|
$self->error($@);
|
|
return undef if $@;
|
|
my $rows;
|
|
eval {
|
|
$rows = $dbi->do($query);
|
|
};
|
|
$self->error($@);
|
|
return undef if $@;
|
|
|
|
$dbi->disconnect;
|
|
$rows*1;
|
|
}
|
|
|
|
1;
|
|
|
|
#------------
|
|
#--- USER ---
|
|
#------------
|
|
|
|
package aUser;
|
|
|
|
use strict;
|
|
use warnings;
|
|
use Digest::SHA qw(sha512_base64);
|
|
|
|
sub new {
|
|
my ($class, $db) = @_;
|
|
my $self = { db => $db};
|
|
bless $self, $class;
|
|
return $self;
|
|
}
|
|
|
|
sub db {
|
|
my ($self, $db) = @_;
|
|
return $self->{db} unless $db;
|
|
$self->{db} = $db;
|
|
$self;
|
|
}
|
|
|
|
# --- DOMAIN ---
|
|
|
|
sub domain_exist {
|
|
my ($self, $name) = @_;
|
|
return undef unless $name;
|
|
my $res = $self->db->exec1("select id from domains where name = '$name' order by id limit 1");
|
|
$res->{id};
|
|
}
|
|
|
|
sub domain_profile {
|
|
my ($self, $id) = @_;
|
|
return undef unless $id;
|
|
my $row = $self->db->exec1("select * from domains where domains.id = $id limit 1");
|
|
$row;
|
|
}
|
|
|
|
sub domain_user_count {
|
|
my ($self, $id) = @_;
|
|
return undef unless $id;
|
|
my $row = $self->db->exec1("select count(users.name) as count
|
|
from domains, users
|
|
where domains.id = users.domain_id and domains.id = $id
|
|
limit 1");
|
|
$row->{count} || 0;
|
|
}
|
|
|
|
sub domain_alias_count {
|
|
my ($self, $id) = @_;
|
|
return undef unless $id;
|
|
my $row = $self->db->exec1("select count(aliases.name) as count
|
|
from domains, aliases
|
|
where domains.id = aliases.domain_id and domains.id = $id
|
|
limit 1");
|
|
$row->{count} || 0;
|
|
}
|
|
|
|
sub domain_nextid {
|
|
my $self = shift;
|
|
my $res = $self->db->exec1("select id from domains order by id desc limit 1");
|
|
my $id = $res->{id} || 0;
|
|
$id += 1;
|
|
}
|
|
|
|
sub domain_add {
|
|
my ($self, $name) = @_;
|
|
return undef unless $name;
|
|
return undef if $self->domain_exist($name);
|
|
my $next_id = $self->domain_nextid;
|
|
$self->db->do("insert into domains (id, name) values ($next_id, '$name')");
|
|
$self->domain_exist($name);
|
|
}
|
|
|
|
sub domain_list {
|
|
my $self = shift;
|
|
$self->db->exec("select * from domains order by id");
|
|
}
|
|
|
|
sub domain_update {
|
|
my ($self, $id, %args) = @_;
|
|
return undef unless $id;
|
|
my $prof = $self->domain_profile($id);
|
|
return undef unless $prof;
|
|
|
|
my $name = $args{name} || $prof->{name};
|
|
my $quota = $args{quota} || $prof->{quota};
|
|
my $size = $prof->{size};
|
|
$size = $args{size} if $args{size} >= 0;
|
|
|
|
$self->db->do("update domains set name = '$name', size = $size, quota = $quota where id = $id");
|
|
my $res = $self->domain_profile($id);
|
|
return undef unless $res->{name} eq $name;
|
|
$id;
|
|
}
|
|
|
|
|
|
sub domain_delete {
|
|
my ($self, $id) = @_;
|
|
return undef unless $id;
|
|
# return $id unless $self->domain_profile($id);
|
|
$self->db->do("delete from domains where id = $id");
|
|
$self->db->do("delete from users where domain_id = $id");
|
|
$self->db->do("delete from aliases where domain_id = $id");
|
|
return undef if $self->domain_profile($id);
|
|
$id;
|
|
}
|
|
|
|
sub alias_exist {
|
|
my ($self, $name, $domain_id) = @_;
|
|
return undef unless $name;
|
|
return undef unless $domain_id;
|
|
my $res = $self->db->exec1("select a.id as id from domains d, aliases a
|
|
where a.name = '$name' and a.domain_id = $domain_id
|
|
limit 1");
|
|
$res->{id};
|
|
}
|
|
|
|
sub alias_profile {
|
|
my ($self, $id) = @_;
|
|
return undef unless $id;
|
|
$self->db->exec1("select a.id as id,
|
|
a.name as name,
|
|
a.name || '\@' || d.name as address,
|
|
a.domain_id as domain_id,
|
|
d.name as domain_name,
|
|
a.list as list
|
|
from aliases a, domains d
|
|
where a.domain_id = d.id and a.id = $id
|
|
limit 1");
|
|
}
|
|
|
|
sub alias_list {
|
|
my ($self, $domain_id) = @_;
|
|
my $and = "and a.domain_id = $domain_id" if $domain_id;
|
|
$self->db->exec("select a.id as id,
|
|
a.name as name,
|
|
a.name || '\@' || d.name as address,
|
|
a.domain_id as domain_id,
|
|
d.name as domain_name,
|
|
a.list as list
|
|
from aliases a, domains d
|
|
where a.domain_id = d.id $and
|
|
order by a.id, d.id"
|
|
);
|
|
}
|
|
|
|
sub alias_nextid {
|
|
my $self = shift;
|
|
my $res = $self->db->exec1('select id from aliases order by id desc limit 1');
|
|
my $id = $res->{id} || 0;
|
|
$id += 1;
|
|
}
|
|
|
|
sub alias_add {
|
|
my ($self, $name, $list, $domain_id) = @_;
|
|
return undef unless $name;
|
|
return undef unless $list;
|
|
return undef unless $domain_id;
|
|
|
|
return undef if $self->alias_exist($name, $domain_id);
|
|
return undef unless $self->domain_profile($domain_id);
|
|
my $next_id = $self->alias_nextid;
|
|
$self->db->do("insert into aliases (id, name, list, domain_id)
|
|
values ($next_id, '$name', '$list', $domain_id)");
|
|
$self->alias_exist($name, $domain_id);
|
|
}
|
|
|
|
sub alias_delete {
|
|
my ($self, $id) = @_;
|
|
return undef unless $id;
|
|
return $id unless $self->alias_profile($id);
|
|
$self->db->do("delete from aliases where id = $id");
|
|
return undef if $self->alias_profile($id);
|
|
$id;
|
|
}
|
|
|
|
sub alias_update {
|
|
my ($self, $id, %args) = @_;
|
|
my $prof = $self->alias_profile($id);
|
|
return undef unless $prof;
|
|
|
|
my $name = $args{name} || $prof->{name};
|
|
my $list = $args{list} || $prof->{list};
|
|
|
|
$self->db->do("update aliases set name = '$name', list = '$list'
|
|
where id = $id");
|
|
my $res = $self->alias_profile($id);
|
|
return undef unless $res->{name} eq $name;
|
|
return undef unless $res->{list} eq $list;
|
|
$id ;
|
|
}
|
|
|
|
# --- USER ---
|
|
|
|
sub user_exist {
|
|
my ($self, $name, $domain_id) = @_;
|
|
return undef unless $name;
|
|
return undef unless $domain_id;
|
|
my $res = $self->db->exec1("select u.id as id from domains d, users u
|
|
where u.name = '$name' and u.domain_id = $domain_id
|
|
limit 1");
|
|
$res->{id};
|
|
}
|
|
|
|
sub user_profile {
|
|
my ($self, $id) = @_;
|
|
return undef unless $id;
|
|
$self->db->exec1("select u.id as id,
|
|
u.name as name,
|
|
u.name || '\@' || d.name as address,
|
|
u.domain_id as domain_id,
|
|
d.name as domain_name,
|
|
u.password as password,
|
|
u.hash as hash,
|
|
u.size as size,
|
|
u.quota as quota
|
|
from users u, domains d
|
|
where u.domain_id = d.id and u.id = $id
|
|
limit 1");
|
|
}
|
|
|
|
sub user_list {
|
|
my ($self, $domain_id) = @_;
|
|
my $and = "and u.domain_id = $domain_id" if $domain_id;
|
|
$self->db->exec("select u.id as id,
|
|
u.name as name,
|
|
u.name || '\@' || d.name as address,
|
|
u.domain_id as domain_id,
|
|
d.name as domain_name,
|
|
u.password as password,
|
|
u.size as size,
|
|
u.quota as quota
|
|
from users u, domains d
|
|
where u.domain_id = d.id $and
|
|
order by u.name, d.name"
|
|
);
|
|
}
|
|
|
|
sub user_nextid {
|
|
my $self = shift;
|
|
my $res = $self->db->exec1('select id from users order by id desc limit 1');
|
|
my $id = $res->{id} || 0;
|
|
$id += 1;
|
|
}
|
|
|
|
sub user_add {
|
|
my ($self, $name, $password, $domain_id) = @_;
|
|
return undef unless $name;
|
|
return undef unless $password;
|
|
return undef unless $domain_id;
|
|
|
|
return undef if $self->user_exist($name, $domain_id);
|
|
return undef unless $self->domain_profile($domain_id);
|
|
my $next_id = $self->user_nextid;
|
|
my $salt = substr(sha512_base64(sprintf("%X", rand(2**31-1))), 4, 16);
|
|
my $hash = crypt($password,'$6$'.$salt.'$');
|
|
|
|
$self->db->do("insert into users (id, name, password, domain_id, hash)
|
|
values ($next_id, '$name', '$password', $domain_id, '$hash')");
|
|
$self->user_exist($name, $domain_id);
|
|
}
|
|
|
|
sub user_update {
|
|
my ($self, $id, %args) = @_;
|
|
my $prof = $self->user_profile($id);
|
|
return undef unless $prof;
|
|
|
|
my $name = $args{name} || $prof->{name};
|
|
my $password = $args{password} || $prof->{password};
|
|
my $hash = $prof->{hash};
|
|
if ($args{password}) {
|
|
my $salt = substr(sha512_base64(sprintf("%X", rand(2**31-1))), 4, 16);
|
|
$hash = crypt($password,'$6$'.$salt.'$');
|
|
}
|
|
|
|
my $quota = $args{quota} || $prof->{quota};
|
|
my $size = $prof->{size};
|
|
$size = $args{size} if $args{size} >= 0;
|
|
$size ||= 0;
|
|
|
|
$self->db->do("update users set name = '$name',
|
|
password = '$password',
|
|
size = $size,
|
|
quota = $quota,
|
|
hash = '$hash'
|
|
where id = $id");
|
|
my $res = $self->user_profile($id);
|
|
return undef unless $res->{name} eq $name;
|
|
return undef unless $res->{password} eq $password;
|
|
$id ;
|
|
}
|
|
|
|
sub user_delete {
|
|
my ($self, $id) = @_;
|
|
return undef unless $id;
|
|
# return $id unless $self->user_profile($id);
|
|
$self->db->do("delete from users where id = $id");
|
|
return undef if $self->user_profile($id);
|
|
$id;
|
|
}
|
|
|
|
1;
|
|
|
|
#--------------
|
|
#--- DAEMON ---
|
|
#--------------
|
|
|
|
package Daemon;
|
|
|
|
use strict;
|
|
use warnings;
|
|
use POSIX qw(getpid setuid setgid geteuid getegid);
|
|
use Cwd qw(cwd getcwd chdir);
|
|
use Mojo::Util qw(dumper);
|
|
|
|
sub new {
|
|
my $class = shift;
|
|
my $self = {};
|
|
bless $self, $class;
|
|
return $self;
|
|
}
|
|
|
|
sub fork {
|
|
my $self = shift;
|
|
my $pid = fork;
|
|
if ($pid > 0) {
|
|
exit;
|
|
}
|
|
chdir("/");
|
|
open(my $stdout, '>&', STDOUT);
|
|
open(my $stderr, '>&', STDERR);
|
|
open(STDOUT, '>>', '/dev/null');
|
|
open(STDERR, '>>', '/dev/null');
|
|
getpid;
|
|
}
|
|
|
|
1;
|
|
|
|
#-------------
|
|
#--- TAIL ----
|
|
#-------------
|
|
|
|
package Tail;
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
sub new {
|
|
my ($class, $file) = @_;
|
|
my $self = {
|
|
file => $file,
|
|
pos => 0
|
|
};
|
|
bless $self, $class;
|
|
return $self;
|
|
}
|
|
|
|
sub file {
|
|
my ($self, $name) = @_;
|
|
return $self->{'file'} unless $name;
|
|
$self->{'file'} = $name;
|
|
}
|
|
|
|
sub pos {
|
|
my ($self, $pos) = @_;
|
|
return $self->{'pos'} unless $pos;
|
|
$self->{'pos'} = $pos;
|
|
}
|
|
|
|
sub first {
|
|
my $self = shift;
|
|
open my $fh, '<', $self->file;
|
|
seek $fh, -2000, 2;
|
|
readline $fh;
|
|
my @res;
|
|
while (my $line = readline $fh) {
|
|
push @res, $line;
|
|
}
|
|
$self->pos(tell $fh);
|
|
\@res;
|
|
}
|
|
|
|
sub last {
|
|
my $self = shift;
|
|
open my $fh, '<', $self->file;
|
|
seek $fh, $self->pos, 0;
|
|
my @res;
|
|
while (my $line = readline $fh) {
|
|
push @res, $line;
|
|
}
|
|
$self->pos(tell $fh);
|
|
\@res;
|
|
}
|
|
|
|
1;
|
|
|
|
#--------------------
|
|
#--- CONTROLLER 1 ---
|
|
#--------------------
|
|
|
|
package MAM::Controller;
|
|
|
|
use strict;
|
|
use warnings;
|
|
use Mojo::Base 'Mojolicious::Controller';
|
|
use Mojo::Util qw(dumper);
|
|
use Mojo::JSON qw(decode_json encode_json);
|
|
|
|
use Apache::Htpasswd;
|
|
|
|
# --- AUTH ---
|
|
|
|
sub pwfile {
|
|
my ($self, $pwfile) = @_;
|
|
return $self->app->config('pwfile') unless $pwfile;
|
|
$self->app->config(pwfile => $pwfile);
|
|
}
|
|
|
|
sub log {
|
|
my ($self, $log) = @_;
|
|
return $self->app->log unless $log;
|
|
$self->app->log = $log;
|
|
}
|
|
|
|
sub ucheck {
|
|
my ($self, $username, $password) = @_;
|
|
return undef unless $password;
|
|
return undef unless $username;
|
|
my $pwfile = $self->pwfile or return undef;
|
|
my $res = undef;
|
|
eval {
|
|
my $ht = Apache::Htpasswd->new({ passwdFile => $pwfile, ReadOnly => 1 });
|
|
$res = $ht->htCheckPassword($username, $password);
|
|
};
|
|
$res;
|
|
}
|
|
|
|
sub login {
|
|
my $self = shift;
|
|
return $self->redirect_to('/') if $self->session('username');
|
|
|
|
my $username = $self->req->param('username') || undef;
|
|
my $password = $self->req->param('password') || undef;
|
|
|
|
return $self->render(template => 'login') unless $username and $password;
|
|
|
|
if ($self->ucheck($username, $password)) {
|
|
$self->session(username => $username);
|
|
return $self->redirect_to('/');
|
|
}
|
|
$self->render(template => 'login');
|
|
}
|
|
|
|
sub logout {
|
|
my $self = shift;
|
|
$self->session(expires => 1);
|
|
$self->redirect_to('/');
|
|
}
|
|
|
|
# --- HELLO ---
|
|
|
|
sub hello {
|
|
my $self = shift;
|
|
$self->render(template => 'hello');
|
|
}
|
|
|
|
# --- DOMAIN ---
|
|
|
|
sub domain_list {
|
|
my $self = shift;
|
|
$self->render(template => 'domain-list');
|
|
}
|
|
sub domain_add_form {
|
|
my $self = shift;
|
|
$self->render(template => 'domain-add-form');
|
|
}
|
|
sub domain_add_handler {
|
|
my $self = shift;
|
|
$self->render(template => 'domain-add-handler');
|
|
}
|
|
sub domain_update_form {
|
|
my $self = shift;
|
|
$self->render(template => 'domain-update-form');
|
|
}
|
|
|
|
sub domain_update_handler {
|
|
my $self = shift;
|
|
$self->render(template => 'domain-update-handler');
|
|
}
|
|
|
|
sub domain_delete_form {
|
|
my $self = shift;
|
|
$self->render(template => 'domain-delete-form');
|
|
}
|
|
|
|
sub domain_delete_handler {
|
|
my $self = shift;
|
|
$self->render(template => 'domain-delete-handler');
|
|
}
|
|
|
|
# --- USER ---
|
|
|
|
sub user_list {
|
|
my $self = shift;
|
|
$self->render(template => 'user-list');
|
|
}
|
|
|
|
sub user_add_form {
|
|
my $self = shift;
|
|
$self->render(template => 'user-add-form');
|
|
}
|
|
sub user_add_handler {
|
|
my $self = shift;
|
|
$self->render(template => 'user-add-handler');
|
|
}
|
|
|
|
sub user_delete_form {
|
|
my $self = shift;
|
|
$self->render(template => 'user-delete-form');
|
|
}
|
|
sub user_delete_handler {
|
|
my $self = shift;
|
|
$self->render(template => 'user-delete-handler');
|
|
}
|
|
|
|
sub user_update_form {
|
|
my $self = shift;
|
|
$self->render(template => 'user-update-form');
|
|
}
|
|
|
|
sub user_update_handler {
|
|
my $self = shift;
|
|
$self->render(template => 'user-update-handler');
|
|
}
|
|
|
|
sub user_rename_form {
|
|
my $self = shift;
|
|
$self->render(template => 'user-rename-form');
|
|
}
|
|
|
|
sub user_rename_handler {
|
|
my $self = shift;
|
|
$self->render(template => 'user-rename-handler');
|
|
}
|
|
|
|
# --- ALIAS ---
|
|
|
|
sub alias_list {
|
|
my $self = shift;
|
|
$self->render(template => 'alias-list');
|
|
}
|
|
|
|
sub alias_add_form {
|
|
my $self = shift;
|
|
$self->render(template => 'alias-add-form');
|
|
}
|
|
sub alias_add_handler {
|
|
my $self = shift;
|
|
$self->render(template => 'alias-add-handler');
|
|
}
|
|
|
|
sub alias_delete_form {
|
|
my $self = shift;
|
|
$self->render(template => 'alias-delete-form');
|
|
}
|
|
sub alias_delete_handler {
|
|
my $self = shift;
|
|
$self->render(template => 'alias-delete-handler');
|
|
}
|
|
|
|
sub alias_update_form {
|
|
my $self = shift;
|
|
$self->render(template => 'alias-update-form');
|
|
}
|
|
|
|
sub alias_update_handler {
|
|
my $self = shift;
|
|
$self->render(template => 'alias-update-handler');
|
|
}
|
|
|
|
|
|
sub alias_rename_form {
|
|
my $self = shift;
|
|
$self->render(template => 'alias-rename-form');
|
|
}
|
|
|
|
sub alias_rename_handler {
|
|
my $self = shift;
|
|
$self->render(template => 'alias-rename-handler');
|
|
}
|
|
|
|
# --- TAIL ---
|
|
|
|
sub mxlog {
|
|
my $self = shift;
|
|
$self->render(template => 'mxlog');
|
|
}
|
|
|
|
1;
|
|
|
|
#-----------
|
|
#--- APP ---
|
|
#-----------
|
|
|
|
package MAM;
|
|
|
|
use strict;
|
|
use warnings;
|
|
use Mojo::Base 'Mojolicious';
|
|
|
|
sub startup {
|
|
my $self = shift;
|
|
}
|
|
|
|
1;
|
|
|
|
#------------
|
|
#--- MAIN ---
|
|
#------------
|
|
|
|
use strict;
|
|
use warnings;
|
|
use Mojo::Server::Prefork;
|
|
use Mojo::Util qw(dumper);
|
|
use File::stat;
|
|
|
|
my $appname = 'maacom';
|
|
|
|
my $server = Mojo::Server::Prefork->new;
|
|
my $app = $server->build_app('MAM');
|
|
$app = $app->controller_class('MAM::Controller');
|
|
|
|
$app->secrets(['6d578e43ba88260e0375a1a35fd7954b']);
|
|
|
|
$app->static->paths(['@app_libdir@/public']);
|
|
$app->renderer->paths(['@app_libdir@/templs']);
|
|
|
|
$app->config(conffile => '@app_confdir@/maacom.conf');
|
|
$app->config(pwfile => '@app_confdir@/maacom.pw');
|
|
$app->config(logfile => '@app_logdir@/maacom.log');
|
|
$app->config(loglevel => 'info');
|
|
$app->config(pidfile => '@app_rundir@/maacom.pid');
|
|
$app->config(crtfile => '@app_confdir@/maacom.crt');
|
|
$app->config(keyfile => '@app_confdir@/maacom.key');
|
|
|
|
$app->config(listenaddr4 => '0.0.0.0');
|
|
$app->config(listenaddr6 => '[::]');
|
|
$app->config(listenport => '8082');
|
|
|
|
$app->config(mxlog => '/var/log/mail.log');
|
|
$app->config(maildir => '/var/vmail');
|
|
|
|
$app->config(dbname => '@app_datadir@/mail.db');
|
|
$app->config(dbhost => '');
|
|
$app->config(dblogin => '');
|
|
$app->config(dbpassword => '');
|
|
$app->config(dbengine => 'sqlite3');
|
|
|
|
if (-r $app->config('conffile')) {
|
|
$app->log->debug("Load configuration from ".$app->config('conffile'));
|
|
$app->plugin('JSONConfig', { file => $app->config('conffile') });
|
|
}
|
|
|
|
#---------------
|
|
#--- HELPERS ---
|
|
#---------------
|
|
$app->helper(
|
|
tail => sub {
|
|
state $tail = Tail->new($app->config('mxlog'));
|
|
});
|
|
|
|
$app->helper(
|
|
db => sub {
|
|
my $engine = 'SQLite' if $app->config('dbengine') =~ /sqlite/i;
|
|
$engine = 'Pg' if $app->config('dbengine') =~ /postgres/i;
|
|
state $db = aDB->new(
|
|
database => $app->config('dbname'),
|
|
hostname => $app->config('dbhost'),
|
|
username => $app->config('dblogin'),
|
|
password => $app->config('dbpassword'),
|
|
engine => $engine
|
|
);
|
|
});
|
|
|
|
$app->helper(
|
|
user => sub {
|
|
state $user = aUser->new($app->db);
|
|
});
|
|
|
|
$app->helper('reply.not_found' => sub {
|
|
my $c = shift;
|
|
return $c->redirect_to('/login') unless $c->session('username');
|
|
$c->render(template => 'not_found.production');
|
|
});
|
|
|
|
|
|
#--------------
|
|
#--- ROUTES ---
|
|
#--------------
|
|
|
|
my $r = $app->routes;
|
|
|
|
$r->add_condition(
|
|
auth => sub {
|
|
my ($route, $c) = @_;
|
|
$c->session('username');
|
|
}
|
|
);
|
|
|
|
$r->any('/login')->to('controller#login');
|
|
$r->any('/logout')->over('auth')->to('controller#logout');
|
|
|
|
$r->any('/')->over('auth')->to('controller#domain_list' );
|
|
$r->any('/hello')->over('auth')->to('controller#hello');
|
|
|
|
$r->any('/domain/list')->over('auth')->to('controller#domain_list' );
|
|
$r->any('/domain/add/form')->over('auth')->to('controller#domain_add_form' );
|
|
$r->any('/domain/add/handler')->over('auth')->to('controller#domain_add_handler' );
|
|
$r->any('/domain/update/form')->over('auth')->to('controller#domain_update_form' );
|
|
$r->any('/domain/update/handler')->over('auth')->to('controller#domain_update_handler' );
|
|
$r->any('/domain/delete/form')->over('auth')->to('controller#domain_delete_form' );
|
|
$r->any('/domain/delete/handler')->over('auth')->to('controller#domain_delete_handler' );
|
|
|
|
$r->any('/user/list')->over('auth')->to('controller#user_list' );
|
|
$r->any('/user/add/form')->over('auth')->to('controller#user_add_form' );
|
|
$r->any('/user/add/handler')->over('auth')->to('controller#user_add_handler' );
|
|
$r->any('/user/update/form')->over('auth')->to('controller#user_update_form' );
|
|
$r->any('/user/update/handler')->over('auth')->to('controller#user_update_handler' );
|
|
$r->any('/user/delete/form')->over('auth')->to('controller#user_delete_form' );
|
|
$r->any('/user/delete/handler')->over('auth')->to('controller#user_delete_handler' );
|
|
$r->any('/user/rename/form')->over('auth')->to('controller#user_rename_form' );
|
|
$r->any('/user/rename/handler')->over('auth')->to('controller#user_rename_handler' );
|
|
|
|
$r->any('/alias/list')->over('auth')->to('controller#alias_list' );
|
|
$r->any('/alias/add/form')->over('auth')->to('controller#alias_add_form' );
|
|
$r->any('/alias/add/handler')->over('auth')->to('controller#alias_add_handler' );
|
|
$r->any('/alias/update/form')->over('auth')->to('controller#alias_update_form' );
|
|
$r->any('/alias/update/handler')->over('auth')->to('controller#alias_update_handler' );
|
|
$r->any('/alias/delete/form')->over('auth')->to('controller#alias_delete_form' );
|
|
$r->any('/alias/delete/handler')->over('auth')->to('controller#alias_delete_handler' );
|
|
$r->any('/alias/rename/form')->over('auth')->to('controller#alias_rename_form' );
|
|
$r->any('/alias/rename/handler')->over('auth')->to('controller#alias_rename_handler' );
|
|
|
|
$r->any('/mxlog')->over('auth')->to('controller#mxlog' );
|
|
|
|
|
|
#----------------
|
|
#--- LISTENER ---
|
|
#----------------
|
|
|
|
my $tls = '?';
|
|
$tls .= 'cert='.$app->config('crtfile');
|
|
$tls .= '&key='.$app->config('keyfile');
|
|
|
|
my $listen4;
|
|
if ($app->config('listenaddr4')) {
|
|
$listen4 = "https://";
|
|
$listen4 .= $app->config('listenaddr4').':'.$app->config('listenport');
|
|
$listen4 .= $tls;
|
|
}
|
|
|
|
my $listen6;
|
|
if ($app->config('listenaddr6')) {
|
|
$listen6 = "https://";
|
|
$listen6 .= $app->config('listenaddr6').':'.$app->config('listenport');
|
|
$listen6 .= $tls;
|
|
}
|
|
|
|
my @listen;
|
|
push @listen, $listen4 if $listen4;
|
|
push @listen, $listen6 if $listen6;
|
|
|
|
$server->listen(\@listen);
|
|
$server->heartbeat_interval(3);
|
|
$server->heartbeat_timeout(60);
|
|
|
|
my $d = Daemon->new;
|
|
$d->fork;
|
|
|
|
$server->pid_file($app->config('pidfile'));
|
|
|
|
$app->log(Mojo::Log->new(
|
|
path => $app->config('logfile'),
|
|
level => $app->config('loglevel')
|
|
));
|
|
|
|
$app->hook(before_dispatch => sub {
|
|
my $c = shift;
|
|
|
|
my $remote_address = $c->tx->remote_address;
|
|
my $method = $c->req->method;
|
|
|
|
my $base = $c->req->url->base->to_string;
|
|
my $path = $c->req->url->path->to_string;
|
|
my $loglevel = $c->app->log->level;
|
|
my $url = $c->req->url->to_abs->to_string;
|
|
|
|
my $username = $c->session('username') || 'undef';
|
|
|
|
unless ($loglevel eq 'debug') {
|
|
#$c->app->log->info("$remote_address $method $base$path $username");
|
|
$c->app->log->info("$remote_address $method $url $username");
|
|
}
|
|
if ($loglevel eq 'debug') {
|
|
$c->app->log->debug("$remote_address $method $url $username");
|
|
}
|
|
});
|
|
|
|
|
|
# Set signal handler
|
|
local $SIG{HUP} = sub {
|
|
$app->log->info('Catch HUP signal');
|
|
$app->log(Mojo::Log->new(
|
|
path => $app->config('logfile'),
|
|
level => $app->config('loglevel')
|
|
));
|
|
};
|
|
|
|
|
|
sub du {
|
|
my ($subj, $maxdeep, $deep) = @_;
|
|
$maxdeep ||= 10;
|
|
$deep ||= 0;
|
|
my $stat = stat($subj);
|
|
return int($stat->size/1024) if -f $subj;
|
|
|
|
$deep += 1;
|
|
return 0 if $deep > $maxdeep;
|
|
opendir(my $dir, $subj) or return 0;
|
|
my $res ||= 0;
|
|
foreach my $rec (readdir $dir) {
|
|
next if $rec =~ /^.$/;
|
|
next if $rec =~ /^..$/;
|
|
$res = $res + du("$subj/$rec", $maxdeep, $deep);
|
|
}
|
|
$res;
|
|
}
|
|
|
|
my $sub = Mojo::IOLoop::Subprocess->new;
|
|
$sub->run(
|
|
sub {
|
|
my $subproc = shift;
|
|
my $loop = Mojo::IOLoop->singleton;
|
|
my $id = $loop->recurring(
|
|
300 => sub {
|
|
my $total = 0;
|
|
foreach my $domain (@{$app->user->domain_list}) {
|
|
my $dir = $app->config('maildir');
|
|
my $domain_id = $domain->{id};
|
|
my $domain = $domain->{name};
|
|
my $size = du("$dir/$domain") || 0;
|
|
$app->user->domain_update($domain_id, size => $size);
|
|
$total += $size;
|
|
}
|
|
foreach my $user (@{$app->user->user_list}) {
|
|
my $dir = $app->config('maildir');
|
|
my $user_id = $user->{id};
|
|
my $user_name = $user->{name};
|
|
my $domain = $user->{domain_name};
|
|
my $size = du("$dir/$domain/$user_name") || 0;
|
|
$app->user->user_update($user_id, size => $size);
|
|
}
|
|
$app->log->info("Disc usage has been wrote, total $total");
|
|
}
|
|
);
|
|
$loop->start unless $loop->is_running;
|
|
1;
|
|
},
|
|
sub {
|
|
my ($subprocess, $err, @results) = @_;
|
|
$app->log->info('Exit subprocess');
|
|
1;
|
|
}
|
|
);
|
|
|
|
my $pid = $sub->pid;
|
|
$app->log->info("Subrocess $pid start ");
|
|
|
|
$server->on(
|
|
finish => sub {
|
|
my ($prefork, $graceful) = @_;
|
|
$app->log->info("Subrocess $pid stop");
|
|
kill('INT', $pid);
|
|
}
|
|
);
|
|
|
|
$server->run;
|
|
#EOF
|
|
</code>
|
|
|
|
====templs/alias-add-form.html.ep====
|
|
|
|
<code perl templs/alias-add-form.html.ep>
|
|
%#
|
|
%# $Id$
|
|
%#
|
|
% layout 'default';
|
|
% title 'Mail';
|
|
|
|
% use Mojo::Util qw(dumper);
|
|
|
|
% my $u = $c->app->user;
|
|
|
|
% my $domain_id = $c->req->param('domain_id');
|
|
|
|
% if ($domain_id) {
|
|
% my $profile = $u->domain_profile($domain_id);
|
|
% my $domain_name = $profile->{name};
|
|
<div class="grid-container">
|
|
<div class="grid-x grid-padding-x">
|
|
<div class="medium-6 medium-centered cell">
|
|
|
|
<form accept-charset="UTF-8" action="/alias/add/handler" method="get" data-abide novalidate>
|
|
<h5 class="text-center">Add alias to domain <%= $domain_name %></h5>
|
|
<input type="hidden" name="domain_id" value="<%= $domain_id %>"/>
|
|
<label>Alias name
|
|
<input type="text" name="alias_name" placeholder="aliasname" required pattern="[_.a-zA-Z0-9\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]{2,42}"/>
|
|
<span class="form-error">Mandatory, 2 or more letter</span>
|
|
</label>
|
|
<label>Destination list
|
|
<input type="text" name="list" placeholder="some@bare.org,foo@bar.com" required pattern="[_.,@a-zA-Z0-9\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]{5,42}"/>
|
|
<span class="form-error">Mandatory, 6 or more letter</span>
|
|
</label>
|
|
<div class="text-center">
|
|
<button type="submit" class="button">Accept</button>
|
|
<a class="button" href="/alias/list?domain_id=<%= $domain_id %>">Escape</a>
|
|
</div>
|
|
</form>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
% }
|
|
|
|
% unless ($domain_id) {
|
|
<div class="grid-container">
|
|
<div class="grid-x grid-padding-x">
|
|
<div class="medium-6 medium-centered cell">
|
|
|
|
<form accept-charset="UTF-8" action="/alias/add/handler" method="get" data-abide novalidate>
|
|
<h5 class="text-center">Add alias</h5>
|
|
<label>Alias name
|
|
<input type="text" name="alias_name" placeholder="aliasname" required pattern="[_.a-zA-Z0-9\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]{2,42}"/>
|
|
<span class="form-error">Mandatory, 2 or more letter</span>
|
|
</label>
|
|
<label>Domain
|
|
<select name="domain_id" required>
|
|
<option value=""></option>
|
|
% foreach my $rec (@{$u->domain_list}) {
|
|
<option value="<%= $rec->{id} %>"><%= $rec->{name} %></option>
|
|
% }
|
|
</select >
|
|
</label>
|
|
<label>Destination list
|
|
<input type="text" name="list" placeholder="some@bare.org,foo@bar.com" required pattern="[_.@,a-zA-Z0-9\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]{5,42}"/>
|
|
<span class="form-error">Mandatory, 6 or more letter</span>
|
|
</label>
|
|
|
|
<div class="text-center">
|
|
<button type="submit" class="button">Accept</button>
|
|
<a class="button" href="/alias/list">Escape</a>
|
|
</div>
|
|
</form>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
% }
|
|
|
|
%#EOF
|
|
</code>
|
|
|
|
====templs/alias-add-handler.html.ep====
|
|
|
|
<code perl templs/alias-add-handler.html.ep>
|
|
%#
|
|
%# $Id$
|
|
%#
|
|
% layout 'default';
|
|
% title 'Mail';
|
|
|
|
% use Mojo::Util qw(dumper);
|
|
|
|
% my $u = $c->app->user;
|
|
|
|
% my $alias_name = $c->req->param('alias_name');
|
|
% my $domain_id = $c->req->param('domain_id');
|
|
% my $list = $c->req->param('list');
|
|
|
|
% my $cid = $u->alias_exist($alias_name, $domain_id);
|
|
|
|
% if ($cid) {
|
|
<div class="callout warning">Alias <%= $alias_name %> already exists</div>
|
|
% }
|
|
|
|
% unless ($cid) {
|
|
% my $id = $u->alias_add($alias_name, $list, $domain_id);
|
|
% if ($id) {
|
|
<div class="callout success">Alias <%= $alias_name %> has been added.</div>
|
|
% }
|
|
|
|
% unless ($id) {
|
|
<div class="callout alert">Alias <%= $alias_name %> was not added.</div>
|
|
% }
|
|
% }
|
|
%#EOF
|
|
</code>
|
|
|
|
====templs/alias-delete-form.html.ep====
|
|
|
|
<code perl templs/alias-delete-form.html.ep>
|
|
%#
|
|
%# $Id$
|
|
%#
|
|
% layout 'default';
|
|
% title 'Mail';
|
|
|
|
% use Mojo::Util qw(dumper);
|
|
|
|
% my $u = $c->app->user;
|
|
|
|
% my $alias_id = $c->req->param('alias_id') || 0;
|
|
% my $profile = $u->alias_profile($alias_id);
|
|
|
|
% if ($profile) {
|
|
% my $alias_name = $profile->{name};
|
|
% my $domain_name = $profile->{domain_name};
|
|
% my $domain_id = $profile->{domain_id};
|
|
% my $address = $profile->{address};
|
|
|
|
<div class="grid-container">
|
|
<div class="grid-x grid-padding-x">
|
|
<div class="medium-6 medium-centered cell">
|
|
|
|
<form accept-charset="UTF-8" action="/alias/delete/handler" method="get" data-abide novalidate>
|
|
<h5 class="text-center">Delete alias <%= $address %></h5>
|
|
<input type="hidden" name="alias_id" value="<%= $alias_id %>"/>
|
|
<div class="text-center">
|
|
<button type="submit" class="button">Accept</button>
|
|
<a class="button" href="/alias/list?domain_id=<%= $domain_id %>">Escape</a>
|
|
</div>
|
|
</form>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
% }
|
|
|
|
% unless ($profile) {
|
|
<div class="callout warning">Alias with id <%= $alias_id %> not exist</div>
|
|
% }
|
|
%#EOF
|
|
</code>
|
|
|
|
====templs/alias-delete-handler.html.ep====
|
|
|
|
<code perl templs/alias-delete-handler.html.ep>
|
|
%#
|
|
%# $Id$
|
|
%#
|
|
% layout 'default';
|
|
% title 'Mail';
|
|
|
|
% use Mojo::Util qw(dumper);
|
|
|
|
% my $u = $c->app->user;
|
|
|
|
% my $alias_id = $c->req->param('alias_id') || 0;
|
|
% my $profile = $u->alias_profile($alias_id);
|
|
|
|
% if ($profile) {
|
|
% my $name = $profile->{name};
|
|
% my $address = $profile->{address};
|
|
|
|
% my $res = $u->alias_delete($alias_id);
|
|
|
|
% if ($res) {
|
|
<div class="callout success">Alias <%= $address %> has been deleted</div>
|
|
% }
|
|
|
|
% unless ($res) {
|
|
<div class="callout alert">Alias <%= $address %> was not deleted</div>
|
|
% }
|
|
% }
|
|
|
|
% unless ($profile) {
|
|
<div class="callout warning">Alias with id <%= $alias_id %> not exist</div>
|
|
% }
|
|
|
|
%#EOF
|
|
|
|
</code>
|
|
|
|
====templs/alias-list.html.ep====
|
|
|
|
<code perl templs/alias-list.html.ep>
|
|
%#
|
|
%# $Id$
|
|
%#
|
|
% layout 'default';
|
|
% title 'Mail';
|
|
|
|
% use Mojo::Util qw(dumper);
|
|
|
|
% my $req = $c->req;
|
|
% my $u = $c->app->user;
|
|
|
|
% my $domain_id = $req->param('domain_id');
|
|
|
|
% unless ($domain_id) {
|
|
<h5 class="text-center">
|
|
Aliases <a href="/alias/list"><i class="fi-refresh"></i></a>
|
|
<a class="float-right button tiny" href="/alias/add/form">
|
|
<i class="fi-plus"></i>
|
|
</a>
|
|
</h5>
|
|
|
|
% my $list = $u->alias_list;
|
|
|
|
<table class="hover" id="table">
|
|
<thead>
|
|
<tr>
|
|
<th>#</th>
|
|
<th>alias</th>
|
|
<th><i class="fi-male-female"></i></th>
|
|
<th><i class="fi-at-sign"></i></th>
|
|
<th><i class="fi-address-book"></i></th>
|
|
<th><i class="fi-pencil"></i></th>
|
|
<th><i class="fi-trash"></i></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
% my $n = 0;
|
|
% if ($list) {
|
|
% foreach my $row (@$list) {
|
|
% $n += 1;
|
|
% my $alias_id = $row->{id};
|
|
% my $address = $row->{address};
|
|
% my $domain_id = $row->{domain_id};
|
|
% my $count = split ",", $row->{list};
|
|
<tr>
|
|
<td><%= $n %></td>
|
|
<td><%= $address %></td>
|
|
<td><%= $count %></td>
|
|
<td><a href="/alias/list?domain_id=<%= $domain_id %>"><i class="fi-at-sign"></i></a></td>
|
|
<td><a href="/alias/rename/form?alias_id=<%= $alias_id %>"><i class="fi-address-book"></i></a></td>
|
|
<td><a href="/alias/update/form?alias_id=<%= $alias_id %>"><i class="fi-pencil"></i></a></td>
|
|
<td><a href="/alias/delete/form?alias_id=<%= $alias_id %>"><i class="fi-trash"></i></a></td>
|
|
</tr>
|
|
% }
|
|
% }
|
|
</tbody>
|
|
</table>
|
|
% }
|
|
|
|
% if ($domain_id) {
|
|
<h5 class="text-center">
|
|
Aliases <a href="/alias/list?domain_id=<%= $domain_id %>"><i class="fi-refresh"></i></a>
|
|
<a class="float-right button tiny" href="/alias/add/form?domain_id=<%= $domain_id %>">
|
|
<i class="fi-plus"></i>
|
|
</a>
|
|
</h5>
|
|
|
|
% my $list = $u->alias_list($domain_id);
|
|
|
|
<table class="hover" id="table">
|
|
<thead>
|
|
<tr>
|
|
<th>#</th>
|
|
<th>alias</th>
|
|
<th><i class="fi-male-female"></i></th>
|
|
<th><i class="fi-address-book"></i></th>
|
|
<th><i class="fi-pencil"></i></th>
|
|
<th><i class="fi-trash"></i></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
% if ($list) {
|
|
% my $n = 0;
|
|
% foreach my $row (@$list) {
|
|
% $n += 1;
|
|
% my $c = split ',', $row->{list};
|
|
|
|
% my $alias_id = $row->{id};
|
|
% my $address = $row->{address};
|
|
% my $domain_id = $row->{domain_id};
|
|
% my $count = split ",", $row->{list};
|
|
<tr>
|
|
<td><%= $n %></td>
|
|
<td><%= $address %></td>
|
|
<td><%= $count %></td>
|
|
<td><a href="/alias/rename/form?alias_id=<%= $alias_id %>"><i class="fi-address-book"></i></a></td>
|
|
<td><a href="/alias/update/form?alias_id=<%= $alias_id %>"><i class="fi-pencil"></i></a></td>
|
|
<td><a href="/alias/delete/form?alias_id=<%= $alias_id %>"><i class="fi-trash"></i></a></td>
|
|
</tr>
|
|
% }
|
|
% }
|
|
</tbody>
|
|
</table>
|
|
% }
|
|
|
|
<script>
|
|
$.extend(true, $.fn.dataTable.defaults, {
|
|
"searching": true,
|
|
"ordering": true,
|
|
"language": {
|
|
"search": "",
|
|
"lengthMenu": "_MENU_",
|
|
"info": "_START_-_END_ of _TOTAL_",
|
|
"infoEmpty": "",
|
|
},
|
|
});
|
|
|
|
$(document).ready(function() {
|
|
$('#table').DataTable();
|
|
});
|
|
</script>
|
|
%# EOF
|
|
|
|
</code>
|
|
|
|
====templs/alias-rename-form.html.ep====
|
|
|
|
<code perl templs/alias-rename-form.html.ep>
|
|
%#
|
|
%# $Id$
|
|
%#
|
|
% layout 'default';
|
|
% title 'Mail';
|
|
|
|
% use Mojo::Util qw(dumper);
|
|
|
|
% my $u = $c->app->user;
|
|
|
|
% my $alias_id = $c->req->param('alias_id') || 0;
|
|
% my $profile = $u->alias_profile($alias_id);
|
|
|
|
% if ($profile) {
|
|
% my $alias_name = $profile->{name};
|
|
% my $domain_name = $profile->{domain_name};
|
|
% my $domain_id = $profile->{domain_id};
|
|
% my $list = $profile->{list};
|
|
% my $address = $profile->{address};
|
|
|
|
<div class="grid-container">
|
|
<div class="grid-x grid-padding-x">
|
|
<div class="medium-6 medium-centered cell">
|
|
|
|
<form accept-charset="UTF-8" action="/alias/update/handler" method="get" data-abide novalidate>
|
|
<h5 class="text-center">Edit alias <%= $address %></h5>
|
|
<input type="hidden" name="alias_id" value="<%= $alias_id %>"/>
|
|
<label>Alias name
|
|
<input type="text" value="<%= $alias_name %>" name="alias_name" required pattern="[_.-zA-Z0-9\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]{2,42}"/>
|
|
<span class="form-error">Mandatory, 2 or more letter</span>
|
|
</label>
|
|
<div class="text-center">
|
|
<button type="submit" class="button">Accept</button>
|
|
<a class="button" href="/alias/list?">Escape</a>
|
|
</div>
|
|
</form>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
% }
|
|
|
|
% unless ($profile) {
|
|
<div class="callout warning">Alias with id <%= $alias_id %> not exist</div>
|
|
% }
|
|
%#EOF
|
|
</code>
|
|
|
|
====templs/alias-rename-handler.html.ep====
|
|
|
|
<code perl templs/alias-rename-handler.html.ep>
|
|
%#
|
|
%# $Id$
|
|
%#
|
|
% layout 'default';
|
|
% title 'Mail';
|
|
|
|
% use Mojo::Util qw(dumper);
|
|
|
|
% my $u = $c->app->user;
|
|
|
|
% my $new_name = $c->req->param('alias_name');
|
|
% my $alias_id = $c->req->param('alias_id') || 0;
|
|
% my $profile = $u->alias_profile($alias_id);
|
|
|
|
% if ($profile) {
|
|
% my $domain_id = $profile->{domain_id};
|
|
% my $address = $profile->{address};
|
|
|
|
% my $cid = $u->alias_exist($new_name, $domain_id);
|
|
% if ($cid) {
|
|
<div class="callout warning">Alias with <%= $address %> already exists</div>
|
|
% }
|
|
|
|
% unless ($cid) {
|
|
% my $res = $u->alias_update($alias_id, name => $new_name);
|
|
% if ($res) {
|
|
<div class="callout success">Alias <%= $address %> has been updated.</div>
|
|
% }
|
|
|
|
% unless ($res) {
|
|
<div class="callout alert">Alias <%= $address %> was not updated.</div>
|
|
% }
|
|
% }
|
|
% }
|
|
|
|
% unless ($profile) {
|
|
<div class="callout warning">Alias with id <%= $alias_id %> not exist</div>
|
|
% }
|
|
|
|
%#EOF
|
|
|
|
|
|
|
|
|
|
</code>
|
|
|
|
====templs/alias-update-form.html.ep====
|
|
|
|
<code perl templs/alias-update-form.html.ep>
|
|
%#
|
|
%# $Id$
|
|
%#
|
|
% layout 'default';
|
|
% title 'Mail';
|
|
|
|
% use Mojo::Util qw(dumper);
|
|
|
|
% my $u = $c->app->user;
|
|
|
|
% my $alias_id = $c->req->param('alias_id') || 0;
|
|
% my $profile = $u->alias_profile($alias_id);
|
|
|
|
% if ($profile) {
|
|
% my $alias_name = $profile->{name};
|
|
% my $domain_name = $profile->{domain_name};
|
|
% my $domain_id = $profile->{domain_id};
|
|
% my $list = $profile->{list};
|
|
% my $address = $profile->{address};
|
|
|
|
<div class="grid-container">
|
|
<div class="grid-x grid-padding-x">
|
|
<div class="medium-6 medium-centered cell">
|
|
|
|
<form accept-charset="UTF-8" action="/alias/update/handler" method="get" data-abide novalidate>
|
|
<h5 class="text-center">Edit alias <%= $address %></h5>
|
|
<input type="hidden" name="alias_id" value="<%= $alias_id %>"/>
|
|
<label>Destinations list
|
|
<textarea rows="5" name="list" required"><%= $list %></textarea>
|
|
<span class="form-error">Mandatory, 6 or more letter</span>
|
|
</label>
|
|
<div class="text-center">
|
|
<button type="submit" class="button">Accept</button>
|
|
<a class="button" href="/alias/list?">Escape</a>
|
|
</div>
|
|
</form>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
% }
|
|
|
|
% unless ($profile) {
|
|
<div class="callout warning">Alias with id <%= $alias_id %> not exist</div>
|
|
% }
|
|
%#EOF
|
|
</code>
|
|
|
|
====templs/alias-update-handler.html.ep====
|
|
|
|
<code perl templs/alias-update-handler.html.ep>
|
|
%#
|
|
%# $Id$
|
|
%#
|
|
% layout 'default';
|
|
% title 'Mail';
|
|
|
|
% use Mojo::Util qw(dumper trim);
|
|
|
|
% my $u = $c->app->user;
|
|
|
|
% my $alias_id = $c->req->param('alias_id') || 0;
|
|
% my $list = $c->req->param('list');
|
|
|
|
% my $profile = $u->alias_profile($alias_id);
|
|
|
|
% if ($profile) {
|
|
% my $domain_id = $profile->{domain_id};
|
|
% my $domain_name = $profile->{domain_name};
|
|
% my $address = $profile->{address};
|
|
|
|
% $list =~ s/[\s\n]/,/g;
|
|
% $list =~ s/,,/,/g;
|
|
% $list =~ s/^,//g;
|
|
% $list =~ s/,$//g;
|
|
|
|
% my $res = $u->alias_update($alias_id, list => $list);
|
|
% if ($res) {
|
|
<div class="callout success">Alias <%= $address %> has been updated.</div>
|
|
% }
|
|
|
|
% unless ($res) {
|
|
<div class="callout alert">Alias <%= $address %> was not updated.</div>
|
|
% }
|
|
% }
|
|
|
|
% unless ($profile) {
|
|
<div class="callout warning">Alias with id <%= $alias_id %> not exist</div>
|
|
% }
|
|
|
|
%#EOF
|
|
|
|
|
|
|
|
|
|
</code>
|
|
|
|
====templs/domain-add-form.html.ep====
|
|
|
|
<code perl templs/domain-add-form.html.ep>
|
|
%#
|
|
%# $Id$
|
|
%#
|
|
% layout 'default';
|
|
% title 'Mail';
|
|
|
|
% use Mojo::Util qw(dumper);
|
|
|
|
% my $u = $c->app->user;
|
|
|
|
<div class="grid-container">
|
|
<div class="grid-x grid-padding-x">
|
|
<div class="medium-6 medium-centered cell">
|
|
|
|
<form accept-charset="UTF-8" action="/domain/add/handler" method="get" data-abide novalidate>
|
|
<h5 class="text-center">Add domain</h5>
|
|
<label>Domain name
|
|
<input type="text" name="domain_name" placeholder="domain.org" required pattern="[_.-zA-Z0-9\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]{5,42}"/>
|
|
<span class="form-error">Mandatory, 5 or more letter</span>
|
|
</label>
|
|
<div class="text-center">
|
|
<button type="submit" class="button">Accept</button>
|
|
<a class="button" href="/domain/list">Escape</a>
|
|
</div>
|
|
</form>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
%#EOF
|
|
</code>
|
|
|
|
====templs/domain-add-handler.html.ep====
|
|
|
|
<code perl templs/domain-add-handler.html.ep>
|
|
%#
|
|
%# $Id$
|
|
%#
|
|
% layout 'default';
|
|
% title 'Mail';
|
|
|
|
% use Mojo::Util qw(dumper);
|
|
|
|
% my $u = $c->app->user;
|
|
% my $name = $c->req->param('domain_name');
|
|
% my $id = $u->domain_exist($name);
|
|
|
|
% if ($id) {
|
|
<div class="callout warning">Domain <%= $name %> already exists</div>
|
|
% }
|
|
|
|
% unless ($id) {
|
|
% my $res = $u->domain_add($name);
|
|
% if ($res) {
|
|
<div class="callout success">Domain <%= $name %> has been added.</div>
|
|
% }
|
|
|
|
% unless ($res) {
|
|
<div class="callout alert">Domain <%= $name %> was not added.</div>
|
|
% }
|
|
% }
|
|
|
|
%#EOF
|
|
|
|
|
|
|
|
|
|
</code>
|
|
|
|
====templs/domain-delete-form.html.ep====
|
|
|
|
<code perl templs/domain-delete-form.html.ep>
|
|
%#
|
|
%# $Id$
|
|
%#
|
|
% layout 'default';
|
|
% title 'Mail';
|
|
|
|
% use Mojo::Util qw(dumper);
|
|
|
|
% my $u = $c->app->user;
|
|
|
|
% my $domain_id = $c->req->param('domain_id') || 0;
|
|
% my $profile = $u->domain_profile($domain_id);
|
|
|
|
% if ($profile) {
|
|
% my $domain_name = $profile->{name};
|
|
|
|
<div class="grid-container">
|
|
<div class="grid-x grid-padding-x">
|
|
<div class="medium-6 medium-centered cell">
|
|
|
|
<form accept-charset="UTF-8" action="/domain/delete/handler" method="get" data-abide novalidate>
|
|
<h5 class="text-center">Delete domain <%= $domain_name %></h5>
|
|
<input type="hidden" name="domain_id" value="<%= $domain_id %>"/>
|
|
<div class="text-center">
|
|
<button type="submit" class="button">Accept</button>
|
|
<a class="button" href="/domain/list">Escape</a>
|
|
</div>
|
|
</form>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
% }
|
|
|
|
% unless ($profile) {
|
|
<div class="callout warning">Domain with id <%= $domain_id %> not exist</div>
|
|
% }
|
|
|
|
%#EOF
|
|
</code>
|
|
|
|
====templs/domain-delete-handler.html.ep====
|
|
|
|
<code perl templs/domain-delete-handler.html.ep>
|
|
%#
|
|
%# $Id$
|
|
%#
|
|
% layout 'default';
|
|
% title 'Mail';
|
|
|
|
% use Mojo::Util qw(dumper);
|
|
|
|
% my $u = $c->app->user;
|
|
|
|
% my $domain_id = $c->req->param('domain_id') || 0;
|
|
% my $profile = $u->domain_profile($domain_id);
|
|
|
|
% if ($profile) {
|
|
% my $name = $profile->{name};
|
|
% my $res = $u->domain_delete($domain_id);
|
|
|
|
% if ($res) {
|
|
<div class="callout success">Domain <%= $name %> has been deleted</div>
|
|
% }
|
|
|
|
% unless ($res) {
|
|
<div class="callout alert">Domain <%= $name %> was not deleted</div>
|
|
% }
|
|
% }
|
|
|
|
% unless ($profile) {
|
|
<div class="callout warning">Domain with id <%= $domain_id %> not exist</div>
|
|
% }
|
|
|
|
%#EOF
|
|
|
|
</code>
|
|
|
|
====templs/domain-list.html.ep====
|
|
|
|
<code perl templs/domain-list.html.ep>
|
|
%#
|
|
%# $Id$
|
|
%#
|
|
% layout 'default';
|
|
% title 'Mail';
|
|
|
|
% use Mojo::Util qw(dumper);
|
|
|
|
% my $u = $c->app->user;
|
|
|
|
<h5 class="text-center">
|
|
Domains <a href="/domain/list"><i class="fi-refresh"></i></a>
|
|
<a class="float-right button tiny" href="/domain/add/form">
|
|
<i class="fi-plus"></i>
|
|
</a>
|
|
</h5>
|
|
|
|
|
|
% my $list = $u->domain_list;
|
|
|
|
% unless ($list) {
|
|
<div class="callout alert">
|
|
Cannot list domains. May be wrong database?
|
|
</div>
|
|
% }
|
|
|
|
<table class="hover" id="table">
|
|
<thead>
|
|
<tr>
|
|
<th>#</th>
|
|
<th>domain</th>
|
|
<th><i class="fi-graph-pie"></i></th>
|
|
<th><i class="fi-male"></i></th>
|
|
<th><i class="fi-male-female"></i></th>
|
|
<th><i class="fi-pencil"></i></th>
|
|
<th><i class="fi-trash"></i></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
% my $n = 0;
|
|
|
|
% if ($list) {
|
|
% foreach my $row (@$list) {
|
|
% $n += 1;
|
|
% my $id = $row->{id};
|
|
% my $name = $row->{name};
|
|
% my $size = $row->{size};
|
|
<tr>
|
|
<td><%= $n %></td>
|
|
<td><%= $name %></td>
|
|
<td><%= $size %></td>
|
|
<td><a href="/user/list?domain_id=<%= $id %>"><%= $u->domain_user_count($id) %></a></td>
|
|
<td><a href="/alias/list?domain_id=<%= $id %>"><%= $u->domain_alias_count($id) %></a></td>
|
|
<td><a href="/domain/update/form?domain_id=<%= $id %>"><i class="fi-pencil"></i></a></td>
|
|
<td><a href="/domain/delete/form?domain_id=<%= $id %>"><i class="fi-trash"></i></a></td>
|
|
</tr>
|
|
% }
|
|
% }
|
|
</tbody>
|
|
</table>
|
|
|
|
<script>
|
|
$.extend(true, $.fn.dataTable.defaults, {
|
|
"searching": true,
|
|
"ordering": true,
|
|
"language": {
|
|
"search": "",
|
|
"lengthMenu": "_MENU_",
|
|
"info": "_START_-_END_ of _TOTAL_",
|
|
"infoEmpty": "",
|
|
},
|
|
|
|
} );
|
|
|
|
$(document).ready(function() {
|
|
$('#table').DataTable();
|
|
});
|
|
</script>
|
|
|
|
%# EOF
|
|
</code>
|
|
|
|
====templs/domain-update-form.html.ep====
|
|
|
|
<code perl templs/domain-update-form.html.ep>
|
|
%#
|
|
%# $Id$
|
|
%#
|
|
% layout 'default';
|
|
% title 'Mail';
|
|
|
|
% use Mojo::Util qw(dumper);
|
|
|
|
% my $u = $c->app->user;
|
|
|
|
% my $domain_id = $c->req->param('domain_id') || 0;
|
|
% my $profile = $u->domain_profile($domain_id);
|
|
|
|
% if ($profile) {
|
|
% my $domain_name = $profile->{name};
|
|
|
|
<div class="grid-container">
|
|
<div class="grid-x grid-padding-x">
|
|
<div class="medium-6 medium-centered cell">
|
|
|
|
<form accept-charset="UTF-8" action="/domain/update/handler" method="get" data-abide novalidate>
|
|
<h5 class="text-center">Edit domain</h5>
|
|
<input type="hidden" name="domain_id" value="<%= $domain_id %>"/>
|
|
<label>Domain name
|
|
<input type="text" value="<%= $domain_name %>" name="domain_name" required pattern="[_.-zA-Z0-9\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]{5,42}"/>
|
|
<span class="form-error">Mandatory, 5 or more letter</span>
|
|
</label>
|
|
<div class="text-center">
|
|
<button type="submit" class="button">Accept</button>
|
|
<a class="button" href="/domain/list">Escape</a>
|
|
</div>
|
|
</form>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
% }
|
|
|
|
% unless ($profile) {
|
|
<div class="callout warning">Domain with id <%= $domain_id %> not exist</div>
|
|
% }
|
|
|
|
|
|
%#EOF
|
|
</code>
|
|
|
|
====templs/domain-update-handler.html.ep====
|
|
|
|
<code perl templs/domain-update-handler.html.ep>
|
|
%#
|
|
%# $Id$
|
|
%#
|
|
% layout 'default';
|
|
% title 'Mail';
|
|
|
|
% use Mojo::Util qw(dumper);
|
|
|
|
% my $u = $c->app->user;
|
|
|
|
% my $name = $c->req->param('domain_name');
|
|
% my $domain_id = $c->req->param('domain_id') || 0;
|
|
% my $profile = $u->domain_profile($domain_id);
|
|
|
|
% if ($profile) {
|
|
% my $cid = $u->domain_exist($name);
|
|
% if ($cid) {
|
|
<div class="callout warning">Domain <%= $name %> already exists</div>
|
|
% }
|
|
|
|
% unless ($cid) {
|
|
% my $res = $u->domain_update($domain_id, name => $name);
|
|
% if ($res) {
|
|
<div class="callout success">Domain <%= $name %> has been updated.</div>
|
|
% }
|
|
|
|
% unless ($res) {
|
|
<div class="callout alert">Domain <%= $name %> was not updated.</div>
|
|
% }
|
|
% }
|
|
% }
|
|
|
|
% unless ($profile) {
|
|
<div class="callout warning">Domain with id <%= $domain_id %> not exist</div>
|
|
% }
|
|
|
|
%#EOF
|
|
|
|
|
|
|
|
|
|
</code>
|
|
|
|
====templs/exception.development.html.ep====
|
|
|
|
<code perl templs/exception.development.html.ep>
|
|
%#
|
|
%# $Id: exception.html.ep 627 2017-04-15 13:02:08Z ziggi $
|
|
%#
|
|
% layout 'default';
|
|
% title 'Error';
|
|
|
|
<h5>Oops... Exception</h5>
|
|
|
|
<pre>
|
|
%= $exception
|
|
</pre>
|
|
|
|
%#EOF
|
|
</code>
|
|
|
|
====templs/exception.production.html.ep====
|
|
|
|
<code perl templs/exception.production.html.ep>
|
|
%#
|
|
%# $Id: exception.html.ep 627 2017-04-15 13:02:08Z ziggi $
|
|
%#
|
|
% layout 'default';
|
|
% title 'Error';
|
|
|
|
<h5>Oops... Exception</h5>
|
|
|
|
<pre>
|
|
%= $exception
|
|
</pre>
|
|
|
|
%#EOF
|
|
</code>
|
|
|
|
====templs/hello.html.ep====
|
|
|
|
<code perl templs/hello.html.ep>
|
|
% layout 'default';
|
|
% title 'Mail';
|
|
|
|
% use Mojo::Util qw(dumper html_unescape unquote);
|
|
|
|
<h5 class="text-center">Hi! How are you there?</h5>
|
|
|
|
%#EOF
|
|
|
|
</code>
|
|
|
|
====templs/login.html.ep====
|
|
|
|
<code perl templs/login.html.ep>
|
|
%#
|
|
%# $Id: login.html.ep 634 2017-04-15 13:55:49Z ziggi $
|
|
%#
|
|
<html class="no-js" lang="en" dir="ltr">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Login</title>
|
|
<link rel="stylesheet" href="/css/foundation-float.min.css">
|
|
<link rel="stylesheet" href="/css/app.css">
|
|
|
|
<link rel="stylesheet" href="/icons/foundation-icons.css">
|
|
|
|
<script src="/js/jquery.min.js"></script>
|
|
<script src="/js/foundation.min.js"></script>
|
|
</head>
|
|
<body>
|
|
|
|
<div class="row"> </div>
|
|
<div class="row">
|
|
<div class="small-3 columns hide-for-small"> </div>
|
|
<div class="small-6 columns text-center">
|
|
<div class="row">
|
|
<div class="columns">
|
|
|
|
<form accept-charset="UTF-8" method="post" action="/login">
|
|
<div class="row column">
|
|
<h4 class="text-center">Login with your username</h4>
|
|
<label>Username
|
|
<input type="text" name="username" placeholder="username" />
|
|
</label>
|
|
<label>Password
|
|
<input type="password" name="password" placeholder="password" />
|
|
</label>
|
|
<p>
|
|
<button type="submit" class="button">Log In</button>
|
|
</p>
|
|
<p class="text-center"></p>
|
|
</div>
|
|
</form>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="small-3 columns hide-for-small"> </div>
|
|
</div>
|
|
|
|
<hr/>
|
|
<div class="row">
|
|
<p class="text-center"><small>Made by <a href="http://wiki.unix7.org">Borodin Oleg</a></small></p>
|
|
</div>
|
|
|
|
<script src="/js/app.js"></script>
|
|
</body>
|
|
</html>
|
|
<!- EOF ->
|
|
%# EOF
|
|
</code>
|
|
|
|
====templs/mxlog.html.ep====
|
|
|
|
<code perl templs/mxlog.html.ep>
|
|
%# $Id$
|
|
|
|
% use Mojo::Util qw(dumper);
|
|
% my $t = $c->app->tail;
|
|
|
|
% unless ($c->req->param('next')) {
|
|
% layout 'default';
|
|
% title 'Mail';
|
|
<h5 class="text-center"><%= $t->file %></h5>
|
|
<div class="callout">
|
|
<small><div id="log">
|
|
% foreach my $line (@{$t->first}) {
|
|
<%= $line %><br/>
|
|
% }
|
|
</div></small>
|
|
</div>
|
|
<div class="text-center">
|
|
<div id="clear" class="button">Clear</div>
|
|
<div id="pause" class="button">Pause</div>
|
|
</div>
|
|
|
|
% $c->session(pos => $t->pos);
|
|
<script>
|
|
function aTail () {
|
|
$.get("", { next : "yes" },
|
|
function (data) {
|
|
$("#log").append(data);
|
|
$('html,body').animate({
|
|
scrollTop: document.body.scrollHeight},
|
|
"slow"
|
|
);
|
|
});
|
|
};
|
|
|
|
$("#clear").click(function() {
|
|
$("#log").empty();
|
|
});
|
|
|
|
var tailRun = 1;
|
|
var timerId = setInterval(function(){ aTail(); }, 2000);
|
|
|
|
$("#pause").click(function() {
|
|
if (tailRun == 1) {
|
|
clearInterval(timerId);
|
|
$("#pause").html("Pause");
|
|
$("#pause").toggleClass("secondary");
|
|
tailRun = 0;
|
|
} else {
|
|
timerId = setInterval(function() {aTail()}, 2000);
|
|
$("#pause").html("Pause");
|
|
$("#pause").toggleClass("secondary");
|
|
tailRun = 1;
|
|
}
|
|
});
|
|
</script>
|
|
% }
|
|
|
|
% if ($c->req->param('next')) {
|
|
% $t->pos($c->session('pos'));
|
|
% foreach my $line (@{$t->last}) {
|
|
<%= $line %><br/>
|
|
% }
|
|
% $c->session(pos => $t->pos);
|
|
% }
|
|
%#EOF
|
|
</code>
|
|
|
|
====templs/not_found.development.html.ep====
|
|
|
|
<code perl templs/not_found.development.html.ep>
|
|
%#
|
|
%# $Id: not_found.html.ep 627 2017-04-15 13:02:08Z ziggi $
|
|
%#
|
|
% layout 'default';
|
|
% title '404 Not found';
|
|
|
|
<h5>404 Page not found</h5>
|
|
|
|
%#EOF
|
|
</code>
|
|
|
|
====templs/not_found.production.html.ep====
|
|
|
|
<code perl templs/not_found.production.html.ep>
|
|
%#
|
|
%# $Id: not_found.html.ep 627 2017-04-15 13:02:08Z ziggi $
|
|
%#
|
|
% layout 'default';
|
|
% title '404 Not found';
|
|
|
|
<h5>404 Page not found</h5>
|
|
|
|
%#EOF
|
|
</code>
|
|
|
|
====templs/user-add-form.html.ep====
|
|
|
|
<code perl templs/user-add-form.html.ep>
|
|
%#
|
|
%# $Id$
|
|
%#
|
|
% layout 'default';
|
|
% title 'Mail';
|
|
|
|
% use Mojo::Util qw(dumper);
|
|
|
|
% my $u = $c->app->user;
|
|
|
|
% my $domain_id = $c->req->param('domain_id');
|
|
|
|
% if ($domain_id) {
|
|
% my $profile = $u->domain_profile($domain_id);
|
|
% my $domain_name = $profile->{name};
|
|
<div class="grid-container">
|
|
<div class="grid-x grid-padding-x">
|
|
<div class="medium-6 medium-centered cell">
|
|
|
|
<form accept-charset="UTF-8" action="/user/add/handler" method="get" data-abide novalidate>
|
|
<h5 class="text-center">Add user to domain <%= $domain_name %></h5>
|
|
<input type="hidden" name="domain_id" value="<%= $domain_id %>"/>
|
|
<label>Username
|
|
<input type="text" name="user_name" placeholder="username" required pattern="[_.-zA-Z0-9\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]{2,42}"/>
|
|
<span class="form-error">Mandatory, 2 or more letter</span>
|
|
</label>
|
|
<label>Password
|
|
<input type="text" name="password" placeholder="xxxxxxxxx" required pattern="[_.-zA-Z0-9\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]{5,42}"/>
|
|
<span class="form-error">Mandatory, 6 or more letter</span>
|
|
</label>
|
|
<div class="text-center">
|
|
<button type="submit" class="button">Accept</button>
|
|
<a class="button" href="/user/list?domain_id=<%= $domain_id %>">Escape</a>
|
|
</div>
|
|
</form>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
% }
|
|
|
|
% unless ($domain_id) {
|
|
<div class="grid-container">
|
|
<div class="grid-x grid-padding-x">
|
|
<div class="medium-6 medium-centered cell">
|
|
|
|
<form accept-charset="UTF-8" action="/user/add/handler" method="get" data-abide novalidate>
|
|
<h5 class="text-center">Add user</h5>
|
|
<label>Username
|
|
<input type="text" name="user_name" placeholder="username" required pattern="[_.-zA-Z0-9\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]{2,42}"/>
|
|
<span class="form-error">Mandatory, 2 or more letter</span>
|
|
</label>
|
|
<label>Password
|
|
<input type="text" name="password" placeholder="xxxxxxxxx" required pattern="[_.-zA-Z0-9\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]{5,42}"/>
|
|
<span class="form-error">Mandatory, 6 or more letter</span>
|
|
</label>
|
|
|
|
<label>Domain
|
|
<select name="domain_id" required>
|
|
<option value=""></option>
|
|
% foreach my $rec (@{$u->domain_list}) {
|
|
<option value="<%= $rec->{id} %>"><%= $rec->{name} %></option>
|
|
% }
|
|
</select >
|
|
</label>
|
|
|
|
<div class="text-center">
|
|
<button type="submit" class="button">Accept</button>
|
|
<a class="button" href="/user/list">Escape</a>
|
|
</div>
|
|
</form>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
% }
|
|
|
|
%#EOF
|
|
</code>
|
|
|
|
====templs/user-add-handler.html.ep====
|
|
|
|
<code perl templs/user-add-handler.html.ep>
|
|
%#
|
|
%# $Id$
|
|
%#
|
|
% layout 'default';
|
|
% title 'Mail';
|
|
|
|
% use Mojo::Util qw(dumper);
|
|
|
|
% my $u = $c->app->user;
|
|
|
|
% my $user_name = $c->req->param('user_name');
|
|
% my $domain_id = $c->req->param('domain_id');
|
|
% my $password = $c->req->param('password');
|
|
|
|
% my $cid = $u->user_exist($user_name, $domain_id);
|
|
|
|
% if ($cid) {
|
|
<div class="callout warning">User <%= $user_name %> already exists</div>
|
|
% }
|
|
|
|
% unless ($cid) {
|
|
% my $id = $u->user_add($user_name, $password, $domain_id);
|
|
% if ($id) {
|
|
<div class="callout success">User <%= $user_name %> has been added.</div>
|
|
% }
|
|
|
|
% unless ($id) {
|
|
<div class="callout alert">User <%= $user_name %> was not added.</div>
|
|
% }
|
|
% }
|
|
%#EOF
|
|
|
|
|
|
|
|
|
|
</code>
|
|
|
|
====templs/user-delete-form.html.ep====
|
|
|
|
<code perl templs/user-delete-form.html.ep>
|
|
%#
|
|
%# $Id$
|
|
%#
|
|
% layout 'default';
|
|
% title 'Mail';
|
|
|
|
% use Mojo::Util qw(dumper);
|
|
|
|
% my $u = $c->app->user;
|
|
|
|
% my $user_id = $c->req->param('user_id') || 0;
|
|
% my $profile = $u->user_profile($user_id);
|
|
|
|
% if ($profile) {
|
|
% my $user_name = $profile->{name};
|
|
% my $domain_name = $profile->{domain_name};
|
|
% my $domain_id = $profile->{domain_id};
|
|
% my $address = $profile->{address};
|
|
|
|
<div class="grid-container">
|
|
<div class="grid-x grid-padding-x">
|
|
<div class="medium-6 medium-centered cell">
|
|
|
|
<form accept-charset="UTF-8" action="/user/delete/handler" method="get" data-abide novalidate>
|
|
<h5 class="text-center">Delete user <%= $address %></h5>
|
|
<input type="hidden" name="user_id" value="<%= $user_id %>"/>
|
|
<div class="text-center">
|
|
<button type="submit" class="button">Accept</button>
|
|
<a class="button" href="/user/list?domain_id=<%= $domain_id %>">Escape</a>
|
|
</div>
|
|
</form>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
% }
|
|
|
|
% unless ($profile) {
|
|
<div class="callout warning">User with id <%= $user_id %> not exist</div>
|
|
% }
|
|
%#EOF
|
|
</code>
|
|
|
|
====templs/user-delete-handler.html.ep====
|
|
|
|
<code perl templs/user-delete-handler.html.ep>
|
|
%#
|
|
%# $Id$
|
|
%#
|
|
% layout 'default';
|
|
% title 'Mail';
|
|
|
|
% use Mojo::Util qw(dumper);
|
|
|
|
% my $u = $c->app->user;
|
|
|
|
% my $user_id = $c->req->param('user_id') || 0;
|
|
% my $profile = $u->user_profile($user_id);
|
|
|
|
% if ($profile) {
|
|
% my $name = $profile->{name};
|
|
% my $address = $profile->{address};
|
|
|
|
% my $res = $u->user_delete($user_id);
|
|
|
|
% if ($res) {
|
|
<div class="callout success">User <%= $address %> has been deleted</div>
|
|
% }
|
|
|
|
% unless ($res) {
|
|
<div class="callout alert">User <%= $address %> was not deleted</div>
|
|
% }
|
|
% }
|
|
|
|
% unless ($profile) {
|
|
<div class="callout warning">User with id <%= $user_id %> not exist</div>
|
|
% }
|
|
|
|
%#EOF
|
|
|
|
</code>
|
|
|
|
====templs/user-list.html.ep====
|
|
|
|
<code perl templs/user-list.html.ep>
|
|
%#
|
|
%# $Id$
|
|
%#
|
|
% layout 'default';
|
|
% title 'Mail';
|
|
|
|
% use Mojo::Util qw(dumper);
|
|
|
|
% my $req = $c->req;
|
|
% my $u = $c->app->user;
|
|
|
|
% my $domain_id = $req->param('domain_id');
|
|
|
|
|
|
|
|
% if ($domain_id) {
|
|
<h5 class="text-center">
|
|
Accounts <a href="/user/list?domain_id=<%= $domain_id %>"><i class="fi-refresh"></i></a>
|
|
<a class="float-right button tiny" href="/user/add/form?domain_id=<%= $domain_id %>">
|
|
<i class="fi-plus"></i>
|
|
</a>
|
|
</h5>
|
|
|
|
% my $list = $u->user_list($domain_id);
|
|
|
|
<table class="hover" id="table">
|
|
<thead>
|
|
<tr>
|
|
<th>#</th>
|
|
<th>address</th>
|
|
<th><i class="fi-graph-pie"></i></th>
|
|
<th><i class="fi-address-book"></i></th>
|
|
<th><i class="fi-pencil"></i></th>
|
|
<th><i class="fi-trash"></i></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
% if ($list) {
|
|
% my $n = 0;
|
|
% foreach my $row (@$list) {
|
|
% $n += 1;
|
|
% my $address = $row->{address};
|
|
% my $user_id = $row->{id};
|
|
% my $domain_id = $row->{domain_id};
|
|
% my $size = $row->{size} || 0;
|
|
<tr>
|
|
<td><%= $n %></td>
|
|
<td><%= $address %></td>
|
|
<td><%= $size %></td>
|
|
<td><a href="/user/rename/form?user_id=<%= $user_id %>"><i class="fi-address-book"></i></a></td>
|
|
<td><a href="/user/update/form?user_id=<%= $user_id %>"><i class="fi-pencil"></i></a></td>
|
|
<td><a href="/user/delete/form?user_id=<%= $user_id %>"><i class="fi-trash"></i></a></td>
|
|
</tr>
|
|
% }
|
|
% }
|
|
</tbody>
|
|
</table>
|
|
% }
|
|
|
|
% unless ($domain_id) {
|
|
<h5 class="text-center">
|
|
Accounts <a href="/user/list"><i class="fi-refresh"></i></a>
|
|
<a class="float-right button tiny" href="/user/add/form">
|
|
<i class="fi-plus"></i>
|
|
</a>
|
|
</h5>
|
|
|
|
% my $list = $u->user_list;
|
|
|
|
<table class="hover" id="table">
|
|
<thead>
|
|
<tr>
|
|
<th>#</th>
|
|
<th>address</th>
|
|
<th><i class="fi-graph-pie"></i></th>
|
|
<th><i class="fi-at-sign"></i></th>
|
|
<th><i class="fi-address-book"></i></th>
|
|
<th><i class="fi-pencil"></i></th>
|
|
<th><i class="fi-trash"></i></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
% my $n = 0;
|
|
% if ($list) {
|
|
% foreach my $row (@$list) {
|
|
% $n += 1;
|
|
% my $address = $row->{address};
|
|
% my $user_id = $row->{id};
|
|
% my $domain_id = $row->{domain_id};
|
|
% my $size = $row->{size} || 0;
|
|
<tr>
|
|
<td><%= $n %></td>
|
|
<td><%= $address %></td>
|
|
<td><%= $size %></td>
|
|
<td><a href="/user/list?domain_id=<%= $domain_id %>"><i class="fi-at-sign"></i></a></td>
|
|
<td><a href="/user/rename/form?user_id=<%= $user_id %>"><i class="fi-address-book"></i></a></td>
|
|
<td><a href="/user/update/form?user_id=<%= $user_id %>"><i class="fi-pencil"></i></a></td>
|
|
<td><a href="/user/delete/form?user_id=<%= $user_id %>"><i class="fi-trash"></i></a></td>
|
|
</tr>
|
|
% }
|
|
% }
|
|
</tbody>
|
|
</table>
|
|
% }
|
|
|
|
<script>
|
|
$.extend(true, $.fn.dataTable.defaults, {
|
|
"searching": true,
|
|
"ordering": true,
|
|
"language": {
|
|
"search": "",
|
|
"lengthMenu": "_MENU_",
|
|
"info": "_START_-_END_ of _TOTAL_",
|
|
"infoEmpty": "",
|
|
},
|
|
});
|
|
|
|
$(document).ready(function() {
|
|
$('#table').DataTable();
|
|
});
|
|
</script>
|
|
%# EOF
|
|
|
|
</code>
|
|
|
|
====templs/user-rename-form.html.ep====
|
|
|
|
<code perl templs/user-rename-form.html.ep>
|
|
%#
|
|
%# $Id$
|
|
%#
|
|
% layout 'default';
|
|
% title 'Mail';
|
|
|
|
% use Mojo::Util qw(dumper);
|
|
|
|
% my $u = $c->app->user;
|
|
|
|
% my $user_id = $c->req->param('user_id') || 0;
|
|
% my $profile = $u->user_profile($user_id);
|
|
|
|
% if ($profile) {
|
|
% my $user_name = $profile->{name};
|
|
% my $domain_name = $profile->{domain_name};
|
|
% my $domain_id = $profile->{domain_id};
|
|
% my $password = $profile->{password};
|
|
% my $address = $profile->{address};
|
|
|
|
<div class="grid-container">
|
|
<div class="grid-x grid-padding-x">
|
|
<div class="medium-6 medium-centered cell">
|
|
|
|
<form accept-charset="UTF-8" action="/user/rename/handler" method="get" data-abide novalidate>
|
|
<h5 class="text-center">Rename user <%= $address %></h5>
|
|
<input type="hidden" name="user_id" value="<%= $user_id %>"/>
|
|
<label>Username
|
|
<input type="text" value="<%= $user_name %>" name="user_name" required pattern="[_.-zA-Z0-9\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]{2,42}"/>
|
|
<span class="form-error">Mandatory, 2 or more letter</span>
|
|
</label>
|
|
<div class="text-center">
|
|
<button type="submit" class="button">Accept</button>
|
|
<a class="button" href="/user/list?domain_id=<%= $domain_id %>">Escape</a>
|
|
</div>
|
|
</form>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
% }
|
|
|
|
% unless ($profile) {
|
|
<div class="callout warning">User with id <%= $user_id %> not exist</div>
|
|
% }
|
|
%#EOF
|
|
</code>
|
|
|
|
====templs/user-rename-handler.html.ep====
|
|
|
|
<code perl templs/user-rename-handler.html.ep>
|
|
%#
|
|
%# $Id$
|
|
%#
|
|
% layout 'default';
|
|
% title 'Mail';
|
|
|
|
% use Mojo::Util qw(dumper);
|
|
|
|
% my $u = $c->app->user;
|
|
|
|
% my $new_name = $c->req->param('user_name');
|
|
% my $user_id = $c->req->param('user_id') || 0;
|
|
% my $profile = $u->user_profile($user_id);
|
|
|
|
% if ($profile) {
|
|
% my $domain_id = $profile->{domain_id};
|
|
% my $address = $profile->{address};
|
|
|
|
% my $cid = $u->user_exist($new_name, $domain_id);
|
|
|
|
% if ($cid) {
|
|
<div class="callout warning">User <%= $address %> already exists</div>
|
|
% }
|
|
|
|
% unless ($cid) {
|
|
% my $res = $u->user_update($user_id, name => $new_name);
|
|
% if ($res) {
|
|
<div class="callout success">User <%= $address %> has been updated.</div>
|
|
% }
|
|
|
|
% unless ($res) {
|
|
<div class="callout alert">User <%= $address %> was not updated.</div>
|
|
% }
|
|
% }
|
|
% }
|
|
|
|
% unless ($profile) {
|
|
<div class="callout warning">User with id <%= $user_id %> not exist</div>
|
|
% }
|
|
|
|
%#EOF
|
|
</code>
|
|
|
|
====templs/user-update-form.html.ep====
|
|
|
|
<code perl templs/user-update-form.html.ep>
|
|
%#
|
|
%# $Id$
|
|
%#
|
|
% layout 'default';
|
|
% title 'Mail';
|
|
|
|
% use Mojo::Util qw(dumper);
|
|
|
|
% my $u = $c->app->user;
|
|
|
|
% my $user_id = $c->req->param('user_id') || 0;
|
|
% my $profile = $u->user_profile($user_id);
|
|
|
|
% if ($profile) {
|
|
% my $user_name = $profile->{name};
|
|
% my $domain_name = $profile->{domain_name};
|
|
% my $domain_id = $profile->{domain_id};
|
|
% my $password = $profile->{password};
|
|
% my $address = $profile->{address};
|
|
|
|
<div class="grid-container">
|
|
<div class="grid-x grid-padding-x">
|
|
<div class="medium-6 medium-centered cell">
|
|
|
|
<form accept-charset="UTF-8" action="/user/update/handler" method="get" data-abide novalidate>
|
|
<h5 class="text-center">Edit user <%= $address %></h5>
|
|
<input type="hidden" name="user_id" value="<%= $user_id %>"/>
|
|
<label>Password
|
|
<input type="text" value="<%= $password %>" name="password" required pattern="[_.-zA-Z0-9\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]{6,42}"/>
|
|
<span class="form-error">Mandatory, 6 or more letter</span>
|
|
</label>
|
|
<div class="text-center">
|
|
<button type="submit" class="button">Accept</button>
|
|
<a class="button" href="/user/list?">Escape</a>
|
|
</div>
|
|
</form>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
% }
|
|
|
|
% unless ($profile) {
|
|
<div class="callout warning">User with id <%= $user_id %> not exist</div>
|
|
% }
|
|
%#EOF
|
|
</code>
|
|
|
|
====templs/user-update-handler.html.ep====
|
|
|
|
<code perl templs/user-update-handler.html.ep>
|
|
%#
|
|
%# $Id$
|
|
%#
|
|
% layout 'default';
|
|
% title 'Mail';
|
|
|
|
% use Mojo::Util qw(dumper);
|
|
|
|
% my $u = $c->app->user;
|
|
|
|
% my $user_id = $c->req->param('user_id') || 0;
|
|
% my $password = $c->req->param('password');
|
|
|
|
% my $profile = $u->user_profile($user_id);
|
|
|
|
% if ($profile) {
|
|
% my $domain_id = $profile->{domain_id};
|
|
% my $domain_name = $profile->{domain_name};
|
|
% my $address = $profile->{address};
|
|
|
|
% my $res = $u->user_update($user_id, password => $password);
|
|
% if ($res) {
|
|
<div class="callout success">User <%= $address %> has been updated.</div>
|
|
% }
|
|
% unless ($res) {
|
|
<div class="callout alert">User <%= $address %> was not updated.</div>
|
|
% }
|
|
% }
|
|
|
|
% unless ($profile) {
|
|
<div class="callout warning">User with id <%= $user_id %> not exist</div>
|
|
% }
|
|
|
|
%#EOF
|
|
|
|
|
|
|
|
|
|
</code>
|
|
|
|
----
|
|
[<>]
|