File Coverage

blib/lib/Decision/ACL.pm
Criterion Covered Total %
statement 81 97 83.5
branch 22 38 57.8
condition 2 3 66.6
subroutine 15 18 83.3
pod 0 8 0.0
total 120 164 73.1


line stmt bran cond sub pod time code
1             package Decision::ACL;
2              
3 2     2   1189 use strict;
  2         3  
  2         62  
4 2     2   13 use Carp;
  2         2  
  2         169  
5 2     2   10 use vars qw($VERSION);
  2         7  
  2         146  
6             $VERSION = '0.02';
7              
8 2     2   1108 use Decision::ACL::Constants qw(:rule);
  2         4  
  2         253  
9 2     2   1067 use Decision::ACL::Rule;
  2         6  
  2         70  
10              
11 2     2   12 use constant AUTO_DENY_NOW => 1;
  2         8  
  2         91  
12 2     2   15 use constant DIE_ON_MALFORMED_RULES => 1;
  2         3  
  2         79  
13 2     2   11 use constant DEBUG_LEVEL => 0;
  2         4  
  2         1989  
14              
15             sub new
16             {
17 1     1 0 53 my ($classname, $args) = @_;
18              
19 1         4 my $self = {
20             rules => [],
21             };
22              
23 1         3 bless $self, $classname;
24              
25 1         4 return $self;
26             }
27              
28             sub ControlFields
29             {
30 8     8 0 14 my $self = shift;
31            
32 8         23 return $self->{control_fields};
33             }
34              
35             sub PushRule
36             {
37 4     4 0 26 my $self = shift;
38 4         6 my $rule = shift;
39              
40 4 50       13 if(defined $rule)
41             {
42 4 50       18 if(UNIVERSAL::isa($rule, 'Decision::ACL::Rule'))
43             {
44 4 50       12 return push(@{$self->{rules}}, $rule) if $self->_VerifyRuleFields($rule);
  4         19  
45             }
46             else
47             {
48 0         0 croak "Attempt to push an object that !ISA Decision::ACL::Rule\n";
49             }
50             }
51             }
52              
53             sub PopRule
54             {
55 0     0 0 0 my $self = shift;
56 0         0 return pop(@{$self->{rules}});
  0         0  
57             }
58              
59             sub ShiftRule
60             {
61 0     0 0 0 my $self = shift;
62 0         0 return shift(@{$self->Rules()});
  0         0  
63             }
64              
65             sub UnshiftRule
66             {
67 0     0 0 0 my $self = shift;
68 0         0 return unshift(@{$self->Rules()});
  0         0  
69             }
70              
71              
72             sub Rules
73             {
74 6     6 0 13 my $self = shift;
75              
76 6         13 return $self->{rules};
77             }
78              
79             sub RunACL
80             {
81 5     5 0 54 my $self = shift;
82 5         8 my $args = shift;
83              
84 5         19 $self->_VerifyControlArgs($args);
85            
86 5         12 my $rules = $self->Rules();
87              
88 5         8 my $allowed = 0;
89              
90 5         7 my $rule_count = 0;
91 5         10 foreach my $rule (@$rules)
92             {
93 14 50       34 next if not defined $rule;
94 14         20 $rule_count++;
95              
96 14 50       44 print STDERR "Asking rule $rule_count about: ".(join ',', map { "$_=".$args->{$_} } (keys %$args))."\n" if $self->DEBUG_LEVEL();
  0         0  
97              
98 14         40 my $rule_status = $rule->Control($args);
99              
100 14 50       47 print STDERR "Rule says -> $rule_status\n" if $self->DEBUG_LEVEL();
101 14 100       69 next if($rule_status == ACL_RULE_UNCONCERNED);
102              
103 4 100       11 if($rule_status == ACL_RULE_ALLOW)
104             {
105 2         3 $allowed++;
106             }
107              
108 4 100 66     30 if($self->AUTO_DENY_NOW() && $rule_status == ACL_RULE_DENY)
109             {
110 2 50       12 print STDERR "Rule will auto deny now.\n" if $self->DEBUG_LEVEL();
111 2 50       12 return ACL_RULE_DENY if($self->AUTO_DENY_NOW());
112             }
113              
114 2 50       6 if($rule->Now() == 1)
115             {
116 2 50       7 print STDERR "Rule needs to act now.\n" if $self->DEBUG_LEVEL();
117 2         7 return $rule_status;
118             }
119              
120             }
121              
122 1 50       4 if($allowed) { return ACL_RULE_ALLOW; }
  0         0  
123              
124 1 50       4 print STDERR "Denying by default.\n" if $self->DEBUG_LEVEL();
125 1         3 return ACL_RULE_DENY;
126             }
127              
128             sub _VerifyControlArgs
129             {
130 5     5   9 my $self = shift;
131 5         6 my $args = shift;
132              
133 5         9 foreach my $control_field (@{ $self->ControlFields() })
  5         11  
134             {
135 20 50       58 next if $args->{$control_field};
136 0         0 croak "Cannot run ACL, missing control field in arguments to RunACL() ($control_field)\n";
137             }
138 5         10 return 1;
139             }
140              
141              
142             sub _VerifyRuleFields
143             {
144 4     4   5 my $self = shift;
145 4         8 my $rule = shift;
146              
147 4 100       19 if($self->{_fields_loaded})
148             {
149 3         5 foreach my $field (@{ $self->ControlFields() })
  3         8  
150             {
151 12 50       32 next if exists $rule->Fields()->{$field};
152 0 0       0 if($self->DIE_ON_MALFORMED_RULES())
153             {
154 0         0 croak "Rule format does not match loaded control fields.\n";
155             }
156 0         0 return 0;
157             }
158             }
159             else
160             {
161 1         2 my $control_fields = [];
162 1         3 foreach my $field (keys %{ $rule->Fields() })
  1         6  
163             {
164 4         8 push(@$control_fields, $field);
165             }
166 1         4 $self->{control_fields} = $control_fields;
167 1         2 $self->{_fields_loaded} = 1;
168             }
169 4         14 return 1;
170             }
171              
172              
173             666;
174             __END__