KEYCLOAK-115 add social provider config page

This commit is contained in:
vrockai 2013-10-25 10:49:05 +02:00 committed by Stian Thorgersen
parent fd6bde829c
commit 508a9a1e6b
9 changed files with 251 additions and 28 deletions

View file

@ -41,7 +41,7 @@ module.config([ '$routeProvider', function($routeProvider) {
return RealmLoader(); return RealmLoader();
} }
}, },
controller : 'RealmTokenDetailCtrl' controller : 'RealmSocialCtrl'
}) })
.when('/realms/:realm/required-credentials', { .when('/realms/:realm/required-credentials', {
templateUrl : 'partials/realm-credentials.html', templateUrl : 'partials/realm-credentials.html',

View file

@ -196,6 +196,123 @@ module.controller('RealmRequiredCredentialsCtrl', function($scope, Realm, realm,
}; };
}); });
module.controller('RealmSocialCtrl', function($scope, realm, Realm, $location, Notifications) {
console.log('RealmSocialCtrl');
$scope.realm = { id : realm.id, realm : realm.realm, social : realm.social, tokenLifespan : realm.tokenLifespan, accessCodeLifespan : realm.accessCodeLifespan };
if (!realm["socialProviders"]){
$scope.realm["socialProviders"] = {};
} else {
$scope.realm["socialProviders"] = realm.socialProviders;
}
// Hardcoded provider list
$scope.availableProviders = [ "google", "facebook", "twitter"];
var oldCopy = angular.copy($scope.realm);
$scope.changed = false;
$scope.callbackUrl = "http://mock.url.org/don/t/know/what/to/place/here";
// To get rid of the "undefined" option in the provider select list
// Setting the 1st option from the list (if the list is not empty)
var selectFirstProvider = function(){
if ($scope.unsetProviders.length > 0){
$scope.newProviderId = $scope.unsetProviders[0];
} else {
$scope.newProviderId = null;
}
}
// Fill in configured providers
var initSocial = function() {
$scope.unsetProviders = [];
$scope.configuredProviders = [];
for (var providerConfig in $scope.realm.socialProviders){
// Get the provider ID which is before the '.' (i.e. google in google.key or google.secret)
if ($scope.realm.socialProviders.hasOwnProperty(providerConfig)){
var pId = providerConfig.split('.')[0];
if ($scope.configuredProviders.indexOf(pId) < 0){
$scope.configuredProviders.push(pId);
}
}
}
// If no providers are already configured, you can add any of them
if ($scope.configuredProviders.length == 0){
$scope.unsetProviders = $scope.availableProviders;
} else {
for (var i = 0; i < $scope.availableProviders.length; i++){
var providerId = $scope.availableProviders[i];
if ($scope.configuredProviders.indexOf(providerId) < 0){
$scope.unsetProviders.push(providerId);
}
}
}
selectFirstProvider();
};
initSocial();
$scope.addProvider = function() {
if ($scope.availableProviders.indexOf($scope.newProviderId) > -1){
$scope.realm.socialProviders[$scope.newProviderId+".key"]="";
$scope.realm.socialProviders[$scope.newProviderId+".secret"]="";
$scope.configuredProviders.push($scope.newProviderId);
$scope.unsetProviders.remove($scope.unsetProviders.indexOf($scope.newProviderId));
selectFirstProvider();
}
};
$scope.removeProvider = function(pId) {
delete $scope.realm.socialProviders[pId+".key"];
delete $scope.realm.socialProviders[pId+".secret"];
$scope.configuredProviders.remove($scope.configuredProviders.indexOf(pId));
$scope.unsetProviders.push(pId);
};
$scope.$watch('realm', function() {
if (!angular.equals($scope.realm, oldCopy)) {
$scope.changed = true;
}
}, true);
$scope.save = function() {
$scope.saveClicked = true;
if ($scope.realmForm.$valid) {
var realmCopy = angular.copy($scope.realm);
realmCopy.social = true;
$scope.changed = false;
Realm.update(realmCopy, function () {
$location.url("/realms/" + realm.id + "/social-settings");
Notifications.success("Saved changes to realm");
});
} else {
$scope.realmForm.showErrors = true;
Notifications.error("Some required fields are missing values.");
}
};
$scope.reset = function() {
$scope.realm = angular.copy(oldCopy);
$scope.changed = false;
// Initialize lists of configured and unset providers again
initSocial();
};
$scope.openHelp = function(pId) {
$scope.helpPId = pId;
$scope.providerHelpModal = true;
};
$scope.closeHelp = function() {
$scope.providerHelpModal = false;
};
});
module.controller('RealmTokenDetailCtrl', function($scope, Realm, realm, $http, $location, Dialog, Notifications) { module.controller('RealmTokenDetailCtrl', function($scope, Realm, realm, $http, $location, Dialog, Notifications) {
console.log('RealmTokenDetailCtrl'); console.log('RealmTokenDetailCtrl');

View file

@ -0,0 +1,28 @@
<p>
Mock page for <i>Facebook provider help</i>.
</p>
<p>Fill in name, description and website. For <i>Callback URL</i> use the following value:</p>
<ul>
<li><b>Callback URL:</b> {{callbackUrl}}</li>
</ul>
<form class="form-horizontal" name="fbHelpForm">
<div class="control-group">
<label class="control-label" for="providerHelp.key">Consumer key </label>
<div class="controls">
<input type="text" class="input-xlarge" id="providerHelp.key" ng-model="realm.socialProviders[helpPId+'.key']">
</div>
</div>
<div class="control-group">
<label class="control-label" for="providerHelp.secret">Consumer secret </label>
<div class="controls">
<input type="text" class="input-xlarge" id="providerHelp.secret" ng-model="realm.socialProviders[helpPId+'.secret']">
</div>
</div>
</form>
<p>
Close the help panel and click <i>save changes</i>.
</p>

View file

@ -21,18 +21,14 @@
<form class="form-horizontal" name="googleHelpForm"> <form class="form-horizontal" name="googleHelpForm">
<div class="control-group"> <div class="control-group">
<label class="control-label" for="providerHelp.key">Client ID </label> <label class="control-label" for="providerHelp.key">Client ID </label>
<div class="controls"> <div class="controls">
<input type="text" class="input-xlarge" id="providerHelp.key" <input type="text" class="input-xlarge" id="providerHelp.key" ng-model="realm.socialProviders[helpPId+'.key']">
data-ng-model="application.providers[providerHelp.index].key">
</div> </div>
</div> </div>
<div class="control-group"> <div class="control-group">
<label class="control-label" for="providerHelp.secret">Client secret </label> <label class="control-label" for="providerHelp.secret">Client secret </label>
<div class="controls"> <div class="controls">
<input type="text" class="input-xlarge" id="providerHelp.secret" <input type="text" class="input-xlarge" id="providerHelp.secret" ng-model="realm.socialProviders[helpPId+'.secret']">
data-ng-model="application.providers[providerHelp.index].secret">
</div> </div>
</div> </div>
</form> </form>

View file

@ -1,6 +1,5 @@
<p> <p>
Open <a href="https://dev.twitter.com/apps" target="_blank">https://dev.twitter.com/apps</a>. Click on <i>Create a Open <a href="https://dev.twitter.com/apps" target="_blank">https://dev.twitter.com/apps</a>. Click on <i>Create a new
new
application</i>. application</i>.
</p> </p>
@ -16,28 +15,23 @@
<p>Insert <i>Consumer key</i> and <i>Consumer secret</i> in the form below.</p> <p>Insert <i>Consumer key</i> and <i>Consumer secret</i> in the form below.</p>
<form class="form-horizontal" name="googleHelpForm"> <form class="form-horizontal" name="twitterHelpForm">
<div class="control-group"> <div class="control-group">
<label class="control-label" for="providerHelp.key">Consumer key </label> <label class="control-label" for="providerHelp.key">Consumer key </label>
<div class="controls"> <div class="controls">
<input type="text" class="input-xlarge" id="providerHelp.key" <input type="text" class="input-xlarge" id="providerHelp.key" ng-model="realm.socialProviders[helpPId+'.key']">
data-ng-model="application.providers[providerHelp.index].key">
</div> </div>
</div> </div>
<div class="control-group"> <div class="control-group">
<label class="control-label" for="providerHelp.secret">Consumer secret </label> <label class="control-label" for="providerHelp.secret">Consumer secret </label>
<div class="controls"> <div class="controls">
<input type="text" class="input-xlarge" id="providerHelp.secret" <input type="text" class="input-xlarge" id="providerHelp.secret" ng-model="realm.socialProviders[helpPId+'.secret']">
data-ng-model="application.providers[providerHelp.index].secret">
</div> </div>
</div> </div>
</form> </form>
<p> <p>
Now click on <i>Settings</i> and tick the box <i>Allow this application to be used to Sign in with Twitter</i>, and Now click on <i>Settings</i> and tick the box <i>Allow this application to be used to Sign in with Twitter</i>, and click on <i>Update
click on <i>Update
this Twitter application's settings</i>. this Twitter application's settings</i>.
</p> </p>

View file

@ -1,4 +1,4 @@
<div id="wrapper" class="container"> <div id="wrapper" class="container social-provider">
<div class="row"> <div class="row">
<div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="'partials/realm-menu.html'"></div> <div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="'partials/realm-menu.html'"></div>
<div id="content-area" class="col-md-9" role="main"> <div id="content-area" class="col-md-9" role="main">
@ -12,11 +12,61 @@
</ul> </ul>
</div> </div>
<div id="content"> <div id="content">
<h2 class="pull-left"><span>{{realm.realm}}</span> Social Providers</h2> <ol class="breadcrumb">
<p class="subtitle"></p> <li><a href="#/realms/{{realm.id}}">{{realm.realm}}</a></li>
<li><a href="#/realms/{{realm.id}}">Settings</a></li>
<li class="active">Social</li>
</ol>
<h2><span>{{realm.realm}}</span> Social Providers Settings</h2>
<form name="realmForm" novalidate> <form name="realmForm" novalidate>
<fieldset> <fieldset>
<legend uncollapsed><span class="text">Social Settings</span></legend> <div>
<table>
<caption class="hidden">Table of social providers</caption>
<thead>
<tr>
<th colspan="5" class="rcue-table-actions">
<div class="actions">
<div class="select-rcue">
<select ng-model="newProviderId"
ng-options="p for p in unsetProviders"></select>
</div>
<div>
<button ng-click="addProvider()" ng-disabled="">Add Provider</button>
</div>
</div>
</th>
</tr>
<tr ng-show="configuredProviders.length > 0">
<th>Provider</th>
<th>Key <span class="required">*</span></th>
<th>Secret <span class="required">*</span></th>
<th colspan="1">Actions</th>
</tr>
</thead>
<tbody ng-show="configuredProviders.length > 0">
<tr ng-repeat="pId in configuredProviders">
<td>
<div class="clearfix">
<input class="input-small disabled" type="text" placeholder="Key" value="{{pId}}" readonly>
</div>
</td>
<td>
<input class="input-small" type="text" placeholder="Key" ng-model="realm.socialProviders[pId+'.key']"
ng-class="{'dirty': saveClicked}" required>
</td>
<td>
<input class="input-small" type="text" placeholder="Secret" ng-model="realm.socialProviders[pId+'.secret']"
ng-class="{'dirty': saveClicked}" required>
</td>
<td>
<div class="action-div"><i class="icon-question" ng-click="openHelp(pId)"></i></div>
<div class="action-div"><i class="icon-remove" ng-click="removeProvider(pId)"></i></div>
</td>
</tr>
</tbody>
</table>
</div>
</fieldset> </fieldset>
<div class="form-actions"> <div class="form-actions">
<button type="submit" data-ng-click="save()" class="primary" data-ng-show="changed">Save <button type="submit" data-ng-click="save()" class="primary" data-ng-show="changed">Save
@ -25,9 +75,47 @@
<button type="submit" data-ng-click="reset()" data-ng-show="changed">Clear changes <button type="submit" data-ng-click="reset()" data-ng-show="changed">Clear changes
</button> </button>
</div> </div>
</form> </form>
</div> </div>
</div> </div>
<div id="container-right-bg"></div> <div id="container-right-bg"></div>
</div> </div>
</div> </div>
<div modal="providerHelpModal" close="closeHelp()" options="opts">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h3>Configure {{helpPId}}</h3>
</div>
<div class="modal-body">
<div ng-include src="'partials/provider/'+ helpPId +'-help.html'"></div>
</div>
<div class="modal-footer">
<button class="btn" ng-click="closeHelp()">Close</button>
</div>
</div>
</div>
</div>
<!-- TODO remove once this page is properly styled -->
<style type="text/css">
.social-provider input.ng-invalid.dirty,
.social-provider input.ng-invalid.ng-dirty {
background-color: #FFEEEE;
}
.social-provider .actions > div {
display: inline-block;
overflow: hidden;
}
.social-provider td {
font-size: 10px;
}
.social-provider .action-div {
display: inline-block;
margin: 5px;
}
</style>

View file

@ -5,7 +5,7 @@
<div class="top-nav"> <div class="top-nav">
<ul class="rcue-tabs"> <ul class="rcue-tabs">
<li><a href="#/realms/{{realm.id}}">General</a></li> <li><a href="#/realms/{{realm.id}}">General</a></li>
<li data-ng-show="realm.social"><a href="#">Social</a></li> <li data-ng-show="realm.social"><a href="#/realms/{{realm.id}}/social-settings">Social</a></li>
<li class="active"><a href="#/realms/{{realm.id}}/roles">Roles</a></li> <li class="active"><a href="#/realms/{{realm.id}}/roles">Roles</a></li>
<li><a href="#/realms/{{realm.id}}/required-credentials">Credentials</a></li> <li><a href="#/realms/{{realm.id}}/required-credentials">Credentials</a></li>
<li><a href="#/realms/{{realm.id}}/token-settings">Token</a></li> <li><a href="#/realms/{{realm.id}}/token-settings">Token</a></li>

View file

@ -5,7 +5,7 @@
<div class="top-nav"> <div class="top-nav">
<ul class="rcue-tabs"> <ul class="rcue-tabs">
<li><a href="#/realms/{{realm.id}}">General</a></li> <li><a href="#/realms/{{realm.id}}">General</a></li>
<li data-ng-show="realm.social"><a href="#">Social</a></li> <li data-ng-show="realm.social"><a href="#/realms/{{realm.id}}/social-settings">Social</a></li>
<li class="active"><a href="#/realms/{{realm.id}}/roles">Roles</a></li> <li class="active"><a href="#/realms/{{realm.id}}/roles">Roles</a></li>
<li><a href="#/realms/{{realm.id}}/required-credentials">Credentials</a></li> <li><a href="#/realms/{{realm.id}}/required-credentials">Credentials</a></li>
<li><a href="#/realms/{{realm.id}}/token-settings">Token</a></li> <li><a href="#/realms/{{realm.id}}/token-settings">Token</a></li>

View file

@ -253,7 +253,7 @@ public class RealmManager {
} }
} }
if (rep.getAccountManagement() != null && rep.getAccountManagement()) { if (rep.isAccountManagement() != null && rep.isAccountManagement()) {
enableAccountManagement(newRealm); enableAccountManagement(newRealm);
} }