File Coverage

lib/Haineko/Root.pm
Criterion Covered Total %
statement 57 76 75.0
branch 6 14 42.8
condition 4 16 25.0
subroutine 11 11 100.0
pod 0 3 0.0
total 78 120 65.0


line stmt bran cond sub pod time code
1             package Haineko::Root;
2 3     3   2196 use feature ':5.10';
  3         6  
  3         351  
3 3     3   18 use strict;
  3         6  
  3         90  
4 3     3   78 use warnings;
  3         6  
  3         250  
5              
6             sub index {
7             # GET /
8 3     3   16 use Haineko;
  3         6  
  3         489  
9 1     1 0 4 my $class = shift;
10 1         2 my $httpd = shift;
11 1         9 my $neko1 = { 'name' => $httpd->name, 'version' => $Haineko::VERSION };
12              
13 1         16 return $httpd->res->json( 200, $neko1 );
14             }
15              
16             sub info {
17             # GET /dump, /conf
18 2     2 0 7 my $class = shift;
19 2         5 my $httpd = shift;
20              
21 2   50     14 my $xforwarded = [ split( ',', $httpd->req->header('X-Forwarded-For') || q() ) ];
22 2   33     537 my $remoteaddr = pop @$xforwarded || $httpd->req->address // undef;
      50        
23 2         47 my $ip4network = undef;
24              
25             # Only 127.0.0.1 is permitted
26 3     3   3463 use Net::CIDR::Lite;
  3         16118  
  3         321  
27 2         21 $ip4network = Net::CIDR::Lite->new( '127.0.0.1/32' );
28              
29 2 50       731 if( $ip4network->find( $remoteaddr ) ) {
30              
31 2         221 my $requesturl = $httpd->req->path_info;
32 2         35 my $configfile = q();
33 2         5 my $configdata = {};
34 2         4 my $smtpconfig = undef;
35              
36 2 100       8 if( $requesturl eq '/dump' ) {
37             # /dump
38 3     3   31283 use Data::Dumper;
  3         35359  
  3         477  
39 1         6 return $httpd->res->text( 200, Data::Dumper::Dumper $httpd );
40              
41             } else {
42             # /conf
43 3     3   42 use Haineko::JSON;
  3         7  
  3         157  
44 3     3   21 use File::Basename;
  3         8  
  3         3633  
45              
46 1 50       7 if( defined $ENV{'HAINEKO_CONF'} ) {
47              
48 0 0       0 if( -f -r -s $ENV{'HAINEKO_CONF'} ) {
49             # HAINEKO_CONF=/path/to/haineko.cf
50 0         0 $configfile = $ENV{'HAINEKO_CONF'};
51              
52             } else {
53 0         0 $configfile = 'Haineko::Default->conf'
54             }
55             }
56              
57 1         6 $configdata->{'haineko.cf'} = {
58             'path' => $configfile,
59             'data' => $httpd->conf,
60             };
61 1         13 $smtpconfig = $configdata->{'haineko.cf'}->{'data'}->{'smtpd'};
62              
63 1         4 for my $e ( 'mailer', 'access' ) {
64             # mailer: auth, mail, rcpt
65             # access: conn, rcpt
66 2         4 for my $f ( keys %{ $smtpconfig->{ $e } } ) {
  2         11  
67             # Load mailertables, access configurations
68 5         13 my $g = $smtpconfig->{ $e }->{ $f };
69 5         505 my $h = File::Basename::basename $g; $h =~ s/[-]debug\z//;
  5         10  
70              
71 5         24 $configdata->{ $h } = {
72             'path' => undef,
73             'data' => undef,
74             };
75 5 50       81 next unless -f -r -s $g;
76              
77 0         0 $configdata->{ $h }->{'path'} = $g;
78 0         0 $configdata->{ $h }->{'data'} = Haineko::JSON->loadfile( $g );
79              
80 0 0       0 next unless $h eq 'authinfo';
81 0         0 for my $i ( keys %{ $configdata->{'authinfo'}->{'data'} } ) {
  0         0  
82             # Mask username and password with '*'
83 0         0 my $j = $configdata->{'authinfo'}->{'data'}->{ $i };
84 0         0 $j->{'username'} =~ s/\A(.).+\z/$1*******/;
85 0         0 $j->{'password'} = '********';
86             }
87             }
88             }
89              
90 1 50 33     8 if( defined $ENV{'HAINEKO_AUTH'} && -f -r -s $ENV{'HAINEKO_AUTH'} ) {
91             # Load password file
92 0         0 $configdata->{'password'} = {
93             'path' => $ENV{'HAINEKO_AUTH'},
94             'data' => Haineko::JSON->loadfile( $ENV{'HAINEKO_AUTH'} ),
95             };
96             }
97              
98 1         7 return $httpd->res->json( 200, Haineko::JSON->dumpjson( $configdata ) );
99             }
100              
101             } else {
102             # Respond "Access denied" as a JSON
103 0         0 require Haineko::SMTPD::Response;
104 0         0 require Haineko::SMTPD::Session;
105              
106 0         0 my $mesg = Haineko::SMTPD::Response->r( 'http', 'forbidden' )->damn;
107 0   0     0 my $argv = {
      0        
      0        
108             'referer' => $httpd->req->referer // undef,
109             'response' => [ $mesg ],
110             'remoteaddr' => $remoteaddr,
111             'remoteport' => $httpd->req->env->{'REMOTE_ADDR'} // undef,
112             'useragent' => $httpd->req->user_agent // undef,
113             };
114 0         0 my $sess = Haineko::SMTPD::Session->new( %$argv )->damn;
115              
116 0         0 $sess->{'queueid'} = undef;
117 0         0 return $httpd->response->json( 403, $sess );
118             }
119             }
120              
121             sub neko {
122             # GET /neko
123 1     1 0 3 my $class = shift;
124 1         2 my $httpd = shift;
125              
126 1         6 return $httpd->res->text( 200, 'Nyaaaaa' );
127             }
128              
129             1;
130             __END__