Skip to content

Instantly share code, notes, and snippets.

@dhoss
Created February 1, 2010 20:36
Show Gist options
  • Save dhoss/291994 to your computer and use it in GitHub Desktop.
Save dhoss/291994 to your computer and use it in GitHub Desktop.
package Catalyst::Model::Twitter;
use Moose;
use namespace::autoclean;
use Try::Tiny;
use Net::Twitter;
use Carp;
use Data::Dumper;
extends 'Catalyst::Model';
has 'consumer_key' => (
is => 'rw',
isa => 'Str',
required => 0,
default => sub { croak "Must provide consumer_key" },
lazy => 1,
);
has 'consumer_secret' => (
is => 'rw',
isa => 'Str',
required => 0,
default => sub { croak "Must provide consumer_secret" },
lazy => 1,
);
has 'nt' => (
is => 'ro',
isa => 'Net::Twitter',
required => 1,
lazy_build => 1,
);
sub _build_nt {
my $self = shift;
return Net::Twitter->new(
traits => [qw/ API::REST OAuth/], ## can and should be changed since i fixed the attr stuff here
consumer_key => $self->consumer_key,
consumer_secret => $self->consumer_secret,
);
}
sub auth_data {
my ( $self, $opts ) = @_;
my $url;
my $nt = $self->nt;
my $auth_hash;
try {
$auth_hash->{'url'} =
$nt->get_authentication_url( callback => $opts->{'callback'} );
}
catch {
$auth_hash->{'error'} = "Couldn't authenticate: $_";
};
$auth_hash->{'oauth_secret'} = $nt->request_token_secret;
return $auth_hash;
}
sub do_auth {
my ( $self, $opts ) = @_;
my $auth_hash;
my $nt = $self->nt;
warn "opts: " . Dumper $opts;
$nt->request_token( $opts->{'request_token'} );
$nt->request_token_secret( $opts->{'request_token_secret'} );
my ( $access_token, $access_secret, $user_id, $screen_name ) =
@{$auth_hash}{qw/access_token access_secret user_id screen_name/} = try {
$nt->request_access_token(
verifier => $opts->{'verifier'} );
};
if ($access_token) {
$auth_hash->{'access_token'} = $access_token;
$auth_hash->{'twitter_user'} = try {
$nt->verify_credentials( { user_id => $user_id } );
}
catch {
$auth_hash->{'error'} = "Twitter error: $_";
};
}
return $auth_hash;
}
__PACKAGE__->meta->make_immutable;
1;
<Model::Twitter>
consumer_key key
consumer_secret secret
<useragent_args>
timeout 15
</useragent_args>
</Model::Twitter>
sub twitter : Chained('login_base') PathPart('twitter') Args(0) {
my ( $self, $c ) = @_;
# $c->detach('not_found') unless $c->req->method eq 'POST';
my $nt = $c->model('Twitter');
my $auth_hash = $nt->auth_data(
{ callback => $c->uri_for_action("/users/twitter_callback") } );
unless ( $auth_hash->{'error'} ) {
$c->session->{'oauth_secret'} = $auth_hash->{'oauth_secret'};
$c->res->redirect( $auth_hash->{'url'} );
}
else {
$c->log->error(
"get_authentication_url failed: " . $auth_hash->{'error'} );
$c->flash( error => $auth_hash->{'error'} );
$c->res->redirect( $c->uri_for('/') );
}
}
sub twitter_callback : Chained('login_base') PathPart('tw_callback') Args(0) {
my ( $self, $c ) = @_;
# default uri for redirection
my $uri = $c->uri_for('/');
if ( my $oauth_token = $c->req->param('oauth_token')
and my $oauth_verifier = $c->req->param('oauth_verifier')
and my $oauth_secret = delete $c->session->{oauth_secret} )
{
my $nt = $c->model('Twitter');
my $twitter_hash = $nt->do_auth(
{
request_token => $oauth_token,
request_token_secret => $oauth_secret,
verifier => $oauth_verifier,
}
);
if ( $twitter_hash->{'access_token'} ) {
$c->session->{twitter_user} = $twitter_hash->{'twitter_user'};
if (
$c->authenticate(
{ twitter_user_id => $twitter_hash->{'user_id'}, },
'twitter'
)
)
{
$uri = delete $c->session->{redirect_to}
|| $uri;
$c->flash( message => "Welcome "
. $c->user->twitter_user
. " You have successfully logged in!" );
}
else {
# authenticated with twitter, but not registered, yet
# we create a skeleton user
my $user = $c->model('Database::User')->create(
{
twitter_user => $twitter_hash->{'screen_name'},
twitter_user_id => $twitter_hash->{'user_id'},
twitter_access_token => $twitter_hash->{'access_token'},
twitter_access_token_secret =>
$twitter_hash->{'access_secret'},
credential_source => 'twitter',
}
);
## *now* we authenticate
$c->authenticate(
{ twitter_user => $twitter_hash->{'screen_name'}, },
'twitter' )
or die "Login failed";
$c->flash( message => "Welcome, "
. $c->user->twitter_user
. ", You have successfully logged in and your account has been created!"
);
$uri = $c->uri_for_action('/quotes/get');
}
}
else {
$c->flash(
error => 'Twitter authentication failed. Please try again.' );
}
$c->res->redirect($uri);
return;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment