package SrvMngr::Controller::Domains; #---------------------------------------------------------------------- # heading : Network # description : Domains # navigation : 6000 300 # # routes : end #---------------------------------------------------------------------- use strict; use warnings; use Mojo::Base 'Mojolicious::Controller'; use Locale::gettext; use SrvMngr::I18N; use SrvMngr qw(theme_list init_session); #use Data::Dumper; #use esmith::FormMagick::Panel::domains; use esmith::DomainsDB; use esmith::AccountsDB; #use URI::Escape; our $ddb = esmith::DomainsDB->open || die "Couldn't open domains db"; our $cdb = esmith::ConfigDB->open || die "Couldn't open configuration db"; our $adb = esmith::AccountsDB->open || die "Couldn't open accounts db"; our $REGEXP_DOMAIN = qq([a-zA-Z0-9\-\.]+); sub main { my $c = shift; $c->app->log->info($c->log_req); my %dom_datas = (); my $title = $c->l('dom_FORM_TITLE'); $dom_datas{trt} = 'LST'; my @domains; for ($ddb->domains()) { my $ns = $_->prop('Nameservers') || 'internet'; push @domains, { Domain => $_->key, $_->props, Nameservers => $ns, }; } ## end for ($ddb->domains()) $dom_datas{forwarder} = $cdb->get_prop('dnscache', 'Forwarder'); $dom_datas{forwarder2} = $cdb->get_prop('dnscache', 'Forwarder2') || ''; $c->stash(title => $title, dom_datas => \%dom_datas, domains => \@domains); $c->render(template => 'domains'); } ## end sub main sub do_display { my $c = shift; $c->app->log->info($c->log_req); my $rt = $c->current_route; my $trt = $c->param('trt'); my $domain = $c->param('Domain') || ''; #$trt = 'DEL' if ( $rt eq 'domaindel1' ); #$trt = 'UPD' if ( $rt eq 'domainupd1' ); #$trt = 'UP2' if ( $rt eq 'domainup21' ); #$trt = 'ADD' if ( $rt eq 'domainadd1' ); my %dom_datas = (); my $title = $c->l('dom_FORM_TITLE'); my $result = ''; $dom_datas{'trt'} = $trt; if ($trt ne 'ADD' and $trt ne 'UPD' and $trt ne 'UP2' and $trt ne 'DEL') { $result = "Trt unknown ( $trt ) !"; } if ($trt eq 'ADD') { #nothing } if ($trt eq 'UPD') { my $rec = $ddb->get($domain); if ($rec) { $dom_datas{domain} = $domain; $dom_datas{description} = $rec->prop('Description') || ''; $dom_datas{content} = $rec->prop('Content') || ''; $dom_datas{nameservers} = $rec->prop('Nameservers') || 'internet'; } else { $result = "Domain $domain not found !"; } } ## end if ($trt eq 'UPD') if ($trt eq 'UP2') { $dom_datas{forwarder} = $cdb->get_prop('dnscache', 'Forwarder') || ''; $dom_datas{forwarder2} = $cdb->get_prop('dnscache', 'Forwarder2') || ''; } if ($trt eq 'DEL') { my $rec = $ddb->get($domain); if ($rec) { $dom_datas{domain} = $domain; $dom_datas{description} = $rec->prop('Description') || ''; } } ## end if ($trt eq 'DEL') if ($trt eq 'LST') { my @domains; if ($adb) { @domains = $ddb->domains(); } $c->stash(domains => \@domains); } ## end if ($trt eq 'LST') if (!$result) { $c->stash(error => $result); } $c->stash(title => $title, dom_datas => \%dom_datas); $c->render(template => 'domains'); } ## end sub do_display sub do_update { my $c = shift; $c->app->log->info($c->log_req); my $rt = $c->current_route; my $trt = $c->param('trt'); my %dom_datas = (); my ($res, $result) = ''; #my $domain = uri_unescape($c->param('domain')); my $domain = $c->param('Domain'); if ($trt eq 'ADD') { my $account = $c->param('Account'); # controls (validate ?????) #? validate_new_domain_name( $c, $domain, $account ); #$result .= $res unless $res eq 'OK'; #$result .= ' blocked'; $res = ''; if (!$result) { $res = $c->create_modify_domain('create', $domain); $result .= $res unless $res eq 'OK'; } if (!$result) { $result = $c->l('dom_SUCCESSFULLY_CREATED') . " $domain"; } } ## end if ($trt eq 'ADD') if ($trt eq 'UPD') { my $description = $c->param('Description'); my $content = $c->param('Content'); my $nameservers = $c->param('Nameservers'); # controls #$res = validate_description( $c, $account ); #$result .= $res unless $res eq 'OK'; #$result .= 'blocked'; $res = ''; if (!$result) { $res = $c->create_modify_domain('modify', $domain); $result .= $res unless $res eq 'OK'; } if (!$result) { $result = $c->l('dom_SUCCESSFULLY_MODIFIED') . " $domain"; } } ## end if ($trt eq 'UPD') if ($trt eq 'UP2') { my $forwarder = $c->param('Forwarder'); my $forwarder2 = $c->param('Forwarder2'); # controls $res = $c->ip_number_or_blank($forwarder); $result .= $res unless $res eq 'OK'; $res = $c->ip_number_or_blank($forwarder2); $result .= $res unless $res eq 'OK'; #$result .= 'blocked'; $res = ''; if (!$result) { $res = $c->modify_dns($forwarder, $forwarder2); $result .= $res unless $res eq 'OK'; } if (!$result) { $result = $c->l('SUCCESS') . " $forwarder $forwarder2"; } } ## end if ($trt eq 'UP2') if ($trt eq 'DEL') { # controls #$res = validate_is_domain($c, $domain); #$result .= $res unless $res eq 'OK'; #$result .= 'blocked'; $res = ''; if (!$result) { $res = $c->delete_domain($domain); $result .= $res unless $res eq 'OK'; } if (!$result) { $result = $c->l('dom_SUCCESSFULLY_DELETED') . " $domain"; } } ## end if ($trt eq 'DEL') # common parts if ($res ne 'OK') { my $title = $c->l('dom_FORM_TITLE'); $dom_datas{'domain'} = $domain; $dom_datas{'trt'} = $trt; $c->stash(error => $result . "($res)"); $c->stash(title => $title, dom_datas => \%dom_datas); return $c->render('domains'); } ## end if ($res ne 'OK') my $message = "'Domains' updates ($trt) DONE"; $c->app->log->info($message); $c->flash(success => $result); $c->redirect_to('/domains'); } ## end sub do_update sub create_modify_domain { my ($c, $action, $domain) = @_; $domain = $1 if ($domain =~ /^($REGEXP_DOMAIN)$/); unless ($domain) { return ( $c->l( $action eq 'create' ? 'dom_ERROR_CREATING_DOMAIN' : 'dom_ERROR_MODIFYING_DOMAIN' ) . ' Ctl' ); } ## end unless ($domain) my $rec = $ddb->get($domain); if ($rec and $action eq 'create') { return $c->l('dom_DOMAIN_IN_USE_ERROR'); } if (not $rec and $action eq 'modify') { return $c->l('dom_NONEXISTENT_DOMAIN_ERROR'); } $rec ||= $ddb->new_record($domain, { type => 'domain' }); my %props; $props{$_} = $c->param($_) for (qw(Content Description Nameservers)); $rec->merge_props(%props); if (system("/sbin/e-smith/signal-event", "domain-$action", "$domain") != 0) { return ( $c->l( $action eq 'create' ? 'dom_ERROR_CREATING_DOMAIN' : 'dom_ERROR_MODIFYING_DOMAIN' ) . " Exe $action" ); } ## end if (system("/sbin/e-smith/signal-event"...)) return 'OK'; } ## end sub create_modify_domain sub delete_domain { my ($c, $domain) = @_; $domain = $1 if ($domain =~ /^($REGEXP_DOMAIN)$/); return ($c->l('dom_ERROR_WHILE_REMOVING_DOMAIN') . ' Ctl') unless ($domain); my $rec = $ddb->get($domain); return ($c->l('dom_NONEXISTENT_DOMAIN_ERROR')) if (not $rec); $rec->set_prop('type', 'domain-deleted'); if (system("/sbin/e-smith/signal-event", "domain-delete", "$domain") != 0) { return ($c->l('dom_ERROR_WHILE_REMOVING_DOMAIN') . 'Exe'); } $rec->delete; return 'OK'; } ## end sub delete_domain sub modify_dns { my ($c, $forwarder, $forwarder2) = @_; my $dnscache = $cdb->get('dnscache'); ($forwarder, $forwarder2) = ($forwarder2, '') if ($forwarder2 and not $forwarder); if ($forwarder) { $dnscache->set_prop('Forwarder', $forwarder); } else { $dnscache->delete_prop('Forwarder'); } if ($forwarder2) { $dnscache->set_prop('Forwarder2', $forwarder2); } else { $dnscache->delete_prop('Forwarder2'); } unless (system("/sbin/e-smith/signal-event", "dns-update") == 0) { return $c->l('dom_ERROR_UPDATING'); } return 'OK'; } ## end sub modify_dns sub existing_accounts_list { my $c = shift; my @existingAccounts = ([ 'Administrator' => 'admin' ]); foreach my $a ($adb->get_all) { if ($a->prop('type') =~ /(user|group)/) { push @existingAccounts, [ $a->key => $a->key ]; } if ($a->prop('type') eq "domain") { my $target = $adb->get($a->prop('Account')); unless ($target) { warn "WARNING: domain (" . $a->key . ") => missing Account(" . $a->prop('Account') . ")\n"; next; } push @existingAccounts, [ $a->key, $a->key ] unless ($target->prop('type') eq "domain"); } ## end if ($a->prop('type') eq...) } ## end foreach my $a ($adb->get_all) return (\@existingAccounts); } ## end sub existing_accounts_list sub content_options_list { my $c = shift; my @options = ([ $c->l('dom_PRIMARY_SITE') => 'Primary' ]); foreach ($adb->ibays) { push @options, [ $_->prop('Name') => $_->key ] if ($_->key ne 'Primary'); } return \@options; } ## end sub content_options_list sub get_content_value { my $c = shift; my $domain = shift; return $domain ? $ddb->get_prop($domain, 'Content') : 'Primary'; } ## end sub get_content_value sub get_description_value { my $c = shift; my $domain = $c->param('Domain') || undef; return $ddb->get_prop($domain, 'Description'); } ## end sub get_description_value sub nameserver_options_list { my $c = shift; my $domain = $c->param('Domain') || undef; my @opts = qw(localhost internet); push @opts, 'corporate' if ($cdb->get_prop('dnscache', 'Forwarder')); my $ns = ($ddb->get_prop($domain, 'Nameservers') || 'internet'); push @opts, $ns unless scalar grep {/^$ns$/} @opts; my @options; foreach (@opts) { push @options, [ $c->l("dom_$_") => $_ ]; } return \@options; } ## end sub nameserver_options_list sub get_nameserver_value { my $c = shift; my $domain = $c->param('Domain') || undef; return ($ddb->get_prop($domain, 'Nameservers') || 'internet'); } ## end sub get_nameserver_value sub validate_Domain { my $c = shift; my $domain = lc shift; return ($domain =~ /^($REGEXP_DOMAIN)$/) ? 'OK' : 'DOMAIN_NAME_VALIDATION_ERROR'; } ## end sub validate_Domain sub validate_Description { # XXX - FIXME - NOTREACHED # We used to use the Description in the Appletalk volume name # which meant it needed validation. I don't see any reason to # do this any more my $c = shift; my $description = shift; return ($description =~ /^([\-\'\w][\-\'\w\s\.]*)$/) ? 'OK' : 'DOMAIN_DESCRIPTION_VALIDATION_ERROR'; } ## end sub validate_Description sub ip_number_or_blank { # XXX - FIXME - we should push this down into CGI::FormMagick my $c = shift; my $ip = shift; if (!defined($ip) || $ip eq "") { return 'OK'; } return ip_number($c, $ip); } ## end sub ip_number_or_blank sub ip_number { # from CGI::FormMagick::Validator qw( ip_number ); my ($c, $data) = @_; return undef unless defined $data; return $c->l('FM_IP_NUMBER1') unless $data =~ /^[\d.]+$/; my @octets = split /\./, $data; my $dots = ($data =~ tr/.//); return $c->l('FM_IP_NUMBER2') unless (scalar @octets == 4 and $dots == 3); foreach my $octet (@octets) { return $c->l("FM_IP_NUMBER3", $octet) if $octet > 255; } return 'OK'; } ## end sub ip_number 1;