mirror of
https://github.com/netzbegruenung/user_saml.git
synced 2024-05-11 13:16:06 +02:00
Allow to configure multiple SAML providers
Signed-off-by: Julius Härtl <jus@bitgrid.net>
This commit is contained in:
parent
9cdcae4bd5
commit
ee5308382b
|
@ -58,5 +58,13 @@ return [
|
|||
'url' => '/saml/selectUserBackEnd',
|
||||
'verb' => 'GET',
|
||||
],
|
||||
[
|
||||
'name' => 'Settings#getSamlProviderSettings',
|
||||
'url' => '/settings/providerSettings/{providerId}',
|
||||
'verb' => 'GET',
|
||||
'defaults' => [
|
||||
'providerId' => '1'
|
||||
]
|
||||
],
|
||||
],
|
||||
];
|
||||
|
|
|
@ -26,6 +26,25 @@
|
|||
clear: both;
|
||||
padding: 7px 0;
|
||||
cursor: pointer;
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
#user-saml .account-list {
|
||||
margin: 10px 0 10px 0;
|
||||
overflow:hidden;
|
||||
padding: 10px 0 10px 0;
|
||||
}
|
||||
#user-saml .account-list li {
|
||||
float: left;
|
||||
}
|
||||
|
||||
#user-saml .account-list li a:not(.button) {
|
||||
padding: 7px;
|
||||
}
|
||||
#user-saml .account-list li a.button {
|
||||
margin-left: 20px;
|
||||
}
|
||||
#user-saml .account-list li.active a {
|
||||
border-bottom: 1px solid #333;
|
||||
font-weight: bold;
|
||||
}
|
99
js/admin.js
99
js/admin.js
|
@ -5,6 +5,22 @@
|
|||
* @namespace OCA.User_SAML.Admin
|
||||
*/
|
||||
OCA.User_SAML.Admin = {
|
||||
currentConfig: '1',
|
||||
providerIds: '1',
|
||||
|
||||
_getAppConfig: function (key) {
|
||||
return $.ajax({
|
||||
type: 'GET',
|
||||
url: OC.linkToOCS('apps/provisioning_api/api/v1', 2) + 'config/apps' + '/user_saml/' + key + '?format=json'
|
||||
});
|
||||
},
|
||||
init: function() {
|
||||
this._getAppConfig('providerIds').done(function (data){
|
||||
if (data.ocs.data.data !== '') {
|
||||
OCA.User_SAML.Admin.providerIds = data.ocs.data.data;
|
||||
}
|
||||
});
|
||||
},
|
||||
chooseEnv: function() {
|
||||
if (OC.PasswordConfirmation.requiresPasswordConfirmation()) {
|
||||
OC.PasswordConfirmation.requirePasswordConfirmation(_.bind(this.chooseEnv, this));
|
||||
|
@ -23,6 +39,32 @@
|
|||
OCP.AppConfig.setValue('user_saml', 'type', 'saml', {success: function() {location.reload();}});
|
||||
},
|
||||
|
||||
getConfigIdentifier: function() {
|
||||
if (this.currentConfig === '1') {
|
||||
return '';
|
||||
}
|
||||
return this.currentConfig + '-';
|
||||
},
|
||||
|
||||
/**
|
||||
* Add a new provider
|
||||
* @returns {number} id of the provider
|
||||
*/
|
||||
addProvider: function(callback) {
|
||||
var providerIds = OCA.User_SAML.Admin.providerIds.split(',');
|
||||
var nextId = 2;
|
||||
while($.inArray('' + nextId, providerIds) >= 0) {
|
||||
nextId++;
|
||||
}
|
||||
console.log(nextId);
|
||||
OCP.AppConfig.setValue('user_saml', 'providerIds', OCA.User_SAML.Admin.providerIds + ',' + nextId, {
|
||||
success: function () {
|
||||
OCA.User_SAML.Admin.providerIds += ',' + nextId;
|
||||
callback(nextId)
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
setSamlConfigValue: function(category, setting, value) {
|
||||
if (OC.PasswordConfirmation.requiresPasswordConfirmation()) {
|
||||
OC.PasswordConfirmation.requirePasswordConfirmation(_.bind(this.setSamlConfigValue, this, category, setting, value));
|
||||
|
@ -30,13 +72,14 @@
|
|||
}
|
||||
|
||||
OC.msg.startSaving('#user-saml-save-indicator');
|
||||
OC.AppConfig.setValue('user_saml', category+'-'+setting, value);
|
||||
OCP.AppConfig.setValue('user_saml', this.getConfigIdentifier() + category + '-' + setting, value);
|
||||
OC.msg.finishedSaving('#user-saml-save-indicator', {status: 'success', data: {message: t('user_saml', 'Saved')}});
|
||||
}
|
||||
}
|
||||
})(OCA);
|
||||
|
||||
$(function() {
|
||||
OCA.User_SAML.Admin.init();
|
||||
// Hide depending on the setup state
|
||||
var type = $('#user-saml').data('type');
|
||||
if(type !== '') {
|
||||
|
@ -68,6 +111,53 @@ $(function() {
|
|||
}
|
||||
});
|
||||
|
||||
var switchProvider = function(providerId) {
|
||||
$('.account-list li').removeClass('active');
|
||||
$('.account-list li[data-id="' + providerId + '"]').addClass('active');
|
||||
OCA.User_SAML.Admin.currentConfig = providerId;
|
||||
$.get(OC.generateUrl('/apps/user_saml/settings/providerSettings/' + providerId)).done(function(data) {
|
||||
Object.keys(data).forEach(function(category, index){
|
||||
var entries = data[category];
|
||||
Object.keys(entries).forEach(function (configKey) {
|
||||
var element = $('*[data-key="' + configKey + '"]');
|
||||
if ($('#user-saml-' + configKey).length) {
|
||||
element = $('#user-saml-' + configKey);
|
||||
}
|
||||
if ($('[name="' + configKey + '"]').length) {
|
||||
element = $('[name="' + configKey + '"]');
|
||||
}
|
||||
if(element.is('input') && element.prop('type') === 'text') {
|
||||
element.val(entries[configKey])
|
||||
}
|
||||
else if(element.is('textarea')) {
|
||||
element.val(entries[configKey]);
|
||||
}
|
||||
else if(element.prop('type') === 'checkbox') {
|
||||
var value = entries[configKey] === '1' ? '1' : '0';
|
||||
element.val(value);
|
||||
} else {
|
||||
console.log('unable to find element for ' + configKey);
|
||||
}
|
||||
});
|
||||
});
|
||||
$('input:checkbox[value="1"]').attr('checked', true);
|
||||
$('input:checkbox[value="0"]').attr('checked', false);
|
||||
});
|
||||
};
|
||||
|
||||
$('.account-list').on('click', 'li:not(.add-provider)', function() {
|
||||
var providerId = '' + $(this).data('id');
|
||||
switchProvider(providerId);
|
||||
});
|
||||
|
||||
$('.account-list .add-provider').on('click', function() {
|
||||
OCA.User_SAML.Admin.addProvider(function (nextId) {
|
||||
$('<li data-id="' + nextId + '"><a>' + t('user_saml', 'Provider') + ' ' + nextId + '</a></li>').insertBefore('.account-list .add-provider');
|
||||
switchProvider(nextId);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// Enable tabs
|
||||
$('input:checkbox[value="1"]').attr('checked', true);
|
||||
|
||||
|
@ -105,6 +195,13 @@ $(function() {
|
|||
var key = $(this).attr('name');
|
||||
OCA.User_SAML.Admin.setSamlConfigValue('general', key, $(this).val());
|
||||
}
|
||||
if(el.data('key') === 'idp0_display_name') {
|
||||
if ($(this).val() !== '') {
|
||||
$('.account-list li[data-id=' + OCA.User_SAML.Admin.currentConfig + '] a').text($(this).val())
|
||||
} else {
|
||||
$('.account-list li[data-id=' + OCA.User_SAML.Admin.currentConfig + '] a').text(t('user_saml', 'Provider') + ' ' + OCA.User_SAML.Admin.currentConfig);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$('#user-saml-general input[type="checkbox"]').change(function(e) {
|
||||
|
|
81
lib/Controller/SettingsController.php
Normal file
81
lib/Controller/SettingsController.php
Normal file
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2018 Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
* @author Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\User_SAML\Controller;
|
||||
|
||||
use OCA\User_SAML\Settings\Admin;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\IConfig;
|
||||
use OCP\IRequest;
|
||||
|
||||
class SettingsController extends Controller {
|
||||
|
||||
/** @var IConfig */
|
||||
private $config;
|
||||
/** @var Admin */
|
||||
private $admin;
|
||||
|
||||
public function __construct($appName,
|
||||
IRequest $request,
|
||||
IConfig $config,
|
||||
Admin $admin) {
|
||||
parent::__construct($appName, $request);
|
||||
$this->config = $config;
|
||||
$this->admin = $admin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $providerId
|
||||
* @return array of categories containing entries for each config parameter with their value
|
||||
*/
|
||||
public function getSamlProviderSettings($providerId) {
|
||||
/**
|
||||
* This uses the list of available config parameters from the admin section
|
||||
* and extends it with fields that are not coming from \OCA\User_SAML\Settings\Admin
|
||||
*/
|
||||
$params = $this->admin->getForm()->getParams();
|
||||
$params['idp'] = [
|
||||
'singleLogoutService.url' => null,
|
||||
'singleSignOnService.url' => null,
|
||||
'idp-entityId' => null,
|
||||
];
|
||||
/* Fetch all config values for the given providerId */
|
||||
$settings = [];
|
||||
foreach ($params as $category => $content) {
|
||||
if (empty($content) || $category === 'providers') {
|
||||
continue;
|
||||
}
|
||||
foreach ($content as $setting => $details) {
|
||||
$prefix = $providerId === '1' ? '' : $providerId . '-';
|
||||
$key = $prefix . $category . '-' . $setting;
|
||||
/* use security as category instead of security-* */
|
||||
if (strpos($category, 'security-') === 0) {
|
||||
$category = 'security';
|
||||
}
|
||||
$settings[$category][$setting] = $this->config->getAppValue('user_saml', $key, '');
|
||||
}
|
||||
}
|
||||
return $settings;
|
||||
}
|
||||
|
||||
}
|
|
@ -54,6 +54,13 @@ class Admin implements ISettings {
|
|||
* @return TemplateResponse
|
||||
*/
|
||||
public function getForm() {
|
||||
$providerIds = explode(',', $this->config->getAppValue('user_saml', 'providerIds', '1'));
|
||||
$providers = [];
|
||||
foreach ($providerIds as $id) {
|
||||
$prefix = $id === '1' ? '' : $id .'-';
|
||||
$name = $this->config->getAppValue('user_saml', $prefix . 'general-idp0_display_name', '');
|
||||
$providers[$id] = $name === '' ? $this->l10n->t('Provider ') . $id : $name;
|
||||
}
|
||||
$serviceProviderFields = [
|
||||
'x509cert' => $this->l10n->t('X.509 certificate of the Service Provider'),
|
||||
'privateKey' => $this->l10n->t('Private key of the Service Provider'),
|
||||
|
@ -135,6 +142,7 @@ class Admin implements ISettings {
|
|||
'general' => $generalSettings,
|
||||
'attributeMappings' => $attributeMappingSettings,
|
||||
'type' => $type,
|
||||
'providers' => $providers
|
||||
];
|
||||
|
||||
return new TemplateResponse('user_saml', 'admin', $params);
|
||||
|
|
|
@ -10,15 +10,6 @@ style('user_saml', 'admin');
|
|||
title="<?php p($l->t('Open documentation'));?>"
|
||||
href="<?php p(link_to_docs('admin-sso')); ?>"></a>
|
||||
|
||||
<div id="user-saml-save-indicator" class="msg success inlineblock" style="display: none;">Saved</div>
|
||||
|
||||
<div id="user-saml-settings">
|
||||
<div id="user-saml-choose-type">
|
||||
<?php p($l->t('Please choose whether you want to authenticate using the SAML provider built-in in Nextcloud or whether you want to authenticate against an environment variable.')) ?>
|
||||
<br/>
|
||||
<button id="user-saml-choose-saml"><?php p($l->t('Use built-in SAML authentication')) ?></button>
|
||||
<button id="user-saml-choose-env"><?php p($l->t('Use environment variable')) ?></button>
|
||||
</div>
|
||||
|
||||
<div class="warning hidden" id="user-saml-warning-admin-user">
|
||||
<?php p(
|
||||
|
@ -33,6 +24,26 @@ style('user_saml', 'admin');
|
|||
?>
|
||||
</div>
|
||||
|
||||
<ul class="account-list">
|
||||
<?php foreach ($_['providers'] as $id => $name) { ?>
|
||||
<li data-id="<?php p($id); ?>" class="<?php if ((string)$id === '1') { p('active'); } ?>">
|
||||
<a href="#"><?php p($name); ?></a>
|
||||
</li>
|
||||
<?php } ?>
|
||||
<li class="add-provider"><a href="#" class="button"><span class="icon-add"></span> Add another account</a></li>
|
||||
</ul>
|
||||
|
||||
<div id="user-saml-save-indicator" class="msg success inlineblock" style="display: none;">Saved</div>
|
||||
|
||||
<div id="user-saml-settings">
|
||||
<div id="user-saml-choose-type">
|
||||
<?php p($l->t('Please choose whether you want to authenticate using the SAML provider built-in in Nextcloud or whether you want to authenticate against an environment variable.')) ?>
|
||||
<br/>
|
||||
<button id="user-saml-choose-saml"><?php p($l->t('Use built-in SAML authentication')) ?></button>
|
||||
<button id="user-saml-choose-env"><?php p($l->t('Use environment variable')) ?></button>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="user-saml-general">
|
||||
<h3><?php p($l->t('General')) ?></h3>
|
||||
<?php foreach($_['general'] as $key => $attribute): ?>
|
||||
|
|
Loading…
Reference in a new issue