File Coverage

blib/lib/RPC/Serialized/AuthzHandler/ACL.pm
Criterion Covered Total %
statement 51 54 94.4
branch 15 22 68.1
condition n/a
subroutine 12 12 100.0
pod 0 3 0.0
total 78 91 85.7


line stmt bran cond sub pod time code
1             #
2             # $HeadURL: https://svn.oucs.ox.ac.uk/people/oliver/pub/librpc-serialized-perl/trunk/lib/RPC/Serialized/AuthzHandler/ACL.pm $
3             # $LastChangedRevision: 1281 $
4             # $LastChangedDate: 2008-10-01 16:16:56 +0100 (Wed, 01 Oct 2008) $
5             # $LastChangedBy: oliver $
6             #
7             package RPC::Serialized::AuthzHandler::ACL;
8             {
9             $RPC::Serialized::AuthzHandler::ACL::VERSION = '1.123630';
10             }
11              
12 1     1   782 use strict;
  1         2  
  1         41  
13 1     1   6 use warnings FATAL => 'all';
  1         1  
  1         47  
14              
15 1     1   5 use base 'RPC::Serialized::AuthzHandler';
  1         1  
  1         615  
16              
17 1     1   813 use Readonly;
  1         3508  
  1         61  
18 1     1   943 use IO::File;
  1         1132  
  1         191  
19 1     1   657 use RPC::Serialized::ACL;
  1         4  
  1         34  
20 1     1   680 use RPC::Serialized::ACL::Group;
  1         4  
  1         32  
21 1     1   5 use RPC::Serialized::Exceptions;
  1         2  
  1         5  
22              
23             Readonly my $GROUP_RX => qr/^define\s+group\s+(\S+)\s+(.+)$/;
24             Readonly my $ACL_RX => qr/^(allow|deny)\s+(\S+)\s+by\s+(\S+)\s+on\s+(\S+)$/;
25              
26             sub _parse_acls {
27 3     3   4 my $acl_path = shift;
28              
29 3 100       40 my $acl_fh = IO::File->new($acl_path)
30             or throw_system "Open $acl_path failed: $!";
31              
32 2         150 my ( @acls, %groups );
33 2         46 while (<$acl_fh>) {
34 8         20 s/#.*$//;
35 8         17 s/^\s+//;
36 8         25 s/\s+$//;
37 8 100       63 next unless length($_);
38              
39 5 100       25 if ( my ( $action, $operation, $subject, $target ) = $_ =~ $ACL_RX ) {
    50          
40 4 50       51 if ( $subject =~ s/^group:// ) {
41 0 0       0 $subject = $groups{$subject}
42             or throw_app
43             "Reference to undefined group at '$acl_path' line $.";
44             }
45 4 50       10 if ( $target =~ s/^group:// ) {
46 0 0       0 $target = $groups{$target}
47             or throw_app
48             "Reference to undefined group at '$acl_path' line $.";
49             }
50 4         21 push @acls,
51             RPC::Serialized::ACL->new(
52             operation => $operation,
53             subject => $subject,
54             target => $target,
55             action => $action,
56             );
57             }
58             elsif ( my ( $name, $uri ) = $_ =~ $GROUP_RX ) {
59 0         0 $groups{$name} = RPC::Serialized::ACL::Group->new($uri);
60             }
61             else {
62 1         31 throw_app "Failed to parse ACLs at '$acl_path' line $.";
63             }
64             }
65              
66 1         19 return \@acls;
67             }
68              
69             sub new {
70 4     4 0 7106 my $class = shift;
71              
72 4 100       20 my $acl_path = shift
73             or throw_app 'ACL path not specified';
74              
75 3         10 return bless {
76             ACLS => _parse_acls($acl_path),
77             }, $class;
78             }
79              
80             sub acls {
81 8     8 0 8 my $self = shift;
82 8         26 $self->{ACLS};
83             }
84              
85             sub check_authz {
86 8     8 0 955 my $self = shift;
87 8         14 my ( $subject, $operation, $target ) = @_;
88              
89 8         8 foreach my $acl ( @{ $self->acls } ) {
  8         17  
90 25         62 my $rc = $acl->check( $subject, $operation, $target );
91 25 100       103 next if $rc == $acl->DECLINE;
92 6 100       60 return $rc == $acl->ALLOW ? 1 : 0;
93             }
94              
95 2         10 return 0;
96             }
97              
98             1;
99