diff --git a/to-wiki.txt b/to-wiki.txt new file mode 100644 index 0000000..cfd67b1 --- /dev/null +++ b/to-wiki.txt @@ -0,0 +1,4042 @@ +=====PGdumper current code===== + +Work still in progress + +====maacom.pl==== + + +#!@perl@ + +package aConfig; + +use strict; +use warnings; + +sub new { + my ($class, $file) = @_; + my $self = { + file => $file + }; + bless $self, $class; + $self; +} + +sub file { + my ($self, $name) = @_; + return $self->{'file'} unless $name; + $self->{'file'} = $name; + $self; +} + +sub read { + my $self = shift; + return undef unless -r $self->file; + open my $fh, '<', $self->file; + my %res; + while (my $line = readline $fh) { + chomp $line; + $line =~ s/^\s+//g; + + next if $line =~ /^#/; + next if $line =~ /^;/; + next unless $line =~ /[=:]/; + + $line =~ s/[\"\']//g; + my ($key, $rawvalue) = split(/==|=>|[=:]/, $line); + next unless $rawvalue and $key; + + my ($value, $comment) = split(/[#;,]/, $rawvalue); + + $key =~ s/^\s+|\s+$//g; + $value =~ s/^\s+|\s+$//g; + + $res{$key} = $value; + } + close $fh; + \%res; +} + +1; + +#---------- +#--- 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; +} + +# --- ALAIS --- + +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; +} + + +# --- FORWARD --- + +sub forwarded_exist { + my ($self, $name) = @_; + return undef unless $name; + my $res = $self->db->exec1("select id from forwarded where name = '$name' order by id limit 1"); + $res->{id}; +} + +sub forwarded_profile { + my ($self, $id) = @_; + return undef unless $id; + my $row = $self->db->exec1("select * from forwarded where forwarded.id = $id limit 1"); + $row; +} + +sub forwarded_nextid { + my $self = shift; + my $res = $self->db->exec1("select id from forwarded order by id desc limit 1"); + my $id = $res->{id} || 0; + $id += 1; +} + +sub forwarded_add { + my ($self, $name) = @_; + return undef unless $name; + return undef if $self->forwarded_exist($name); + my $next_id = $self->forwarded_nextid; + $self->db->do("insert into forwarded (id, name) values ($next_id, '$name')"); + $self->forwarded_exist($name); +} + +sub forwarded_list { + my $self = shift; + $self->db->exec("select * from forwarded order by id"); +} + +sub forwarded_update { + my ($self, $id, %args) = @_; + return undef unless $id; + my $prof = $self->forwarded_profile($id); + return undef unless $prof; + + my $name = $args{name} || $prof->{name}; + + $self->db->do("update forwarded set name = '$name' where id = $id"); + my $res = $self->forwarded_profile($id); + return undef unless $res->{name} eq $name; + $id; +} + + +sub forwarded_delete { + my ($self, $id) = @_; + return undef unless $id; +# return $id unless $self->forwarded_profile($id); + $self->db->do("delete from forwarded where id = $id"); + return undef if $self->forwarded_profile($id); + $id; +} + + +# --- UNWANTED --- + +sub unwanted_exist { + my ($self, $name) = @_; + return undef unless $name; + my $res = $self->db->exec1("select id from unwanted where name = '$name' order by id limit 1"); + $res->{id}; +} + +sub unwanted_profile { + my ($self, $id) = @_; + return undef unless $id; + my $row = $self->db->exec1("select * from unwanted where unwanted.id = $id limit 1"); + $row; +} + +sub unwanted_nextid { + my $self = shift; + my $res = $self->db->exec1("select id from unwanted order by id desc limit 1"); + my $id = $res->{id} || 0; + $id += 1; +} + +sub unwanted_add { + my ($self, $name) = @_; + return undef unless $name; + return undef if $self->unwanted_exist($name); + my $next_id = $self->unwanted_nextid; + $self->db->do("insert into unwanted (id, name) values ($next_id, '$name')"); + $self->unwanted_exist($name); +} + +sub unwanted_list { + my $self = shift; + $self->db->exec("select * from unwanted order by id"); +} + +sub unwanted_update { + my ($self, $id, %args) = @_; + return undef unless $id; + my $prof = $self->unwanted_profile($id); + return undef unless $prof; + + my $name = $args{name} || $prof->{name}; + + $self->db->do("update unwanted set name = '$name' where id = $id"); + my $res = $self->unwanted_profile($id); + return undef unless $res->{name} eq $name; + $id; +} + + +sub unwanted_delete { + my ($self, $id) = @_; + return undef unless $id; +# return $id unless $self->unwanted_profile($id); + $self->db->do("delete from unwanted where id = $id"); + return undef if $self->unwanted_profile($id); + $id; +} + +# --- TRUSTED --- + +sub trusted_exist { + my ($self, $name) = @_; + return undef unless $name; + my $res = $self->db->exec1("select id from trusted where name = '$name' order by id limit 1"); + $res->{id}; +} + +sub trusted_profile { + my ($self, $id) = @_; + return undef unless $id; + my $row = $self->db->exec1("select * from trusted where trusted.id = $id limit 1"); + $row; +} + +sub trusted_nextid { + my $self = shift; + my $res = $self->db->exec1("select id from trusted order by id desc limit 1"); + my $id = $res->{id} || 0; + $id += 1; +} + +sub trusted_add { + my ($self, $name) = @_; + return undef unless $name; + return undef if $self->trusted_exist($name); + my $next_id = $self->trusted_nextid; + $self->db->do("insert into trusted (id, name) values ($next_id, '$name')"); + $self->trusted_exist($name); +} + +sub trusted_list { + my $self = shift; + $self->db->exec("select * from trusted order by id"); +} + +sub trusted_update { + my ($self, $id, %args) = @_; + return undef unless $id; + my $prof = $self->trusted_profile($id); + return undef unless $prof; + + my $name = $args{name} || $prof->{name}; + + $self->db->do("update trusted set name = '$name' where id = $id"); + my $res = $self->trusted_profile($id); + return undef unless $res->{name} eq $name; + $id; +} + + +sub trusted_delete { + my ($self, $id) = @_; + return undef unless $id; +# return $id unless $self->trusted_profile($id); + $self->db->do("delete from trusted where id = $id"); + return undef if $self->trusted_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, $user, $group) = @_; + my $self = { + user => $user, + group => $group + }; + bless $self, $class; + return $self; +} + +sub fork { + my $self = shift; + + my $pid = fork; + if ($pid > 0) { + exit; + } + chdir("/"); + + my $uid = getpwnam($self->{user}) if $self->{user}; + my $gid = getgrnam($self->{group}) if $self->{group}; + + setuid($uid) if $uid; + setgid($gid) if $gid; + + 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'); +} + +# --- FORWARD --- + +sub forwarded_list { + my $self = shift; + $self->render(template => 'forwarded-list'); +} +sub forwarded_add_form { + my $self = shift; + $self->render(template => 'forwarded-add-form'); +} +sub forwarded_add_handler { + my $self = shift; + $self->render(template => 'forwarded-add-handler'); +} +sub forwarded_update_form { + my $self = shift; + $self->render(template => 'forwarded-update-form'); +} + +sub forwarded_update_handler { + my $self = shift; + $self->render(template => 'forwarded-update-handler'); +} + +sub forwarded_delete_form { + my $self = shift; + $self->render(template => 'forwarded-delete-form'); +} + +sub forwarded_delete_handler { + my $self = shift; + $self->render(template => 'forwarded-delete-handler'); +} + +# --- UNWANTED --- + +sub unwanted_list { + my $self = shift; + $self->render(template => 'unwanted-list'); +} +sub unwanted_add_form { + my $self = shift; + $self->render(template => 'unwanted-add-form'); +} +sub unwanted_add_handler { + my $self = shift; + $self->render(template => 'unwanted-add-handler'); +} +sub unwanted_update_form { + my $self = shift; + $self->render(template => 'unwanted-update-form'); +} + +sub unwanted_update_handler { + my $self = shift; + $self->render(template => 'unwanted-update-handler'); +} + +sub unwanted_delete_form { + my $self = shift; + $self->render(template => 'unwanted-delete-form'); +} + +sub unwanted_delete_handler { + my $self = shift; + $self->render(template => 'unwanted-delete-handler'); +} + +# --- TRUSTED --- + +sub trusted_list { + my $self = shift; + $self->render(template => 'trusted-list'); +} +sub trusted_add_form { + my $self = shift; + $self->render(template => 'trusted-add-form'); +} +sub trusted_add_handler { + my $self = shift; + $self->render(template => 'trusted-add-handler'); +} +sub trusted_update_form { + my $self = shift; + $self->render(template => 'trusted-update-form'); +} + +sub trusted_update_handler { + my $self = shift; + $self->render(template => 'trusted-update-handler'); +} + +sub trusted_delete_form { + my $self = shift; + $self->render(template => 'trusted-delete-form'); +} + +sub trusted_delete_handler { + my $self = shift; + $self->render(template => 'trusted-delete-handler'); +} + +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'); + +$app->config(group => '@app_group@'); +$app->config(user => '@app_user@'); + +if (-r $app->config('conffile')) { + $app->log->debug("Load configuration from ".$app->config('conffile')); +# $app->plugin('JSONConfig', { file => $app->config('conffile') }); + my $c = aConfig->new($app->config('conffile')); + my $hash = $c->read; + foreach my $key (keys %$hash) { + $app->config($key => $hash->{$key}); + } +} + +#--------------- +#--- 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' ); + +$r->any('/forwarded/list')->over('auth')->to('controller#forwarded_list' ); +$r->any('/forwarded/add/form')->over('auth')->to('controller#forwarded_add_form' ); +$r->any('/forwarded/add/handler')->over('auth')->to('controller#forwarded_add_handler' ); +$r->any('/forwarded/update/form')->over('auth')->to('controller#forwarded_update_form' ); +$r->any('/forwarded/update/handler')->over('auth')->to('controller#forwarded_update_handler' ); +$r->any('/forwarded/delete/form')->over('auth')->to('controller#forwarded_delete_form' ); +$r->any('/forwarded/delete/handler')->over('auth')->to('controller#forwarded_delete_handler' ); + +$r->any('/unwanted/list')->over('auth')->to('controller#unwanted_list' ); +$r->any('/unwanted/add/form')->over('auth')->to('controller#unwanted_add_form' ); +$r->any('/unwanted/add/handler')->over('auth')->to('controller#unwanted_add_handler' ); +$r->any('/unwanted/update/form')->over('auth')->to('controller#unwanted_update_form' ); +$r->any('/unwanted/update/handler')->over('auth')->to('controller#unwanted_update_handler' ); +$r->any('/unwanted/delete/form')->over('auth')->to('controller#unwanted_delete_form' ); +$r->any('/unwanted/delete/handler')->over('auth')->to('controller#unwanted_delete_handler' ); + + +$r->any('/trusted/list')->over('auth')->to('controller#trusted_list' ); +$r->any('/trusted/add/form')->over('auth')->to('controller#trusted_add_form' ); +$r->any('/trusted/add/handler')->over('auth')->to('controller#trusted_add_handler' ); +$r->any('/trusted/update/form')->over('auth')->to('controller#trusted_update_form' ); +$r->any('/trusted/update/handler')->over('auth')->to('controller#trusted_update_handler' ); +$r->any('/trusted/delete/form')->over('auth')->to('controller#trusted_delete_form' ); +$r->any('/trusted/delete/handler')->over('auth')->to('controller#trusted_delete_handler' ); + + +#---------------- +#--- 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); + + +$server->pid_file($app->config('pidfile')); + +$app->log(Mojo::Log->new( + path => $app->config('logfile'), + level => $app->config('loglevel') +)); + + +my $user = $app->config('user'); +my $group = $app->config('group'); +my $d = Daemon->new($user, $group); +$d->fork; + + + +$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 + + +====templs/alias-add-form.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% 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}; +
+
+
+ +
+
Add alias to domain <%= $domain_name %>
+ + + +
+ + Escape +
+
+ +
+
+
+% } + +% unless ($domain_id) { +
+
+
+ +
+
Add alias
+ + + + +
+ + Escape +
+
+ +
+
+
+% } + +%#EOF +
+ +====templs/alias-add-handler.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% 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) { +
Alias <%= $alias_name %> already exists
+% } + +% unless ($cid) { + % my $id = $u->alias_add($alias_name, $list, $domain_id); + % if ($id) { +
Alias <%= $alias_name %> has been added.
+ % } + + % unless ($id) { +
Alias <%= $alias_name %> was not added.
+ % } +% } +%#EOF +
+ +====templs/alias-delete-form.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% 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}; + +
+
+
+ +
+
Delete alias <%= $address %>
+ +
+ + Escape +
+
+ +
+
+
+% } + +% unless ($profile) { +
Alias with id <%= $alias_id %> not exist
+% } +%#EOF +
+ +====templs/alias-delete-handler.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% 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) { +
Alias <%= $address %> has been deleted
+ % } + + % unless ($res) { +
Alias <%= $address %> was not deleted
+ % } +% } + +% unless ($profile) { +
Alias with id <%= $alias_id %> not exist
+% } + +%#EOF + +
+ +====templs/alias-list.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% use Mojo::Util qw(dumper); + +% my $req = $c->req; +% my $u = $c->app->user; + +% my $domain_id = $req->param('domain_id'); + +% unless ($domain_id) { +
+ Aliases + + + +
+ + % my $list = $u->alias_list; + + + + + + + + + + + + + + + % 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}; + + + + + + + + + + % } + % } + +
#alias
<%= $n %><%= $address %><%= $count %>
+% } + +% if ($domain_id) { + % my $domain_name = $u->domain_profile($domain_id)->{name}; +
+ Aliases <%= $domain_name %> + + + +
+ + % my $list = $u->alias_list($domain_id); + + + + + + + + + + + + + + % 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}; + + + + + + + + + % } + % } + +
#alias
<%= $n %><%= $address %><%= $count %>
+% } + + +%# EOF + +
+ +====templs/alias-rename-form.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% 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}; + +
+
+
+ +
+
Edit alias <%= $address %>
+ + +
+ + Escape +
+
+ +
+
+
+% } + +% unless ($profile) { +
Alias with id <%= $alias_id %> not exist
+% } +%#EOF +
+ +====templs/alias-rename-handler.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% 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) { +
Alias with <%= $address %> already exists
+ % } + + % unless ($cid) { + % my $res = $u->alias_update($alias_id, name => $new_name); + % if ($res) { +
Alias <%= $address %> has been updated.
+ % } + + % unless ($res) { +
Alias <%= $address %> was not updated.
+ % } + % } +% } + +% unless ($profile) { +
Alias with id <%= $alias_id %> not exist
+% } + +%#EOF + + + + +
+ +====templs/alias-update-form.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% 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}; + +
+
+
+ +
+
Edit alias <%= $address %>
+ + +
+ + Escape +
+
+ +
+
+
+% } + +% unless ($profile) { +
Alias with id <%= $alias_id %> not exist
+% } +%#EOF +
+ +====templs/alias-update-handler.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% 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) { +
Alias <%= $address %> has been updated.
+ % } + + % unless ($res) { +
Alias <%= $address %> was not updated.
+ % } +% } + +% unless ($profile) { +
Alias with id <%= $alias_id %> not exist
+% } + +%#EOF + + + + +
+ +====templs/domain-add-form.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% use Mojo::Util qw(dumper); + +% my $u = $c->app->user; + +
+
+
+ +
+
Add domain
+ +
+ + Escape +
+
+ +
+
+
+%#EOF +
+ +====templs/domain-add-handler.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% 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) { +
Domain <%= $name %> already exists
+% } + +% unless ($id) { + % my $res = $u->domain_add($name); + % if ($res) { +
Domain <%= $name %> has been added.
+ % } + + % unless ($res) { +
Domain <%= $name %> was not added.
+ % } +% } + +%#EOF + + + + +
+ +====templs/domain-delete-form.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% 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}; + +
+
+
+ +
+
Delete domain <%= $domain_name %>
+ +
+ + Escape +
+
+ +
+
+
+% } + +% unless ($profile) { +
Domain with id <%= $domain_id %> not exist
+% } + +%#EOF +
+ +====templs/domain-delete-handler.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% 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) { +
Domain <%= $name %> has been deleted
+ % } + + % unless ($res) { +
Domain <%= $name %> was not deleted
+ % } +% } + +% unless ($profile) { +
Domain with id <%= $domain_id %> not exist
+% } + +%#EOF + +
+ +====templs/domain-list.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% use Mojo::Util qw(dumper); + +% my $u = $c->app->user; + +
+ Domains + + + +
+ + +% my $list = $u->domain_list; + +% unless ($list) { +
+ Cannot list domains. May be wrong database? +
+% } + + + + + + + + + + + + + + +% my $n = 0; + +% if ($list) { + % foreach my $row (@$list) { + % $n += 1; + % my $id = $row->{id}; + % my $name = $row->{name}; + % my $size = $row->{size}; + + + + + + + + + + % } +% } + +
#domain
<%= $n %><%= $name %><%= $size %><%= $u->domain_user_count($id) %><%= $u->domain_alias_count($id) %>
+ + + +%# EOF +
+ +====templs/domain-update-form.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% 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}; + +
+
+
+ +
+
Edit domain
+ + +
+ + Escape +
+
+ +
+
+
+% } + +% unless ($profile) { +
Domain with id <%= $domain_id %> not exist
+% } + + +%#EOF +
+ +====templs/domain-update-handler.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% 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) { +
Domain <%= $name %> already exists
+ % } + + % unless ($cid) { + % my $res = $u->domain_update($domain_id, name => $name); + % if ($res) { +
Domain <%= $name %> has been updated.
+ % } + + % unless ($res) { +
Domain <%= $name %> was not updated.
+ % } + % } +% } + +% unless ($profile) { +
Domain with id <%= $domain_id %> not exist
+% } + +%#EOF + + + + +
+ +====templs/exception.development.html.ep==== + + +%# +%# $Id: exception.html.ep 627 2017-04-15 13:02:08Z ziggi $ +%# +% layout 'default'; +% title 'Error'; + +
Oops... Exception
+ +
  
