File Coverage

blib/lib/Net/OpenID/ClaimedIdentity.pm
Criterion Covered Total %
statement 12 97 12.3
branch 0 60 0.0
condition 0 14 0.0
subroutine 4 12 33.3
pod 6 8 75.0
total 22 191 11.5


line stmt bran cond sub pod time code
1 6     6   28 use strict;
  6         11  
  6         133  
2 6     6   30 use Carp ();
  6         11  
  6         321  
3              
4             ############################################################################
5             package Net::OpenID::ClaimedIdentity;
6             {
7             $Net::OpenID::ClaimedIdentity::VERSION = '1.16';
8             }
9             use fields (
10 6         35 'identity', # the canonical URL that was found, following redirects
11             'server', # author-identity identity provider endpoint
12             'consumer', # ref up to the Net::OpenID::Consumer which generated us
13             'delegate', # the delegated URL actually asserted by the provider
14             'protocol_version', # The version of the OpenID Authentication Protocol that is used
15             'semantic_info', # Stuff that we've discovered in the identifier page's metadata
16             'extension_args', # Extension arguments that the caller wants to add to the request
17 6     6   29 );
  6         16  
18              
19 6     6   4946 use Digest::SHA qw(hmac_sha1_hex);
  6         19151  
  6         8154  
20              
21             sub new {
22 0     0 0   my Net::OpenID::ClaimedIdentity $self = shift;
23 0 0         $self = fields::new( $self ) unless ref $self;
24 0           my %opts = @_;
25 0           for my $f (qw( identity server consumer delegate protocol_version semantic_info )) {
26 0           $self->{$f} = delete $opts{$f};
27             }
28              
29 0   0       $self->{protocol_version} ||= 1;
30 0 0 0       unless ($self->{protocol_version} == 1 || $self->{protocol_version} == 2) {
31 0           Carp::croak("Unsupported protocol version");
32             }
33              
34             # lowercase the scheme and hostname
35 0           $self->{'identity'} =~ s!^(https?://.+?)(/(?:.*))?$!lc($1) . $2!ie;
  0            
36              
37 0           $self->{extension_args} = {};
38              
39 0 0         Carp::croak("unknown options: " . join(", ", keys %opts)) if %opts;
40 0           return $self;
41             }
42              
43             sub claimed_url {
44 0     0 1   my Net::OpenID::ClaimedIdentity $self = shift;
45 0 0         Carp::croak("Too many parameters") if @_;
46 0           return $self->{'identity'};
47             }
48              
49             sub delegated_url {
50 0     0 1   my Net::OpenID::ClaimedIdentity $self = shift;
51 0 0         Carp::croak("Too many parameters") if @_;
52 0           return $self->{'delegate'};
53             }
54              
55             sub identity_server {
56 0     0 1   my Net::OpenID::ClaimedIdentity $self = shift;
57 0 0         Carp::croak("Too many parameters") if @_;
58 0           return $self->{server};
59             }
60              
61             sub protocol_version {
62 0     0 1   my Net::OpenID::ClaimedIdentity $self = shift;
63 0 0         Carp::croak("Too many parameters") if @_;
64 0           return $self->{protocol_version};
65             }
66              
67             sub semantic_info {
68 0     0 0   my Net::OpenID::ClaimedIdentity $self = shift;
69 0 0         Carp::croak("Too many parameters") if @_;
70 0 0         return $self->{semantic_info} if $self->{semantic_info};
71 0           my $final_url = '';
72 0           my $info = $self->{consumer}->_find_semantic_info($self->claimed_url, \$final_url);
73             # Don't return anything if the URL has changed. Something bad may be happening.
74 0 0         $info = {} if $final_url ne $self->claimed_url;
75 0           return $self->{semantic_info} = $info;
76             }
77              
78             sub set_extension_args {
79 0     0 1   my Net::OpenID::ClaimedIdentity $self = shift;
80 0           my $ext_uri = shift;
81 0           my $args = shift;
82 0 0         Carp::croak("Too many parameters") if @_;
83 0 0         Carp::croak("No extension URI given") unless $ext_uri;
84 0 0 0       Carp::croak("Expecting hashref of args") if defined($args) && ref $args ne 'HASH';
85              
86 0           $self->{extension_args}{$ext_uri} = $args;
87             }
88              
89             sub check_url {
90 0     0 1   my Net::OpenID::ClaimedIdentity $self = shift;
91 0           my (%opts) = @_;
92              
93 0           my $return_to = delete $opts{'return_to'};
94 0           my $trust_root = delete $opts{'trust_root'};
95 0           my $delayed_ret = delete $opts{'delayed_return'};
96 0           my $force_reassociate = delete $opts{'force_reassociate'};
97 0           my $use_assoc_handle = delete $opts{'use_assoc_handle'};
98 0           my $actually_return_association = delete $opts{'actually_return_association'};
99              
100 0 0         Carp::croak("Unknown options: " . join(", ", keys %opts)) if %opts;
101 0 0         Carp::croak("Invalid/missing return_to") unless $return_to =~ m!^https?://!;
102              
103 0           my $csr = $self->{consumer};
104              
105             my $ident_server = $self->{server} or
106 0 0         Carp::croak("No identity server");
107              
108             # get an assoc (or undef for dumb mode)
109 0           my $assoc;
110 0 0         if ($use_assoc_handle) {
111 0           $assoc = Net::OpenID::Association::handle_assoc($csr, $ident_server, $use_assoc_handle);
112             } else {
113             $assoc = Net::OpenID::Association::server_assoc($csr, $ident_server, $force_reassociate, (
114 0           %{$csr->assoc_options},
  0            
115             protocol_version => $self->protocol_version,
116             ));
117             }
118              
119             # for the openid-test project: (doing interop testing)
120 0 0         if ($actually_return_association) {
121 0           return $assoc;
122             }
123              
124 0   0       my $identity_arg = $self->{'delegate'} || $self->{'identity'};
125              
126             # make a note back to ourselves that we're using a delegate
127             # but only in the 1.1 case because 2.0 has a core field for this
128 0 0 0       if ($self->{'delegate'} && $self->protocol_version == 1) {
129             OpenID::util::push_url_arg(\$return_to,
130 0           "oic.identity", $self->{identity});
131             }
132              
133             # add a HMAC-signed time so we can verify the return_to URL wasn't spoofed
134 0           my $sig_time = time();
135 0           my $c_secret = $csr->_get_consumer_secret($sig_time);
136 0           my $sig = substr(hmac_sha1_hex($sig_time, $c_secret), 0, 20);
137 0           OpenID::util::push_url_arg(\$return_to,
138             "oic.time", "${sig_time}-$sig");
139              
140 0           my $curl = $ident_server;
141 0 0         if ($self->protocol_version == 1) {
    0          
142 0 0         OpenID::util::push_url_arg(\$curl,
    0          
    0          
143             "openid.mode" => ($delayed_ret ? "checkid_setup" : "checkid_immediate"),
144             "openid.identity" => $identity_arg,
145             "openid.return_to" => $return_to,
146              
147             ($trust_root ? (
148             "openid.trust_root" => $trust_root
149             ) : ()),
150              
151             ($assoc ? (
152             "openid.assoc_handle" => $assoc->handle
153             ) : ()),
154             );
155             }
156             elsif ($self->protocol_version == 2) {
157             # NOTE: OpenID Auth 2.0 uses different terminology for a bunch
158             # of things than 1.1 did. This library still uses the 1.1 terminology
159             # in its API.
160 0 0         OpenID::util::push_openid2_url_arg(\$curl,
    0          
    0          
161             "mode" => ($delayed_ret ? "checkid_setup" : "checkid_immediate"),
162             "claimed_id" => $self->claimed_url,
163             "identity" => $identity_arg,
164             "return_to" => $return_to,
165              
166             ($trust_root ? (
167             "realm" => $trust_root
168             ) : ()),
169              
170             ($assoc ? (
171             "assoc_handle" => $assoc->handle
172             ) : ()),
173             );
174             }
175              
176             # Finally we add in the extension arguments, if any
177 0           my %ext_url_args = ();
178 0           my $ext_idx = 1;
179 0           foreach my $ext_uri (keys %{$self->{extension_args}}) {
  0            
180 0           my $ext_alias;
181              
182 0 0         if ($ext_uri eq "http://openid.net/extensions/sreg/1.1") {
    0          
183             # For OpenID 1.1 only the "SREG" extension is allowed,
184             # and it must use the "openid.sreg." prefix.
185 0           $ext_alias = "sreg";
186             }
187             elsif ($self->protocol_version < 2) {
188 0           next;
189             }
190             else {
191 0           $ext_alias = 'e'.($ext_idx++);
192             }
193 0           $ext_url_args{'openid.ns.'.$ext_alias} = $ext_uri;
194              
195 0           foreach my $k (keys %{$self->{extension_args}{$ext_uri}}) {
  0            
196 0           $ext_url_args{'openid.'.$ext_alias.'.'.$k} = $self->{extension_args}{$ext_uri}{$k};
197             }
198             }
199 0 0         OpenID::util::push_url_arg(\$curl, %ext_url_args) if %ext_url_args;
200              
201 0           $self->{consumer}->_debug("check_url for (del=$self->{delegate}, id=$self->{identity}) = $curl");
202 0           return $curl;
203             }
204              
205              
206             1;
207              
208             __END__