Merge pull request #841 from pingiun/github-login
Implement GitHub logins
This commit is contained in:
@ -30,6 +30,8 @@ sub noLoginNeeded {
|
||||
return $whitelisted ||
|
||||
$c->request->path eq "api/push-github" ||
|
||||
$c->request->path eq "google-login" ||
|
||||
$c->request->path eq "github-redirect" ||
|
||||
$c->request->path eq "github-login" ||
|
||||
$c->request->path eq "login" ||
|
||||
$c->request->path eq "logo" ||
|
||||
$c->request->path =~ /^static\//;
|
||||
|
@ -4,6 +4,7 @@ use utf8;
|
||||
use strict;
|
||||
use warnings;
|
||||
use base 'Hydra::Base::Controller::REST';
|
||||
use File::Slurp;
|
||||
use Crypt::RandPasswd;
|
||||
use Digest::SHA1 qw(sha1_hex);
|
||||
use Hydra::Helper::Nix;
|
||||
@ -154,6 +155,67 @@ sub google_login :Path('/google-login') Args(0) {
|
||||
doEmailLogin($self, $c, "google", $data->{email}, $data->{name} // undef);
|
||||
}
|
||||
|
||||
sub github_login :Path('/github-login') Args(0) {
|
||||
my ($self, $c) = @_;
|
||||
|
||||
my $client_id = $c->config->{github_client_id} or die "github_client_id not configured.";
|
||||
my $client_secret = $c->config->{github_client_secret} // do {
|
||||
my $client_secret_file = $c->config->{github_client_secret_file} or die "github_client_secret nor github_client_secret_file is configured.";
|
||||
my $client_secret = read_file($client_secret_file);
|
||||
$client_secret =~ s/\s+//;
|
||||
$client_secret;
|
||||
};
|
||||
die "No github secret configured" unless $client_secret;
|
||||
|
||||
my $ua = new LWP::UserAgent;
|
||||
my $response = $ua->post(
|
||||
'https://github.com/login/oauth/access_token',
|
||||
{
|
||||
client_id => $client_id,
|
||||
client_secret => $client_secret,
|
||||
code => ($c->req->params->{code} // die "No token."),
|
||||
}, Accept => 'application/json');
|
||||
error($c, "Did not get a response from GitHub.") unless $response->is_success;
|
||||
|
||||
my $data = decode_json($response->decoded_content) or die;
|
||||
my $access_token = $data->{access_token} // die "No access_token in response from GitHub.";
|
||||
|
||||
$response = $ua->get('https://api.github.com/user/emails', Accept => 'application/vnd.github.v3+json', Authorization => "token $access_token");
|
||||
error($c, "Did not get a response from GitHub for email info.") unless $response->is_success;
|
||||
|
||||
$data = decode_json($response->decoded_content) or die;
|
||||
my $email;
|
||||
|
||||
foreach my $eml (@{$data}) {
|
||||
$email = $eml->{email} if $eml->{verified} && $eml->{primary};
|
||||
}
|
||||
|
||||
die "No primary email for this GitHub profile" unless $email;
|
||||
|
||||
$response = $ua->get('https://api.github.com/user', Authorization => "token $access_token");
|
||||
error($c, "Did not get a response from GitHub for user info.") unless $response->is_success;
|
||||
$data = decode_json($response->decoded_content) or die;
|
||||
|
||||
doEmailLogin($self, $c, "github", $email, $data->{name} // undef);
|
||||
|
||||
$c->res->redirect($c->uri_for($c->res->cookies->{'after_github'}));
|
||||
}
|
||||
|
||||
sub github_redirect :Path('/github-redirect') Args(0) {
|
||||
my ($self, $c) = @_;
|
||||
|
||||
my $client_id = $c->config->{github_client_id} or die "github_client_id not configured.";
|
||||
|
||||
my $after = "/" . $c->req->params->{after};
|
||||
|
||||
$c->res->cookies->{'after_github'} = {
|
||||
name => 'after_github',
|
||||
value => $after,
|
||||
};
|
||||
|
||||
$c->res->redirect("https://github.com/login/oauth/authorize?client_id=$client_id&scope=user:email");
|
||||
}
|
||||
|
||||
|
||||
sub captcha :Local Args(0) {
|
||||
my ($self, $c) = @_;
|
||||
|
Reference in New Issue
Block a user