Created
September 26, 2013 18:13
-
-
Save gideondsouza/6718246 to your computer and use it in GitHub Desktop.
Dancer2::Plugin::Github::Auth
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package Dancer2::Plugin::Auth::Github; | |
use strict; | |
use warnings FATAL => 'all'; | |
use Carp 'croak'; | |
use Dancer2; | |
use Dancer2::Plugin; | |
use Digest::SHA qw(sha256_hex); | |
use LWP::UserAgent; | |
use JSON qw(decode_json); | |
our $VERSION = '0.01'; | |
my $client_id; | |
my $client_secret; | |
my $scope = ""; | |
my $github_redirect_url = 'https://github.com/login/oauth/authorize/'; | |
my $github_post_url = 'https://github.com/login/oauth/access_token/'; | |
my $github_auth_failed = '/auth/github/failed'; | |
my $github_auth_success = '/'; | |
my $state_salt = "RandomSalt"; | |
#dancer2 stuff. | |
#A method to initialize everything | |
register 'auth_github_init' => sub { | |
warn "auth github loaded"; | |
my $dsl = shift; | |
my $config = plugin_setting; | |
$client_id = $config->{client_id}; | |
$client_secret = $config->{client_secret}; | |
for my $param (qw/client_id client_secret/) { | |
croak "$param is expected but not found in configuration" | |
unless $config->{$param}; | |
} | |
#sthe following configs are optional. | |
if($config->{scope}) | |
{ | |
$scope = $config->{scope}; | |
} | |
#these configs have default values. | |
if($config->{github_auth_failed}) | |
{ | |
$github_auth_failed = $config->{github_auth_failed}; | |
} | |
if($config->{github_auth_success}) | |
{ | |
$github_auth_success = $config->{github_auth_success}; | |
} | |
#$dsl->debug 'Loaded config..'; | |
#registers this as a callback url | |
$dsl->app->add_route( | |
regexp => '/auth/github/callback', | |
code => sub { | |
my $generate_state = sha256_hex($client_id.$client_secret.$state_salt); | |
my $state_received = $dsl->params->{'state'}; | |
if($state_received eq $generate_state) { | |
warn("State received correctly."); | |
my $code = $dsl->params->{'code'}; | |
my $browser = LWP::UserAgent->new; | |
my $resp = $browser->post($github_post_url, | |
[ | |
client_id => $client_id, | |
client_secret => $client_secret, | |
code => $code, | |
state => $state_received | |
]); | |
die "error while fetching: ", $resp->status_line | |
unless $resp->is_success; | |
my %querystr = parse_query_str($resp->decoded_content); | |
my $acc = $querystr{access_token}; | |
warn "got access token? $acc"; | |
if($acc) { | |
my $jresp = $browser->get("https://api.github.com/user?access_token=$acc"); | |
my $json = decode_json($jresp->decoded_content); | |
warn("setting session"); | |
$dsl->session(github_user => $json); | |
warn Data::Dumper::Dumper($dsl->app->session('github_user')); | |
$dsl->session(github_access_token => $acc); | |
#session 'logged_in' => true; | |
warn("before redirect"); | |
$dsl->redirect($github_auth_success); | |
return; | |
} | |
} | |
$dsl->redirect($github_auth_failed); | |
}, | |
method => 'get'); | |
}; | |
#returns the url you need to redirect to to authenticate on github | |
register 'auth_github_authenticate_url' => sub { | |
my $generate_state = sha256_hex($client_id.$client_secret.$state_salt); | |
return "$github_redirect_url?&client_id=$client_id&scope=$scope&state=$generate_state"; | |
}; | |
#helper method to parse query string. | |
sub parse_query_str { | |
my $str = shift; | |
my %in = (); | |
if (length ($str) > 0){ | |
my $buffer = $str; | |
my @pairs = split(/&/, $buffer); | |
foreach my $pair (@pairs){ | |
my ($name, $value) = split(/=/, $pair); | |
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; | |
$in{$name} = $value; | |
} | |
} | |
return %in; | |
} | |
register_plugin; | |
1; # End of Dancer::Plugin::Auth::Github |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment