Add support for Dex to Quay

Fixes #306

- Adds support for Dex as an OAuth external login provider
- Adds support for OIDC in general
- Extract out external logins on the JS side into a service
- Add a feature flag for disabling direct login
- Add support for directing to the single external login service
- Does *not* yet support the config in the superuser tool
This commit is contained in:
Joseph Schorr 2015-09-04 16:14:46 -04:00
parent 46f150cafb
commit c0286d1ac3
27 changed files with 533 additions and 176 deletions

View file

@ -15,14 +15,14 @@ angular.module('quay').directive('externalLoginButton', function () {
'provider': '@provider',
'action': '@action'
},
controller: function($scope, $timeout, $interval, ApiService, KeyService, CookieService, Features, Config) {
controller: function($scope, $timeout, $interval, ApiService, KeyService, CookieService, ExternalLoginService) {
$scope.signingIn = false;
$scope.isEnterprise = KeyService.isEnterprise;
$scope.providerInfo = ExternalLoginService.getProvider($scope.provider);
$scope.startSignin = function(service) {
$scope.signInStarted({'service': service});
$scope.startSignin = function() {
$scope.signInStarted({'service': $scope.provider});
var url = KeyService.getExternalLoginUrl(service, $scope.action || 'login');
var url = ExternalLoginService.getLoginUrl($scope.provider, $scope.action || 'login');
// Save the redirect URL in a cookie so that we can redirect back after the service returns to us.
var redirectURL = $scope.redirectUrl || window.location.toString();

View file

@ -11,41 +11,37 @@ angular.module('quay').directive('externalLoginsManager', function () {
scope: {
'user': '=user',
},
controller: function($scope, $element, ApiService, UserService, Features, Config, KeyService) {
controller: function($scope, $element, ApiService, UserService, Features, Config, KeyService,
ExternalLoginService) {
$scope.Features = Features;
$scope.Config = Config;
$scope.KeyService = KeyService;
$scope.EXTERNAL_LOGINS = ExternalLoginService.EXTERNAL_LOGINS;
$scope.externalLoginInfo = {};
$scope.hasSingleSignin = ExternalLoginService.hasSingleSignin();
UserService.updateUserIn($scope, function(user) {
$scope.cuser = jQuery.extend({}, user);
$scope.externalLoginInfo = {};
if ($scope.cuser.logins) {
for (var i = 0; i < $scope.cuser.logins.length; i++) {
var login = $scope.cuser.logins[i];
login.metadata = login.metadata || {};
if (login.service == 'github') {
$scope.hasGithubLogin = true;
$scope.githubLogin = login.metadata['service_username'];
$scope.githubEndpoint = KeyService['githubEndpoint'];
}
if (login.service == 'google') {
$scope.hasGoogleLogin = true;
$scope.googleLogin = login.metadata['service_username'];
}
$scope.externalLoginInfo[login.service] = login;
}
}
});
$scope.detachExternalLogin = function(kind) {
if (!Features.DIRECT_LOGIN) { return; }
var params = {
'servicename': kind
};
ApiService.detachExternalLogin(null, params).then(function() {
$scope.hasGithubLogin = false;
$scope.hasGoogleLogin = false;
UserService.load();
}, ApiService.errorDisplay('Count not detach service'));
};

View file

@ -14,7 +14,10 @@ angular.module('quay').directive('headerBar', function () {
},
controller: function($rootScope, $scope, $element, $location, $timeout, hotkeys, UserService,
PlanService, ApiService, NotificationService, Config, CreateService, Features,
DocumentationService) {
DocumentationService, ExternalLoginService) {
$scope.externalSigninUrl = ExternalLoginService.getSingleSigninUrl();
var hotkeysAdded = false;
var userUpdated = function(cUser) {
$scope.searchingAllowed = Features.ANONYMOUS_ACCESS || !cUser.anonymous;

View file

@ -14,10 +14,12 @@ angular.module('quay').directive('signinForm', function () {
'signInStarted': '&signInStarted',
'signedIn': '&signedIn'
},
controller: function($scope, $location, $timeout, $interval, ApiService, KeyService, UserService, CookieService, Features, Config) {
controller: function($scope, $location, $timeout, $interval, ApiService, KeyService, UserService, CookieService, Features, Config, ExternalLoginService) {
$scope.tryAgainSoon = 0;
$scope.tryAgainInterval = null;
$scope.signingIn = false;
$scope.EXTERNAL_LOGINS = ExternalLoginService.EXTERNAL_LOGINS;
$scope.Features = Features;
$scope.markStarted = function() {
$scope.signingIn = true;
@ -45,7 +47,7 @@ angular.module('quay').directive('signinForm', function () {
});
$scope.signin = function() {
if ($scope.tryAgainSoon > 0) { return; }
if ($scope.tryAgainSoon > 0 || !Features.DIRECT_LOGIN) { return; }
$scope.markStarted();
$scope.cancelInterval();

View file

@ -13,11 +13,13 @@ angular.module('quay').directive('signupForm', function () {
'hideRegisteredMessage': '@hideRegisteredMessage',
'userRegistered': '&userRegistered'
},
controller: function($scope, $location, $timeout, ApiService, KeyService, UserService, Config, UIService) {
controller: function($scope, $location, $timeout, ApiService, KeyService, UserService, Config, UIService, ExternalLoginService) {
$('.form-signup').popover();
$scope.awaitingConfirmation = false;
$scope.registering = false;
$scope.EXTERNAL_LOGINS = ExternalLoginService.EXTERNAL_LOGINS;
$scope.singleSigninUrl = ExternalLoginService.getSingleSigninUrl();
$scope.register = function() {
UIService.hidePopover('#signupButton');