File Coverage

lib/Mail/TempAddress.pm
Criterion Covered Total %
statement 104 106 98.1
branch 25 28 89.2
condition 5 5 100.0
subroutine 17 18 94.4
pod 4 11 36.3
total 155 168 92.2


line stmt bran cond sub pod time code
1             package Mail::TempAddress;
2              
3 2     2   1870 use strict;
  2         4  
  2         141  
4             my $pod = do { local $/; };
5              
6 2     2   9 use base 'Mail::Action';
  2         3  
  2         1659  
7 2     2   207932 use Carp 'croak';
  2         4  
  2         107  
8              
9 2     2   12 use Mail::Mailer;
  2         4  
  2         30  
10 2     2   26 use Email::Address;
  2         4  
  2         46  
11              
12 2     2   11 use Mail::TempAddress::Addresses;
  2         5  
  2         54  
13              
14 2     2   10 use vars '$VERSION';
  2         4  
  2         2218  
15             $VERSION = '0.62';
16              
17             sub storage_class
18             {
19 22     22 0 72284 'Mail::TempAddress::Addresses'
20             }
21              
22             sub process
23             {
24 16     16 1 9444 my $self = shift;
25              
26 16 50       315 return if $self->request()->message()->header( 'X-MTA-Seen' );
27              
28 16         904 my $command = $self->find_command();
29 16 100       613 return $self->$command() if $command;
30              
31 12         59 my ($address, $key) = $self->fetch_address();
32              
33             my $result = eval
34 12         261 {
35 12 100       53 die "No address found\n" unless $address;
36 11 100       55 return $self->respond( $address, $key ) if $key;
37 7 50       49 return $self->deliver( $address ) if $address;
38             };
39              
40 12 100       862 return $result unless $@;
41 4         27 $self->reject( $@ );
42             }
43              
44             sub command_help
45             {
46 0     0 1 0 my $self = shift;
47 0         0 $self->SUPER::command_help( $pod, 'USING ADDRESSES', 'DIRECTIVES' );
48             }
49              
50             sub deliver
51             {
52 8     8 0 8239 my ($self, $address) = @_;
53              
54 8         56 my $expires = $address->expires();
55 8 100 100     233 $self->reject() if $expires and $expires < time();
56              
57 6         36 my $request = $self->request();
58 6         109 my $from = $request->header( 'From' )->address();
59 6         135 my $key = $address->add_sender( $from );
60 6         117 my $desc = $address->description();
61 6         138 my $to = $request->recipient();
62 6         48 my $user = $to->user();
63 6         83 my $host = $to->host();
64              
65 1         13 my @all_to =
66 1         14 map { $self->build_address( $_, $address, $user, $host ) }
67 6         252 grep { $_->address() ne $to->address() }
68             $request->header( 'To' );
69              
70 1         11 my @all_cc =
71 1         13 map { $self->build_address( $_, $address, $user, $host ) }
72 6         79 grep { $_->address() ne $to->address() }
73             $request->header( 'Cc' );
74              
75 6         69 my $headers = $request->copy_headers();
76              
77 6         1263 $headers->{From} = $from;
78 6         41 $headers->{To} = [ $address->owner(), @all_to ];
79 6 100       109 $headers->{Cc} = \@all_cc if @all_cc;
80 6         27 $headers->{'Reply-To'} = "$user+$key\@$host";
81 6 100       22 $headers->{'X-MTA-Description'} = $desc if $desc;
82              
83 6         49 $self->storage->save( $address, $address->name() );
84              
85 6         16175 $self->reply( $headers, $request->message->body_raw() );
86             }
87              
88             sub build_address
89             {
90 2     2 0 6 my ($self, $addy, $address, $user, $host) = @_;
91              
92 2         6 my $real_addy = $addy->address();
93 2         13 my $comment = '(' . $real_addy . ')';
94 2         6 my $key = $address->add_sender( $real_addy );
95 2         8 my $keyed = '<' . $user . '+' . $key . '@' . $host . '>';
96              
97 2         10 return $comment . ' ' . $keyed;
98             }
99              
100             sub respond
101             {
102 4     4 0 17518 my ($self, $address, $key) = @_;
103              
104 4         27 my $request = $self->request();
105 4 100       42 my $to = $address->get_sender( $key )
106             or die "No sender for '$key'\n";
107              
108 3         78 my $message = $self->message();
109              
110 3         1778 my $addy = $request->recipient();
111 3         63 my $host = $addy->host();
112 3         99 my $from = $address->name() . "\@$host";
113              
114 3         70 my $headers = $request->copy_headers();
115 3         786 $headers->{To} = $to;
116 3         10 $headers->{From} = $from;
117 3         9 delete $headers->{Cc};
118              
119 3         8 $self->reply( $headers, join("\n", @{ $request->remove_sig() } ));
  3         15  
120             }
121              
122             sub fetch_address
123             {
124 10     10 1 139 my $self = shift;
125 10         35 my ($alias, $key) = $self->parse_alias( $self->request()->recipient() );
126 10         45 my $addresses = $self->storage();
127              
128 10 100       117 return unless $addresses->exists( $alias );
129              
130 9         184 my $addy = $addresses->fetch( $alias );
131              
132 9 100       230 return wantarray ? ( $addy, $key ) : $addy;
133             }
134              
135             sub parse_alias
136             {
137 10     10 0 103 my ($self, $address) = @_;
138 10         41 my ($add) = Email::Address->parse( $address );
139 10         587 my $user = $add->user();
140 10         693 my $expansion_pattern = $self->expansion_pattern();
141 10 100       71 my $key = ( $user =~ s/$expansion_pattern// ? $1 : undef );
142 10 50       54 return wantarray ? ( $user, $key ) : $user;
143             }
144              
145             sub expansion_pattern
146             {
147 10     10 1 49 return qr/\+([^+]+)$/;
148             }
149              
150             sub command_new
151             {
152 4     4 0 188 my $self = shift;
153 4         45 my $request = $self->request();
154 4         31 my $from = $request->header( 'From' )->address();
155 4         62 my $to = $request->recipient();
156 4         31 my $domain = $to->host();
157              
158 4         281 my $addresses = $self->storage();
159 4         38 my $address = $addresses->create( $from );
160 4         85 my $tempaddy = $addresses->generate_address();
161              
162 4         72 $self->process_body( $address );
163 4         437 $addresses->save( $address, $tempaddy );
164              
165 4         25951 $self->reply({
166             To => $from,
167             From => $to->address(),
168             Subject => 'Temporary address created' },
169             "A new temporary address has been created for $from: $tempaddy\@$domain" );
170             }
171              
172             sub reject
173             {
174 5     5 0 8358 my ($self, $error) = @_;
175 5   100     29 $error ||= "Invalid address";
176 5         11 $! = 100;
177 5         43 die "$error\n";
178             }
179              
180             1;
181             __DATA__