Merge pull request #447 from coreos-inc/ronon

Add support for Dex to Quay
This commit is contained in:
josephschorr 2015-09-10 11:42:01 -04:00
commit edef283697
27 changed files with 533 additions and 176 deletions

View file

@ -1,3 +1,8 @@
.external-login-button i.fa {
.external-login-button i.fa,
.external-login-button img {
margin-right: 4px;
width: 24px;
font-size: 18px;
text-align: center;
vertical-align: middle;
}

View file

@ -6,6 +6,9 @@
font-size: 18px;
}
.external-logins-manager .external-auth-provider td:first-child i.fa {
.external-logins-manager .external-auth-provider-title i.fa,
.external-logins-manager .external-auth-provider-title img {
margin-right: 6px;
width: 24px;
text-align: center;
}

View file

@ -4,4 +4,14 @@
.signup-form-element .co-alert {
color: black;
}
.signup-form-element .single-sign-on a {
font-size: 24px;
}
.signup-form-element .single-sign-on .external-login-button i.fa,
.signup-form-element .single-sign-on .external-login-button img {
width: 30px;
font-size: 24px;
}

View file

@ -1,24 +1,14 @@
<span class="external-login-button-element">
<span ng-if="provider == 'github'">
<a href="javascript:void(0)" ng-class="isLink ? '' : 'btn btn-primary btn-block'" quay-require="['GITHUB_LOGIN']" ng-click="startSignin('github')" style="margin-bottom: 10px" ng-disabled="signingIn">
<i class="fa fa-github fa-lg"></i>
<span ng-if="action != 'attach'">
Sign In with GitHub
<span ng-if="isEnterprise('github')">Enterprise</span>
</span>
<span ng-if="action == 'attach'">
Attach to GitHub
<span ng-if="isEnterprise('github')">Enterprise</span>
Account
</span>
</a>
</span>
<span ng-if="provider == 'google'">
<a href="javascript:void(0)" ng-class="isLink ? '' : 'btn btn-primary btn-block'" quay-require="['GOOGLE_LOGIN']" ng-click="startSignin('google')" ng-disabled="signingIn">
<i class="fa fa-google fa-lg"></i>
<span ng-if="action != 'attach'">Sign In with Google</span>
<span ng-if="action == 'attach'">Attach to Google Account</span>
</a>
</span>
<a href="javascript:void(0)" ng-class="isLink ? '' : 'btn btn-primary btn-block'"
ng-if="providerInfo.enabled" ng-click="startSignin()" style="margin-bottom: 10px"
ng-disabled="signingIn">
<img ng-src="{{ providerInfo.icon().url }}" ng-if="providerInfo.icon().url">
<i class="fa" ng-class="providerInfo.icon().icon" ng-if="providerInfo.icon().icon"></i>
<span ng-if="action != 'attach'">
Sign In with {{ providerInfo.title() }}
</span>
<span ng-if="action == 'attach'">
Attach to {{ providerInfo.title() }}
</span>
</a>
</span>

View file

@ -9,52 +9,35 @@
<thead>
<td>Provider</td>
<td>Account Status</td>
<td>Attach/Detach</td>
<td quay-show="Features.DIRECT_LOGIN">Attach/Detach</td>
</thead>
<!-- GitHub Login -->
<tr class="external-auth-provider" ng-show="Features.GITHUB_LOGIN">
<td>
<i class="fa fa-github"></i> GitHub <span ng-if="KeyService.isEnterprise('github')">Enterprise</span>
<tr class="external-auth-provider" ng-repeat="provider in EXTERNAL_LOGINS">
<td class="external-auth-provider-title">
<img ng-src="{{ provider.icon().url }}" ng-if="provider.icon().url">
<i class="fa" ng-class="provider.icon().icon" ng-if="provider.icon().icon"></i>
{{ provider.title() }}
</td>
<td>
<span ng-if="hasGithubLogin">
Attached to GitHub <span ng-if="KeyService.isEnterprise('github')">Enterprise</span> account <b><a href="{{githubEndpoint}}{{githubLogin}}" target="_blank">{{githubLogin}}</a></b>
<span ng-if="externalLoginInfo[provider.id]">
Attached to {{ provider.title() }} account
<b ng-if="provider.hasUserInfo">
<a ng-href="{{ provider.getUserInfo(externalLoginInfo[provider.id]).endpoint }}" target="_blank">
{{ provider.getUserInfo(externalLoginInfo[provider.id]).username }}
</a>
</b>
</span>
<span class="empty" ng-if="!hasGithubLogin">
(Not attached to GitHub<span ng-if="KeyService.isEnterprise('github')"> Enterprise</span>)
<span class="empty" ng-if="!externalLoginInfo[provider.id]">
Not attached to {{ provider.title() }}
</span>
</td>
<td>
<span class="external-login-button" provider="github" action="attach" is-link="true"
ng-if="!hasGithubLogin"></span>
<a href="javascript:void(0)" ng-if="hasGithubLogin"
ng-click="detachExternalLogin('github')">Detach Account</a>
</td>
</tr>
<!-- Google Login -->
<tr class="external-auth-provider" ng-show="Features.GOOGLE_LOGIN">
<td>
<i class="fa fa-google"></i> Google Account
</td>
<td>
<span ng-if="hasGoogleLogin">
Attached to Google account <b>{{ googleLogin }}</b>
</span>
<span class="empty" ng-if="!hasGoogleLogin">
(Not attached to a Google account)
</span>
</td>
<td>
<span class="external-login-button" provider="google" action="attach" is-link="true"
ng-if="!hasGoogleLogin"></span>
<a href="javascript:void(0)" ng-if="hasGoogleLogin"
ng-click="detachExternalLogin('google')">Detach Account</a>
<span class="external-login-button" provider="{{ provider.id }}" action="attach" is-link="true"
ng-if="!externalLoginInfo[provider.id]"></span>
<a href="javascript:void(0)" ng-if="externalLoginInfo[provider.id] && Features.DIRECT_LOGIN"
ng-click="detachExternalLogin(provider.id)">Detach Account</a>
</td>
</tr>
</table>

View file

@ -42,7 +42,8 @@
</a>
</li>
<li ng-switch-default>
<a class="user-view" href="/signin/" target="{{ appLinkTarget() }}">Sign in</a>
<a class="user-view" href="/signin/" target="{{ appLinkTarget() }}" ng-if="!externalSigninUrl">Sign in</a>
<a class="user-view" ng-href="{{ externalSigninUrl }}" ng-if="externalSigninUrl">Sign in</a>
</li>
</ul>
@ -133,7 +134,8 @@
</ul>
</li>
<li ng-switch-default>
<a class="user-view" href="/signin/" target="{{ appLinkTarget() }}">Sign in</a>
<a class="user-view" href="/signin/" target="{{ appLinkTarget() }}" ng-if="!externalSigninUrl">Sign in</a>
<a class="user-view" ng-href="{{ externalSigninUrl }}" ng-if="externalSigninUrl">Sign in</a>
</li>
</ul>
</div><!-- /.navbar-collapse -->

View file

@ -1,25 +1,28 @@
<div class="signin-form-element" style="position: relative">
<span class="cor-loader" ng-show="signingIn"></span>
<form class="form-signin" ng-submit="signin();" ng-show="!signingIn">
<input type="text" class="form-control input-lg" name="username"
placeholder="Username or E-mail Address" ng-model="user.username" autofocus>
<input type="password" class="form-control input-lg" name="password"
placeholder="Password" ng-model="user.password">
<div quay-show="Features.DIRECT_LOGIN">
<input type="text" class="form-control input-lg" name="username"
placeholder="Username or E-mail Address" ng-model="user.username" autofocus>
<input type="password" class="form-control input-lg" name="password"
placeholder="Password" ng-model="user.password">
</div>
<div class="co-alert co-alert-warning" ng-show="tryAgainSoon > 0">
Too many attempts have been made to login. Please try again in {{ tryAgainSoon }} second<span ng-if="tryAgainSoon != 1">s</span>.
</div>
<span ng-show="tryAgainSoon == 0">
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign In</button>
<button class="btn btn-lg btn-primary btn-block" type="submit" quay-show="Features.DIRECT_LOGIN">Sign In</button>
<span class="social-alternate" quay-show="Features.GITHUB_LOGIN || Features.GOOGLE_LOGIN">
<span class="social-alternate" quay-show="EXTERNAL_LOGINS.length && Features.DIRECT_LOGIN">
<i class="fa fa-circle"></i>
<span class="inner-text">OR</span>
</span>
<div class="external-login-button" provider="github" redirect-url="redirectUrl" sign-in-started="markStarted()"></div>
<div class="external-login-button" provider="google" redirect-url="redirectUrl" sign-in-started="markStarted()"></div>
<div class="external-login-button" provider="{{ provider.id }}" redirect-url="redirectUrl"
sign-in-started="markStarted()" ng-repeat="provider in EXTERNAL_LOGINS"></div>
</span>
</form>

View file

@ -1,32 +1,39 @@
<div class="signup-form-element"
quay-show="Features.USER_CREATION && Config.AUTHENTICATION_TYPE == 'Database'">
<form class="form-signup" name="signupForm" ng-submit="register()" ng-show="!awaitingConfirmation && !registering">
<input type="text" class="form-control" placeholder="Create a username" name="username" ng-model="newUser.username" autofocus required ng-pattern="/^[a-z0-9_]{4,30}$/">
<input type="email" class="form-control" placeholder="Email address" ng-model="newUser.email" required>
<input type="password" class="form-control" placeholder="Create a password" ng-model="newUser.password" required
ng-pattern="/^.{8,}$/">
<input type="password" class="form-control" placeholder="Verify your password" ng-model="newUser.repeatPassword"
match="newUser.password" required
ng-pattern="/^.{8,}$/">
<div class="form-group signin-buttons">
<button id="signupButton"
class="btn btn-primary btn-block landing-signup-button" ng-disabled="signupForm.$invalid" type="submit"
analytics-on analytics-event="register">
<span quay-show="Features.BILLING">Sign Up for Free!</span>
<span quay-show="!Features.BILLING">Sign Up</span>
</button>
<span class="social-alternate" quay-require="['GITHUB_LOGIN']">
<i class="fa fa-circle"></i>
<span class="inner-text">OR</span>
</span>
<div class="external-login-button" provider="github"></div>
<div class="external-login-button" provider="google"></div>
<div class="signup-form-element">
<div quay-show="singleSigninUrl" class="single-sign-on">
<div class="external-login-button" provider="{{ EXTERNAL_LOGINS[0].id }}"></div>
</div>
<div quay-show="Features.USER_CREATION && Config.AUTHENTICATION_TYPE == 'Database' && !singleSigninUrl">
<form class="form-signup" name="signupForm" ng-submit="register()" ng-show="!awaitingConfirmation && !registering">
<div quay-show="Features.DIRECT_LOGIN">
<input type="text" class="form-control" placeholder="Create a username" name="username" ng-model="newUser.username" autofocus required ng-pattern="/^[a-z0-9_]{4,30}$/">
<input type="email" class="form-control" placeholder="Email address" ng-model="newUser.email" required>
<input type="password" class="form-control" placeholder="Create a password" ng-model="newUser.password" required
ng-pattern="/^.{8,}$/">
<input type="password" class="form-control" placeholder="Verify your password" ng-model="newUser.repeatPassword"
match="newUser.password" required
ng-pattern="/^.{8,}$/">
</div>
<div class="form-group signin-buttons">
<button id="signupButton"
class="btn btn-primary btn-block landing-signup-button" ng-disabled="signupForm.$invalid" type="submit"
analytics-on analytics-event="register"
quay-show="Features.DIRECT_LOGIN">
<span quay-show="Features.BILLING">Sign Up for Free!</span>
<span quay-show="!Features.BILLING">Sign Up</span>
</button>
<span class="social-alternate" quay-show="Features.DIRECT_LOGIN && EXTERNAL_LOGINS.length">
<i class="fa fa-circle"></i>
<span class="inner-text">OR</span>
</span>
<div class="external-login-button" provider="{{ provider.id }}" ng-repeat="provider in EXTERNAL_LOGINS"></div>
</div>
</form>
<div class="cor-loader" ng-show="registering"></div>
<div class="co-alert co-alert-info"
ng-show="awaitingConfirmation && hideRegisteredMessage != 'true'">
Thank you for registering! We have sent you an activation email.
You must <b>verify your email address</b> before you can continue.
</div>
</form>
<div class="cor-loader" ng-show="registering"></div>
<div class="co-alert co-alert-info"
ng-show="awaitingConfirmation && hideRegisteredMessage != 'true'">
Thank you for registering! We have sent you an activation email.
You must <b>verify your email address</b> before you can continue.
</div>
</div>

View file

@ -15,7 +15,7 @@
</div>
</div>
<div class="panel panel-default"
quay-show="Features.USER_CREATION && Config.AUTHENTICATION_TYPE == 'Database'">
quay-show="Features.USER_CREATION && Config.AUTHENTICATION_TYPE == 'Database' && Features.DIRECT_LOGIN">
<div class="panel-heading">
<h6 class="panel-title accordion-title">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion" data-target="#collapseRegister">
@ -30,7 +30,7 @@
</div>
</div>
<div class="panel panel-default"
quay-show="Features.MAILING && Config.AUTHENTICATION_TYPE == 'Database'">
quay-show="Features.MAILING && Config.AUTHENTICATION_TYPE == 'Database' && Features.DIRECT_LOGIN">
<div class="panel-heading">
<h6 class="panel-title accordion-title">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion" data-target="#collapseForgot">

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');

View file

@ -8,7 +8,12 @@
});
}]);
function SignInCtrl($scope, $location) {
function SignInCtrl($scope, $location, ExternalLoginService, Features) {
$scope.redirectUrl = '/';
var singleUrl = ExternalLoginService.getSingleSigninUrl();
if (singleUrl) {
document.location = singleUrl;
}
}
})();

