Add superuser config panel support for OIDC login

This commit is contained in:
Joseph Schorr 2017-02-28 16:18:34 -05:00
parent 157640e696
commit 1146b62c13
3 changed files with 265 additions and 125 deletions

View file

@ -431,6 +431,18 @@ a:focus {
border-top: 1px solid #eee; border-top: 1px solid #eee;
} }
.co-panel-body .co-panel-heading {
font-size: 120%;
border-bottom: 0px;
margin: 0px;
margin-bottom: -6px;
}
.co-panel-body .co-panel-body {
padding-left: 38px;
}
.config-bool-field-element input { .config-bool-field-element input {
margin-right: 6px; margin-right: 6px;
font-size: 24px; font-size: 24px;

View file

@ -525,17 +525,18 @@
</div> </div>
</div> <!-- /E-mail --> </div> <!-- /E-mail -->
<!-- Authentication --> <!-- Internal Authentication -->
<div class="co-panel"> <div class="co-panel">
<div class="co-panel-heading"> <div class="co-panel-heading">
<i class="fa fa-users"></i> Authentication <i class="fa fa-users"></i> Internal Authentication
</div> </div>
<div class="co-panel-body"> <div class="co-panel-body">
<div class="description"> <div class="description">
<p> <p>
Authentication for the registry can be handled by either the registry itself, LDAP or external JWT endpoint. Authentication for the registry can be handled by either the registry itself, LDAP or external JWT endpoint.
<br> </p>
Additional external authentication providers (such as GitHub) can be used on top of this choice. <p>
Additional <strong>external</strong> authentication providers (such as GitHub) can be used in addition for <strong>login into the UI</strong>.
</p> </p>
</div> </div>
@ -807,134 +808,204 @@
</tr> </tr>
</table> </table>
</div> </div>
</div> <!-- /Authentication --> </div> <!-- / Internal Authentication -->
<!-- GitHub Authentication --> <div class="co-panel"> <!-- External Authentication -->
<div class="co-panel">
<div class="co-panel-heading"> <div class="co-panel-heading">
<i class="fa fa-github"></i> GitHub (Enterprise) Authentication <i class="fa fa-id-card"></i> External Authorization (OAuth)
</div> </div>
<div class="co-panel-body"> <div class="co-panel-body">
<div class="description"> <!-- GitHub Authentication -->
<p> <div class="co-panel">
If enabled, users can use GitHub or GitHub Enterprise to authenticate to the registry. <div class="co-panel-heading">
</p> <i class="fa fa-github"></i> GitHub (Enterprise) Authentication
<p> </div>
<strong>Note:</strong> A registered GitHub (Enterprise) OAuth application is required. <div class="co-panel-body">
View instructions on how to <div class="description">
<a href="https://coreos.com/docs/enterprise-registry/github-app/" ng-safenewtab> <p>
Create an OAuth Application in GitHub If enabled, users can use GitHub or GitHub Enterprise to authenticate to the registry.
</a> </p>
</p> <p>
<strong>Note:</strong> A registered GitHub (Enterprise) OAuth application is required.
View instructions on how to
<a href="https://coreos.com/docs/enterprise-registry/github-app/" ng-safenewtab>
Create an OAuth Application in GitHub
</a>
</p>
</div>
<div class="config-bool-field" binding="config.FEATURE_GITHUB_LOGIN">
Enable GitHub Authentication
</div>
<table class="config-table" ng-if="config.FEATURE_GITHUB_LOGIN">
<tr>
<td>GitHub:</td>
<td>
<select class="form-control" ng-model="mapped.GITHUB_LOGIN_KIND">
<option value="hosted">GitHub.com</option>
<option value="enterprise">GitHub Enterprise</option>
</select>
</td>
</tr>
<tr ng-if="mapped.GITHUB_LOGIN_KIND == 'enterprise'">
<td>GitHub Endpoint:</td>
<td>
<span class="config-string-field"
binding="config.GITHUB_LOGIN_CONFIG.GITHUB_ENDPOINT"
placeholder="https://my.githubserver"
pattern="{{ GITHOST_REGEX }}">
</span>
<div class="help-text">
The GitHub Enterprise endpoint. Must start with http:// or https://.
</div>
</td>
</tr>
<tr>
<td>OAuth Client ID:</td>
<td>
<span class="config-string-field" binding="config.GITHUB_LOGIN_CONFIG.CLIENT_ID">
</span>
</td>
</tr>
<tr>
<td>OAuth Client Secret:</td>
<td>
<span class="config-string-field" binding="config.GITHUB_LOGIN_CONFIG.CLIENT_SECRET">
</span>
</td>
</tr>
<tr>
<td>Organization Filtering:</td>
<td>
<div class="config-bool-field" binding="config.GITHUB_LOGIN_CONFIG.ORG_RESTRICT">
Restrict By Organization Membership
</div>
<div class="help-text" style="margin-bottom: 20px;">
If enabled, only members of specified GitHub
<span ng-if="mapped.GITHUB_LOGIN_KIND == 'enterprise'">Enterprise</span> organizations will be allowed to login via GitHub
<span ng-if="mapped.GITHUB_LOGIN_KIND == 'enterprise'">Enterprise</span>.
</div>
<span class="config-list-field"
item-title="Organization ID"
binding="config.GITHUB_LOGIN_CONFIG.ALLOWED_ORGANIZATIONS"
ng-if="config.GITHUB_LOGIN_CONFIG.ORG_RESTRICT">
</span>
</td>
</tr>
</table>
</div>
</div> <!-- /GitHub Authentication -->
<!-- Google Authentication -->
<div class="co-panel">
<div class="co-panel-heading">
<i class="fa fa-google"></i> Google Authentication
</div>
<div class="co-panel-body">
<div class="description">
<p>
If enabled, users can use Google to authenticate to the registry.
</p>
<p>
<strong>Note:</strong> A registered Google OAuth application is required.
Visit the
<a href="https://console.developers.google.com" ng-safenewtab>
Google Developer Console
</a>
to register an application.
</p>
</div>
<div class="config-bool-field" binding="config.FEATURE_GOOGLE_LOGIN">
Enable Google Authentication
</div>
<table class="config-table" ng-if="config.FEATURE_GOOGLE_LOGIN">
<tr>
<td>OAuth Client ID:</td>
<td>
<span class="config-string-field" binding="config.GOOGLE_LOGIN_CONFIG.CLIENT_ID">
</span>
</td>
</tr>
<tr>
<td>OAuth Client Secret:</td>
<td>
<span class="config-string-field" binding="config.GOOGLE_LOGIN_CONFIG.CLIENT_SECRET">
</span>
</td>
</tr>
</table>
</div>
</div> <!-- /Google Authentication -->
<!-- Custom OIDC providers -->
<div class="co-panel" ng-repeat="provider in getOIDCProviders(config)">
<div class="co-panel-heading">
<span class="icon-image-view" value="{{ config[provider]['SERVICE_ICON'] || 'fa-user-circle' }}" style="margin-right: 6px;"></span>
{{ config[provider]['SERVICE_NAME'] || (getOIDCProviderId(provider) + ' Authentication') }}
<span style="display: inline-block; margin-left: 10px">(<a href="javascript:void(0)" ng-click="removeOIDCProvider(provider)">Delete</a>)</span>
</div>
<div class="co-panel-body">
<table class="config-table">
<tr>
<td class="non-input">Service ID:</td>
<td>
<code>{{ getOIDCProviderId(provider) }}</code>
</td>
</tr>
<tr>
<td>OIDC Server:</td>
<td>
<span class="config-string-field"
binding="config[provider].OIDC_SERVER"
placeholder="https://path/to/oidc/compliant/server"
pattern="https://.+">
</span>
<div class="help-text">
The URL of an OIDC-compliant server.
</div>
</td>
</tr>
<tr>
<td>Service Name:</td>
<td>
<span class="config-string-field"
binding="config[provider].SERVICE_NAME"
placeholder="My Authentication Service">
</span>
<div class="help-text">
The user friendly name to display for the service on the login page.
</div>
</td>
</tr>
<tr>
<td>Service Icon (optional):</td>
<td>
<span class="config-string-field"
binding="config[provider].SERVICE_ICON"
placeholder="URL of the icon to use for this service OR a font awesome CSS name"
is-optional="true">
</span>
<div class="help-text">
If specified, the icon to display for this login service on the login page. Can be either a URL to an icon or a CSS class name from <a href="http://fontawesome.io" ng-safenewtab>Font Awesome</a>
</div>
</td>
</tr>
</table>
</div>
</div> </div>
<div class="config-bool-field" binding="config.FEATURE_GITHUB_LOGIN"> <!-- Add Provider -->
Enable GitHub Authentication <a class="btn btn-default" ng-click="addOIDCProvider()" style="margin-right: 6px;">Add OIDC Provider</a>
</div> <a href="http://openid.net/connect/" ng-safenewtab>What is OIDC?</a>
<table class="config-table" ng-if="config.FEATURE_GITHUB_LOGIN">
<tr>
<td>GitHub:</td>
<td>
<select class="form-control" ng-model="mapped.GITHUB_LOGIN_KIND">
<option value="hosted">GitHub.com</option>
<option value="enterprise">GitHub Enterprise</option>
</select>
</td>
</tr>
<tr ng-if="mapped.GITHUB_LOGIN_KIND == 'enterprise'">
<td>GitHub Endpoint:</td>
<td>
<span class="config-string-field"
binding="config.GITHUB_LOGIN_CONFIG.GITHUB_ENDPOINT"
placeholder="https://my.githubserver"
pattern="{{ GITHOST_REGEX }}">
</span>
<div class="help-text">
The GitHub Enterprise endpoint. Must start with http:// or https://.
</div>
</td>
</tr>
<tr>
<td>OAuth Client ID:</td>
<td>
<span class="config-string-field" binding="config.GITHUB_LOGIN_CONFIG.CLIENT_ID">
</span>
</td>
</tr>
<tr>
<td>OAuth Client Secret:</td>
<td>
<span class="config-string-field" binding="config.GITHUB_LOGIN_CONFIG.CLIENT_SECRET">
</span>
</td>
</tr>
<tr>
<td>Organization Filtering:</td>
<td>
<div class="config-bool-field" binding="config.GITHUB_LOGIN_CONFIG.ORG_RESTRICT">
Restrict By Organization Membership
</div>
<div class="help-text" style="margin-bottom: 20px;">
If enabled, only members of specified GitHub
<span ng-if="mapped.GITHUB_LOGIN_KIND == 'enterprise'">Enterprise</span> organizations will be allowed to login via GitHub
<span ng-if="mapped.GITHUB_LOGIN_KIND == 'enterprise'">Enterprise</span>.
</div>
<span class="config-list-field"
item-title="Organization ID"
binding="config.GITHUB_LOGIN_CONFIG.ALLOWED_ORGANIZATIONS"
ng-if="config.GITHUB_LOGIN_CONFIG.ORG_RESTRICT">
</span>
</td>
</tr>
</table>
</div> </div>
</div> <!-- /GitHub Authentication --> </div> <!-- /External Authentication -->
<!-- Google Authentication -->
<div class="co-panel">
<div class="co-panel-heading">
<i class="fa fa-google"></i> Google Authentication
</div>
<div class="co-panel-body">
<div class="description">
<p>
If enabled, users can use Google to authenticate to the registry.
</p>
<p>
<strong>Note:</strong> A registered Google OAuth application is required.
Visit the
<a href="https://console.developers.google.com" ng-safenewtab>
Google Developer Console
</a>
to register an application.
</p>
</div>
<div class="config-bool-field" binding="config.FEATURE_GOOGLE_LOGIN">
Enable Google Authentication
</div>
<table class="config-table" ng-if="config.FEATURE_GOOGLE_LOGIN">
<tr>
<td>OAuth Client ID:</td>
<td>
<span class="config-string-field" binding="config.GOOGLE_LOGIN_CONFIG.CLIENT_ID">
</span>
</td>
</tr>
<tr>
<td>OAuth Client Secret:</td>
<td>
<span class="config-string-field" binding="config.GOOGLE_LOGIN_CONFIG.CLIENT_SECRET">
</span>
</td>
</tr>
</table>
</div>
</div> <!-- /Google Authentication -->
<!-- Build Support --> <!-- Build Support -->
<div class="co-panel"> <div class="co-panel">

View file

@ -71,7 +71,11 @@ angular.module("core-config-setup", ['angularFileUpload'])
{'id': 'bittorrent', 'title': 'BitTorrent downloads', 'condition': function(config) { {'id': 'bittorrent', 'title': 'BitTorrent downloads', 'condition': function(config) {
return config.FEATURE_BITTORRENT; return config.FEATURE_BITTORRENT;
}} }},
{'id': 'oidc-login', 'title': 'OIDC Login(s)', 'condition': function(config) {
return $scope.getOIDCProviders(config).length > 0;
}},
]; ];
$scope.STORAGE_CONFIG_FIELDS = { $scope.STORAGE_CONFIG_FIELDS = {
@ -147,6 +151,59 @@ angular.module("core-config-setup", ['angularFileUpload'])
$scope.validating = null; $scope.validating = null;
$scope.savingConfiguration = false; $scope.savingConfiguration = false;
$scope.removeOIDCProvider = function(provider) {
delete $scope.config[provider];
};
$scope.addOIDCProvider = function() {
bootbox.prompt('Enter an ID for the OIDC provider', function(result) {
if (!result) {
return;
}
result = result.toUpperCase();
if (!result.match(/^[A-Z0-9]+$/)) {
bootbox.alert('Invalid ID for OIDC provider: must be alphanumeric');
return;
}
if (result == 'GITHUB' || result == 'GOOGLE') {
bootbox.alert('Invalid ID for OIDC provider: cannot be a reserved name');
return;
}
var key = result + '_LOGIN_CONFIG';
if ($scope.config[key]) {
bootbox.alert('Invalid ID for OIDC provider: already exists');
return;
}
$scope.config[key] = {};
});
};
$scope.getOIDCProviderId = function(key) {
var index = key.indexOf('_LOGIN_CONFIG');
if (index <= 0) {
return null;
}
return key.substr(0, index);
};
$scope.getOIDCProviders = function(config) {
var keys = Object.keys(config || {});
return keys.filter(function(key) {
if (key == 'GITHUB_LOGIN_CONFIG' || key == 'GOOGLE_LOGIN_CONFIG') {
// Has custom UI and config.
return false;
}
return !!$scope.getOIDCProviderId(key);
});
};
$scope.getServices = function(config) { $scope.getServices = function(config) {
var services = []; var services = [];
if (!config) { return services; } if (!config) { return services; }