Skip to content

Instantly share code, notes, and snippets.

@semifor
Created February 7, 2010 03:13
Show Gist options
  • Save semifor/297169 to your computer and use it in GitHub Desktop.
Save semifor/297169 to your computer and use it in GitHub Desktop.
### The model ####
package MyApp::Model::Twitter;
use Moose;
use Carp;
use Net::Twitter;
use namespace::autoclean;
extends 'Catalyst::Component';
__PACKAGE__->config(
session_key => '__twitter_oauth',
);
sub COMPONENT {
my ( $class, $app, $args ) = @_;
croak "traits required for $class" unless exists $args->{traits};
push @{$args->{traits}}, 'Catalyst';
return Net::Twitter->new({
session_key => $class->config->{session_key},
%$args
});
}
__PACKAGE__->meta->make_immutable;
1;
### The Net::Twitter role ###
package Net::Twitter::Role::Catalyst;
use Moose::Role;
use Carp;
use namespace::autoclean;
=head1 NAME
Net::Twitter::Role::Catalyst
=cut
with 'Net::Twitter::Role::OAuth';
has session_key => (
isa => 'Str',
is => 'rw',
required => 1,
);
sub twitter_authentication_redirect { shift->_oauth_redirect(get_authentication_url => @_) }
sub twitter_authorization_redirect { shift->_oauth_redirect(get_authorization_url => @_) }
sub _oauth_redirect {
my ( $self, $method, $c, $callback_action ) = @_;
my $url = $self->$method(callback => $c->uri_for($callback_action));
$c->session->{$self->session_key}{oauth_secret} = $self->request_token_secret;
$c->res->redirect($url);
}
sub twitter_login {
my ( $self, $c ) = @_;
my $oauth_token = $c->req->param('oauth_token') and
my $oauth_verifier = $c->req->param('oauth_verifier')
or croak "Missing oauth paramaters";
my $oauth_secret = delete $c->session->{$self->session_key}{oauth_secret}
or croak "oauth_secret is not in the session data";
$self->request_token($oauth_token);
$self->request_token_secret($oauth_secret);
my %oauth;
@{oauth}{qw/access_token access_secret user_id screen_name/} =
$self->request_access_token(verifier => $oauth_verifier);
return \%oauth;
}
1;
### the config ###
'Model::Twitter' => {
traits => [qw/API::REST/],
consumer_key => 'key',
consumer_secret => 'secret',
useragent_args => { timeout => 15 },
},
### controller usage ###
sub twitter_auth :Local {
my ( $self, $c ) = @_;
$c->detach('not_found') unless $c->req->method eq 'POST';
try {
$c->model('Twitter')->twitter_authentication_redirect($c, '/login');
}
catch {
$c->log->error("twitter_authentication_redirect failed: $_");
$c->flash(error => 'Twitter failed to respond. Please try again');
$c->res->redirect($c->uri_for('/'));
};
}
sub login :Local {
my ( $self, $c ) = @_;
# default uri for redirection
my $uri = $c->uri_for('/');
try {
my $oauth = $c->model('Twitter')->twitter_login($c);
my ( $access_token, $access_secret, $user_id, $screen_name ) =
@{$c->session}{qw/access_token access_secret user_id screen_name/} =
@{$oauth}{qw/access_token access_secret user_id screen_name/};
if ( $c->authenticate({ id => $user_id }) ) {
$c->user->get_object->update({
screen_name => $screen_name,
oauth_token => $access_token,
oauth_secret => $access_secret,
});
$uri = delete $c->session->{redirect_to_after_login} || $uri;
$c->log->debug("Redirecting to $uri");
}
else {
# authenticated with twitter, but not registered, yet
$uri = $c->uri_for('register');
}
}
catch {
$c->flash(error => 'Twitter authentication failed. Please try again.');
return;
};
$c->res->redirect($uri);
return;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment