line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Mojolicious::Plugin::AccessControl; |
2
|
2
|
|
|
2
|
|
28476
|
use strict; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
88
|
|
3
|
2
|
|
|
2
|
|
13
|
use warnings; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
115
|
|
4
|
|
|
|
|
|
|
our $VERSION = '0.04'; |
5
|
|
|
|
|
|
|
|
6
|
2
|
|
|
2
|
|
941
|
use Mojo::Base 'Mojolicious::Plugin'; |
|
2
|
|
|
|
|
12487
|
|
|
2
|
|
|
|
|
19
|
|
7
|
2
|
|
|
2
|
|
5388
|
use Net::CIDR::Lite; |
|
2
|
|
|
|
|
10137
|
|
|
2
|
|
|
|
|
87
|
|
8
|
2
|
|
|
2
|
|
162
|
use Carp (); |
|
2
|
|
|
|
|
7
|
|
|
2
|
|
|
|
|
574
|
|
9
|
|
|
|
|
|
|
|
10
|
2
|
|
|
2
|
|
17
|
use constant CONDITION_NAME => 'access'; |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
2345
|
|
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
sub register { |
13
|
1
|
|
|
1
|
1
|
64
|
my ( $self, $app ) = @_; |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
$app->routes->add_condition( |
16
|
|
|
|
|
|
|
CONDITION_NAME() => sub { |
17
|
24
|
|
|
24
|
|
1112214
|
my ( $r, $c, $cap, $args ) = @_; |
18
|
24
|
|
50
|
|
|
130
|
$args ||= []; |
19
|
|
|
|
|
|
|
|
20
|
24
|
|
|
|
|
50
|
my $opt = {}; |
21
|
24
|
|
|
|
|
118
|
my @rule_list = @$args; |
22
|
|
|
|
|
|
|
|
23
|
24
|
100
|
|
|
|
86
|
if ( ref $args->[0] eq 'HASH' ) { |
24
|
3
|
|
|
|
|
8
|
$opt = $args->[0]; |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
# Remove option ref from rule list |
27
|
3
|
|
|
|
|
12
|
@rule_list = splice(@$args, 1); |
28
|
|
|
|
|
|
|
} |
29
|
|
|
|
|
|
|
|
30
|
24
|
50
|
66
|
|
|
117
|
if ( $opt->{on_deny} && ref $opt->{on_deny} ne 'CODE' ) { |
31
|
0
|
|
|
|
|
0
|
Carp::croak "on_deny must be a CODEREF"; |
32
|
|
|
|
|
|
|
} |
33
|
|
|
|
|
|
|
|
34
|
24
|
100
|
|
|
|
159
|
$opt->{cache} = 1 unless ( defined $opt->{cache} ); |
35
|
24
|
50
|
66
|
|
|
184
|
my $rules = ( $opt->{cache} ) |
36
|
|
|
|
|
|
|
? ( $r->{ __PACKAGE__ . '._rules' } ||= $self->_rules(@rule_list) ) # caches to Mojolicious::Routes::Route |
37
|
|
|
|
|
|
|
: $self->_rules(@rule_list); |
38
|
|
|
|
|
|
|
|
39
|
24
|
|
|
|
|
70
|
for my $rule (@$rules) { |
40
|
24
|
|
|
|
|
44
|
my ( $check, $allow ) = @{$rule}; |
|
24
|
|
|
|
|
59
|
|
41
|
|
|
|
|
|
|
|
42
|
24
|
|
|
|
|
63
|
my $result = $check->($c); |
43
|
24
|
100
|
66
|
|
|
1328
|
if ( defined $result && $result ) { |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
# denied |
46
|
21
|
100
|
100
|
|
|
298
|
if ( !$allow && $opt->{on_deny} ) { |
47
|
3
|
|
|
|
|
13
|
$opt->{on_deny}->($c); |
48
|
|
|
|
|
|
|
} |
49
|
|
|
|
|
|
|
|
50
|
21
|
|
|
|
|
3587
|
return $allow; |
51
|
|
|
|
|
|
|
} |
52
|
|
|
|
|
|
|
} |
53
|
|
|
|
|
|
|
|
54
|
3
|
|
|
|
|
43
|
return 1; |
55
|
|
|
|
|
|
|
} |
56
|
1
|
|
|
|
|
31
|
); |
57
|
|
|
|
|
|
|
} |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
sub _rules { |
60
|
8
|
|
|
8
|
|
24
|
my ($self, @args) = @_; |
61
|
|
|
|
|
|
|
|
62
|
8
|
|
|
|
|
17
|
my @rules; |
63
|
8
|
|
|
|
|
30
|
for ( my $i = 0; $i < @args; $i += 2 ) { |
64
|
11
|
|
|
|
|
33
|
my ( $allowing, $rule ) = ( $args[$i], $args[ $i + 1 ] ); |
65
|
|
|
|
|
|
|
|
66
|
11
|
50
|
|
|
|
71
|
Carp::croak "must be allow or deny" |
67
|
|
|
|
|
|
|
unless $allowing =~ /^(allow|deny)$/; |
68
|
|
|
|
|
|
|
|
69
|
11
|
100
|
|
|
|
32
|
$allowing = ( $allowing eq 'allow' ) ? 1 : 0; |
70
|
11
|
|
|
|
|
18
|
my $check = $rule; |
71
|
|
|
|
|
|
|
|
72
|
11
|
100
|
|
|
|
73
|
if ( $rule =~ /^ALL$/i ) { |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
73
|
3
|
|
|
3
|
|
17
|
$check = sub {1}; |
|
3
|
|
|
|
|
6
|
|
74
|
|
|
|
|
|
|
} |
75
|
|
|
|
|
|
|
elsif ( $rule =~ /[A-Z]$/i ) { |
76
|
|
|
|
|
|
|
$check = sub { |
77
|
6
|
|
|
6
|
|
29
|
my $host = $_[0]->req->env->{'REMOTE_HOST'}; |
78
|
6
|
50
|
|
|
|
484
|
return unless defined $host; # skip |
79
|
6
|
|
|
|
|
122
|
return $host =~ /^(.*\.)?\Q${rule}\E$/; |
80
|
2
|
|
|
|
|
23
|
}; |
81
|
|
|
|
|
|
|
} |
82
|
|
|
|
|
|
|
elsif ( ref($rule) ne 'CODE' ) { |
83
|
5
|
|
|
|
|
125
|
my $cidr = Net::CIDR::Lite->new(); |
84
|
5
|
|
|
|
|
73
|
$cidr->add_any($rule); |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
$check = sub { |
87
|
12
|
|
|
12
|
|
286
|
my $addr = $_[0]->tx->remote_address; |
88
|
12
|
50
|
|
|
|
968
|
if ( defined $addr ) { |
89
|
12
|
50
|
|
|
|
67
|
return ( $cidr->find($addr) ) ? 1 : 0; |
90
|
|
|
|
|
|
|
} |
91
|
5
|
|
|
|
|
732
|
}; |
92
|
|
|
|
|
|
|
} |
93
|
|
|
|
|
|
|
|
94
|
11
|
|
|
|
|
59
|
push @rules, [ $check => $allowing ]; |
95
|
|
|
|
|
|
|
} |
96
|
|
|
|
|
|
|
|
97
|
8
|
|
|
|
|
47
|
return \@rules; |
98
|
|
|
|
|
|
|
} |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1; |
101
|
|
|
|
|
|
|
__END__ |