File Coverage

blib/lib/Net/Amazon/S3/ACL.pm
Criterion Covered Total %
statement 16 18 88.8
branch n/a
condition n/a
subroutine 6 6 100.0
pod n/a
total 22 24 91.6


line stmt bran cond sub pod time code
1             package Net::Amazon::S3::ACL;
2              
3 2     2   25406 use warnings;
  2         5  
  2         77  
4 2     2   11 use strict;
  2         6  
  2         65  
5 2     2   1570 use version; our $VERSION = qv('0.1.0');
  2         5522  
  2         13  
6              
7 2     2   174 use Carp;
  2         4  
  2         193  
8 2     2   1775 use English qw( -no_match_vars );
  2         7804  
  2         11  
9 2     2   2510 use Net::Amazon::S3::ACL::XMLHelper qw( xpc );
  0            
  0            
10             use Net::Amazon::S3::ACL::Grant;
11             use Scalar::Util qw( blessed );
12              
13             use base qw(Class::Accessor::Fast);
14             __PACKAGE__->mk_accessors(qw( owner_id owner_displayname grants ));
15              
16             # Module implementation here
17             sub new {
18             my $class = shift;
19              
20             my $params = shift || {};
21             my $xml = delete $params->{xml};
22             my $self = $class->SUPER::new($params);
23              
24             $self->parse($xml) if defined $xml;
25             $self->grants({}) unless $self->grants();
26              
27             return $self;
28             } ## end sub new
29              
30             sub parse {
31             my ($self, $xml) = @_;
32             my $xpc = xpc($xml);
33              
34             $self->owner_id($xpc->findvalue('//s3:Owner/s3:ID'));
35             $self->owner_displayname($xpc->findvalue('//s3:Owner/s3:DisplayName'));
36              
37             my %grants = map {
38             my $grant = Net::Amazon::S3::ACL::Grant->create(
39             {
40             xpc => $xpc,
41             node => $_,
42             }
43             );
44             ($grant->key() => $grant);
45             } $xpc->findnodes('.//s3:AccessControlList/s3:Grant');
46             $self->grants(\%grants);
47              
48             return $self;
49             } ## end sub parse
50              
51             sub delete {
52             my $self = shift;
53             if (@_ == 1 && blessed($_[0])) {
54             $self->_delete(undef, @_);
55             return $self;
56             }
57              
58             my @grants = ref $_[0] ? %{$_[0]} : @_;
59             while (my ($target, $item) = splice @grants, 0, 2) {
60             $self->_delete($target, $item);
61             }
62             return $self;
63             }
64              
65             sub _delete {
66             my $self = shift;
67             my $item = Net::Amazon::S3::ACL::Grant->canonical(@_);
68             #use Data::Dumper; warn Dumper $item;
69             my $target = $item->key();
70              
71             my $grants = $self->grants() or return;
72             my $perms = $item->{permissions} || [];
73             if (scalar(@$perms)) {
74             my $previous = $grants->{$target} or return;
75             my %forbidden = map { $_ => 1 } @$perms;
76             $previous->{permissions} =
77             [grep { !$forbidden{$_} } @{$previous->{permissions} || []}];
78             delete $grants->{$target} unless @{$previous->{permissions}};
79             } ## end if (defined($item->{permissions...
80             else {
81             #use Data::Dumper; warn Dumper($grants, \$target);
82             delete $grants->{$target};
83             }
84             return;
85             } ## end sub _delete
86              
87             sub add {
88             my $self = shift;
89             if (@_ == 1 && blessed($_[0])) {
90             $self->_add(undef, @_);
91             return $self;
92             }
93              
94             my @grants = ref $_[0] ? %{$_[0]} : @_;
95             while (my ($target, $item) = splice @grants, 0, 2) {
96             $self->_add($target, $item);
97             }
98             return $self;
99             } ## end sub add
100              
101             sub _add {
102             my $self = shift;
103             my $item = Net::Amazon::S3::ACL::Grant->canonical(@_);
104             #use Data::Dumper; warn Dumper $item;
105             my $target = $item->key();
106              
107             my $grants = $self->grants();
108             $self->grants($grants = {}) unless $grants;
109              
110             my $previous = $grants->{$target} ||= $item;
111             my %flag; # to filter out duplicates
112             $previous->{permissions} = [
113             grep { !$flag{$_}++ } @{$previous->{permissions} || []},
114             @{$item->{permissions} || []}
115             ];
116              
117             delete $grants->{$target} unless @{$previous->{permissions}};
118             return;
119             } ## end sub _add
120              
121             sub stringify {
122             my $self = shift;
123              
124             my $owner_chunk = $self->_stringify_owner();
125             my $grants_chunk = $self->_stringify_grants();
126              
127             # Indent for pretty printing
128             s/^/ /mxsg for $owner_chunk, $grants_chunk;
129              
130             return <<"END_OF_ACL";
131            
132            
133             $owner_chunk$grants_chunk
134            
135             END_OF_ACL
136             } ## end sub stringify
137              
138             sub _stringify_owner {
139             my ($self) = @_;
140              
141             defined(my $owner_id = $self->owner_id()) or return '';
142             my $owner_displayname = $self->owner_displayname();
143             $owner_displayname = '' unless defined $owner_displayname;
144              
145             return <<"END_OF_OWNER";
146            
147             $owner_id
148             $owner_displayname
149            
150             END_OF_OWNER
151             } ## end sub _stringify_owner
152              
153             sub _stringify_grants {
154             my ($self) = @_;
155              
156             my $list = join "\n",
157             map { $_->stringify(); }
158             grep { $_->is_valid()}
159             values %{$self->grants()};
160              
161             $list =~ s/^/ /mxsg; # indented
162             return "\n$list\n";
163             } ## end sub _stringify_acl
164              
165             sub dump {
166             my $self = shift;
167              
168             eval {
169             require YAML;
170             return YAML::Dump({
171             grants => $self->grants(),
172             owner => {
173             id => $self->owner_id(),
174             displayname => $self->owner_displayname(),
175             },
176             });
177             } or return $self->stringify();
178             }
179              
180             1; # Magic true value required at end of module
181             __END__