+%= $exception
+
+ +%#EOF +
+ +====templs/exception.production.html.ep==== + + +%# +%# $Id: exception.html.ep 627 2017-04-15 13:02:08Z ziggi $ +%# +% layout 'default'; +% title 'Error'; + +
Oops... Exception
+ +
+%= $exception
+
+ +%#EOF +
+ +====templs/forwarded-add-form.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% use Mojo::Util qw(dumper); + +% my $u = $c->app->user; + +
+
+
+ +
+
Add forwardeded domain
+ +
+ + Escape +
+
+ +
+
+
+%#EOF +
+ +====templs/forwarded-add-handler.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% use Mojo::Util qw(dumper); + +% my $u = $c->app->user; +% my $name = $c->req->param('forwarded_name'); +% my $id = $u->forwarded_exist($name); + +% if ($id) { +
Domain <%= $name %> already exists
+% } + +% unless ($id) { + % my $res = $u->forwarded_add($name); + % if ($res) { +
Domain <%= $name %> has been added.
+ % } + + % unless ($res) { +
Domain <%= $name %> was not added.
+ % } +% } + +%#EOF + + + + +
+ +====templs/forwarded-delete-form.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% use Mojo::Util qw(dumper); + +% my $u = $c->app->user; + +% my $forwarded_id = $c->req->param('forwarded_id') || 0; +% my $profile = $u->forwarded_profile($forwarded_id); + +% if ($profile) { + % my $forwarded_name = $profile->{name}; + +
+
+
+ +
+
Delete domain <%= $forwarded_name %>
+ +
+ + Escape +
+
+ +
+
+
+% } + +% unless ($profile) { +
Domain with id <%= $forwarded_id %> not exist
+% } + +%#EOF +
+ +====templs/forwarded-delete-handler.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% use Mojo::Util qw(dumper); + +% my $u = $c->app->user; + +% my $forwarded_id = $c->req->param('forwarded_id') || 0; +% my $profile = $u->forwarded_profile($forwarded_id); + +% if ($profile) { + % my $name = $profile->{name}; + % my $res = $u->forwarded_delete($forwarded_id); + + % if ($res) { +
Domain <%= $name %> has been deleted
+ % } + + % unless ($res) { +
Domain <%= $name %> was not deleted
+ % } +% } + +% unless ($profile) { +
Domain with id <%= $forwarded_id %> not exist
+% } + +%#EOF + +
+ +====templs/forwarded-list.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% use Mojo::Util qw(dumper); + +% my $u = $c->app->user; + +
+ Domains + + + +
+ + +% my $list = $u->forwarded_list; + +% unless ($list) { +
+ Cannot list domains. May be wrong database? +
+% } + + + + + + + + + + + +% my $n = 0; + +% if ($list) { + % foreach my $row (@$list) { + % $n += 1; + % my $id = $row->{id}; + % my $name = $row->{name}; + % my $size = $row->{size}; + + + + + + + % } +% } + +
#domain
<%= $n %><%= $name %>
+ + + +%# EOF +
+ +====templs/forwarded-update-form.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% use Mojo::Util qw(dumper); + +% my $u = $c->app->user; + +% my $forwarded_id = $c->req->param('forwarded_id') || 0; +% my $profile = $u->forwarded_profile($forwarded_id); + +% if ($profile) { + % my $forwarded_name = $profile->{name}; + +
+
+
+ +
+
Edit domain
+ + +
+ + Escape +
+
+ +
+
+
+% } + +% unless ($profile) { +
Domain with id <%= $forwarded_id %> not exist
+% } + + +%#EOF +
+ +====templs/forwarded-update-handler.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% use Mojo::Util qw(dumper); + +% my $u = $c->app->user; + +% my $name = $c->req->param('forwarded_name'); +% my $forwarded_id = $c->req->param('forwarded_id') || 0; +% my $profile = $u->forwarded_profile($forwarded_id); + +% if ($profile) { + % my $cid = $u->forwarded_exist($name); + % if ($cid) { +
Domain <%= $name %> already exists
+ % } + + % unless ($cid) { + % my $res = $u->forwarded_update($forwarded_id, name => $name); + % if ($res) { +
Domain <%= $name %> has been updated.
+ % } + + % unless ($res) { +
Domain <%= $name %> was not updated.
+ % } + % } +% } + +% unless ($profile) { +
Domain with id <%= $forwarded_id %> not exist
+% } + +%#EOF + + + + +
+ +====templs/hello.html.ep==== + + +% layout 'default'; +% title 'Maacom'; + +% use Mojo::Util qw(dumper html_unescape unquote); + +
Hi! How are you there?
+ +%#EOF + +
+ +====templs/login.html.ep==== + + +%# +%# $Id: login.html.ep 634 2017-04-15 13:55:49Z ziggi $ +%# + + + + + + Login + + + + + + + + + + +
 
