Implement GitHub logins

Requires the following configuration options
enable_github_login = 1
github_client_id
github_client_secret
Or github_client_secret_file which points to a file with the secret
This commit is contained in:
Jelle Besseling
2020-12-26 17:58:16 +01:00
parent bde8d81876
commit bbd4891133
5 changed files with 68 additions and 10 deletions

View File

@ -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\//;

View File

@ -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,57 @@ 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) = @_;
error($c, "Logging in via GitHub is not enabled.") unless $c->config->{enable_github_login};
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', 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", $data->{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) = @_;
error($c, "Logging in via GitHub is not enabled.") unless $c->config->{enable_github_login};
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");
}
sub captcha :Local Args(0) {
my ($self, $c) = @_;