Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: NixOS/hydra
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 20d09518f867
Choose a base ref
...
head repository: NixOS/hydra
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: be0aa7eb8589
Choose a head ref
  • 8 commits
  • 5 files changed
  • 2 contributors

Commits on Dec 28, 2020

  1. 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
    pingiun committed Dec 28, 2020
    Copy the full SHA
    bbd4891 View commit details

Commits on Dec 31, 2020

  1. Use email api call

    pingiun committed Dec 31, 2020
    Copy the full SHA
    e88355b View commit details
  2. Use email scope

    pingiun committed Dec 31, 2020
    Copy the full SHA
    5f4eddb View commit details

Commits on Jan 4, 2021

  1. Update src/lib/Hydra/Controller/User.pm

    Co-authored-by: Eelco Dolstra <edolstra@gmail.com>
    pingiun and edolstra authored Jan 4, 2021
    Copy the full SHA
    19f9d82 View commit details
  2. Update src/lib/Hydra/Controller/User.pm

    Co-authored-by: Eelco Dolstra <edolstra@gmail.com>
    pingiun and edolstra authored Jan 4, 2021
    Copy the full SHA
    20d8134 View commit details
  3. Die when no email is found

    pingiun committed Jan 4, 2021
    Copy the full SHA
    c49ca66 View commit details
  4. Don't use enable_github_login option after all

    Instead the github_client_id option is used to detect if github logins
    should be enabled.
    pingiun committed Jan 4, 2021
    Copy the full SHA
    43d662f View commit details

Commits on Jan 5, 2021

  1. Merge pull request #841 from pingiun/github-login

    Implement GitHub logins
    edolstra authored Jan 5, 2021
    Copy the full SHA
    be0aa7e View commit details
Showing with 78 additions and 10 deletions.
  1. +2 −0 src/lib/Hydra/Controller/Root.pm
  2. +62 −0 src/lib/Hydra/Controller/User.pm
  3. +4 −0 src/root/topbar.tt
  4. +9 −9 src/script/hydra-create-user
  5. +1 −1 src/sql/hydra.sql
2 changes: 2 additions & 0 deletions src/lib/Hydra/Controller/Root.pm
Original file line number Diff line number Diff line change
@@ -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\//;
62 changes: 62 additions & 0 deletions src/lib/Hydra/Controller/User.pm
Original file line number Diff line number Diff line change
@@ -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) = @_;
4 changes: 4 additions & 0 deletions src/root/topbar.tt
Original file line number Diff line number Diff line change
@@ -136,6 +136,10 @@
<li><a href="#" id="google-signin">Sign in with Google</a></li>
<li class="divider"></li>
[% END %]
[% IF c.config.github_client_id %]
<li><a href="/github-redirect?after=[% c.req.path %]">Sign in with GitHub</a></li>
<li class="divider"></li>
[% END %]
<li>
<a href="#hydra-signin" data-toggle="modal">Sign in with a Hydra account</a>
</li>
18 changes: 9 additions & 9 deletions src/script/hydra-create-user
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@ sub showHelp {
print <<EOF;
Usage: $0 NAME
[--rename-from NAME]
[--type hydra|google]
[--type hydra|google|github]
[--full-name FULLNAME]
[--email-address EMAIL-ADDRESS]
[--password PASSWORD]
@@ -49,8 +49,8 @@ GetOptions("rename-from=s" => \$renameFrom,
die "$0: one user name required\n" if scalar @ARGV != 1;
my $userName = $ARGV[0];

die "$0: type must be `hydra' or `google'\n"
if defined $type && $type ne "hydra" && $type ne "google";
die "$0: type must be `hydra', `google' or `github'\n"
if defined $type && $type ne "hydra" && $type ne "google" && $type ne "github";

my $db = Hydra::Model::DB->new();

@@ -67,19 +67,19 @@ $db->txn_do(sub {
{ username => $userName, type => "hydra", emailaddress => "", password => "!" });
}

die "$0: Google user names must be email addresses\n"
if $user->type eq "google" && $userName !~ /\@/;
die "$0: Google or GitHub user names must be email addresses\n"
if ($user->type eq "google" || $user->type eq "github") && $userName !~ /\@/;

$user->update({ type => $type }) if defined $type;

$user->update({ fullname => $fullName eq "" ? undef : $fullName }) if defined $fullName;

if ($user->type eq "google") {
die "$0: Google accounts do not have an explicitly set email address.\n"
if ($user->type eq "google" || $user->type eq "github") {
die "$0: Google and GitHub accounts do not have an explicitly set email address.\n"
if defined $emailAddress;
die "$0: Google accounts do not have a password.\n"
die "$0: Google and GitHub accounts do not have a password.\n"
if defined $password;
die "$0: Google accounts do not have a password.\n"
die "$0: Google and GitHub accounts do not have a password.\n"
if defined $passwordHash;
$user->update({ emailaddress => $userName, password => "!" });
} else {
2 changes: 1 addition & 1 deletion src/sql/hydra.sql
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@ create table Users (
emailAddress text not null,
password text not null, -- sha256 hash
emailOnError integer not null default 0,
type text not null default 'hydra', -- either "hydra" or "google"
type text not null default 'hydra', -- either "hydra", "google" or "github"
publicDashboard boolean not null default false
);