View file

@ -10,7 +10,7 @@
})
}]);
function UserViewCtrl($scope, $routeParams, $timeout, ApiService, UserService, UIService, AvatarService, Config) {
function UserViewCtrl($scope, $routeParams, $timeout, ApiService, UserService, UIService, AvatarService, Config, ExternalLoginService) {
var username = $routeParams.username;
$scope.showInvoicesCounter = 0;
@ -18,6 +18,7 @@
$scope.showRobotsCounter = 0;
$scope.changeEmailInfo = {};
$scope.changePasswordInfo = {};
$scope.hasSingleSignin = ExternalLoginService.hasSingleSignin();
UserService.updateUserIn($scope);

View file

@ -0,0 +1,141 @@
/**
* Service which exposes the supported external logins.
*/
angular.module('quay').factory('ExternalLoginService', ['KeyService', 'Features', 'Config',
function(KeyService, Features, Config) {
var externalLoginService = {};
externalLoginService.getLoginUrl = function(service, action) {
var serviceInfo = externalLoginService.getProvider(service);
if (!serviceInfo) { return ''; }
var stateClause = '';
if (Config.MIXPANEL_KEY && window.mixpanel) {
if (mixpanel.get_distinct_id !== undefined) {
stateClause = "&state=" + encodeURIComponent(mixpanel.get_distinct_id());
}
}
var loginUrl = KeyService.getConfiguration(serviceInfo.key, 'AUTHORIZE_ENDPOINT');
var clientId = KeyService.getConfiguration(serviceInfo.key, 'CLIENT_ID');
var scope = serviceInfo.scopes();
var redirectUri = Config.getUrl('/oauth2/' + service + '/callback');
if (action == 'attach') {
redirectUri += '/attach';
}
var url = loginUrl + 'client_id=' + clientId + '&scope=' + scope + '&redirect_uri=' +
redirectUri + stateClause;
return url;
};
var DEX = {
id: 'dex',
key: 'DEX_LOGIN_CONFIG',
title: function() {
return KeyService.getConfiguration('DEX_LOGIN_CONFIG', 'OIDC_TITLE');
},
icon: function() {
return {'url': KeyService.getConfiguration('DEX_LOGIN_CONFIG', 'OIDC_LOGO') };
},
scopes: function() {
return 'openid email profile'
},
enabled: Features.DEX_LOGIN
};
var GITHUB = {
id: 'github',
key: 'GITHUB_LOGIN_CONFIG',
title: function() {
return KeyService.isEnterprise('github') ? 'GitHub Enterprise' : 'GitHub';
},
icon: function() {
return {'icon': 'fa-github'};
},
hasUserInfo: true,
getUserInfo: function(service_info) {
username = service_info['metadata']['service_username'];
return {
'username': username,
'endpoint': KeyService['githubEndpoint'] + username
}
},
scopes: function() {
var scopes = 'user:email';
if (KeyService.getConfiguration('GITHUB_LOGIN_CONFIG', 'ORG_RESTRICT')) {
scopes += ' read:org';
}
return scopes;
},
enabled: Features.GITHUB_LOGIN
};
var GOOGLE = {
id: 'google',
key: 'GOOGLE_LOGIN_CONFIG',
title: function() {
return 'Google';
},
icon: function() {
return {'icon': 'fa-google'};
},
scopes: function() {
return 'openid email';
},
enabled: Features.GOOGLE_LOGIN
};
externalLoginService.ALL_EXTERNAL_LOGINS = [
DEX, GITHUB, GOOGLE
];
externalLoginService.EXTERNAL_LOGINS = externalLoginService.ALL_EXTERNAL_LOGINS.filter(function(el) {
return el.enabled;
});
externalLoginService.getProvider = function(providerId) {
for (var i = 0; i < externalLoginService.EXTERNAL_LOGINS.length; ++i) {
var current = externalLoginService.EXTERNAL_LOGINS[i];
if (current.id == providerId) {
return current;
}
}
return null;
};
externalLoginService.hasSingleSignin = function() {
return externalLoginService.EXTERNAL_LOGINS.length == 1 && !Features.DIRECT_LOGIN;
};
externalLoginService.getSingleSigninUrl = function() {
// If there is a single external login service and direct login is disabled,
// then redirect to the external login directly.
if (externalLoginService.hasSingleSignin()) {
return externalLoginService.getLoginUrl(externalLoginService.EXTERNAL_LOGINS[0].id);
}
return null;
};
return externalLoginService;
}]);

View file

@ -10,35 +10,26 @@ angular.module('quay').factory('KeyService', ['$location', 'Config', function($l
keyService['gitlabTriggerClientId'] = oauth['GITLAB_TRIGGER_CONFIG']['CLIENT_ID'];
keyService['githubTriggerClientId'] = oauth['GITHUB_TRIGGER_CONFIG']['CLIENT_ID'];
keyService['githubLoginClientId'] = oauth['GITHUB_LOGIN_CONFIG']['CLIENT_ID'];
keyService['googleLoginClientId'] = oauth['GOOGLE_LOGIN_CONFIG']['CLIENT_ID'];
keyService['gitlabRedirectUri'] = Config.getUrl('/oauth2/gitlab/callback');
keyService['githubRedirectUri'] = Config.getUrl('/oauth2/github/callback');
keyService['googleRedirectUri'] = Config.getUrl('/oauth2/google/callback');
keyService['githubLoginUrl'] = oauth['GITHUB_LOGIN_CONFIG']['AUTHORIZE_ENDPOINT'];
keyService['googleLoginUrl'] = oauth['GOOGLE_LOGIN_CONFIG']['AUTHORIZE_ENDPOINT'];
keyService['githubEndpoint'] = oauth['GITHUB_LOGIN_CONFIG']['GITHUB_ENDPOINT'];
keyService['githubTriggerEndpoint'] = oauth['GITHUB_TRIGGER_CONFIG']['GITHUB_ENDPOINT'];
keyService['githubTriggerAuthorizeUrl'] = oauth['GITHUB_TRIGGER_CONFIG']['AUTHORIZE_ENDPOINT'];
keyService['gitlabTriggerEndpoint'] = oauth['GITLAB_TRIGGER_CONFIG']['GITLAB_ENDPOINT'];
keyService['gitlabTriggerAuthorizeUrl'] = oauth['GITLAB_TRIGGER_CONFIG']['AUTHORIZE_ENDPOINT'];
keyService['githubLoginScope'] = 'user:email';
if (oauth['GITHUB_LOGIN_CONFIG']['ORG_RESTRICT']) {
keyService['githubLoginScope'] += ',read:org';
}
keyService['googleLoginScope'] = 'openid email';
keyService.getConfiguration = function(parent, key) {
return oauth[parent][key];
};
keyService.isEnterprise = function(service) {
switch (service) {
case 'github':
return keyService['githubLoginUrl'].indexOf('https://github.com/') < 0;
var loginUrl = oauth['GITHUB_LOGIN_CONFIG']['AUTHORIZE_ENDPOINT'];
return loginUrl.indexOf('https://github.com/') < 0;
case 'github-trigger':
return keyService['githubTriggerAuthorizeUrl'].indexOf('https://github.com/') < 0;
@ -47,26 +38,5 @@ angular.module('quay').factory('KeyService', ['$location', 'Config', function($l
return false;
};
keyService.getExternalLoginUrl = function(service, action) {
var state_clause = '';
if (Config.MIXPANEL_KEY && window.mixpanel) {
if (mixpanel.get_distinct_id !== undefined) {
state_clause = "&state=" + encodeURIComponent(mixpanel.get_distinct_id());
}
}
var client_id = keyService[service + 'LoginClientId'];
var scope = keyService[service + 'LoginScope'];
var redirect_uri = keyService[service + 'RedirectUri'];
if (action == 'attach') {
redirect_uri += '/attach';
}
var url = keyService[service + 'LoginUrl'] + 'client_id=' + client_id + '&scope=' + scope +
'&redirect_uri=' + redirect_uri + state_clause;
return url;
};
return keyService;
}]);

View file

@ -43,7 +43,8 @@
tab-init="showInvoices()" quay-show="Features.BILLING">
<i class="fa ci-invoice"></i>
</span>
<span class="cor-tab" tab-title="External Logins" tab-target="#external">
<span class="cor-tab" tab-title="External Logins" tab-target="#external"
quay-show="!hasSingleSignin">
<i class="fa fa-external-link-square"></i>
</span>
<span class="cor-tab" tab-title="Authorized Applications" tab-target="#applications"
@ -70,7 +71,7 @@
</div>
<!-- External Logins -->
<div id="external" class="tab-pane">
<div id="external" class="tab-pane" quay-show="!hasSingleSignin">
<div class="external-logins-manager" user="viewuser"></div>
</div>