File Coverage

blib/lib/Catalyst/Authentication/Credential/Flickr.pm
Criterion Covered Total %
statement 11 13 84.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 16 18 88.8


line stmt bran cond sub pod time code
1             package Catalyst::Authentication::Credential::Flickr;
2              
3 1     1   53282 use strict;
  1         4  
  1         32  
4 1     1   6 use warnings;
  1         2  
  1         31  
5 1     1   5 use base qw( Class::Accessor::Fast );
  1         7  
  1         4661  
6              
7             BEGIN {
8 1     1   10494 __PACKAGE__->mk_accessors(qw/_flickr key secret perms/);
9             }
10              
11             our $VERSION = "0.04";
12              
13 1     1   746 use Catalyst::Exception ();
  0            
  0            
14             use Flickr::API;
15              
16             sub new {
17             my ($class, $config, $c, $realm) = @_;
18             my $self = {};
19             bless $self, $class;
20              
21             # Hack to make lookup of the configuration parameters less painful
22             my $params = { %{ $config }, %{ $realm->{config} } };
23              
24             # Check for required params (yes, nasty)
25             for my $param (qw/key secret perms/) {
26             $self->$param($params->{$param}) or
27             Catalyst::Exception->throw("$param not defined")
28             }
29              
30             # Create a Flickr::API instance
31             $self->_flickr(Flickr::API->new({ key => $self->key,
32             secret => $self->secret }));
33              
34             return $self;
35             }
36              
37             sub authenticate {
38             my ( $self, $c, $realm, $authinfo ) = @_;
39              
40             my $frob = $c->req->params->{frob} or return;
41            
42             my $api_response = $self->_flickr->execute_method( 'flickr.auth.getToken',
43             { frob => $frob, } );
44              
45             # Mapping the XML (why, oh why use XML::Parser::Lite::Tree ?)
46             # Let's pray really hard that Flickr will never ever change the layout
47             # of their XML. This _will_ break in that case.
48              
49             my $user = {};
50             foreach my $node (@{$api_response->{tree}{children}[1]{children}}) {
51             if(defined $node->{children} && $node->{children}[0]{content}) {
52             $user->{$node->{name}} = $node->{children}[0]{content}
53             }
54             if(defined $node->{attributes}) {
55             $user->{$_} = $node->{attributes}{$_}
56             for(keys %{$node->{attributes}});
57             }
58             }
59            
60             my $user_obj = $realm->find_user( $user, $c );
61             return ref $user_obj ? $user_obj : undef;
62             }
63            
64             sub authenticate_flickr_url {
65             my ($self, $c) = @_;
66              
67             my $uri = $self->_flickr->request_auth_url($self->perms);
68             return $uri;
69             }
70              
71             =head1 NAME
72              
73             Catalyst::Authentication::Credential::Flickr - Flickr authentication for Catalyst
74              
75             =head1 SYNOPSIS
76              
77             In MyApp.pm
78              
79             use Catalyst qw/
80             Authentication
81             Session
82             Session::Store::FastMmap
83             Session::State::Cookie
84             /;
85            
86             MyApp->config(
87             "Plugin::Authentication" => {
88             default_realm => "flickr",
89             realms => {
90             flickr => {
91             credential => {
92             class => "Flickr",
93             },
94              
95             key => 'flickr-key-here',
96             secret => 'flickr-secret-here',
97             perms => 'read',
98             },
99             },
100             },
101             );
102              
103             And then in your Controller:
104              
105             sub login : Local {
106             my ($self, $c) = @_;
107            
108             my $realm = $c->get_auth_realm('flickr');
109             $c->res->redirect( $realm->credential->authenticate_flickr_url($c) );
110             }
111              
112             And finally the callback you specified in your API key request (e.g.
113             example.com/flickr/ ):
114              
115             sub flickr : Local {
116             my ($self, $c) = @_;
117            
118             $c->authenticate();
119             $c->res->redirect("/super/secret/member/area");
120             }
121              
122             =head1 DESCRIPTION
123              
124             This module handles Flickr API authentication in a Catalyst application.
125              
126             When L<Catalyst::Plugin::Authentication> 0.10 was released, the API had
127             changed, resulting in broken code when using
128             L<Catalyst::Plugin::Authentication::Credential::Flickr>.
129              
130             This module tries to follow the guidelines of the new API and deprecate
131             L<Catalyst::Plugin::Authentication::Credential::Flickr>.
132              
133             Code changes are needed, but are fairly minimal.
134              
135             =head1 METHODS
136              
137             As per guidelines of L<Catalyst::Plugin::Authentication>, there are two
138             mandatory methods, C<new> and C<authenticate>. Since this is not really
139             enough for the Flickr API, I've added one more (and an alias).
140              
141             =head2 new()
142              
143             Will not be called by you directly, but will use the configuration you
144             provide (see above). Mandatory parameters are C<key>, C<secret> and
145             C<perms>. Please see L<Flickr::API> for more details on them.
146              
147             =head2 authenticate_flickr_url( $c )
148              
149             This method will return the authentication URL. Bounce your users there
150             before calling the C<authentication> method.
151              
152             =head2 authenticate( )
153              
154             Handles the authentication. Nothing more, nothing less. It returns
155             a L<Catalyst::Authentication::User::Hash> with the following keys
156             (all coming straight from Flickr).
157              
158             =over 4
159              
160             =item fullname
161              
162             =item nsid
163              
164             =item perms
165              
166             =item token
167              
168             =item username
169              
170             =back
171              
172             =head1 AUTHOR
173              
174             M. Blom
175             E<lt>blom@cpan.orgE<gt>
176             L<http://menno.b10m.net/perl/>
177              
178             =head1 COPYRIGHT
179              
180             This program is free software; you can redistribute
181             it and/or modify it under the same terms as Perl itself.
182              
183             The full text of the license can be found in the
184             LICENSE file included with this module.
185              
186             =head1 SEE ALSO
187              
188             L<Catalyst::Plugin::Authentication>, L<Flickr::API>
189              
190             =head1 BUGS
191              
192             C<Bugs? Impossible!>. Please report bugs to L<http://rt.cpan.org/Ticket/Create.html?Queue=Catalyst-Authentication-Credential-Flickr>
193              
194             =head1 THANKS
195              
196             Thanks go out Daisuke Murase for writing C::P::A::Credential::Flickr,
197             Ashley Pond for inspiration and help in C::A::Credential::OpenID,
198             Cal Henderson for Flickr::API.
199              
200             =cut
201              
202             1;