File Coverage

blib/lib/WebService/Cmis/Agent/CookieAuth.pm
Criterion Covered Total %
statement 15 73 20.5
branch 0 24 0.0
condition 0 11 0.0
subroutine 5 13 38.4
pod 4 4 100.0
total 24 125 19.2


line stmt bran cond sub pod time code
1             package WebService::Cmis::Agent::CookieAuth;
2              
3             =head1 NAME
4              
5             WebService::Cmis::Agent::CookieAuth - cookie-based authentication handler
6              
7             =head1 DESCRIPTION
8              
9             This user agent allows to remain logged in based on cookie information returned by the server.
10              
11             my $client = WebService::Cmis::getClient(
12             url => "http://localhost:8080/nuxeo/atom/cmis",
13             useragent => new WebService::Cmis::Agent::CookieAuth(
14             user => "user",
15             password => "password",
16             loginUrl => "http://localhost:8080/nuxeo/nxstartup.faces",
17             cookieDir => "/tmp",
18             )
19             );
20            
21             my $cookie = $client->login;
22             my $repo = $client->getRepository;
23              
24             Parent class: L
25              
26             =cut
27              
28 1     1   7106 use strict;
  1         3  
  1         50  
29 1     1   7 use warnings;
  1         2  
  1         33  
30              
31 1     1   6 use WebService::Cmis::Agent ();
  1         1  
  1         12  
32 1     1   5 use URI ();
  1         2  
  1         41  
33             our @ISA = qw(WebService::Cmis::Agent);
34              
35 1     1   4 use Error qw(:try);
  1         3  
  1         25  