+
+
 
+
+
+
+ +
+
+

Login with your username

+ + +

+ +

+

+
+
+ +
+
+
+
 
+
+ +
+
+

Made by Borodin Oleg

+
+ + + + + +%# EOF +
+ +====templs/mxlog.html.ep==== + + +%# $Id$ + +% use Mojo::Util qw(dumper); +% my $t = $c->app->tail; + +% unless ($c->req->param('next')) { +% layout 'default'; +% title 'Maacom'; +
<%= $t->file %>
+
+
+% foreach my $line (@{$t->first}) { + <%= $line %>
+% } +
+
+
+
Clear
+
Pause
+
+ +% $c->session(pos => $t->pos); + +% } + +% if ($c->req->param('next')) { +% $t->pos($c->session('pos')); +% foreach my $line (@{$t->last}) { + <%= $line %>
+% } +% $c->session(pos => $t->pos); +% } +%#EOF +
+ +====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'; + +
404 Page not found
+ +%#EOF +
+ +====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'; + +
404 Page not found
+ +%#EOF +
+ +====templs/trusted-add-form.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% use Mojo::Util qw(dumper); + +% my $u = $c->app->user; + +
+
+
+ +
+
Add trusted host
+ +
+ + Escape +
+
+ +
+
+
+%#EOF +
+ +====templs/trusted-add-handler.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% use Mojo::Util qw(dumper); + +% my $u = $c->app->user; +% my $name = $c->req->param('trusted_name'); +% my $id = $u->trusted_exist($name); + +% if ($id) { +
Host <%= $name %> already exists
+% } + +% unless ($id) { + % my $res = $u->trusted_add($name); + % if ($res) { +
Host <%= $name %> has been added.
+ % } + + % unless ($res) { +
Host <%= $name %> was not added.
+ % } +% } + +%#EOF + + + + +
+ +====templs/trusted-delete-form.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% use Mojo::Util qw(dumper); + +% my $u = $c->app->user; + +% my $trusted_id = $c->req->param('trusted_id') || 0; +% my $profile = $u->trusted_profile($trusted_id); + +% if ($profile) { + % my $trusted_name = $profile->{name}; + +
+
+
+ +
+
Delete host <%= $trusted_name %>
+ +
+ + Escape +
+
+ +
+
+
+% } + +% unless ($profile) { +
Host with id <%= $trusted_id %> not exist
+% } + +%#EOF +
+ +====templs/trusted-delete-handler.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% use Mojo::Util qw(dumper); + +% my $u = $c->app->user; + +% my $trusted_id = $c->req->param('trusted_id') || 0; +% my $profile = $u->trusted_profile($trusted_id); + +% if ($profile) { + % my $name = $profile->{name}; + % my $res = $u->trusted_delete($trusted_id); + + % if ($res) { +
Host <%= $name %> has been deleted
+ % } + + % unless ($res) { +
Host <%= $name %> was not deleted
+ % } +% } + +% unless ($profile) { +
Host with id <%= $trusted_id %> not exist
+% } + +%#EOF + +
+ +====templs/trusted-list.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% use Mojo::Util qw(dumper); + +% my $u = $c->app->user; + +
+ Hosts + + + +
+ + +% my $list = $u->trusted_list; + +% unless ($list) { +
+ Cannot list hosts. May be wrong database? +
+% } + + + + + + + + + + + +% my $n = 0; + +% if ($list) { + % foreach my $row (@$list) { + % $n += 1; + % my $id = $row->{id}; + % my $name = $row->{name}; + % my $size = $row->{size}; + + + + + + + % } +% } + +
#host
<%= $n %><%= $name %>
+ + + +%# EOF +
+ +====templs/trusted-update-form.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% use Mojo::Util qw(dumper); + +% my $u = $c->app->user; + +% my $trusted_id = $c->req->param('trusted_id') || 0; +% my $profile = $u->trusted_profile($trusted_id); + +% if ($profile) { + % my $trusted_name = $profile->{name}; + +
+
+
+ +
+
Edit host
+ + +
+ + Escape +
+
+ +
+
+
+% } + +% unless ($profile) { +
Host with id <%= $trusted_id %> not exist
+% } + + +%#EOF +
+ +====templs/trusted-update-handler.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% use Mojo::Util qw(dumper); + +% my $u = $c->app->user; + +% my $name = $c->req->param('trusted_name'); +% my $trusted_id = $c->req->param('trusted_id') || 0; +% my $profile = $u->trusted_profile($trusted_id); + +% if ($profile) { + % my $cid = $u->trusted_exist($name); + % if ($cid) { +
Host <%= $name %> already exists
+ % } + + % unless ($cid) { + % my $res = $u->trusted_update($trusted_id, name => $name); + % if ($res) { +
Host <%= $name %> has been updated.
+ % } + + % unless ($res) { +
Host <%= $name %> was not updated.
+ % } + % } +% } + +% unless ($profile) { +
Host with id <%= $trusted_id %> not exist
+% } + +%#EOF + + + + +
+ +====templs/unwanted-add-form.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% use Mojo::Util qw(dumper); + +% my $u = $c->app->user; + +
+
+
+ +
+
Add unwanted host
+ +
+ + Escape +
+
+ +
+
+
+%#EOF +
+ +====templs/unwanted-add-handler.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% use Mojo::Util qw(dumper); + +% my $u = $c->app->user; +% my $name = $c->req->param('unwanted_name'); +% my $id = $u->unwanted_exist($name); + +% if ($id) { +
Host <%= $name %> already exists
+% } + +% unless ($id) { + % my $res = $u->unwanted_add($name); + % if ($res) { +
Host <%= $name %> has been added.
+ % } + + % unless ($res) { +
Host <%= $name %> was not added.
+ % } +% } + +%#EOF + + + + +
+ +====templs/unwanted-delete-form.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% use Mojo::Util qw(dumper); + +% my $u = $c->app->user; + +% my $unwanted_id = $c->req->param('unwanted_id') || 0; +% my $profile = $u->unwanted_profile($unwanted_id); + +% if ($profile) { + % my $unwanted_name = $profile->{name}; + +
+
+
+ +
+
Delete host <%= $unwanted_name %>
+ +
+ + Escape +
+
+ +
+
+
+% } + +% unless ($profile) { +
Host with id <%= $unwanted_id %> not exist
+% } + +%#EOF +
+ +====templs/unwanted-delete-handler.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% use Mojo::Util qw(dumper); + +% my $u = $c->app->user; + +% my $unwanted_id = $c->req->param('unwanted_id') || 0; +% my $profile = $u->unwanted_profile($unwanted_id); + +% if ($profile) { + % my $name = $profile->{name}; + % my $res = $u->unwanted_delete($unwanted_id); + + % if ($res) { +
Host <%= $name %> has been deleted
+ % } + + % unless ($res) { +
Host <%= $name %> was not deleted
+ % } +% } + +% unless ($profile) { +
Host with id <%= $unwanted_id %> not exist
+% } + +%#EOF + +
+ +====templs/unwanted-list.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% use Mojo::Util qw(dumper); + +% my $u = $c->app->user; + +
+ Hosts + + + +
+ + +% my $list = $u->unwanted_list; + +% unless ($list) { +
+ Cannot list hosts. May be wrong database? +
+% } + + + + + + + + + + + +% my $n = 0; + +% if ($list) { + % foreach my $row (@$list) { + % $n += 1; + % my $id = $row->{id}; + % my $name = $row->{name}; + % my $size = $row->{size}; + + + + + + + % } +% } + +
#host
<%= $n %><%= $name %>
+ + + +%# EOF +
+ +====templs/unwanted-update-form.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% use Mojo::Util qw(dumper); + +% my $u = $c->app->user; + +% my $unwanted_id = $c->req->param('unwanted_id') || 0; +% my $profile = $u->unwanted_profile($unwanted_id); + +% if ($profile) { + % my $unwanted_name = $profile->{name}; + +
+
+
+ +
+
Edit host
+ + +
+ + Escape +
+
+ +
+
+
+% } + +% unless ($profile) { +
Host with id <%= $unwanted_id %> not exist
+% } + + +%#EOF +
+ +====templs/unwanted-update-handler.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% use Mojo::Util qw(dumper); + +% my $u = $c->app->user; + +% my $name = $c->req->param('unwanted_name'); +% my $unwanted_id = $c->req->param('unwanted_id') || 0; +% my $profile = $u->unwanted_profile($unwanted_id); + +% if ($profile) { + % my $cid = $u->unwanted_exist($name); + % if ($cid) { +
Host <%= $name %> already exists
+ % } + + % unless ($cid) { + % my $res = $u->unwanted_update($unwanted_id, name => $name); + % if ($res) { +
Host <%= $name %> has been updated.
+ % } + + % unless ($res) { +
Host <%= $name %> was not updated.
+ % } + % } +% } + +% unless ($profile) { +
Host with id <%= $unwanted_id %> not exist
+% } + +%#EOF + + + + +
+ +====templs/user-add-form.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% 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}; +
+
+
+ +
+
Add user to domain <%= $domain_name %>
+ + + +
+ + Escape +
+
+ +
+
+
+% } + +% unless ($domain_id) { +
+
+
+ +
+
Add user
+ + + + + +
+ + Escape +
+
+ +
+
+
+% } + +%#EOF +
+ +====templs/user-add-handler.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% 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) { +
User <%= $user_name %> already exists
+% } + +% unless ($cid) { + % my $id = $u->user_add($user_name, $password, $domain_id); + % if ($id) { +
User <%= $user_name %> has been added.
+ % } + + % unless ($id) { +
User <%= $user_name %> was not added.
+ % } +% } +%#EOF + + + + +
+ +====templs/user-delete-form.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% 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}; + +
+
+
+ +
+
Delete user <%= $address %>
+ +
+ + Escape +
+
+ +
+
+
+% } + +% unless ($profile) { +
User with id <%= $user_id %> not exist
+% } +%#EOF +
+ +====templs/user-delete-handler.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% 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) { +
User <%= $address %> has been deleted
+ % } + + % unless ($res) { +
User <%= $address %> was not deleted
+ % } +% } + +% unless ($profile) { +
User with id <%= $user_id %> not exist
+% } + +%#EOF + +
+ +====templs/user-list.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% use Mojo::Util qw(dumper); + +% my $req = $c->req; +% my $u = $c->app->user; + +% my $domain_id = $req->param('domain_id'); + +% if ($domain_id) { + % my $domain_name = $u->domain_profile($domain_id)->{name}; +
+ Accounts <%= $domain_name %> + + + +
+ + % my $list = $u->user_list($domain_id); + + + + + + + + + + + + + + % 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; + + + + + + + + + % } + % } + +
#address
<%= $n %><%= $address %><%= $size %>
+% } + +% unless ($domain_id) { +
+ Accounts + + + +
+ + % my $list = $u->user_list; + + + + + + + + + + + + + + + % 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; + + + + + + + + + + % } + % } + +
#address
<%= $n %><%= $address %><%= $size %>
+% } + + +%# EOF + +
+ +====templs/user-rename-form.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% 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}; + +
+
+
+ +
+
Rename user <%= $address %>
+ + +
+ + Escape +
+
+ +
+
+
+% } + +% unless ($profile) { +
User with id <%= $user_id %> not exist
+% } +%#EOF +
+ +====templs/user-rename-handler.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% 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) { +
User <%= $address %> already exists
+ % } + + % unless ($cid) { + % my $res = $u->user_update($user_id, name => $new_name); + % if ($res) { +
User <%= $address %> has been updated.
+ % } + + % unless ($res) { +
User <%= $address %> was not updated.
+ % } + % } +% } + +% unless ($profile) { +
User with id <%= $user_id %> not exist
+% } + +%#EOF +
+ +====templs/user-update-form.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% 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}; + +
+
+
+ +
+
Edit user <%= $address %>
+ + +
+ + Escape +
+
+ +
+
+
+% } + +% unless ($profile) { +
User with id <%= $user_id %> not exist
+% } +%#EOF +
+ +====templs/user-update-handler.html.ep==== + + +%# +%# $Id$ +%# +% layout 'default'; +% title 'Maacom'; + +% 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) { +
User <%= $address %> has been updated.
+ % } + % unless ($res) { +
User <%= $address %> was not updated.
+ % } +% } + +% unless ($profile) { +
User with id <%= $user_id %> not exist
+% } + +%#EOF + + + + +
+ +---- +[<>]