36              
37             =head1 METHODS
38              
39             =over 4
40              
41             =item new(%params)
42              
43             Create a new WebService::Cmis::Agent::CookieAuth.
44              
45             Parameters:
46              
47             =over 4
48              
49             =item * user
50              
51             =item * password
52              
53             =item * loginUrl (defaults to the cmis client's atom endpoint)
54              
55             =item * cookieDir (defaults to /tmp)
56              
57             =back
58              
59             See L for more options.
60              
61             =cut
62              
63             sub new {
64 0     0 1   my ($class, %params) = @_;
65              
66 0           my $user = delete $params{user};
67 0           my $password = delete $params{password};
68 0           my $loginUrl = delete $params{loginUrl};
69 0   0       my $cookieDir = delete $params{cookieDir} || "/tmp";
70              
71 0           my $this = $class->SUPER::new(%params);
72              
73 0           $this->{user} = $user;
74 0           $this->{password} = $password;
75 0           $this->{loginUrl} = $loginUrl;
76 0           $this->{cookieDir} = $cookieDir;
77              
78 0           return $this;
79             }
80              
81             =item login(%params) -> $cookie
82              
83             logs in to the web service
84              
85             Parameters:
86              
87             =over 4
88              
89             =item * user
90              
91             =item * password
92              
93             =item * cookie
94              
95             =back
96              
97             Login using basic auth or based on a cookie previously collected.
98              
99             my $cookie = $client->login({
100             user => "user",
101             password => "pasword"
102             });
103              
104             $client->login({
105             cookie => $cookie
106             });
107              
108             =cut
109              
110             sub login {
111 0     0 1   my $this = shift;
112 0           my %params = @_;
113              
114 0 0         $this->{cookie} = $params{cookie} if defined $params{cookie};
115 0 0         $this->{user} = $params{user} if defined $params{user};
116 0 0         $this->{password} = $params{password} if defined $params{password};
117              
118 0 0         $this->{loginUrl} = $this->{client}{repositoryUrl}
119             unless defined $this->{loginUrl};
120              
121 0 0         throw Error::Simple("loginUrl undefined ... where do I get my cookies from")
122             unless defined $this->{loginUrl};
123              
124 0 0         $this->_createCookieJar if defined $this->{user};
125              
126 0 0         if (defined $this->{cookie}) {
127             #print STDERR "setting cookie\n";
128              
129 0           $this->cookie_jar->set_cookie(@{$this->{cookie}});
  0            
130              
131             } else {
132 0           my @sig = $this->_getCookieSignarure;
133              
134 0 0         if ($this->_readCookie(@sig)) {
135             #print STDERR "found cookie in jar\n";
136 0           $this->{password} = undef;
137             } else {
138             #print STDERR "getting a new cookie\n";
139 0           $this->{client}->request("GET", $this->{loginUrl});
140 0           $this->_readCookie(@sig);
141              
142             # another request against the real endpoint
143 0           $this->{client}->get;
144             }
145              
146             #print STDERR "cookie=".join(", ", map {defined($_)?$_:'undef'} @{$this->{cookie}})."\n" if defined $this->{cookie};
147              
148 0 0         throw("No cookie found in response") unless defined $this->{cookie};
149             }
150              
151 0           return $this->{cookie};
152             }
153              
154             sub _getCookieSignarure {
155 0     0     my $this = shift;
156              
157 0           my $uri = URI->new($this->{loginUrl});
158 0           my $path = $uri->path;
159 0           my $host = $uri->host;
160 0           my $port = $uri->port;
161 0           $path =~ s,/[^/]*$,,;
162 0 0         $host .= ".local" unless $host =~ /\./;
163              
164             #print STDERR "path=$path, host=$host, path=$path\n";
165              
166 0           return ($host, $port, $path);
167             }
168              
169             sub _createCookieJar {
170 0     0     my $this = shift;
171              
172 0           my $cookieFile = $this->{cookieDir}."/cmiscookies-$this->{user}";
173             # $cookieFile =~ /^(.*)/;
174             # $cookieFile = $1; #untaint
175              
176             #print STDERR "using a cookie jar at $cookieFile\n";
177 0           $this->cookie_jar({
178             file => $cookieFile,
179             autosave => 1,
180             ignore_discard => 1,
181             });
182             }
183              
184             sub _readCookie {
185 0     0     my ($this, $loginHost, $loginPort, $loginPath) = @_;
186              
187             #print STDERR "searching cookie for loginPath=$loginPath, loginHost=$loginHost, loginPort=".($loginPort||'undef')."\n";
188 0           $this->{cookie} = undef;
189              
190             $this->cookie_jar->scan(
191             sub {
192 0     0     my ($version, $key, $val, $path, $domain, $port, $path_spec, $secure, $expires, $discard, $hash) = @_;
193             #print STDERR "version=$version, key=$key, val=$val, path=$path, domain=$domain, port=".($port||'undef')."\n";
194 0 0 0       if ($path eq $loginPath && $domain eq $loginHost && (!$port || $port eq $loginPort)) {
      0        
      0        
195             #print STDERR "yep, found it\n";
196 0           $this->{cookie} = [
197             $version, $key, $val, $path, $domain, $port, $path_spec, $secure, $expires, $discard
198             ];
199             }
200             }
201 0           );
202              
203 0           return $this->{cookie};
204             }
205              
206              
207             =item logout()
208              
209             logs out of the web service deleting a cookie previously aquired
210              
211             =cut
212              
213             sub logout {
214 0     0 1   my $this = shift;
215              
216 0           $this->{user} = undef;
217 0           $this->{password} = undef;
218 0           $this->{cookie} = undef;
219            
220 0           my $cookieJar = $this->cookie_jar;
221 0 0         if ($cookieJar) {
222 0           my ($host, $port, $path) = $this->_getCookieSignarure;
223            
224             #print STDERR "clearing cookie for $host, $path\n";
225 0           $cookieJar->clear($host, $path);
226             }
227             }
228              
229             =item get_basic_credentials()
230              
231             overrides the method in LWP::UserAgent to implement the given authentication mechanism.
232              
233             =cut
234              
235             sub get_basic_credentials {
236 0     0 1   my $this = shift;
237              
238             #print STDERR "called get_basic_credentials\n";
239              
240 0           return ($this->{user}, $this->{password});
241             }
242              
243             =back
244              
245             =head1 COPYRIGHT AND LICENSE
246              
247             Copyright 2012-2013 Michael Daum
248              
249             This module is free software; you can redistribute it and/or modify it under
250             the same terms as Perl itself. See F.
251              
252             =cut
253              
254             1;
255