keycloak-uncached
Changes
admin-ui/src/main/resources/META-INF/resources/admin/partials/application-scope-mappings.html 2(+1 -1)
dist/assembly.xml 2(+1 -1)
dist/build.xml 14(+8 -6)
dist/pom.xml 34(+31 -3)
dist/src/main/xslt/standalone.xsl 33(+33 -0)
examples/as7-eap-demo/server/pom.xml 5(+5 -0)
examples/as7-eap-dev/server/pom.xml 5(+5 -0)
examples/js/testrealm.json 1(+0 -1)
forms/pom.xml 14(+1 -13)
model/jpa/pom.xml 24(+24 -0)
model/picketlink/pom.xml 5(+0 -5)
pom.xml 2(+1 -1)
server/pom.xml 70(+21 -49)
services/pom.xml 49(+5 -44)
testsuite/integration/pom.xml 10(+10 -0)
Details
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/index.html b/admin-ui/src/main/resources/META-INF/resources/admin/index.html
index 9487218..4be31ec 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/index.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/index.html
@@ -73,8 +73,10 @@
</button>
</div>
- <div id="loading">
- <i class="icon-spinner icon-spin"></i> Loading...
+ <div id="loading" class="loading-backdrop">
+ <div class="loading">
+ <span>Loading...</span>
+ </div>
</div>
</div>
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/js/app.js b/admin-ui/src/main/resources/META-INF/resources/admin/js/app.js
index 7025d2e..34a20d6 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/js/app.js
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/js/app.js
@@ -2,6 +2,7 @@
var module = angular.module('keycloak', [ 'keycloak.services', 'keycloak.loaders', 'keycloak.controllers', 'ui.bootstrap', 'ui.select2' ]);
var resourceRequests = 0;
+var loadingTimer = -1;
module.config([ '$routeProvider', function($routeProvider) {
@@ -46,6 +47,21 @@ module.config([ '$routeProvider', function($routeProvider) {
},
controller : 'RealmSocialCtrl'
})
+ .when('/realms/:realm/registration-settings', {
+ templateUrl : 'partials/realm-registration.html',
+ resolve : {
+ realm : function(RealmLoader) {
+ return RealmLoader();
+ },
+ applications : function(ApplicationListLoader) {
+ return ApplicationListLoader();
+ },
+ roles : function(RoleListLoader) {
+ return RoleListLoader();
+ }
+ },
+ controller : 'RealmRegistrationCtrl'
+ })
.when('/realms/:realm/required-credentials', {
templateUrl : 'partials/realm-credentials.html',
resolve : {
@@ -281,7 +297,10 @@ module.config(function($httpProvider) {
var spinnerFunction = function(data, headersGetter) {
if (resourceRequests == 0) {
- $('#loading').show();
+ loadingTimer = window.setTimeout(function() {
+ $('#loading').show();
+ loadingTimer = -1;
+ }, 500);
}
resourceRequests++;
return data;
@@ -301,7 +320,7 @@ module.factory('errorInterceptor', function($q, $window, $rootScope, $location,
if (response.status == 401) {
console.log('session timeout?');
Auth.loggedIn = false;
- $location.url('/');
+ window.location = '/auth-server/rest/saas/login?path=' + $location.path();
} else {
$rootScope.httpProviderError = response.status;
}
@@ -315,12 +334,20 @@ module.factory('spinnerInterceptor', function($q, $window, $rootScope, $location
return promise.then(function(response) {
resourceRequests--;
if (resourceRequests == 0) {
+ if(loadingTimer != -1) {
+ window.clearTimeout(loadingTimer);
+ loadingTimer = -1;
+ }
$('#loading').hide();
}
return response;
}, function(response) {
resourceRequests--;
if (resourceRequests == 0) {
+ if(loadingTimer != -1) {
+ window.clearTimeout(loadingTimer);
+ loadingTimer = -1;
+ }
$('#loading').hide();
}
@@ -368,10 +395,42 @@ module.directive('collapsed', function() {
}
});
-
-
-
-
+/**
+ * Directive for presenting an ON-OFF switch for checkbox.
+ * Usage: <input ng-model="mmm" name="nnn" id="iii" onoffswitch [on-text="ooo" off-text="fff"] />
+ */
+module.directive('onoffswitch', function() {
+ return {
+ restrict: "EA",
+ require: 'ngModel',
+ replace: true,
+ scope: {
+ ngModel: '=',
+ ngBind: '=',
+ name: '=',
+ id: '=',
+ onText: '@onText',
+ offText: '@offText'
+ },
+ compile: function(element, attrs) {
+ if (!attrs.onText) { attrs.onText = "ON"; }
+ if (!attrs.offText) { attrs.offText = "OFF"; }
+
+ var html = "<div class=\"onoffswitch\">" +
+ "<input type=\"checkbox\" data-ng-model=\"ngModel\" class=\"onoffswitch-checkbox\" name=\"" + attrs.name + "\" id=\"" + attrs.id + "\">" +
+ "<label for=\"" + attrs.id + "\" class=\"onoffswitch-label\">" +
+ "<span class=\"onoffswitch-inner\">" +
+ "<span class=\"onoffswitch-active\">{{onText}}</span>" +
+ "<span class=\"onoffswitch-inactive\">{{offText}}</span>" +
+ "</span>" +
+ "<span class=\"onoffswitch-switch\"></span>" +
+ "</label>" +
+ "</div>";
+
+ element.replaceWith($(html));
+ }
+ }
+});
module.directive('kcInput', function() {
@@ -430,16 +489,28 @@ module.filter('remove', function() {
for ( var i = 0; i < input.length; i++) {
var e = input[i];
- for (var j = 0; j < remove.length; j++) {
+ if (Array.isArray(remove)) {
+ for (var j = 0; j < remove.length; j++) {
+ if (attribute) {
+ if (remove[j][attribute] == e[attribute]) {
+ e = null;
+ break;
+ }
+ } else {
+ if (remove[j] == e) {
+ e = null;
+ break;
+ }
+ }
+ }
+ } else {
if (attribute) {
- if (remove[j][attribute] == e[attribute]) {
+ if (remove[attribute] == e[attribute]) {
e = null;
- break;
}
} else {
- if (remove[j] == e) {
+ if (remove == e) {
e = null;
- break;
}
}
}
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers.js b/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers.js
index a154da3..8516462 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers.js
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers.js
@@ -19,5 +19,4 @@ function randomString(len) {
randomString += charSet.substring(randomPoz,randomPoz+1);
}
return randomString;
-}
-
+}
\ No newline at end of file
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/realm.js b/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/realm.js
index fa11a54..410d324 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/realm.js
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/realm.js
@@ -15,6 +15,7 @@ module.controller('GlobalCtrl', function($scope, $http, Auth, Current, $location
$scope.$watch(function() {
return $location.path();
}, function() {
+ $scope.fragment = $location.path();
$scope.path = $location.path().substring(1).split("/");
});
@@ -73,6 +74,9 @@ module.controller('RealmDetailCtrl', function($scope, Current, Realm, realm, $ht
$scope.realm.requireSsl = !realm.sslNotRequired;
}
+ $scope.social = $scope.realm.social;
+ $scope.registrationAllowed = $scope.realm.registrationAllowed;
+
var oldCopy = angular.copy($scope.realm);
@@ -104,6 +108,8 @@ module.controller('RealmDetailCtrl', function($scope, Current, Realm, realm, $ht
}
$location.url("/realms/" + id);
Notifications.success("The realm has been created.");
+ $scope.social = $scope.realm.social;
+ $scope.registrationAllowed = $scope.realm.registrationAllowed;
});
});
} else {
@@ -122,6 +128,8 @@ module.controller('RealmDetailCtrl', function($scope, Current, Realm, realm, $ht
});
$location.url("/realms/" + id);
Notifications.success("Your changes have been saved to the realm.");
+ $scope.social = $scope.realm.social;
+ $scope.registrationAllowed = $scope.realm.registrationAllowed;
});
}
} else {
@@ -158,7 +166,8 @@ module.controller('RealmRequiredCredentialsCtrl', function($scope, Realm, realm,
id : realm.id, realm : realm.realm, social : realm.social,
requiredCredentials : realm.requiredCredentials,
requiredApplicationCredentials : realm.requiredApplicationCredentials,
- requiredOAuthClientCredentials : realm.requiredOAuthClientCredentials
+ requiredOAuthClientCredentials : realm.requiredOAuthClientCredentials,
+ registrationAllowed : realm.registrationAllowed
};
$scope.userCredentialOptions = {
@@ -196,10 +205,156 @@ module.controller('RealmRequiredCredentialsCtrl', function($scope, Realm, realm,
};
});
+module.controller('RealmRegistrationCtrl', function ($scope, Realm, realm, applications, roles, Notifications, ApplicationRole, Application) {
+
+ console.log('RealmRegistrationCtrl');
+
+ $scope.realm = realm;
+
+ $scope.availableRealmRoles = [];
+ $scope.selectedRealmRoles = [];
+ $scope.selectedRealmDefRoles = [];
+
+ $scope.applications = angular.copy(applications);
+
+ $scope.availableAppRoles = [];
+ $scope.selectedAppRoles = [];
+ $scope.selectedAppDefRoles = [];
+
+ if (!$scope.realm.hasOwnProperty('defaultRoles') || $scope.realm.defaultRoles === null) {
+ $scope.realm.defaultRoles = [];
+ }
+
+ // Populate available roles. Available roles are neither already assigned or system roles.
+ for (var i = 0; i < roles.length; i++) {
+ var item = roles[i].name;
+
+ if ($scope.realm.defaultRoles.indexOf(item) < 0) {
+ $scope.availableRealmRoles.push(item);
+ }
+ }
+
+ $scope.addRealmDefaultRole = function () {
+
+ // Remove selected roles from the Available roles and add them to realm default roles (move from left to right).
+ for (var i = 0; i < $scope.selectedRealmRoles.length; i++) {
+ var selectedRole = $scope.selectedRealmRoles[i];
+
+ $scope.realm.defaultRoles.push(selectedRole);
+
+ var index = $scope.availableRealmRoles.indexOf(selectedRole);
+ if (index > -1) {
+ $scope.availableRealmRoles.splice(index, 1);
+ }
+ }
+
+ // Update/save the realm with new default roles.
+ Realm.update($scope.realm, function () {
+ Notifications.success("Realm default roles updated.");
+ });
+ };
+
+ $scope.deleteRealmDefaultRole = function () {
+
+ // Remove selected roles from the realm default roles and add them to available roles (move from right to left).
+ for (var i = 0; i < $scope.selectedRealmDefRoles.length; i++) {
+ $scope.availableRealmRoles.push($scope.selectedRealmDefRoles[i]);
+
+ var index = $scope.realm.defaultRoles.indexOf($scope.selectedRealmDefRoles[i]);
+ if (index > -1) {
+ $scope.realm.defaultRoles.splice(index, 1);
+ }
+ }
+
+ // Update/save the realm with new default roles.
+ //var realmCopy = angular.copy($scope.realm);
+ Realm.update($scope.realm, function () {
+ Notifications.success("Realm default roles updated.");
+ });
+ };
+
+ $scope.changeApplication = function () {
+
+ $scope.selectedAppRoles = [];
+ $scope.selectedAppDefRoles = [];
+
+ // Populate available roles for selected application
+ var appDefaultRoles = ApplicationRole.query({realm: $scope.realm.id, application: $scope.application.id}, function () {
+
+ if (!$scope.application.hasOwnProperty('defaultRoles') || $scope.application.defaultRoles === null) {
+ $scope.application.defaultRoles = [];
+ }
+
+ $scope.availableAppRoles = [];
+
+ for (var i = 0; i < appDefaultRoles.length; i++) {
+ var roleName = appDefaultRoles[i].name;
+
+ if (systemRoles.indexOf(roleName) < 0 && $scope.application.defaultRoles.indexOf(roleName) < 0) {
+ $scope.availableAppRoles.push(roleName);
+ }
+ }
+ });
+ };
+
+ $scope.addAppDefaultRole = function () {
+
+ // Remove selected roles from the app available roles and add them to app default roles (move from left to right).
+ for (var i = 0; i < $scope.selectedAppRoles.length; i++) {
+ var role = $scope.selectedAppRoles[i];
+
+ var idx = $scope.application.defaultRoles.indexOf(role);
+ if (idx < 0) {
+ $scope.application.defaultRoles.push(role);
+ }
+
+ idx = $scope.availableAppRoles.indexOf(role);
+
+ if (idx != -1) {
+ $scope.availableAppRoles.splice(idx, 1);
+ }
+ }
+
+ // Update/save the selected application with new default roles.
+ Application.update({
+ realm: $scope.realm.id,
+ id: $scope.application.id
+ }, $scope.application, function () {
+ Notifications.success("Your changes have been saved to the application.");
+ });
+ };
+
+ $scope.rmAppDefaultRole = function () {
+
+ // Remove selected roles from the app default roles and add them to app available roles (move from right to left).
+ for (var i = 0; i < $scope.selectedAppDefRoles.length; i++) {
+ var role = $scope.selectedAppDefRoles[i];
+ var idx = $scope.application.defaultRoles.indexOf(role);
+ if (idx != -1) {
+ $scope.application.defaultRoles.splice(idx, 1);
+ }
+ idx = $scope.availableAppRoles.indexOf(role);
+ if (idx < 0) {
+ $scope.availableAppRoles.push(role);
+ }
+ }
+
+ // Update/save the selected application with new default roles.
+ Application.update({
+ realm: $scope.realm.id,
+ id: $scope.application.id
+ }, $scope.application, function () {
+ Notifications.success("Your changes have been saved to the application.");
+ });
+ };
+
+});
+
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 };
+ $scope.realm = { id : realm.id, realm : realm.realm, social : realm.social, registrationAllowed : realm.registrationAllowed,
+ tokenLifespan : realm.tokenLifespan, accessCodeLifespan : realm.accessCodeLifespan };
if (!realm["socialProviders"]){
$scope.realm["socialProviders"] = {};
@@ -207,8 +362,13 @@ module.controller('RealmSocialCtrl', function($scope, realm, Realm, $location, N
$scope.realm["socialProviders"] = realm.socialProviders;
}
- // Hardcoded provider list
- $scope.availableProviders = [ "google", "facebook", "twitter"];
+ // Hardcoded provider list in form of map providerId:providerName
+ $scope.allProviders = { google:"Google", facebook:"Facebook", twitter:"Twitter" };
+ $scope.availableProviders = [];
+
+ for (var provider in $scope.allProviders){
+ $scope.availableProviders.push(provider);
+ }
var oldCopy = angular.copy($scope.realm);
$scope.changed = false;
@@ -226,6 +386,9 @@ module.controller('RealmSocialCtrl', function($scope, realm, Realm, $location, N
// Fill in configured providers
var initSocial = function() {
+ // postSaveProviders is used for remembering providers which were already validated after pressing the save button
+ // thanks to this it's easy to distinguish between newly added fields and those already tried to be saved
+ $scope.postSaveProviders = [];
$scope.unsetProviders = [];
$scope.configuredProviders = [];
@@ -241,7 +404,7 @@ module.controller('RealmSocialCtrl', function($scope, realm, Realm, $location, N
// If no providers are already configured, you can add any of them
if ($scope.configuredProviders.length == 0){
- $scope.unsetProviders = $scope.availableProviders;
+ $scope.unsetProviders = $scope.availableProviders.slice(0);
} else {
for (var i = 0; i < $scope.availableProviders.length; i++){
var providerId = $scope.availableProviders[i];
@@ -270,6 +433,13 @@ module.controller('RealmSocialCtrl', function($scope, realm, Realm, $location, N
delete $scope.realm.socialProviders[pId+".key"];
delete $scope.realm.socialProviders[pId+".secret"];
$scope.configuredProviders.remove($scope.configuredProviders.indexOf(pId));
+
+ // Removing from postSaveProviders, so the empty fields are not red if the provider is added to the list again
+ var rId = $scope.postSaveProviders.indexOf(pId);
+ if (rId > -1){
+ $scope.postSaveProviders.remove(rId)
+ }
+
$scope.unsetProviders.push(pId);
};
@@ -280,8 +450,6 @@ module.controller('RealmSocialCtrl', function($scope, realm, Realm, $location, N
}, true);
$scope.save = function() {
- $scope.saveClicked = true;
-
if ($scope.realmForm.$valid) {
var realmCopy = angular.copy($scope.realm);
realmCopy.social = true;
@@ -289,10 +457,12 @@ module.controller('RealmSocialCtrl', function($scope, realm, Realm, $location, N
Realm.update(realmCopy, function () {
$location.url("/realms/" + realm.id + "/social-settings");
Notifications.success("Saved changes to realm");
+ oldCopy = realmCopy;
});
} else {
$scope.realmForm.showErrors = true;
Notifications.error("Some required fields are missing values.");
+ $scope.postSaveProviders = $scope.configuredProviders.slice(0);
}
};
@@ -317,7 +487,10 @@ module.controller('RealmSocialCtrl', function($scope, realm, Realm, $location, N
module.controller('RealmTokenDetailCtrl', function($scope, Realm, realm, $http, $location, Dialog, Notifications) {
console.log('RealmTokenDetailCtrl');
- $scope.realm = { id : realm.id, realm : realm.realm, social : realm.social, tokenLifespan : realm.tokenLifespan, accessCodeLifespan : realm.accessCodeLifespan , accessCodeLifespanUserAction : realm.accessCodeLifespanUserAction };
+ $scope.realm = { id : realm.id, realm : realm.realm, social : realm.social, registrationAllowed : realm.registrationAllowed,
+ tokenLifespan : realm.tokenLifespan, accessCodeLifespan : realm.accessCodeLifespan,
+ accessCodeLifespanUserAction : realm.accessCodeLifespanUserAction };
+
$scope.realm.tokenLifespanUnit = 'Seconds';
$scope.realm.accessCodeLifespanUnit = 'Seconds';
$scope.realm.accessCodeLifespanUserActionUnit = 'Seconds';
@@ -376,6 +549,7 @@ module.controller('RealmTokenDetailCtrl', function($scope, Realm, realm, $http,
});
module.controller('RoleListCtrl', function($scope, $location, realm, roles) {
+
$scope.realm = realm;
$scope.roles = roles;
@@ -456,7 +630,7 @@ module.controller('RoleDetailCtrl', function($scope, realm, role, Role, $locatio
module.controller('RealmSMTPSettingsCtrl', function($scope, Current, Realm, realm, $http, $location, Dialog, Notifications) {
$scope.realm = {
- id : realm.id, realm : realm.realm, social : realm.social,
+ id : realm.id, realm : realm.realm, social : realm.social, registrationAllowed : realm.registrationAllowed,
smtpServer: realm.smtpServer
};
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/js/services.js b/admin-ui/src/main/resources/META-INF/resources/admin/js/services.js
index 4ee4a90..71485f3 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/js/services.js
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/js/services.js
@@ -17,8 +17,8 @@ module.service('Dialog', function($dialog) {
var dialog = {};
dialog.confirmDelete = function(name, type, success) {
var title = 'Delete ' + type.charAt(0).toUpperCase() + type.slice(1);
- var msg = '<p class="primary">Are you sure you want to permanently delete the ' + type + ' "' + name + '"?</p>' +
- '<p>This action can\'t be undone.</p>';
+ var msg = '<span class="primary">Are you sure you want to permanently delete the ' + type + ' "' + name + '"?</span>' +
+ '<span>This action can\'t be undone.</span>';
var btns = [ {
result : 'cancel',
label : 'Cancel'
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-detail.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-detail.html
index 2c11b73..e766d57 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-detail.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-detail.html
@@ -44,17 +44,7 @@
<div class="form-group clearfix block">
<label for="enabled" class="control-label">Enabled</label>
- <div class="onoffswitch">
- <input type="checkbox" data-ng-model="application.enabled" class="onoffswitch-checkbox"
- name="enabled" id="enabled">
- <label for="enabled" class="onoffswitch-label">
- <span class="onoffswitch-inner">
- <span class="onoffswitch-active">ON</span>
- <span class="onoffswitch-inactive">OFF</span>
- </span>
- <span class="onoffswitch-switch"></span>
- </label>
- </div>
+ <input ng-model="application.enabled" name="enabled" id="enabled" onoffswitch />
</div>
<div class="form-group">
<label for="baseUrl" class="control-label">Base URL</label>
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-scope-mappings.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-scope-mappings.html
index 6ca4b0b..ebabbd9 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-scope-mappings.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-scope-mappings.html
@@ -56,7 +56,7 @@
<label for="applications">Application</label>
<div class="input-group">
<div class="select-rcue">
- <select id="applications" name="applications" ng-change="changeApplication()" ng-model="targetApp" ng-options="a.name for a in applications">
+ <select id="applications" name="applications" ng-change="changeApplication()" ng-model="targetApp" ng-options="a.name for a in (applications|remove:application:'id')">
<option value="" selected> Select an Application </option>
</select>
</div>
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/menu.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/menu.html
index d62d21d..13d6d99 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/menu.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/menu.html
@@ -3,7 +3,7 @@
<div class="navbar-inner clearfix container">
<h1><a href="#/realms/{{realm.id}}"><strong>Keycloak</strong> Central Login</a></h1>
<ul class="nav pull-right" data-ng-hide="auth.loggedIn">
- <li><a href="/auth-server/rest/saas/login">Login</a></li>
+ <li><a href="/auth-server/rest/saas/login?path={{fragment}}">Login</a></li>
<li><a href="/auth-server/rest/saas/registrations">Register</a></li>
</ul>
<ul class="nav pull-right" data-ng-show="auth.loggedIn">
@@ -25,7 +25,7 @@
<span class="dropdown-label" data-ng-show="showNav()">Realm:</span>
<div class="select-rcue" data-ng-show="showNav()">
<select ng-change="changeRealm()" ng-model="current.realm" ng-options="r.realm for r in current.realms"></select>
- </div><a href="#/realms/{{realm.id}}" id="refresh" data-ng-show="showNav()"><span class="icon-spinner6">Icon: spinner</span></a>
+ </div><a href="#/realms/{{current.realm.id}}" id="refresh" data-ng-show="showNav()"><span class="icon-spinner6">Icon: spinner</span></a>
</li>
</ul>
<div class="pull-right" data-ng-show="auth.loggedIn">
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-credentials.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-credentials.html
index 0f9f849..c3a538e 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-credentials.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-credentials.html
@@ -6,6 +6,7 @@
<ul class="rcue-tabs">
<li><a href="#/realms/{{realm.id}}">General</a></li>
<li data-ng-show="realm.social"><a href="#/realms/{{realm.id}}/social-settings">Social</a></li>
+ <li data-ng-show="realm.registrationAllowed"><a href="#/realms/{{realm.id}}/registration-settings">Registration</a></li>
<li><a href="#/realms/{{realm.id}}/roles">Roles</a></li>
<li class="active"><a href="#/realms/{{realm.id}}/required-credentials">Credentials</a></li>
<li><a href="#/realms/{{realm.id}}/token-settings">Token</a></li>
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-detail.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-detail.html
index d35d8cd..5c3bb5d 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-detail.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-detail.html
@@ -5,7 +5,8 @@
<div class="top-nav" data-ng-hide="createRealm">
<ul class="rcue-tabs">
<li class="active"><a href="#/realms/{{realm.id}}">General</a></li>
- <li data-ng-show="realm.social"><a href="#/realms/{{realm.id}}/social-settings">Social</a></li>
+ <li data-ng-show="social"><a href="#/realms/{{realm.id}}/social-settings">Social</a></li>
+ <li data-ng-show="registrationAllowed"><a href="#/realms/{{realm.id}}/registration-settings">Registration</a></li>
<li><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}}/token-settings">Token</a></li>
@@ -34,115 +35,41 @@
</div>
<div class="form-group">
<label for="enabled" class="control-label">Enabled</label>
-
- <div class="onoffswitch">
- <input type="checkbox" data-ng-model="realm.enabled" class="onoffswitch-checkbox"
- name="enabled" id="enabled">
- <label for="enabled" class="onoffswitch-label">
- <span class="onoffswitch-inner">
- <span class="onoffswitch-active">ON</span>
- <span class="onoffswitch-inactive">OFF</span>
- </span>
- <span class="onoffswitch-switch"></span>
- </label>
- </div>
+ <input ng-model="realm.enabled" name="enabled" id="enabled" onoffswitch />
</div>
</fieldset>
<fieldset>
<legend uncollapsed><span class="text">Login Options</span></legend>
<div class="form-group clearfix block">
<label for="social" class="control-label">Social login</label>
- <div class="onoffswitch">
- <input type="checkbox" data-ng-model="realm.social" class="onoffswitch-checkbox" name="social" id="social">
- <label for="social" class="onoffswitch-label">
- <span class="onoffswitch-inner">
- <span class="onoffswitch-active">ON</span>
- <span class="onoffswitch-inactive">OFF</span>
- </span>
- <span class="onoffswitch-switch"></span>
- </label>
- </div>
+ <input ng-model="realm.social" name="social" id="social" onoffswitch />
</div>
<div class="form-group clearfix block">
<label for="registrationAllowed" class="control-label">User registration</label>
- <div class="onoffswitch">
- <input type="checkbox" data-ng-model="realm.registrationAllowed" class="onoffswitch-checkbox" name="registrationAllowed" id="registrationAllowed">
- <label for="registrationAllowed" class="onoffswitch-label">
- <span class="onoffswitch-inner">
- <span class="onoffswitch-active">ON</span>
- <span class="onoffswitch-inactive">OFF</span>
- </span>
- <span class="onoffswitch-switch"></span>
- </label>
- </div>
+ <input ng-model="realm.registrationAllowed" name="registrationAllowed" id="registrationAllowed" onoffswitch />
</div>
<div class="form-group clearfix block">
<label for="resetPasswordAllowed" class="control-label">Reset password</label>
- <div class="onoffswitch">
- <input type="checkbox" data-ng-model="realm.resetPasswordAllowed" class="onoffswitch-checkbox" name="resetPasswordAllowed" id="resetPasswordAllowed">
- <label for="resetPasswordAllowed" class="onoffswitch-label">
- <span class="onoffswitch-inner">
- <span class="onoffswitch-active">ON</span>
- <span class="onoffswitch-inactive">OFF</span>
- </span>
- <span class="onoffswitch-switch"></span>
- </label>
- </div>
+ <input ng-model="realm.resetPasswordAllowed" name="resetPasswordAllowed" id="resetPasswordAllowed" onoffswitch />
</div>
<div class="form-group clearfix block">
<label for="verifyEmail" class="control-label">Verify email</label>
- <div class="onoffswitch">
- <input type="checkbox" data-ng-model="realm.verifyEmail" class="onoffswitch-checkbox" name="verifyEmail" id="verifyEmail">
- <label for="verifyEmail" class="onoffswitch-label">
- <span class="onoffswitch-inner">
- <span class="onoffswitch-active">ON</span>
- <span class="onoffswitch-inactive">OFF</span>
- </span>
- <span class="onoffswitch-switch"></span>
- </label>
- </div>
+ <input ng-model="realm.verifyEmail" name="verifyEmail" id="verifyEmail" onoffswitch />
</div>
<div class="form-group clearfix block">
<label for="accountManagement" class="control-label two-lines">User account management</label>
- <div class="onoffswitch">
- <input type="checkbox" data-ng-model="realm.accountManagement" class="onoffswitch-checkbox"
- name="accountManagement" id="accountManagement">
- <label for="accountManagement" class="onoffswitch-label">
- <span class="onoffswitch-inner">
- <span class="onoffswitch-active">ON</span>
- <span class="onoffswitch-inactive">OFF</span>
- </span>
- <span class="onoffswitch-switch"></span>
- </label>
- </div>
+ <input ng-model="realm.accountManagement" name="accountManagement" id="accountManagement" onoffswitch />
</div>
<div class="form-group clearfix block">
<label for="requireSsl" class="control-label">Require SSL</label>
- <div class="onoffswitch">
- <input type="checkbox" data-ng-model="realm.requireSsl" class="onoffswitch-checkbox" name="requireSsl" id="requireSsl">
- <label for="requireSsl" class="onoffswitch-label">
- <span class="onoffswitch-inner">
- <span class="onoffswitch-active">ON</span>
- <span class="onoffswitch-inactive">OFF</span>
- </span>
- <span class="onoffswitch-switch"></span>
- </label>
- </div>
+ <input ng-model="realm.requireSsl" name="requireSsl" id="requireSsl" onoffswitch />
</div>
<div class="form-group">
<label for="cookieLoginAllowed" class="control-label">Cookie login allowed</label>
- <div class="onoffswitch">
- <input type="checkbox" data-ng-model="realm.cookieLoginAllowed" class="onoffswitch-checkbox" name="cookieLoginAllowed" id="cookieLoginAllowed">
- <label for="cookieLoginAllowed" class="onoffswitch-label">
- <span class="onoffswitch-inner">
- <span class="onoffswitch-active">ON</span>
- <span class="onoffswitch-inactive">OFF</span>
- </span>
- <span class="onoffswitch-switch"></span>
- </label>
- </div>
+ <input ng-model="realm.cookieLoginAllowed" name="cookieLoginAllowed" id="cookieLoginAllowed" onoffswitch />
</div>
</fieldset>
+
<div class="form-actions" data-ng-show="createRealm">
<button type="submit" data-ng-click="save()" class="primary" data-ng-show="changed">Save
</button>
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-menu.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-menu.html
index 16f7b78..87e0ed1 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-menu.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-menu.html
@@ -1,5 +1,5 @@
<ul data-ng-hide="createRealm">
- <li data-ng-class="(!path[2] || path[1] == 'role' || path[2] == 'roles' || path[2] == 'token-settings' || path[2] == 'social-settings' || path[2] == 'required-credentials') && 'active'"><a href="#/realms/{{realm.id}}">Settings</a></li>
+ <li data-ng-class="(!path[2] || path[1] == 'role' || path[2] == 'roles' || path[2] == 'token-settings' || path[2] == 'social-settings' || path[2] == 'required-credentials' || path[2] == 'smtp-settings') && 'active'"><a href="#/realms/{{realm.id}}">Settings</a></li>
<li data-ng-class="(path[2] == 'users' || path[1] == 'user') && 'active'"><a href="#/realms/{{realm.id}}/users">Users</a>
</li>
<li data-ng-class="(path[2] == 'applications' || path[1] == 'application') && 'active'"><a href="#/realms/{{realm.id}}/applications">Applications</a></li>
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-registration.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-registration.html
new file mode 100755
index 0000000..1e38da4
--- /dev/null
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-registration.html
@@ -0,0 +1,95 @@
+<div id="wrapper" class="container">
+ <div class="row">
+ <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 class="top-nav" data-ng-hide="createRealm">
+ <ul class="rcue-tabs">
+ <li><a href="#/realms/{{realm.id}}">General</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}}/registration-settings">Registration</a></li>
+ <li><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}}/token-settings">Token</a></li>
+ <li><a href="#/realms/{{realm.id}}/smtp-settings">SMTP</a></li>
+ </ul>
+ </div>
+ <div id="content">
+ <ol class="breadcrumb">
+ <li><a href="#/realms/{{realm.id}}">{{realm.realm}}</a></li>
+ <li><a href="#/realms/{{realm.id}}">Settings</a></li>
+ <li class="active">Registration</li>
+ </ol>
+ <h2><span>{{realm.realm}}</span> Registration Settings</h2>
+ <form name="realmForm" novalidate>
+ <fieldset>
+ <legend uncollapsed><span class="text">Realm Default Roles</span> </legend>
+ <div class="form-group">
+ <div class="controls changing-selectors">
+ <div class="select-title">
+ <label for="available">Available Roles</label>
+ <select id="available" class="form-control" multiple size="5"
+ ng-multiple="true"
+ ng-model="selectedRealmRoles"
+ ng-options="r for r in availableRealmRoles">
+ </select>
+ </div>
+ <div class="middle-buttons">
+ <button type="submit" ng-click="addRealmDefaultRole()" tooltip="Move right" tooltip-placement="right"><span class="icon-arrow-right">Move right</span></button>
+ <button type="submit" ng-click="rmRealmDefaultRole()" tooltip="Move left" tooltip-placement="right"><span class="icon-arrow-left">Move left</span></button>
+ </div>
+ <div class="select-title">
+ <label for="assigned">Realm Default Roles</label>
+ <select id="assigned" class="form-control" multiple size=5
+ ng-multiple="true"
+ ng-model="selectedRealmDefRoles"
+ ng-options="r for r in realm.defaultRoles">
+ </select>
+ </div>
+ </div>
+ </div>
+ </fieldset>
+
+ <fieldset ng-show="applications.length > 0">
+ <legend uncollapsed><span class="text">Application Default Roles</span> </legend>
+ <div class="form-group input-select">
+ <label for="applications">Application</label>
+ <div class="input-group">
+ <div class="select-rcue">
+ <select id="applications" name="applications" ng-change="changeApplication()" ng-model="application" ng-options="a.name for a in applications">
+ <option value="" selected> Select an Application...</option>
+ </select>
+ </div>
+ </div>
+ </div>
+ <div class="form-group" ng-show="application">
+ <div class="controls changing-selectors application">
+ <div class="select-title">
+ <label for="available-app">Available Roles</label>
+ <select id="available-app" class="form-control" multiple size="5"
+ ng-multiple="true"
+ ng-model="selectedAppRoles"
+ ng-options="r for r in availableAppRoles">
+ </select>
+ </div>
+ <div class="middle-buttons">
+ <button type="submit" ng-click="addAppDefaultRole()" tooltip="Move right" tooltip-placement="right"><span class="icon-arrow-right">Move right</span></button>
+ <button type="submit" ng-click="rmAppDefaultRole()" tooltip="Move left" tooltip-placement="right"><span class="icon-arrow-left">Move left</span></button>
+ </div>
+ <div class="select-title">
+ <label for="assigned-app">Assigned Default Roles</label>
+ <select id="assigned-app" class="form-control" multiple size=5
+ ng-multiple="true"
+ ng-model="selectedAppDefRoles"
+ ng-options="r for r in application.defaultRoles">
+ </select>
+ </div>
+ </div>
+ </div>
+ </fieldset>
+
+ </form>
+ </div>
+ </div>
+ <div id="container-right-bg"></div>
+ </div>
+</div>
\ No newline at end of file
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-smtp.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-smtp.html
index 6abd4ee..02940a1 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-smtp.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-smtp.html
@@ -6,6 +6,7 @@
<ul class="rcue-tabs">
<li><a href="#/realms/{{realm.id}}">General</a></li>
<li data-ng-show="realm.social"><a href="#/realms/{{realm.id}}/social-settings">Social</a></li>
+ <li data-ng-show="realm.registrationAllowed"><a href="#/realms/{{realm.id}}/registration-settings">Registration</a></li>
<li><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}}/token-settings">Token</a></li>
@@ -42,45 +43,18 @@
</div>
<div class="form-group clearfix">
<label for="smtpSSL" class="control-label">Enable SSL</label>
- <div class="onoffswitch">
- <input type="checkbox" data-ng-model="realm.smtpServer.ssl" class="onoffswitch-checkbox" name="smtpSSL" id="smtpSSL">
- <label for="smtpSSL" class="onoffswitch-label">
- <span class="onoffswitch-inner">
- <span class="onoffswitch-active">ON</span>
- <span class="onoffswitch-inactive">OFF</span>
- </span>
- <span class="onoffswitch-switch"></span>
- </label>
- </div>
+ <input ng-model="realm.smtpServer.ssl" name="smtpSSL" id="smtpSSL" onoffswitch />
</div>
<div class="form-group clearfix">
<label for="smtpStartTLS" class="control-label">Enable StartTLS</label>
- <div class="onoffswitch">
- <input type="checkbox" data-ng-model="realm.smtpServer.starttls" class="onoffswitch-checkbox" name="smtpStartTLS" id="smtpStartTLS">
- <label for="smtpStartTLS" class="onoffswitch-label">
- <span class="onoffswitch-inner">
- <span class="onoffswitch-active">ON</span>
- <span class="onoffswitch-inactive">OFF</span>
- </span>
- <span class="onoffswitch-switch"></span>
- </label>
- </div>
+ <input ng-model="realm.smtpServer.starttls" name="smtpStartTLS" id="smtpStartTLS" onoffswitch />
</div>
</fieldset>
<fieldset>
<legend collapsed><span class="text">Authentication</span></legend>
<div class="form-group clearfix">
<label for="smtpAuth" class="control-label">Enabled</label>
- <div class="onoffswitch">
- <input type="checkbox" data-ng-model="realm.smtpServer.auth" class="onoffswitch-checkbox" name="smtpAuth" id="smtpAuth">
- <label for="smtpAuth" class="onoffswitch-label">
- <span class="onoffswitch-inner">
- <span class="onoffswitch-active">ON</span>
- <span class="onoffswitch-inactive">OFF</span>
- </span>
- <span class="onoffswitch-switch"></span>
- </label>
- </div>
+ <input ng-model="realm.smtpServer.auth" name="smtpAuth" id="smtpAuth" onoffswitch />
</div>
<div class="form-group clearfix">
<label for="smtpUsername" class="control-label">Username <span class="required" ng-show="realm.smtpServer.auth">*</span></label>
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-social.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-social.html
index a046cc5..34b0a8b 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-social.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-social.html
@@ -6,6 +6,7 @@
<ul class="rcue-tabs">
<li><a href="#/realms/{{realm.id}}">General</a></li>
<li class="active" data-ng-show="realm.social"><a href="#/realms/{{realm.id}}/social-settings">Social</a></li>
+ <li data-ng-show="realm.registrationAllowed"><a href="#/realms/{{realm.id}}/registration-settings">Registration</a></li>
<li><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}}/token-settings">Token</a></li>
@@ -30,7 +31,8 @@
<div class="actions">
<div class="select-rcue">
<select ng-model="newProviderId"
- ng-options="p for p in unsetProviders"></select>
+ ng-options="p as allProviders[p] for p in unsetProviders"
+ placeholder="Please select"></select>
</div>
<div>
<button ng-click="addProvider()" ng-disabled="">Add Provider</button>
@@ -49,16 +51,16 @@
<tr ng-repeat="pId in configuredProviders">
<td>
<div class="clearfix">
- <input class="input-small disabled" type="text" placeholder="Key" value="{{pId}}" readonly>
+ <input class="input-small disabled" type="text" value="{{allProviders[pId]}}" readonly>
</div>
</td>
<td>
<input class="input-small" type="text" placeholder="Key" ng-model="realm.socialProviders[pId+'.key']"
- ng-class="{'dirty': saveClicked}" required>
+ ng-class="{'dirty': postSaveProviders.indexOf(pId) > -1}" required>
</td>
<td>
<input class="input-small" type="text" placeholder="Secret" ng-model="realm.socialProviders[pId+'.secret']"
- ng-class="{'dirty': saveClicked}" required>
+ ng-class="{'dirty': postSaveProviders.indexOf(pId) > -1}" required>
</td>
<td>
<div class="action-div"><i class="icon-question" ng-click="openHelp(pId)"></i></div>
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-tokens.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-tokens.html
index 4092a90..72146da 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-tokens.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-tokens.html
@@ -6,6 +6,7 @@
<ul class="rcue-tabs">
<li><a href="#/realms/{{realm.id}}">General</a></li>
<li data-ng-show="realm.social"><a href="#/realms/{{realm.id}}/social-settings">Social</a></li>
+ <li data-ng-show="realm.registrationAllowed"><a href="#/realms/{{realm.id}}/registration-settings">Registration</a></li>
<li><a href="#/realms/{{realm.id}}/roles">Roles</a></li>
<li><a href="#/realms/{{realm.id}}/required-credentials">Credentials</a></li>
<li class="active"><a href="#/realms/{{realm.id}}/token-settings">Token</a></li>
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/role-list.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/role-list.html
index b1ae532..c16515e 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/role-list.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/role-list.html
@@ -6,6 +6,7 @@
<ul class="rcue-tabs">
<li><a href="#/realms/{{realm.id}}">General</a></li>
<li data-ng-show="realm.social"><a href="#/realms/{{realm.id}}/social-settings">Social</a></li>
+ <li data-ng-show="realm.registrationAllowed"><a href="#/realms/{{realm.id}}/registration-settings">Registration</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}}/token-settings">Token</a></li>
diff --git a/admin-ui-styles/src/main/resources/META-INF/resources/admin-ui/css/admin-console.css b/admin-ui-styles/src/main/resources/META-INF/resources/admin-ui/css/admin-console.css
index bf52b71..1cea3b5 100644
--- a/admin-ui-styles/src/main/resources/META-INF/resources/admin-ui/css/admin-console.css
+++ b/admin-ui-styles/src/main/resources/META-INF/resources/admin-ui/css/admin-console.css
@@ -55,17 +55,44 @@ body {
color: #fff;
font-weight: bold;
}
-.loading span {
- background: url(img/loader.gif) no-repeat center top;
+.loading-backdrop {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1031;
+ background-color: #FFFFFF;
+ opacity: 0.75;
+}
+.loading {
position: fixed;
- z-index: 1000;
+ z-index: 1032;
top: 50%;
left: 50%;
+ width: 6em;
+ height: 6em;
+ margin-top: -3em;
+ margin-left: -3em;
+ text-align: center;
+}
+.loading img {
+ width: 3em;
+ height: 3em;
+ background-color: #f0f0f0;
+ display: inline-block;
+ padding: 0.3em;
+ border-radius: 0.4em;
+}
+.loading span {
+ background: url(img/loader.gif) no-repeat center top;
+ font-size: 1.2em;
+ color: #666;
+ display: inline-block;
+ padding-top: 0.36363636363636em;
margin-top: -2.27272727272727em;
margin-left: -2.27272727272727em;
padding-top: 2.90909090909091em;
- font-size: 1.1em;
- color: #666;
}
/* Header */
.header.rcue {
@@ -485,11 +512,11 @@ td.token-cell button {
font-family: "Open Sans", sans-serif;
margin: 0;
}
-.modal .modal-body p {
+.modal .modal-body p span {
+ display: block;
font-size: 1.1em;
}
-.modal .modal-body p.primary {
- font-size: 1.1em;
+.modal .modal-body p span.primary {
font-weight: bold;
margin-bottom: 0.45454545454545em;
}
diff --git a/admin-ui-styles/src/main/resources/META-INF/resources/admin-ui/css/admin-console.less b/admin-ui-styles/src/main/resources/META-INF/resources/admin-ui/css/admin-console.less
index 7ef77be..d5bfdf2 100644
--- a/admin-ui-styles/src/main/resources/META-INF/resources/admin-ui/css/admin-console.less
+++ b/admin-ui-styles/src/main/resources/META-INF/resources/admin-ui/css/admin-console.less
@@ -74,19 +74,46 @@ body {
}
}
+.loading-backdrop {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1031;
+ background-color: #FFFFFF;
+ opacity: 0.75;
+}
+
.loading {
-
+ position: fixed;
+ z-index: 1032;
+ top: 50%;
+ left: 50%;
+ width: 6em;
+ height: 6em;
+ margin-top: -3em;
+ margin-left: -3em;
+ text-align: center;
+
+ img {
+ width: 3em;
+ height: 3em;
+ background-color: #f0f0f0;
+ display: inline-block;
+ padding: 0.3em;
+ border-radius: 0.4em;
+ }
+
span {
background: url(img/loader.gif) no-repeat center top;
- position: fixed;
- z-index: 1000;
- top: 50%;
- left: 50%;
+ font-size: 1.2em;
+ color: #666;
+ display: inline-block;
+ padding-top: 0.36363636363636em;
margin-top: -2.27272727272727em;
margin-left: -2.27272727272727em;
padding-top: 2.90909090909091em;
- font-size: 1.1em;
- color: #666;
}
}
@@ -592,11 +619,11 @@ td.token-cell button {
.modal-body {
- p {
+ p span {
+ display: block;
font-size: 1.1em;
-
+
&.primary {
- font-size: 1.1em;
font-weight: bold;
margin-bottom: 0.45454545454545em;
}
diff --git a/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java
index 59347ca..bab05a0 100755
--- a/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java
@@ -14,7 +14,6 @@ public class ApplicationRepresentation {
protected String adminUrl;
protected String baseUrl;
protected boolean surrogateAuthRequired;
- protected boolean useRealmMappings;
protected boolean enabled;
protected List<CredentialRepresentation> credentials;
protected List<RoleRepresentation> roles;
@@ -142,14 +141,6 @@ public class ApplicationRepresentation {
return this;
}
- public boolean isUseRealmMappings() {
- return useRealmMappings;
- }
-
- public void setUseRealmMappings(boolean useRealmMappings) {
- this.useRealmMappings = useRealmMappings;
- }
-
public List<String> getRedirectUris() {
return redirectUris;
}
diff --git a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
index c520fd3..3b9b4d1 100755
--- a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
@@ -33,6 +33,7 @@ public class RealmRepresentation {
protected Set<String> requiredApplicationCredentials;
protected Set<String> requiredOAuthClientCredentials;
protected List<UserRepresentation> users;
+ protected List<UserRepresentation> clients;
protected List<UserRoleMappingRepresentation> roleMappings;
protected List<ScopeMappingRepresentation> scopeMappings;
protected List<SocialMappingRepresentation> socialMappings;
@@ -68,6 +69,10 @@ public class RealmRepresentation {
return users;
}
+ public List<UserRepresentation> getClients() {
+ return clients;
+ }
+
public List<ApplicationRepresentation> getApplications() {
return applications;
}
@@ -84,6 +89,10 @@ public class RealmRepresentation {
this.users = users;
}
+ public void setClients(List<UserRepresentation> clients) {
+ this.clients = clients;
+ }
+
public UserRepresentation user(String username) {
UserRepresentation user = new UserRepresentation();
user.setUsername(username);
dist/assembly.xml 2(+1 -1)
diff --git a/dist/assembly.xml b/dist/assembly.xml
index 4c892d1..62241e2 100644
--- a/dist/assembly.xml
+++ b/dist/assembly.xml
@@ -16,7 +16,7 @@
<excludes>
<exclude>**/*.sh</exclude>
<exclude>domain/tmp/auth</exclude>
- <exclude>domain/tmp/auth</exclude>
+ <exclude>standalone/tmp/auth</exclude>
<exclude>**/*-users.properties</exclude>
</excludes>
</fileSet>
dist/build.xml 14(+8 -6)
diff --git a/dist/build.xml b/dist/build.xml
index c9bfd95..d48480d 100644
--- a/dist/build.xml
+++ b/dist/build.xml
@@ -1,19 +1,20 @@
<project name="keycloak-dist" basedir=".">
- <target name="jboss">
- <unzip src="${org.jboss.as:jboss-as-dist:zip}" dest="${project.build.directory}"/>
+ <target name="wildfly">
+ <unzip src="${org.wildfly:wildfly-dist:zip}" dest="${project.build.directory}"/>
<chmod perm="755">
- <fileset dir="${project.build.directory}/jboss-as-${jboss.version}/bin">
+ <fileset dir="${project.build.directory}/wildfly-${wildfly.version}/bin">
<include name="**/*.sh"/>
</fileset>
</chmod>
<move todir="${build.target.dir}" overwrite="true">
- <fileset dir="${project.build.directory}/jboss-as-${jboss.version}">
+ <fileset dir="${project.build.directory}/wildfly-${wildfly.version}">
<include name="**/*"/>
</fileset>
</move>
- <delete dir="${project.build.directory}/jboss-as-${jboss.version}"/>
+ <delete dir="${project.build.directory}/wildfly-${wildfly.version}"/>
</target>
+ <!--
<target name="resteasy-modules">
<get src="http://sourceforge.net/projects/resteasy/files/Resteasy%20JAX-RS/${resteasy.version}/resteasy-jaxrs-${resteasy.version}-all.zip"
dest="${project.build.directory}" skipexisting="true"/>
@@ -27,11 +28,12 @@
<unzip src="${project.build.directory}/resteasy-jboss-modules-${resteasy.version}.zip"
dest="${build.target.dir}/modules"/>
</target>
+ -->
<target name="keycloak-server">
<copy file="${org.keycloak:keycloak-server:war}"
tofile="${build.target.dir}/standalone/deployments/auth-server.war" overwrite="true"/>
</target>
- <target name="all" depends="jboss, resteasy-modules, keycloak-server"/>
+ <target name="all" depends="wildfly, keycloak-server"/>
</project>
dist/pom.xml 34(+31 -3)
diff --git a/dist/pom.xml b/dist/pom.xml
index ef0ff99..2876183 100644
--- a/dist/pom.xml
+++ b/dist/pom.xml
@@ -35,9 +35,9 @@
<type>war</type>
</dependency>
<dependency>
- <groupId>org.jboss.as</groupId>
- <artifactId>jboss-as-dist</artifactId>
- <version>${jboss.version}</version>
+ <groupId>org.wildfly</groupId>
+ <artifactId>wildfly-dist</artifactId>
+ <version>${wildfly.version}</version>
<type>zip</type>
</dependency>
</dependencies>
@@ -67,6 +67,34 @@
</plugin>
<plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>xml-maven-plugin</artifactId>
+ <version>1.0</version>
+ <executions>
+ <execution>
+ <id>generate-resources</id>
+ <phase>package</phase>
+ <goals>
+ <goal>transform</goal>
+ </goals>
+ <configuration>
+ <transformationSets>
+ <transformationSet>
+ <dir>${build.target.dir}/standalone/configuration</dir>
+ <stylesheet>src/main/xslt/standalone.xsl</stylesheet>
+ <includes>
+ <include>standalone*.xml</include>
+ </includes>
+ <outputDir>${build.target.dir}/standalone/configuration</outputDir>
+ </transformationSet>
+ </transformationSets>
+ <targetDirectory>${project.build.directory}</targetDirectory>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
dist/src/main/xslt/standalone.xsl 33(+33 -0)
diff --git a/dist/src/main/xslt/standalone.xsl b/dist/src/main/xslt/standalone.xsl
new file mode 100644
index 0000000..711b71f
--- /dev/null
+++ b/dist/src/main/xslt/standalone.xsl
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:xalan="http://xml.apache.org/xalan"
+ xmlns:j="urn:jboss:domain:1.3"
+ version="2.0"
+ exclude-result-prefixes="xalan j">
+
+ <xsl:param name="config"/>
+
+ <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" xalan:indent-amount="4" standalone="no"/>
+ <xsl:strip-space elements="*"/>
+
+ <xsl:template match="node()[name(.)='datasources']">
+ <xsl:copy>
+ <xsl:apply-templates select="node()|@*"/>
+ <datasource jndi-name="java:jboss/datasources/KeycloakDS" pool-name="KeycloakDS" enabled="true" use-java-context="true">
+ <connection-url>jdbc:h2:${jboss.server.data.dir}/keycloak;DB_CLOSE_DELAY=-1</connection-url>
+ <driver>h2</driver>
+ <security>
+ <user-name>sa</user-name>
+ <password>sa</password>
+ </security>
+ </datasource>
+ </xsl:copy>
+ </xsl:template>
+
+ <xsl:template match="@*|node()">
+ <xsl:copy>
+ <xsl:apply-templates select="@*|node()" />
+ </xsl:copy>
+ </xsl:template>
+
+</xsl:stylesheet>
\ No newline at end of file
examples/as7-eap-demo/server/pom.xml 5(+5 -0)
diff --git a/examples/as7-eap-demo/server/pom.xml b/examples/as7-eap-demo/server/pom.xml
index 6d21685..8b82f4b 100755
--- a/examples/as7-eap-demo/server/pom.xml
+++ b/examples/as7-eap-demo/server/pom.xml
@@ -112,6 +112,11 @@
<version>4.1</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.jboss.spec.javax.servlet</groupId>
+ <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+ <scope>provided</scope>
+ </dependency>
</dependencies>
<build>
diff --git a/examples/as7-eap-demo/server/src/main/resources/META-INF/testrealm.json b/examples/as7-eap-demo/server/src/main/resources/META-INF/testrealm.json
index 284a4be..cc267ee 100755
--- a/examples/as7-eap-demo/server/src/main/resources/META-INF/testrealm.json
+++ b/examples/as7-eap-demo/server/src/main/resources/META-INF/testrealm.json
@@ -26,7 +26,9 @@
{ "type" : "password",
"value" : "password" }
]
- },
+ }
+ ],
+ "clients" : [
{
"username" : "third-party",
"enabled": true,
@@ -50,10 +52,6 @@
{
"username": "bburke@redhat.com",
"roles": ["user"]
- },
- {
- "username": "third-party",
- "roles": ["KEYCLOAK_IDENTITY_REQUESTER"]
}
],
"scopeMappings": [
@@ -67,7 +65,6 @@
"name": "customer-portal",
"enabled": true,
"adminUrl": "http://localhost:8080/customer-portal/j_admin_request",
- "useRealmMappings": true,
"credentials": [
{
"type": "password",
@@ -79,7 +76,6 @@
"name": "product-portal",
"enabled": true,
"adminUrl": "http://localhost:8080/product-portal/j_admin_request",
- "useRealmMappings": true,
"credentials": [
{
"type": "password",
@@ -88,4 +84,4 @@
]
}
]
-}
\ No newline at end of file
+}
diff --git a/examples/as7-eap-demo/server/src/main/webapp/WEB-INF/web.xml b/examples/as7-eap-demo/server/src/main/webapp/WEB-INF/web.xml
index fafd744..6829b0e 100755
--- a/examples/as7-eap-demo/server/src/main/webapp/WEB-INF/web.xml
+++ b/examples/as7-eap-demo/server/src/main/webapp/WEB-INF/web.xml
@@ -21,10 +21,6 @@
<async-supported>true</async-supported>
</servlet>
- <listener>
- <listener-class>org.keycloak.services.listeners.MongoRunnerListener</listener-class>
- </listener>
-
<filter>
<filter-name>Keycloak Session Management</filter-name>
<filter-class>org.keycloak.services.filters.KeycloakSessionServletFilter</filter-class>
examples/as7-eap-dev/server/pom.xml 5(+5 -0)
diff --git a/examples/as7-eap-dev/server/pom.xml b/examples/as7-eap-dev/server/pom.xml
index 4ccbd3e..6428b6e 100755
--- a/examples/as7-eap-dev/server/pom.xml
+++ b/examples/as7-eap-dev/server/pom.xml
@@ -95,6 +95,11 @@
<version>4.1</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.jboss.spec.javax.servlet</groupId>
+ <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+ <scope>provided</scope>
+ </dependency>
</dependencies>
<build>
diff --git a/examples/as7-eap-dev/server/src/main/resources/META-INF/testrealm.json b/examples/as7-eap-dev/server/src/main/resources/META-INF/testrealm.json
index 41fe13e..888a518 100755
--- a/examples/as7-eap-dev/server/src/main/resources/META-INF/testrealm.json
+++ b/examples/as7-eap-dev/server/src/main/resources/META-INF/testrealm.json
@@ -26,7 +26,9 @@
{ "type" : "password",
"value" : "password" }
]
- },
+ }
+ ],
+ "clients" : [
{
"username" : "third-party",
"enabled": true,
@@ -50,10 +52,6 @@
{
"username": "bburke@redhat.com",
"roles": ["user"]
- },
- {
- "username": "third-party",
- "roles": ["KEYCLOAK_IDENTITY_REQUESTER"]
}
],
"scopeMappings": [
@@ -67,7 +65,6 @@
"name": "customer-portal",
"enabled": true,
"adminUrl": "http://localhost:8080/customer-portal/j_admin_request",
- "useRealmMappings": true,
"webOrigins" : [ "http://localhost1:8080"],
"credentials": [
{
@@ -80,7 +77,6 @@
"name": "product-portal",
"enabled": true,
"adminUrl": "http://localhost:8080/product-portal/j_admin_request",
- "useRealmMappings": true,
"credentials": [
{
"type": "password",
@@ -89,4 +85,4 @@
]
}
]
-}
\ No newline at end of file
+}
examples/js/testrealm.json 1(+0 -1)
diff --git a/examples/js/testrealm.json b/examples/js/testrealm.json
index 38225c6..ee72300 100755
--- a/examples/js/testrealm.json
+++ b/examples/js/testrealm.json
@@ -48,7 +48,6 @@
"name": "test-app",
"enabled": true,
"adminUrl": "http://localhost:8081/app/logout",
- "useRealmMappings": true,
"webOrigins": [ "http://localhost", "http://localhost:8000", "http://localhost:8080" ],
"credentials": [
{
forms/pom.xml 14(+1 -13)
diff --git a/forms/pom.xml b/forms/pom.xml
index 933b9ae..08694ad 100755
--- a/forms/pom.xml
+++ b/forms/pom.xml
@@ -38,19 +38,7 @@
<artifactId>resteasy-jaxrs</artifactId>
<scope>provided</scope>
</dependency>
- <dependency>
- <groupId>org.jboss.spec.javax.servlet</groupId>
- <artifactId>jboss-servlet-api_3.0_spec</artifactId>
- </dependency>
- <dependency>
- <groupId>com.google.zxing</groupId>
- <artifactId>core</artifactId>
- </dependency>
- <dependency>
- <groupId>com.google.zxing</groupId>
- <artifactId>javase</artifactId>
- </dependency>
- <dependency>
+ <dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
</dependency>
diff --git a/forms/src/main/java/org/keycloak/service/FormServiceImpl.java b/forms/src/main/java/org/keycloak/service/FormServiceImpl.java
index b7b914c..28ed554 100755
--- a/forms/src/main/java/org/keycloak/service/FormServiceImpl.java
+++ b/forms/src/main/java/org/keycloak/service/FormServiceImpl.java
@@ -104,7 +104,7 @@ public class FormServiceImpl implements FormService {
Configuration cfg = new Configuration();
try {
- cfg.setClassForTemplateLoading(FormServiceImpl.class,"/META-INF/resources");
+ cfg.setClassForTemplateLoading(FormServiceImpl.class,"/META-INF/resources/forms/theme/default");
Template template = cfg.getTemplate(temp);
template.process(input, out);
diff --git a/forms/src/main/resources/META-INF/resources/forms/theme/default/css/login-register.css b/forms/src/main/resources/META-INF/resources/forms/theme/default/css/login-register.css
index bc25029..e26aa9d 100644
--- a/forms/src/main/resources/META-INF/resources/forms/theme/default/css/login-register.css
+++ b/forms/src/main/resources/META-INF/resources/forms/theme/default/css/login-register.css
@@ -71,7 +71,7 @@ body {
width: auto;
position: relative;
}
-.rcue-login-register .background-area .separator .section,
+.rcue-login-register .background-area .section,
.rcue-login-register .background-area .social .section {
padding-top: 1.5em;
padding-bottom: 1.5em;
@@ -303,10 +303,24 @@ a.zocial:before {
.rcue-login-register .background-area .content-area ul li {
border-top: 1px solid #34393C;
padding: 2em;
+ position: relative;
}
-.rcue-login-register .background-area .content-area ul li span:first-child {
+.rcue-login-register .background-area .content-area ul li span {
font-size: 1.3em;
+ line-height: 1.3em;
+}
+
+.rcue-login-register .background-area .content-area ul li span:first-child {
+ padding-right: 11.5384615384615em;
+}
+
+.rcue-login-register .background-area .content-area ul li span.parent {
+ position: absolute;
+ left: 26em;
+ top: 1.53846153846154em;
+ width: 12.3076923076923em;
}
+
.rcue-login-register .background-area .content-area ul li span.icon-info {
float: right;
margin-top: 0.5em;
diff --git a/forms/src/main/resources/META-INF/resources/forms/theme/default/login-oauth-grant.ftl b/forms/src/main/resources/META-INF/resources/forms/theme/default/login-oauth-grant.ftl
index 85121de..8ff76db 100755
--- a/forms/src/main/resources/META-INF/resources/forms/theme/default/login-oauth-grant.ftl
+++ b/forms/src/main/resources/META-INF/resources/forms/theme/default/login-oauth-grant.ftl
@@ -19,17 +19,13 @@
</li>
</#list>
- <#list oauth.resourceRolesRequested?keys as resourceRole>
- <li>
- <strong>${resourceRole}</strong>
- <ul>
- <#list oauth.resourceRolesRequested[resourceRole] as role>
- <li>
- <span><#if role.description??>${role.description}<#else>${role.name}</#if></span>
- </li>
- </#list>
- </ul>
- </li>
+ <#list oauth.resourceRolesRequested?keys as resource>
+ <#list oauth.resourceRolesRequested[resource] as role>
+ <li>
+ <span><#if role.description??>${role.description}<#else>${role.name}</#if></span>
+ <span class="parent">in <strong>${resource}</strong></span>
+ </li>
+ </#list>
</#list>
</ul>
diff --git a/forms/src/main/resources/META-INF/resources/forms/theme/default/login-reset-password.ftl b/forms/src/main/resources/META-INF/resources/forms/theme/default/login-reset-password.ftl
index 96f8795..7a045e5 100755
--- a/forms/src/main/resources/META-INF/resources/forms/theme/default/login-reset-password.ftl
+++ b/forms/src/main/resources/META-INF/resources/forms/theme/default/login-reset-password.ftl
@@ -1,5 +1,5 @@
<#import "template-login-action.ftl" as layout>
-<@layout.registrationLayout bodyClass="reset"; section>
+<@layout.registrationLayout bodyClass="reset" isSeparator=true forceSeparator=true; section>
<#if section = "title">
${rb.getString('emailForgotHeader')}
@@ -23,6 +23,6 @@
</form>
</div>
<#elseif section = "info" >
- <p><a href="#">« Back to Login</a></p>
+ <p><a href="${url.loginUrl}">« Back to Login</a></p>
</#if>
</@layout.registrationLayout>
\ No newline at end of file
diff --git a/forms/src/main/resources/META-INF/resources/forms/theme/default/login-update-password.ftl b/forms/src/main/resources/META-INF/resources/forms/theme/default/login-update-password.ftl
index 74142e0..955d4df 100755
--- a/forms/src/main/resources/META-INF/resources/forms/theme/default/login-update-password.ftl
+++ b/forms/src/main/resources/META-INF/resources/forms/theme/default/login-update-password.ftl
@@ -1,5 +1,5 @@
<#import "template-login-action.ftl" as layout>
-<@layout.registrationLayout bodyClass="reset"; section>
+<@layout.registrationLayout bodyClass="reset" isSeparator=false forceSeparator=true; section>
<#if section = "title">
${rb.getString('emailUpdateHeader')}
diff --git a/forms/src/main/resources/META-INF/resources/forms/theme/default/login-update-profile.ftl b/forms/src/main/resources/META-INF/resources/forms/theme/default/login-update-profile.ftl
index 32bdd23..ca707a5 100755
--- a/forms/src/main/resources/META-INF/resources/forms/theme/default/login-update-profile.ftl
+++ b/forms/src/main/resources/META-INF/resources/forms/theme/default/login-update-profile.ftl
@@ -1,5 +1,5 @@
<#import "template-login-action.ftl" as layout>
-<@layout.registrationLayout bodyClass=""; section>
+<@layout.registrationLayout bodyClass="" isSeparator=false forceSeparator=true; section>
<#if section = "title">
Update Account Information
diff --git a/forms/src/main/resources/META-INF/resources/forms/theme/default/login-verify-email.ftl b/forms/src/main/resources/META-INF/resources/forms/theme/default/login-verify-email.ftl
index 0832666..cc83a85 100755
--- a/forms/src/main/resources/META-INF/resources/forms/theme/default/login-verify-email.ftl
+++ b/forms/src/main/resources/META-INF/resources/forms/theme/default/login-verify-email.ftl
@@ -1,5 +1,5 @@
<#import "template-login-action.ftl" as layout>
-<@layout.registrationLayout bodyClass="email"; section>
+<@layout.registrationLayout bodyClass="email" isSeparator=false forceSeparator=true; section>
<#if section = "title">
Email verification
diff --git a/forms/src/main/resources/META-INF/resources/forms/theme/default/template-login.ftl b/forms/src/main/resources/META-INF/resources/forms/theme/default/template-login.ftl
index acbb082..10c668a 100644
--- a/forms/src/main/resources/META-INF/resources/forms/theme/default/template-login.ftl
+++ b/forms/src/main/resources/META-INF/resources/forms/theme/default/template-login.ftl
@@ -1,4 +1,4 @@
-<#macro registrationLayout bodyClass>
+<#macro registrationLayout bodyClass isSeparator=false forceSeparator=false>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
@@ -7,6 +7,7 @@
<title>
<#nested "title">
</title>
+ <link rel="icon" href="${template.formsPath}/theme/${template.theme}/img/favicon.ico">
<link href="${template.themeConfig.styles}" rel="stylesheet" />
<style type="text/css">
body.rcue-login-register {
@@ -18,7 +19,7 @@
<body class="rcue-login-register ${bodyClass}">
<#if (template.themeConfig.logo)?has_content>
<h1>
- <a href="#" title="Go to the login page"><img src="${template.themeConfig.logo}" alt="Red Hat Logo" /></a>
+ <a href="${url.loginUrl}" title="Go to the login page"><img src="${template.themeConfig.logo}" alt="Red Hat Logo" /></a>
</h1>
</#if>
@@ -28,7 +29,12 @@
</h2>
<div class="background-area">
- <div class="form-area ${(realm.social)?string('social','')} clearfix">
+ <#if !forceSeparator && realm?has_content>
+ <#assign drawSeparator = realm.registrationAllowed>
+ <#else>
+ <#assign drawSeparator = isSeparator>
+ </#if>
+ <div class="form-area ${(realm.social && bodyClass != "register")?string('social','')} ${(drawSeparator)?string('separator','')} clearfix">
<div class="section app-form">
<h3>Application login area</h3>
<#if message?has_content && message.error>
diff --git a/forms/src/main/resources/META-INF/resources/forms/theme/default/template-login-action.ftl b/forms/src/main/resources/META-INF/resources/forms/theme/default/template-login-action.ftl
index 982b31f..f3113dc 100644
--- a/forms/src/main/resources/META-INF/resources/forms/theme/default/template-login-action.ftl
+++ b/forms/src/main/resources/META-INF/resources/forms/theme/default/template-login-action.ftl
@@ -1,4 +1,4 @@
-<#macro registrationLayout bodyClass isErrorPage=false>
+<#macro registrationLayout bodyClass isErrorPage=false isSeparator=false forceSeparator=false>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
@@ -7,6 +7,7 @@
<title>
<#nested "title">
</title>
+ <link rel="icon" href="${template.formsPath}/theme/${template.theme}/img/favicon.ico">
<link href="${template.themeConfig.styles}" rel="stylesheet" />
<style type="text/css">
body.rcue-login-register {
@@ -25,7 +26,7 @@
</div>
<#if (template.themeConfig.logo)?has_content>
<h1>
- <a href="#" title="Go to the login page"><img src="${template.themeConfig.logo}" alt="Red Hat Logo" /></a>
+ <a href="${url.loginUrl}" title="Go to the login page"><img src="${template.themeConfig.logo}" alt="Red Hat Logo" /></a>
</h1>
</#if>
@@ -35,7 +36,12 @@
</h2>
<div class="background-area">
- <div class="form-area clearfix">
+ <#if !forceSeparator && realm?has_content>
+ <#assign drawSeparator = realm.registrationAllowed>
+ <#else>
+ <#assign drawSeparator = isSeparator>
+ </#if>
+ <div class="form-area clearfix ${(drawSeparator)?string('separator','')}">
<div class="section app-form">
<#if !isErrorPage && message?has_content>
<#if message.error>
diff --git a/forms/src/main/resources/META-INF/resources/forms/theme/default/template-main.ftl b/forms/src/main/resources/META-INF/resources/forms/theme/default/template-main.ftl
index 61e24a8..4a45d93 100644
--- a/forms/src/main/resources/META-INF/resources/forms/theme/default/template-main.ftl
+++ b/forms/src/main/resources/META-INF/resources/forms/theme/default/template-main.ftl
@@ -4,8 +4,7 @@
<head>
<meta charset="utf-8">
<title>Edit Account - <#nested "title"></title>
- <!-- TODO replace with actual logo once
- <link rel="icon" href="img/favicon.ico">
+ <link rel="icon" href="${template.formsPath}/theme/${template.theme}/img/favicon.ico">
<!-- Frameworks -->
<link rel="stylesheet" href="${template.formsPath}/theme/${template.theme}/css/reset.css">
diff --git a/forms/src/main/resources/org/keycloak/forms/messages.properties b/forms/src/main/resources/org/keycloak/forms/messages.properties
index be120c2..aa13cf8 100644
--- a/forms/src/main/resources/org/keycloak/forms/messages.properties
+++ b/forms/src/main/resources/org/keycloak/forms/messages.properties
@@ -22,15 +22,15 @@ passwordNewConfirm=New Password confirmation
authenticatorCode=One-time-password
clientCertificate=Client Certificate
-invalidUser=Invalid username or password
-invalidPassword=Invalid username or password
+invalidUser=Invalid username or password.
+invalidPassword=Invalid username or password.
accountDisabled=Account is disabled, contact admin
missingFirstName=Please specify first name
missingLastName=Please specify last name
missingEmail=Please specify email
missingUsername=Please specify username
-missingPassword=Please specify password
+missingPassword=Please specify password.
notMatchPassword=Passwords don't match
missingTotp=Please specify authenticator code
@@ -49,7 +49,7 @@ actionTotpWarning=You need to set up the Google Authenticator to activate your a
actionProfileWarning=You need to update your user profile to activate your account.
actionPasswordWarning=You need to change your password to activate your account.
actionEmailWarning=You need to verify your email address to activate your account.
-actionFollow=Please follow the steps below.
+actionFollow=Please fill in the fields below.
successHeader=Success!
errorHeader=Error!
diff --git a/model/api/src/main/java/org/keycloak/models/Constants.java b/model/api/src/main/java/org/keycloak/models/Constants.java
index b02c9c2..fb29037 100755
--- a/model/api/src/main/java/org/keycloak/models/Constants.java
+++ b/model/api/src/main/java/org/keycloak/models/Constants.java
@@ -5,16 +5,14 @@ package org.keycloak.models;
* @version $Revision: 1 $
*/
public interface Constants {
+ String INTERNAL_ROLE = "KEYCLOAK_";
String ADMIN_REALM = "Keycloak Administration";
String ADMIN_CONSOLE_APPLICATION = "Admin Console";
String ADMIN_CONSOLE_ADMIN_ROLE = "admin";
- String APPLICATION_ROLE = "KEYCLOAK_APPLICATION";
- String IDENTITY_REQUESTER_ROLE = "KEYCLOAK_IDENTITY_REQUESTER";
- String WILDCARD_ROLE = "*";
+ String APPLICATION_ROLE = INTERNAL_ROLE + "_APPLICATION";
+ String IDENTITY_REQUESTER_ROLE = INTERNAL_ROLE + "_IDENTITY_REQUESTER";
String ACCOUNT_APPLICATION = "Account";
String ACCOUNT_PROFILE_ROLE = "view-profile";
String ACCOUNT_MANAGE_ROLE = "manage-account";
-
- String ACCOUNT_MANAGEMENT_APPLICATION = "Account Management";
}
diff --git a/model/api/src/main/java/org/keycloak/models/ModelProvider.java b/model/api/src/main/java/org/keycloak/models/ModelProvider.java
index 6e8e31e..1e166ac 100755
--- a/model/api/src/main/java/org/keycloak/models/ModelProvider.java
+++ b/model/api/src/main/java/org/keycloak/models/ModelProvider.java
@@ -5,5 +5,7 @@ package org.keycloak.models;
* @version $Revision: 1 $
*/
public interface ModelProvider {
+ String getId();
+
KeycloakSessionFactory createFactory();
}
diff --git a/model/api/src/main/java/org/keycloak/models/RealmModel.java b/model/api/src/main/java/org/keycloak/models/RealmModel.java
index 3b0b149..724d3b5 100755
--- a/model/api/src/main/java/org/keycloak/models/RealmModel.java
+++ b/model/api/src/main/java/org/keycloak/models/RealmModel.java
@@ -84,6 +84,8 @@ public interface RealmModel extends RoleContainerModel, RoleMapperModel, ScopeMa
UserModel addUser(String username);
+ boolean deleteUser(String name);
+
List<String> getDefaultRoles();
void addDefaultRole(String name);
model/jpa/pom.xml 24(+24 -0)
diff --git a/model/jpa/pom.xml b/model/jpa/pom.xml
index 243e438..c8cba66 100755
--- a/model/jpa/pom.xml
+++ b/model/jpa/pom.xml
@@ -34,6 +34,30 @@
<artifactId>hibernate-jpa-2.0-api</artifactId>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate-entitymanager</artifactId>
+ <version>${hibernate.entitymanager.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.resteasy</groupId>
+ <artifactId>resteasy-jaxrs</artifactId>
+ <scope>provided</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
</dependencies>
<build>
<plugins>
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationEntity.java
index 54d628d..c8a7400 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationEntity.java
@@ -4,6 +4,7 @@ import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
@@ -18,7 +19,7 @@ import java.util.Collection;
@Entity
public class ApplicationEntity {
@Id
- @GeneratedValue
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
private String id;
private String name;
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/CredentialEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/CredentialEntity.java
index 4b13fd6..64cf3cf 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/CredentialEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/CredentialEntity.java
@@ -2,6 +2,7 @@ package org.keycloak.models.jpa.entities;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
@@ -17,7 +18,7 @@ import javax.persistence.NamedQuery;
@Entity
public class CredentialEntity {
@Id
- @GeneratedValue
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
protected String id;
protected String type;
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/OAuthClientEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/OAuthClientEntity.java
index 28e158d..9d440c3 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/OAuthClientEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/OAuthClientEntity.java
@@ -3,6 +3,7 @@ package org.keycloak.models.jpa.entities;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
@@ -21,7 +22,7 @@ import javax.persistence.OneToOne;
@Entity
public class OAuthClientEntity {
@Id
- @GeneratedValue
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
private String id;
private String name;
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RequiredCredentialEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RequiredCredentialEntity.java
index 40c11c9..8a35808 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RequiredCredentialEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RequiredCredentialEntity.java
@@ -2,6 +2,7 @@ package org.keycloak.models.jpa.entities;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
import javax.persistence.Id;
/**
@@ -11,7 +12,7 @@ import javax.persistence.Id;
@Entity
public class RequiredCredentialEntity {
@Id
- @GeneratedValue
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
protected String id;
protected String type;
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RoleEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RoleEntity.java
index 63ff8e8..38beeb3 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RoleEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RoleEntity.java
@@ -2,6 +2,7 @@ package org.keycloak.models.jpa.entities;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
import javax.persistence.Id;
/**
@@ -11,7 +12,7 @@ import javax.persistence.Id;
@Entity
public class RoleEntity {
@Id
- @GeneratedValue
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
private String id;
private String name;
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/SocialLinkEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/SocialLinkEntity.java
index 87d75ee..ccc0a59 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/SocialLinkEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/SocialLinkEntity.java
@@ -2,6 +2,7 @@ package org.keycloak.models.jpa.entities;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
@@ -19,7 +20,7 @@ import javax.persistence.NamedQuery;
@Entity
public class SocialLinkEntity {
@Id
- @GeneratedValue
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@ManyToOne
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserEntity.java
index 6b8fc5a..90d3341 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserEntity.java
@@ -2,11 +2,13 @@ package org.keycloak.models.jpa.entities;
import org.keycloak.models.UserModel;
+import javax.persistence.CascadeType;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.MapKeyColumn;
@@ -32,8 +34,11 @@ import java.util.Set;
})
@Entity
public class UserEntity {
+
+ public static final Class[] RELATIONSHIPS = new Class[] { ApplicationUserRoleMappingEntity.class, RealmUserRoleMappingEntity.class, SocialLinkEntity.class };
+
@Id
- @GeneratedValue
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
protected String id;
protected String loginName;
@@ -65,7 +70,7 @@ public class UserEntity {
@CollectionTable
protected Set<String> redirectUris = new HashSet<String>();
- @OneToMany
+ @OneToMany(cascade = CascadeType.REMOVE, orphanRemoval = true)
protected Collection<CredentialEntity> credentials = new ArrayList<CredentialEntity>();
public String getId() {
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserRoleMappingEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserRoleMappingEntity.java
index 2befc8d..efb7478 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserRoleMappingEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserRoleMappingEntity.java
@@ -1,6 +1,7 @@
package org.keycloak.models.jpa.entities;
import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.MappedSuperclass;
@@ -12,7 +13,7 @@ import javax.persistence.MappedSuperclass;
@MappedSuperclass
public abstract class UserRoleMappingEntity {
@Id
- @GeneratedValue
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
protected long id;
@ManyToOne
protected UserEntity user;
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaModelProvider.java b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaModelProvider.java
index 1c5f743..629f795 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaModelProvider.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaModelProvider.java
@@ -11,6 +11,12 @@ import javax.persistence.Persistence;
* @version $Revision: 1 $
*/
public class JpaModelProvider implements ModelProvider {
+
+ @Override
+ public String getId() {
+ return "jpa";
+ }
+
@Override
public KeycloakSessionFactory createFactory() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpa-keycloak-identity-store");
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
index 8eb89d5..9cf12e0 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
@@ -11,6 +11,7 @@ import org.keycloak.models.SocialLinkModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.jpa.entities.ApplicationEntity;
+import org.keycloak.models.jpa.entities.ApplicationUserRoleMappingEntity;
import org.keycloak.models.jpa.entities.CredentialEntity;
import org.keycloak.models.jpa.entities.OAuthClientEntity;
import org.keycloak.models.jpa.entities.RealmEntity;
@@ -457,6 +458,25 @@ public class RealmAdapter implements RealmModel {
}
@Override
+ public boolean deleteUser(String name) {
+ TypedQuery<UserEntity> query = em.createNamedQuery("getRealmUserByLoginName", UserEntity.class);
+ query.setParameter("loginName", name);
+ query.setParameter("realm", realm);
+ List<UserEntity> results = query.getResultList();
+ if (results.size() == 0) return false;
+
+ UserEntity user = results.get(0);
+
+ for (Class r : UserEntity.RELATIONSHIPS) {
+ em.createQuery("delete from " + r.getSimpleName() + " where user = :user").setParameter("user", user).executeUpdate();
+ }
+
+ em.remove(user);
+
+ return true;
+ }
+
+ @Override
public List<String> getDefaultRoles() {
Collection<RoleEntity> entities = realm.getDefaultRoles();
List<String> roles = new ArrayList<String>();
@@ -548,8 +568,6 @@ public class RealmAdapter implements RealmModel {
em.persist(applicationData);
em.flush();
ApplicationModel resource = new ApplicationAdapter(em, applicationData);
- resource.addRole("*");
- resource.addScopeMapping(new UserAdapter(user), "*");
em.flush();
return resource;
}
@@ -643,13 +661,13 @@ public class RealmAdapter implements RealmModel {
for (Map.Entry<String, String> entry : attributes.entrySet()) {
String attribute = null;
if (entry.getKey().equals(UserModel.LOGIN_NAME)) {
- attribute = "loginName";
+ attribute = "lower(loginName)";
} else if (entry.getKey().equalsIgnoreCase(UserModel.FIRST_NAME)) {
- attribute = "firstName";
+ attribute = "lower(firstName)";
} else if (entry.getKey().equalsIgnoreCase(UserModel.LAST_NAME)) {
- attribute = "lastName";
+ attribute = "lower(lastName)";
} else if (entry.getKey().equalsIgnoreCase(UserModel.EMAIL)) {
- attribute = "email";
+ attribute = "lower(email)";
}
if (attribute == null) continue;
if (first) {
@@ -658,9 +676,10 @@ public class RealmAdapter implements RealmModel {
} else {
builder.append(" and ");
}
- builder.append(attribute).append("='").append(entry.getValue()).append("'");
+ builder.append(attribute).append(" like '%").append(entry.getValue().toLowerCase()).append("%'");
}
- TypedQuery<UserEntity> query = em.createQuery(builder.toString(), UserEntity.class);
+ String q = builder.toString();
+ TypedQuery<UserEntity> query = em.createQuery(q, UserEntity.class);
List<UserEntity> results = query.getResultList();
List<UserModel> users = new ArrayList<UserModel>();
for (UserEntity entity : results) users.add(new UserAdapter(entity));
diff --git a/model/jpa/src/main/resources/META-INF/services/org.keycloak.models.ModelProvider b/model/jpa/src/main/resources/META-INF/services/org.keycloak.models.ModelProvider
new file mode 100644
index 0000000..199922e
--- /dev/null
+++ b/model/jpa/src/main/resources/META-INF/services/org.keycloak.models.ModelProvider
@@ -0,0 +1 @@
+org.keycloak.models.jpa.JpaModelProvider
\ No newline at end of file
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
index 391334a..7d4aa72 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
@@ -451,8 +451,6 @@ public class RealmAdapter implements RealmModel {
noSQL.saveObject(appData);
ApplicationModel resource = new ApplicationAdapter(appData, noSQL);
- resource.addRole("*");
- resource.addScopeMapping(resourceUser, "*");
return resource;
}
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/MongoModelProvider.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/MongoModelProvider.java
index 87c62af..c035b56 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/MongoModelProvider.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/MongoModelProvider.java
@@ -3,13 +3,31 @@ package org.keycloak.models.mongo.keycloak;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.ModelProvider;
+import java.lang.Override;
+
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class MongoModelProvider implements ModelProvider {
+
+ @Override
+ public String getId() {
+ return "mongo";
+ }
+
@Override
public KeycloakSessionFactory createFactory() {
- return null; //To change body of implemented methods use File | Settings | File Templates.
+ String host = PropertiesManager.getMongoHost();
+ int port = PropertiesManager.getMongoPort();
+ String dbName = PropertiesManager.getMongoDbName();
+ boolean dropDatabaseOnStartup = PropertiesManager.dropDatabaseOnStartup();
+
+ // Create MongoDBSessionFactory via reflection now
+ try {
+ return new MongoDBSessionFactory(host, port, dbName, dropDatabaseOnStartup);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
}
}
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/PropertiesManager.java b/model/mongo/src/main/java/org/keycloak/models/mongo/PropertiesManager.java
new file mode 100755
index 0000000..9e897ae
--- /dev/null
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/PropertiesManager.java
@@ -0,0 +1,58 @@
+package org.keycloak.models.mongo;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class PropertiesManager {
+
+ private static final String MONGO_HOST = "keycloak.mongodb.host";
+ private static final String MONGO_PORT = "keycloak.mongodb.port";
+ private static final String MONGO_DB_NAME = "keycloak.mongodb.databaseName";
+ private static final String MONGO_DROP_DB_ON_STARTUP = "keycloak.mongodb.dropDatabaseOnStartup";
+ private static final String BOOTSTRAP_EMBEDDED_MONGO_AT_CONTEXT_INIT = "keycloak.mongodb.bootstrapEmbeddedMongoAtContextInit";
+
+ // Port where embedded MongoDB will be started during keycloak bootstrap. Same port will be used by KeycloakApplication then
+ private static final int MONGO_DEFAULT_PORT_KEYCLOAK_WAR_EMBEDDED = 37017;
+
+ // Port where MongoDB instance is normally started on linux. This port should be used if we're not starting embedded instance (keycloak.mongodb.bootstrapEmbeddedMongoAtContextInit is false)
+ private static final int MONGO_DEFAULT_PORT_KEYCLOAK_WAR = 27017;
+
+ // Port where unit tests will start embedded MongoDB instance
+ public static final int MONGO_DEFAULT_PORT_UNIT_TESTS = 27777;
+
+ public static String getMongoHost() {
+ return System.getProperty(MONGO_HOST, "localhost");
+ }
+
+ public static void setMongoHost(String mongoHost) {
+ System.setProperty(MONGO_HOST, mongoHost);
+ }
+
+ public static int getMongoPort() {
+ return Integer.parseInt(System.getProperty(MONGO_PORT, String.valueOf(MONGO_DEFAULT_PORT_KEYCLOAK_WAR_EMBEDDED)));
+ }
+
+ public static void setMongoPort(int mongoPort) {
+ System.setProperty(MONGO_PORT, String.valueOf(mongoPort));
+ }
+
+ public static String getMongoDbName() {
+ return System.getProperty(MONGO_DB_NAME, "keycloak");
+ }
+
+ public static void setMongoDbName(String mongoMongoDbName) {
+ System.setProperty(MONGO_DB_NAME, mongoMongoDbName);
+ }
+
+ public static boolean dropDatabaseOnStartup() {
+ return Boolean.parseBoolean(System.getProperty(MONGO_DROP_DB_ON_STARTUP, "true"));
+ }
+
+ public static void setDropDatabaseOnStartup(boolean dropDatabaseOnStartup) {
+ System.setProperty(MONGO_DROP_DB_ON_STARTUP, String.valueOf(dropDatabaseOnStartup));
+ }
+
+ public static boolean bootstrapEmbeddedMongoAtContextInit() {
+ return isMongoSessionFactory() && Boolean.parseBoolean(System.getProperty(BOOTSTRAP_EMBEDDED_MONGO_AT_CONTEXT_INIT, "true"));
+ }
+}
diff --git a/model/mongo/src/main/resources/META-INF/services/org.keycloak.models.ModelProvider b/model/mongo/src/main/resources/META-INF/services/org.keycloak.models.ModelProvider
new file mode 100644
index 0000000..c9e7539
--- /dev/null
+++ b/model/mongo/src/main/resources/META-INF/services/org.keycloak.models.ModelProvider
@@ -0,0 +1 @@
+org.keycloak.models.mongo.keycloak.MongoModelProvider
\ No newline at end of file
model/picketlink/pom.xml 5(+0 -5)
diff --git a/model/picketlink/pom.xml b/model/picketlink/pom.xml
index b42cd80..4d91e5e 100755
--- a/model/picketlink/pom.xml
+++ b/model/picketlink/pom.xml
@@ -37,27 +37,22 @@
<dependency>
<groupId>org.picketlink</groupId>
<artifactId>picketlink-idm-api</artifactId>
- <scope>provided</scope>
</dependency>
<dependency>
<groupId>org.picketlink</groupId>
<artifactId>picketlink-common</artifactId>
- <scope>provided</scope>
</dependency>
<dependency>
<groupId>org.picketlink</groupId>
<artifactId>picketlink-idm-impl</artifactId>
- <scope>provided</scope>
</dependency>
<dependency>
<groupId>org.picketlink</groupId>
<artifactId>picketlink-idm-simple-schema</artifactId>
- <scope>provided</scope>
</dependency>
<dependency>
<groupId>org.picketlink</groupId>
<artifactId>picketlink-config</artifactId>
- <scope>provided</scope>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
diff --git a/model/picketlink/src/main/java/org/keycloak/models/picketlink/PicketlinkModelProvider.java b/model/picketlink/src/main/java/org/keycloak/models/picketlink/PicketlinkModelProvider.java
index 67f4d7a..3a87fa3 100755
--- a/model/picketlink/src/main/java/org/keycloak/models/picketlink/PicketlinkModelProvider.java
+++ b/model/picketlink/src/main/java/org/keycloak/models/picketlink/PicketlinkModelProvider.java
@@ -37,6 +37,11 @@ public class PicketlinkModelProvider implements ModelProvider {
return new PicketlinkKeycloakSessionFactory(emf, buildPartitionManager());
}
+ @Override
+ public String getId() {
+ return "picketlink";
+ }
+
public static PartitionManager buildPartitionManager() {
IdentityConfigurationBuilder builder = new IdentityConfigurationBuilder();
diff --git a/model/picketlink/src/main/java/org/keycloak/models/picketlink/RealmAdapter.java b/model/picketlink/src/main/java/org/keycloak/models/picketlink/RealmAdapter.java
index 3279abf..9fb4eec 100755
--- a/model/picketlink/src/main/java/org/keycloak/models/picketlink/RealmAdapter.java
+++ b/model/picketlink/src/main/java/org/keycloak/models/picketlink/RealmAdapter.java
@@ -519,6 +519,16 @@ public class RealmAdapter implements RealmModel {
}
@Override
+ public boolean deleteUser(String name) {
+ User user = findPicketlinkUser(name);
+ if (user == null) {
+ return false;
+ }
+ getIdm().remove(user);
+ return true;
+ }
+
+ @Override
public RoleAdapter getRole(String name) {
Role role = SampleModel.getRole(getIdm(), name);
if (role == null) return null;
@@ -615,8 +625,6 @@ public class RealmAdapter implements RealmModel {
resourceRelationship.setApplication(applicationData.getName());
getRelationshipManager().add(resourceRelationship);
ApplicationModel resource = new ApplicationAdapter(applicationData, this, partitionManager);
- resource.addRole("*");
- resource.addScopeMapping(new UserAdapter(resourceUser, idm), "*");
return resource;
}
diff --git a/model/picketlink/src/main/resources/META-INF/services/org.keycloak.models.ModelProvider b/model/picketlink/src/main/resources/META-INF/services/org.keycloak.models.ModelProvider
new file mode 100644
index 0000000..225bcaa
--- /dev/null
+++ b/model/picketlink/src/main/resources/META-INF/services/org.keycloak.models.ModelProvider
@@ -0,0 +1 @@
+org.keycloak.models.picketlink.PicketlinkModelProvider
\ No newline at end of file
pom.xml 2(+1 -1)
diff --git a/pom.xml b/pom.xml
index 7351a4c..8155a68 100755
--- a/pom.xml
+++ b/pom.xml
@@ -20,7 +20,7 @@
<dom4j.version>1.6.1</dom4j.version>
<mysql.version>5.1.25</mysql.version>
<slf4j.version>1.6.1</slf4j.version>
- <jboss.version>7.1.1.Final</jboss.version>
+ <wildfly.version>8.0.0.Beta1</wildfly.version>
</properties>
<url>http://keycloak.org</url>
server/pom.xml 70(+21 -49)
diff --git a/server/pom.xml b/server/pom.xml
index 51b450c..ae947f6 100755
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -47,11 +47,6 @@
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
- <artifactId>keycloak-model-picketlink</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.keycloak</groupId>
<artifactId>keycloak-model-jpa</artifactId>
<version>${project.version}</version>
</dependency>
@@ -64,6 +59,24 @@
<groupId>org.keycloak</groupId>
<artifactId>keycloak-social-google</artifactId>
<version>${project.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.codehaus.jackson</groupId>
+ <artifactId>jackson-core-asl</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
@@ -81,55 +94,14 @@
<version>${project.version}</version>
</dependency>
<dependency>
- <groupId>org.picketlink</groupId>
- <artifactId>picketlink-idm-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.picketlink</groupId>
- <artifactId>picketlink-idm-impl</artifactId>
- </dependency>
- <dependency>
- <groupId>org.picketlink</groupId>
- <artifactId>picketlink-idm-simple-schema</artifactId>
- </dependency>
- <dependency>
- <groupId>org.picketlink</groupId>
- <artifactId>picketlink-config</artifactId>
- </dependency>
- <dependency>
- <groupId>org.jboss.resteasy</groupId>
- <artifactId>resteasy-jaxrs</artifactId>
- <scope>provided</scope>
- <exclusions>
- <exclusion>
- <groupId>log4j</groupId>
- <artifactId>log4j</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-simple</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>jaxrs-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
- <groupId>com.h2database</groupId>
- <artifactId>h2</artifactId>
- <version>1.3.161</version>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.1</version>
- <scope>test</scope>
+ <groupId>org.jboss.spec.javax.servlet</groupId>
+ <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+ <scope>provided</scope>
</dependency>
</dependencies>
diff --git a/server/src/main/resources/META-INF/jboss-deployment-structure.xml b/server/src/main/resources/META-INF/jboss-deployment-structure.xml
new file mode 100644
index 0000000..ad328f4
--- /dev/null
+++ b/server/src/main/resources/META-INF/jboss-deployment-structure.xml
@@ -0,0 +1,8 @@
+<jboss-deployment-structure>
+ <deployment>
+ <dependencies>
+ <module name="org.apache.httpcomponents"/>
+ <module name="org.codehaus.jackson.jackson-core-asl"/>
+ </dependencies>
+ </deployment>
+</jboss-deployment-structure>
\ No newline at end of file
diff --git a/server/src/main/resources/META-INF/persistence.xml b/server/src/main/resources/META-INF/persistence.xml
index 5d5eed0..89a3822 100755
--- a/server/src/main/resources/META-INF/persistence.xml
+++ b/server/src/main/resources/META-INF/persistence.xml
@@ -2,32 +2,26 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
- <persistence-unit name="keycloak-identity-store" transaction-type="RESOURCE_LOCAL">
- <jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source>
-
- <class>org.picketlink.idm.jpa.model.sample.simple.AttributedTypeEntity</class>
- <class>org.picketlink.idm.jpa.model.sample.simple.AccountTypeEntity</class>
- <class>org.picketlink.idm.jpa.model.sample.simple.RoleTypeEntity</class>
- <class>org.picketlink.idm.jpa.model.sample.simple.GroupTypeEntity</class>
- <class>org.picketlink.idm.jpa.model.sample.simple.IdentityTypeEntity</class>
- <class>org.picketlink.idm.jpa.model.sample.simple.RelationshipTypeEntity</class>
- <class>org.picketlink.idm.jpa.model.sample.simple.RelationshipIdentityTypeEntity</class>
- <class>org.picketlink.idm.jpa.model.sample.simple.PartitionTypeEntity</class>
- <class>org.picketlink.idm.jpa.model.sample.simple.PasswordCredentialTypeEntity</class>
- <class>org.picketlink.idm.jpa.model.sample.simple.DigestCredentialTypeEntity</class>
- <class>org.picketlink.idm.jpa.model.sample.simple.X509CredentialTypeEntity</class>
- <class>org.picketlink.idm.jpa.model.sample.simple.OTPCredentialTypeEntity</class>
- <class>org.picketlink.idm.jpa.model.sample.simple.AttributeTypeEntity</class>
- <class>org.keycloak.models.picketlink.mappings.RealmEntity</class>
- <class>org.keycloak.models.picketlink.mappings.ApplicationEntity</class>
+ <persistence-unit name="jpa-keycloak-identity-store" transaction-type="RESOURCE_LOCAL">
+ <jta-data-source>java:jboss/datasources/KeycloakDS</jta-data-source>
+ <class>org.keycloak.models.jpa.entities.ApplicationEntity</class>
+ <class>org.keycloak.models.jpa.entities.ApplicationScopeMappingEntity</class>
+ <class>org.keycloak.models.jpa.entities.ApplicationUserRoleMappingEntity</class>
+ <class>org.keycloak.models.jpa.entities.CredentialEntity</class>
+ <class>org.keycloak.models.jpa.entities.OAuthClientEntity</class>
+ <class>org.keycloak.models.jpa.entities.RealmEntity</class>
+ <class>org.keycloak.models.jpa.entities.RealmScopeMappingEntity</class>
+ <class>org.keycloak.models.jpa.entities.RealmUserRoleMappingEntity</class>
+ <class>org.keycloak.models.jpa.entities.RequiredCredentialEntity</class>
+ <class>org.keycloak.models.jpa.entities.RoleEntity</class>
+ <class>org.keycloak.models.jpa.entities.SocialLinkEntity</class>
+ <class>org.keycloak.models.jpa.entities.UserEntity</class>
+ <class>org.keycloak.models.jpa.entities.UserRoleMappingEntity</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
- <property name="hibernate.hbm2ddl.auto" value="create" />
- <property name="hibernate.show_sql" value="false" />
- <property name="hibernate.format_sql" value="false" />
+ <property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
-
</persistence>
diff --git a/server/src/main/webapp/WEB-INF/web.xml b/server/src/main/webapp/WEB-INF/web.xml
index 08bf314..117c014 100755
--- a/server/src/main/webapp/WEB-INF/web.xml
+++ b/server/src/main/webapp/WEB-INF/web.xml
@@ -20,6 +20,10 @@
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
+
+ <welcome-file-list>
+ <welcome-file>index.html</welcome-file>
+ </welcome-file-list>
<filter>
<filter-name>Keycloak Session Management</filter-name>
services/pom.xml 49(+5 -44)
diff --git a/services/pom.xml b/services/pom.xml
index 1df957c..084f6df 100755
--- a/services/pom.xml
+++ b/services/pom.xml
@@ -31,14 +31,15 @@
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
- <artifactId>keycloak-model-picketlink</artifactId>
+ <artifactId>keycloak-model-jpa</artifactId>
<version>${project.version}</version>
- <scope>provided</scope>
+ <scope>test</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
- <artifactId>keycloak-model-jpa</artifactId>
+ <artifactId>keycloak-model-picketlink</artifactId>
<version>${project.version}</version>
+ <scope>test</scope>
</dependency>
<!--<dependency>
@@ -58,31 +59,6 @@
<scope>provided</scope>
</dependency>
<dependency>
- <groupId>org.picketlink</groupId>
- <artifactId>picketlink-idm-api</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.picketlink</groupId>
- <artifactId>picketlink-common</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.picketlink</groupId>
- <artifactId>picketlink-idm-impl</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.picketlink</groupId>
- <artifactId>picketlink-idm-simple-schema</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.picketlink</groupId>
- <artifactId>picketlink-config</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<scope>provided</scope>
@@ -157,21 +133,6 @@
<scope>provided</scope>
</dependency>
<dependency>
- <groupId>org.picketlink</groupId>
- <artifactId>picketlink-common</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.mongodb</groupId>
- <artifactId>mongo-java-driver</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>de.flapdoodle.embed</groupId>
- <artifactId>de.flapdoodle.embed.mongo</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
</dependency>
@@ -183,7 +144,7 @@
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
- <scope>provided</scope>
+ <scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
diff --git a/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java b/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java
index 3754164..bf53fc8 100755
--- a/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java
+++ b/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java
@@ -1,5 +1,6 @@
package org.keycloak.services.managers;
+import org.jboss.resteasy.logging.Logger;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession;
@@ -17,12 +18,15 @@ import java.util.UUID;
*/
public class ApplianceBootstrap {
+ private static final Logger logger = Logger.getLogger(ApplianceBootstrap.class);
- public void initKeycloakAdminRealm(RealmModel realm) {
+ public void bootstrap(KeycloakSession session) {
+ if (session.getRealm(Constants.ADMIN_REALM) != null) {
+ return;
+ }
- }
+ logger.info("Initializing " + Constants.ADMIN_REALM + " realm");
- public void bootstrap(KeycloakSession session) {
RealmManager manager = new RealmManager(session);
RealmModel realm = manager.createRealm(Constants.ADMIN_REALM, Constants.ADMIN_REALM);
realm.setName(Constants.ADMIN_REALM);
@@ -37,7 +41,6 @@ public class ApplianceBootstrap {
realm.setCookieLoginAllowed(true);
realm.setRegistrationAllowed(false);
manager.generateRealmKeys(realm);
- initKeycloakAdminRealm(realm);
ApplicationModel adminConsole = realm.addApplication(Constants.ADMIN_CONSOLE_APPLICATION);
adminConsole.setEnabled(true);
@@ -59,8 +62,6 @@ public class ApplianceBootstrap {
adminUser.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
adminConsole.grantRole(adminUser, adminRole);
-
-
-
}
+
}
diff --git a/services/src/main/java/org/keycloak/services/managers/ApplicationManager.java b/services/src/main/java/org/keycloak/services/managers/ApplicationManager.java
index 67a8286..6b97269 100755
--- a/services/src/main/java/org/keycloak/services/managers/ApplicationManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/ApplicationManager.java
@@ -102,7 +102,6 @@ public class ApplicationManager {
}
}
}
- if (resourceRep.isUseRealmMappings()) realm.addScopeMapping(applicationModel.getApplicationUser(), "*");
return applicationModel;
}
diff --git a/services/src/main/java/org/keycloak/services/managers/RealmManager.java b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
index 8cd43a0..6c72da6 100755
--- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
@@ -68,7 +68,6 @@ public class RealmManager {
public RealmModel createRealm(String id, String name) {
RealmModel realm = identitySession.createRealm(id, name);
realm.setName(name);
- realm.addRole(Constants.WILDCARD_ROLE);
realm.addRole(Constants.APPLICATION_ROLE);
realm.addRole(Constants.IDENTITY_REQUESTER_ROLE);
return realm;
@@ -129,7 +128,7 @@ public class RealmManager {
}
private void enableAccountManagement(RealmModel realm) {
- ApplicationModel application = realm.getApplicationById(Constants.ACCOUNT_APPLICATION);
+ ApplicationModel application = realm.getApplicationNameMap().get(Constants.ACCOUNT_APPLICATION);
if (application == null) {
application = realm.addApplication(Constants.ACCOUNT_APPLICATION);
application.addDefaultRole(Constants.ACCOUNT_PROFILE_ROLE);
@@ -224,6 +223,14 @@ public class RealmManager {
}
}
+ if (rep.getClients() != null) {
+ for (UserRepresentation clientRep : rep.getClients()) {
+ UserModel client = createUser(newRealm, clientRep);
+ newRealm.grantRole(client, newRealm.getRole(Constants.IDENTITY_REQUESTER_ROLE));
+ userMap.put(client.getLoginName(), client);
+ }
+ }
+
if (rep.getRoles() != null) {
for (RoleRepresentation roleRep : rep.getRoles()) {
createRole(newRealm, roleRep);
@@ -237,7 +244,10 @@ public class RealmManager {
}
if (rep.getApplications() != null) {
- createApplications(rep, newRealm);
+ Map<String, ApplicationModel> appMap = createApplications(rep, newRealm);
+ for (ApplicationModel app : appMap.values()) {
+ userMap.put(app.getApplicationUser().getLoginName(), app.getApplicationUser());
+ }
}
if (rep.getRoleMappings() != null) {
@@ -398,12 +408,15 @@ public class RealmManager {
}
- protected void createApplications(RealmRepresentation rep, RealmModel realm) {
+ protected Map<String, ApplicationModel> createApplications(RealmRepresentation rep, RealmModel realm) {
+ Map<String, ApplicationModel> appMap = new HashMap<String, ApplicationModel>();
RoleModel loginRole = realm.getRole(Constants.APPLICATION_ROLE);
ApplicationManager manager = new ApplicationManager(this);
for (ApplicationRepresentation resourceRep : rep.getApplications()) {
- manager.createApplication(realm, loginRole, resourceRep);
+ ApplicationModel app = manager.createApplication(realm, loginRole, resourceRep);
+ appMap.put(app.getName(), app);
}
+ return appMap;
}
public static UserRepresentation toRepresentation(UserModel user) {
diff --git a/services/src/main/java/org/keycloak/services/managers/TokenManager.java b/services/src/main/java/org/keycloak/services/managers/TokenManager.java
index d5b955f..689139e 100755
--- a/services/src/main/java/org/keycloak/services/managers/TokenManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/TokenManager.java
@@ -46,54 +46,38 @@ public class TokenManager {
public AccessCodeEntry createAccessCode(String scopeParam, String state, String redirect, RealmModel realm, UserModel client, UserModel user) {
+ boolean applicationResource = realm.hasRole(client, realm.getRole(Constants.APPLICATION_ROLE));
+
AccessCodeEntry code = new AccessCodeEntry();
SkeletonKeyScope scopeMap = null;
if (scopeParam != null) scopeMap = decodeScope(scopeParam);
List<RoleModel> realmRolesRequested = code.getRealmRolesRequested();
MultivaluedMap<String, RoleModel> resourceRolesRequested = code.getResourceRolesRequested();
Set<String> realmMapping = realm.getRoleMappingValues(user);
- realmMapping.addAll(realm.getDefaultRoles());
if (realmMapping != null && realmMapping.size() > 0 && (scopeMap == null || scopeMap.containsKey("realm"))) {
Set<String> scope = realm.getScopeMappingValues(client);
if (scope.size() > 0) {
- Set<String> scopeRequest = null;
- if (scopeMap != null) {
- if (scopeRequest == null) {
- scopeRequest = new HashSet<String>();
- }
- scopeRequest.addAll(scopeMap.get("realm"));
- if (scopeRequest.contains(Constants.WILDCARD_ROLE)) scopeRequest = null;
- }
+ Set<String> scopeRequest = scopeMap != null ? new HashSet<String>(scopeMap.get("realm")) : null;
for (String role : realmMapping) {
- if (
- (scopeRequest == null || scopeRequest.contains(role)) &&
- (scope.contains("*") || scope.contains(role))
- )
+ if ((scopeRequest == null || scopeRequest.contains(role)) && scope.contains(role))
realmRolesRequested.add(realm.getRole(role));
}
}
}
for (ApplicationModel resource : realm.getApplications()) {
- Set<String> mapping = resource.getRoleMappingValues(user);
- mapping.addAll(resource.getDefaultRoles());
- if (mapping != null && mapping.size() > 0 && (scopeMap == null || scopeMap.containsKey(resource.getName()))) {
- Set<String> scope = resource.getScopeMappingValues(client);
- if (scope.size() > 0) {
- Set<String> scopeRequest = null;
- if (scopeMap != null) {
- if (scopeRequest == null) {
- scopeRequest = new HashSet<String>();
+ if (applicationResource && resource.getApplicationUser().getLoginName().equals(client.getLoginName())) {
+ resourceRolesRequested.addAll(resource.getName(), resource.getRoles());
+ } else {
+ Set<String> mapping = resource.getRoleMappingValues(user);
+ if (mapping != null && mapping.size() > 0 && (scopeMap == null || scopeMap.containsKey(resource.getName()))) {
+ Set<String> scope = resource.getScopeMappingValues(client);
+ if (scope.size() > 0) {
+ Set<String> scopeRequest = scopeMap != null ? new HashSet<String>(scopeMap.get(resource.getName())) : null;
+ for (String role : mapping) {
+ if ((scopeRequest == null || scopeRequest.contains(role)) && scope.contains(role))
+ resourceRolesRequested.add(resource.getName(), resource.getRole(role));
}
- scopeRequest.addAll(scopeMap.get(resource.getName()));
- if (scopeRequest.contains(Constants.WILDCARD_ROLE)) scopeRequest = null;
- }
- for (String role : mapping) {
- if (
- (scopeRequest == null || scopeRequest.contains(role)) &&
- (scope.contains("*") || scope.contains(role))
- )
- resourceRolesRequested.add(resource.getName(), resource.getRole(role));
}
}
}
diff --git a/services/src/main/java/org/keycloak/services/resources/AccountService.java b/services/src/main/java/org/keycloak/services/resources/AccountService.java
index f176061..584ef1c 100755
--- a/services/src/main/java/org/keycloak/services/resources/AccountService.java
+++ b/services/src/main/java/org/keycloak/services/resources/AccountService.java
@@ -373,7 +373,8 @@ public class AccountService {
UserModel client = auth.getClient();
if (realm.hasRole(client, Constants.APPLICATION_ROLE)) {
// Tokens from cookies don't have roles
- if (hasRole(client, Constants.ACCOUNT_MANAGE_ROLE) || (role != null && hasRole(client, role))) {
+ UserModel user = auth.getUser();
+ if (hasRole(user, Constants.ACCOUNT_MANAGE_ROLE) || (role != null && hasRole(user, role))) {
return true;
}
}
@@ -389,9 +390,6 @@ public class AccountService {
}
private boolean hasRole(UserModel user, String role) {
- if (application.getDefaultRoles().contains(role)) {
- return true;
- }
return application.hasRole(user, role);
}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java
index c0c0a5f..1ab393f 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java
@@ -1,6 +1,7 @@
package org.keycloak.services.resources.admin;
import org.jboss.resteasy.annotations.cache.NoCache;
+import org.keycloak.models.Constants;
import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel;
import org.keycloak.representations.idm.RoleRepresentation;
@@ -39,9 +40,11 @@ public class RoleContainerResource {
List<RoleModel> roleModels = roleContainer.getRoles();
List<RoleRepresentation> roles = new ArrayList<RoleRepresentation>();
for (RoleModel roleModel : roleModels) {
- RoleRepresentation role = new RoleRepresentation(roleModel.getName(), roleModel.getDescription());
- role.setId(roleModel.getId());
- roles.add(role);
+ if (!roleModel.getName().startsWith(Constants.INTERNAL_ROLE)) {
+ RoleRepresentation role = new RoleRepresentation(roleModel.getName(), roleModel.getDescription());
+ role.setId(roleModel.getId());
+ roles.add(role);
+ }
}
return roles;
}
@@ -52,7 +55,7 @@ public class RoleContainerResource {
@Produces("application/json")
public RoleRepresentation getRole(final @PathParam("id") String id) {
RoleModel roleModel = roleContainer.getRoleById(id);
- if (roleModel == null) {
+ if (roleModel == null || roleModel.getName().startsWith(Constants.INTERNAL_ROLE)) {
throw new NotFoundException();
}
RoleRepresentation rep = new RoleRepresentation(roleModel.getName(), roleModel.getDescription());
@@ -65,7 +68,7 @@ public class RoleContainerResource {
@Consumes("application/json")
public void updateRole(final @PathParam("id") String id, final RoleRepresentation rep) {
RoleModel role = roleContainer.getRoleById(id);
- if (role == null) {
+ if (role == null || role.getName().startsWith(Constants.INTERNAL_ROLE)) {
throw new NotFoundException();
}
role.setName(rep.getName());
@@ -76,7 +79,7 @@ public class RoleContainerResource {
@POST
@Consumes("application/json")
public Response createRole(final @Context UriInfo uriInfo, final RoleRepresentation rep) {
- if (roleContainer.getRole(rep.getName()) != null) {
+ if (roleContainer.getRole(rep.getName()) != null || rep.getName().startsWith(Constants.INTERNAL_ROLE)) {
throw new InternalServerErrorException(); // todo appropriate status here.
}
RoleModel role = roleContainer.addRole(rep.getName());
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
index 029d4c9..2f506b1 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
@@ -3,6 +3,7 @@ package org.keycloak.services.resources.admin;
import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.logging.Logger;
import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
@@ -66,8 +67,10 @@ public class UsersResource {
user.setEmail(rep.getEmail());
user.setFirstName(rep.getFirstName());
user.setLastName(rep.getLastName());
- for (Map.Entry<String, String> attr : rep.getAttributes().entrySet()) {
- user.setAttribute(attr.getKey(), attr.getValue());
+ if (rep.getAttributes() != null) {
+ for (Map.Entry<String, String> attr : rep.getAttributes().entrySet()) {
+ user.setAttribute(attr.getKey(), attr.getValue());
+ }
}
}
@@ -98,12 +101,19 @@ public class UsersResource {
@Produces("application/json")
public UserRepresentation getUser(final @PathParam("username") String username) {
UserModel user = realm.getUser(username);
- if (user == null) {
+ if (user == null || !isUser(user)) {
throw new NotFoundException();
}
return new RealmManager(session).toRepresentation(user);
}
+ @Path("{username}")
+ @DELETE
+ @NoCache
+ public void deleteUser(final @PathParam("username") String username) {
+ realm.deleteUser(username);
+ }
+
@GET
@NoCache
@Produces("application/json")
@@ -117,7 +127,9 @@ public class UsersResource {
if (search != null) {
List<UserModel> userModels = manager.searchUsers(search, realm);
for (UserModel user : userModels) {
- results.add(manager.toRepresentation(user));
+ if (isUser(user)) {
+ results.add(manager.toRepresentation(user));
+ }
}
} else {
Map<String, String> attributes = new HashMap<String, String>();
@@ -142,6 +154,10 @@ public class UsersResource {
return results;
}
+ private boolean isUser(UserModel user) {
+ return !realm.hasRole(user, realm.getRole(Constants.IDENTITY_REQUESTER_ROLE)) && !realm.hasRole(user, realm.getRole(Constants.APPLICATION_ROLE));
+ }
+
@Path("{username}/role-mappings")
@GET
@Produces("application/json")
diff --git a/services/src/main/java/org/keycloak/services/resources/flows/Pages.java b/services/src/main/java/org/keycloak/services/resources/flows/Pages.java
index 695ecbb..9ee5ad4 100644
--- a/services/src/main/java/org/keycloak/services/resources/flows/Pages.java
+++ b/services/src/main/java/org/keycloak/services/resources/flows/Pages.java
@@ -26,34 +26,34 @@ package org.keycloak.services.resources.flows;
*/
public class Pages {
- public final static String ACCESS = "/forms/access.ftl";
+ public final static String ACCESS = "access.ftl";
- public final static String ACCOUNT = "/forms/account.ftl";
+ public final static String ACCOUNT = "account.ftl";
- public final static String LOGIN = "/forms/login.ftl";
+ public final static String LOGIN = "login.ftl";
- public final static String LOGIN_TOTP = "/forms/login-totp.ftl";
+ public final static String LOGIN_TOTP = "login-totp.ftl";
- public final static String LOGIN_CONFIG_TOTP = "/forms/login-config-totp.ftl";
+ public final static String LOGIN_CONFIG_TOTP = "login-config-totp.ftl";
- public final static String LOGIN_VERIFY_EMAIL = "/forms/login-verify-email.ftl";
+ public final static String LOGIN_VERIFY_EMAIL = "login-verify-email.ftl";
- public final static String OAUTH_GRANT = "/forms/login-oauth-grant.ftl";
+ public final static String OAUTH_GRANT = "login-oauth-grant.ftl";
- public final static String PASSWORD = "/forms/password.ftl";
+ public final static String PASSWORD = "password.ftl";
- public final static String LOGIN_RESET_PASSWORD = "/forms/login-reset-password.ftl";
+ public final static String LOGIN_RESET_PASSWORD = "login-reset-password.ftl";
- public final static String LOGIN_UPDATE_PASSWORD = "/forms/login-update-password.ftl";
+ public final static String LOGIN_UPDATE_PASSWORD = "login-update-password.ftl";
- public final static String REGISTER = "/forms/register.ftl";
+ public final static String REGISTER = "register.ftl";
- public final static String ERROR = "/forms/error.ftl";
+ public final static String ERROR = "error.ftl";
- public final static String SOCIAL = "/forms/social.ftl";
+ public final static String SOCIAL = "social.ftl";
- public final static String TOTP = "/forms/totp.ftl";
+ public final static String TOTP = "totp.ftl";
- public final static String LOGIN_UPDATE_PROFILE = "/forms/login-update-profile.ftl";
+ public final static String LOGIN_UPDATE_PROFILE = "login-update-profile.ftl";
}
diff --git a/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java b/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java
index 867c2c1..01e3b45 100755
--- a/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java
+++ b/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java
@@ -1,18 +1,19 @@
package org.keycloak.services.resources;
+import org.jboss.resteasy.logging.Logger;
import org.keycloak.SkeletonKeyContextResolver;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.ModelProvider;
import org.keycloak.services.managers.SocialRequestManager;
import org.keycloak.services.managers.TokenManager;
-import org.keycloak.services.utils.PropertiesManager;
import javax.annotation.PreDestroy;
import javax.servlet.ServletContext;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Context;
-import java.lang.reflect.Constructor;
import java.util.HashSet;
+import java.util.Iterator;
+import java.util.ServiceLoader;
import java.util.Set;
/**
@@ -21,14 +22,19 @@ import java.util.Set;
*/
public class KeycloakApplication extends Application {
+ private static final Logger log = Logger.getLogger(KeycloakApplication.class);
+
+ private static final String MODEL_PROVIDER = "keycloak.model";
+ private static final String DEFAULT_MODEL_PROVIDER = "jpa";
+
protected Set<Object> singletons = new HashSet<Object>();
protected Set<Class<?>> classes = new HashSet<Class<?>>();
protected KeycloakSessionFactory factory;
public KeycloakApplication(@Context ServletContext context) {
- KeycloakSessionFactory f = createSessionFactory();
- this.factory = f;
+ this.factory = createSessionFactory();
+
context.setAttribute(KeycloakSessionFactory.class.getName(), factory);
//classes.add(KeycloakSessionCleanupFilter.class);
@@ -41,57 +47,36 @@ public class KeycloakApplication extends Application {
classes.add(QRCodeResource.class);
}
- protected KeycloakSessionFactory createSessionFactory() {
- return buildSessionFactory();
- }
+ public static KeycloakSessionFactory createSessionFactory() {
+ ServiceLoader<ModelProvider> providers = ServiceLoader.load(ModelProvider.class);
+ String configuredProvider = System.getProperty(MODEL_PROVIDER);
+ ModelProvider provider = null;
- public static KeycloakSessionFactory buildSessionFactory() {
- if (PropertiesManager.isMongoSessionFactory()) {
- return buildMongoDBSessionFactory();
- } else if (PropertiesManager.isPicketlinkSessionFactory()) {
- return buildPicketlinkSessionFactory();
- } else if (PropertiesManager.isJpaSessionFactory()) {
- return buildJpaSessionFactory();
+ if (configuredProvider != null) {
+ for (ModelProvider p : providers) {
+ if (p.getId().equals(configuredProvider)) {
+ provider = p;
+ }
+ }
} else {
- throw new IllegalStateException("Unknown session factory type: " + PropertiesManager.getSessionFactoryType());
+ for (ModelProvider p : providers) {
+ if (provider == null) {
+ provider = p;
+ }
+
+ if (p.getId().equals(DEFAULT_MODEL_PROVIDER)) {
+ provider = p;
+ break;
+ }
+ }
}
- }
- private static KeycloakSessionFactory buildJpaSessionFactory() {
- ModelProvider provider = null;
- try {
- provider = (ModelProvider)Class.forName("org.keycloak.models.jpa.JpaModelProvider").newInstance();
- } catch (Exception e) {
- throw new RuntimeException(e);
+ if (provider != null) {
+ log.debug("Model provider: " + provider.getId());
+ return provider.createFactory();
}
- return provider.createFactory();
- }
-
- private static KeycloakSessionFactory buildPicketlinkSessionFactory() {
- ModelProvider provider = null;
- try {
- provider = (ModelProvider)Class.forName("org.keycloak.models.picketlink.PicketlinkModelProvider").newInstance();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- return provider.createFactory();
- }
-
- private static KeycloakSessionFactory buildMongoDBSessionFactory() {
- String host = PropertiesManager.getMongoHost();
- int port = PropertiesManager.getMongoPort();
- String dbName = PropertiesManager.getMongoDbName();
- boolean dropDatabaseOnStartup = PropertiesManager.dropDatabaseOnStartup();
-
- // Create MongoDBSessionFactory via reflection now
- try {
- Class<? extends KeycloakSessionFactory> mongoDBSessionFactoryClass = (Class<? extends KeycloakSessionFactory>)Class.forName("org.keycloak.models.mongo.keycloak.adapters.MongoDBSessionFactory");
- Constructor<? extends KeycloakSessionFactory> constr = mongoDBSessionFactoryClass.getConstructor(String.class, int.class, String.class, boolean.class);
- return constr.newInstance(host, port, dbName, dropDatabaseOnStartup);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
+ throw new RuntimeException("Model provider not found");
}
public KeycloakSessionFactory getFactory() {
@@ -103,9 +88,6 @@ public class KeycloakApplication extends Application {
factory.close();
}
-
-
-
@Override
public Set<Class<?>> getClasses() {
return classes;
diff --git a/services/src/main/java/org/keycloak/services/resources/SaasService.java b/services/src/main/java/org/keycloak/services/resources/SaasService.java
index ef936df..fc43120 100755
--- a/services/src/main/java/org/keycloak/services/resources/SaasService.java
+++ b/services/src/main/java/org/keycloak/services/resources/SaasService.java
@@ -263,7 +263,7 @@ public class SaasService {
@Path("login")
@GET
@NoCache
- public Response loginPage() {
+ public Response loginPage(@QueryParam("path") String path) {
logger.debug("loginPage ********************** <---");
RealmManager realmManager = new RealmManager(session);
RealmModel realm = getAdminstrationRealm(realmManager);
@@ -277,7 +277,7 @@ public class SaasService {
URI redirectUri = uriInfo.getBaseUriBuilder().path(SaasService.class).path(SaasService.class, "loginRedirect").build();
logger.debug("redirectUri: {0}", redirectUri.toString());
oauth.setStateCookiePath(redirectUri.getPath());
- return oauth.redirect(uriInfo, redirectUri.toString());
+ return oauth.redirect(uriInfo, redirectUri.toString(), path);
}
@Path("login-redirect")
@@ -316,7 +316,7 @@ public class SaasService {
logger.debug("state not specified");
throw new BadRequestException();
}
- new JaxrsOAuthClient().checkStateCookie(uriInfo, headers);
+ String path = new JaxrsOAuthClient().checkStateCookie(uriInfo, headers);
JWSInput input = new JWSInput(code, providers);
boolean verifiedCode = false;
@@ -358,7 +358,12 @@ public class SaasService {
}
logger.debug("loginRedirect SUCCESS");
NewCookie cookie = authManager.createSaasIdentityCookie(realm, accessCode.getUser(), uriInfo);
- return Response.status(302).cookie(cookie).location(contextRoot(uriInfo).path(adminPath).build()).build();
+
+ URI redirectUri = contextRoot(uriInfo).path(adminPath).build();
+ if (path != null) {
+ redirectUri = redirectUri.resolve("#" + path);
+ }
+ return Response.status(302).cookie(cookie).location(redirectUri).build();
} finally {
authManager.expireCookie(AbstractOAuthClient.OAUTH_TOKEN_REQUEST_STATE, uriInfo.getAbsolutePath().getPath());
}
diff --git a/services/src/main/java/org/keycloak/services/resources/TokenService.java b/services/src/main/java/org/keycloak/services/resources/TokenService.java
index d9690df..580473b 100755
--- a/services/src/main/java/org/keycloak/services/resources/TokenService.java
+++ b/services/src/main/java/org/keycloak/services/resources/TokenService.java
@@ -8,6 +8,7 @@ import org.jboss.resteasy.jwt.JsonSerialization;
import org.jboss.resteasy.logging.Logger;
import org.jboss.resteasy.spi.HttpRequest;
import org.jboss.resteasy.spi.HttpResponse;
+import org.keycloak.models.ApplicationModel;
import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakTransaction;
@@ -323,6 +324,17 @@ public class TokenService {
realm.updateCredential(user, credentials);
}
+ for (String r : realm.getDefaultRoles()) {
+ realm.grantRole(user, realm.getRole(r));
+ }
+
+ for (ApplicationModel application : realm.getApplications()) {
+ for (String r : application.getDefaultRoles()) {
+ application.grantRole(user, application.getRole(r));
+ }
+ }
+
+
return null;
}
@@ -423,7 +435,7 @@ public class TokenService {
logger.debug("accessRequest SUCCESS");
AccessTokenResponse res = accessTokenResponse(realm.getPrivateKey(), accessCode.getToken());
- return Cors.add(request, Response.ok(res)).allowedOrigins(client).build();
+ return Cors.add(request, Response.ok(res)).allowedOrigins(client).allowedMethods("POST").build();
}
protected AccessTokenResponse accessTokenResponse(PrivateKey privateKey, SkeletonKeyToken token) {
diff --git a/services/src/test/java/org/keycloak/test/AdapterTest.java b/services/src/test/java/org/keycloak/test/AdapterTest.java
index 1c86dfe..fff9532 100755
--- a/services/src/test/java/org/keycloak/test/AdapterTest.java
+++ b/services/src/test/java/org/keycloak/test/AdapterTest.java
@@ -4,11 +4,13 @@ import org.junit.Assert;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
+import org.keycloak.models.ApplicationModel;
import org.keycloak.models.Constants;
import org.keycloak.models.OAuthClientModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RequiredCredentialModel;
import org.keycloak.models.RoleModel;
+import org.keycloak.models.SocialLinkModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.representations.idm.CredentialRepresentation;
@@ -174,6 +176,34 @@ public class AdapterTest extends AbstractKeycloakTest {
}
@Test
+ public void deleteUser() throws Exception {
+ test1CreateRealm();
+
+ UserModel user = realmModel.addUser("bburke");
+ user.setAttribute("attr1", "val1");
+ user.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
+
+ RoleModel testRole = realmModel.addRole("test");
+ realmModel.grantRole(user, testRole);
+
+ ApplicationModel app = realmModel.addApplication("test-app");
+ RoleModel appRole = app.addRole("test");
+ app.grantRole(user, appRole);
+
+ SocialLinkModel socialLink = new SocialLinkModel("google", user.getLoginName());
+ realmModel.addSocialLink(user, socialLink);
+
+ UserCredentialModel cred = new UserCredentialModel();
+ cred.setType(CredentialRepresentation.PASSWORD);
+ cred.setValue("password");
+ realmModel.updateCredential(user, cred);
+
+ Assert.assertTrue(realmModel.deleteUser("bburke"));
+ Assert.assertFalse(realmModel.deleteUser("bburke"));
+ Assert.assertNull(realmModel.getUser("bburke"));
+ }
+
+ @Test
public void testUserSearch() throws Exception {
test1CreateRealm();
{
@@ -199,6 +229,15 @@ public class AdapterTest extends AbstractKeycloakTest {
Assert.assertEquals(bburke.getEmail(), "bburke@redhat.com");
}
+ {
+ List<UserModel> userModels = adapter.searchUsers("bil burk", realmModel);
+ Assert.assertEquals(userModels.size(), 1);
+ UserModel bburke = userModels.get(0);
+ Assert.assertEquals(bburke.getFirstName(), "Bill");
+ Assert.assertEquals(bburke.getLastName(), "Burke");
+ Assert.assertEquals(bburke.getEmail(), "bburke@redhat.com");
+ }
+
{
List<UserModel> userModels = adapter.searchUsers("bburke@redhat.com", realmModel);
@@ -210,6 +249,15 @@ public class AdapterTest extends AbstractKeycloakTest {
}
{
+ List<UserModel> userModels = adapter.searchUsers("rke@redhat.com", realmModel);
+ Assert.assertEquals(userModels.size(), 1);
+ UserModel bburke = userModels.get(0);
+ Assert.assertEquals(bburke.getFirstName(), "Bill");
+ Assert.assertEquals(bburke.getLastName(), "Burke");
+ Assert.assertEquals(bburke.getEmail(), "bburke@redhat.com");
+ }
+
+ {
List<UserModel> userModels = adapter.searchUsers("bburke", realmModel);
Assert.assertEquals(userModels.size(), 1);
UserModel bburke = userModels.get(0);
@@ -219,6 +267,15 @@ public class AdapterTest extends AbstractKeycloakTest {
}
{
+ List<UserModel> userModels = adapter.searchUsers("BurK", realmModel);
+ Assert.assertEquals(userModels.size(), 1);
+ UserModel bburke = userModels.get(0);
+ Assert.assertEquals(bburke.getFirstName(), "Bill");
+ Assert.assertEquals(bburke.getLastName(), "Burke");
+ Assert.assertEquals(bburke.getEmail(), "bburke@redhat.com");
+ }
+
+ {
List<UserModel> userModels = adapter.searchUsers("Burke", realmModel);
Assert.assertEquals(userModels.size(), 1);
UserModel bburke = userModels.get(0);
@@ -293,7 +350,7 @@ public class AdapterTest extends AbstractKeycloakTest {
realmModel.addRole("admin");
realmModel.addRole("user");
List<RoleModel> roles = realmModel.getRoles();
- Assert.assertEquals(6, roles.size());
+ Assert.assertEquals(5, roles.size());
UserModel user = realmModel.addUser("bburke");
RoleModel role = realmModel.getRole("user");
realmModel.grantRole(user, role);
diff --git a/services/src/test/java/org/keycloak/test/ApplicationModelTest.java b/services/src/test/java/org/keycloak/test/ApplicationModelTest.java
index a5e2a01..e322481 100755
--- a/services/src/test/java/org/keycloak/test/ApplicationModelTest.java
+++ b/services/src/test/java/org/keycloak/test/ApplicationModelTest.java
@@ -31,7 +31,7 @@ public class ApplicationModelTest extends AbstractKeycloakServerTest {
@Before
public void before() throws Exception {
- factory = KeycloakApplication.buildSessionFactory();
+ factory = KeycloakApplication.createSessionFactory();
identitySession = factory.createSession();
identitySession.getTransaction().begin();
manager = new RealmManager(identitySession);
diff --git a/services/src/test/java/org/keycloak/test/common/AbstractKeycloakTest.java b/services/src/test/java/org/keycloak/test/common/AbstractKeycloakTest.java
index a6debbf..11512d7 100755
--- a/services/src/test/java/org/keycloak/test/common/AbstractKeycloakTest.java
+++ b/services/src/test/java/org/keycloak/test/common/AbstractKeycloakTest.java
@@ -72,7 +72,7 @@ public abstract class AbstractKeycloakTest {
@Before
public void before() throws Exception {
testContext.initEnvironment();
- factory = KeycloakApplication.buildSessionFactory();
+ factory = KeycloakApplication.createSessionFactory();
identitySession = factory.createSession();
identitySession.getTransaction().begin();
realmManager = new RealmManager(identitySession);
diff --git a/services/src/test/java/org/keycloak/test/ImportTest.java b/services/src/test/java/org/keycloak/test/ImportTest.java
index 9bd13f9..2645f6d 100755
--- a/services/src/test/java/org/keycloak/test/ImportTest.java
+++ b/services/src/test/java/org/keycloak/test/ImportTest.java
@@ -50,8 +50,7 @@ public class ImportTest extends AbstractKeycloakTest {
UserModel user = realm.getUser("loginclient");
Assert.assertNotNull(user);
Set<String> scopes = realm.getScopeMappingValues(user);
- System.out.println("Scopes size: " + scopes.size());
- Assert.assertTrue(scopes.contains("*"));
+ Assert.assertEquals(0, scopes.size());
Assert.assertEquals(0, realm.getSocialLinks(user).size());
List<ApplicationModel> resources = realm.getApplications();
diff --git a/services/src/test/java/org/keycloak/test/ModelTest.java b/services/src/test/java/org/keycloak/test/ModelTest.java
index 33eb405..6771e29 100755
--- a/services/src/test/java/org/keycloak/test/ModelTest.java
+++ b/services/src/test/java/org/keycloak/test/ModelTest.java
@@ -23,7 +23,7 @@ public class ModelTest extends AbstractKeycloakServerTest {
@Before
public void before() throws Exception {
- factory = KeycloakApplication.buildSessionFactory();
+ factory = KeycloakApplication.createSessionFactory();
identitySession = factory.createSession();
identitySession.getTransaction().begin();
manager = new RealmManager(identitySession);
diff --git a/services/src/test/java/org/keycloak/test/UserModelTest.java b/services/src/test/java/org/keycloak/test/UserModelTest.java
index 910a20c..338af77 100755
--- a/services/src/test/java/org/keycloak/test/UserModelTest.java
+++ b/services/src/test/java/org/keycloak/test/UserModelTest.java
@@ -26,7 +26,7 @@ public class UserModelTest extends AbstractKeycloakServerTest {
@Before
public void before() throws Exception {
- factory = KeycloakApplication.buildSessionFactory();
+ factory = KeycloakApplication.createSessionFactory();
identitySession = factory.createSession();
identitySession.getTransaction().begin();
manager = new RealmManager(identitySession);
diff --git a/services/src/test/resources/testrealm.json b/services/src/test/resources/testrealm.json
index cfe5215..d21823a 100755
--- a/services/src/test/resources/testrealm.json
+++ b/services/src/test/resources/testrealm.json
@@ -64,12 +64,6 @@
"roles": ["admin"]
}
],
- "scopeMappings": [
- {
- "username": "loginclient",
- "roles": ["*"]
- }
- ],
"socialMappings": [
{
"username": "mySocialUser",
diff --git a/services/src/test/resources/testrealm-demo.json b/services/src/test/resources/testrealm-demo.json
index 92d23ea..9e96d21 100755
--- a/services/src/test/resources/testrealm-demo.json
+++ b/services/src/test/resources/testrealm-demo.json
@@ -23,7 +23,9 @@
{ "type" : "Password",
"value" : "password" }
]
- },
+ }
+ ],
+ "clients" : [
{
"username" : "third-party",
"enabled": true,
@@ -47,10 +49,6 @@
{
"username": "bburke@redhat.com",
"roles": ["user"]
- },
- {
- "username": "third-party",
- "roles": ["KEYCLOAK_IDENTITY_REQUESTER"]
}
],
"scopeMappings": [
@@ -64,7 +62,6 @@
"name": "customer-portal",
"enabled": true,
"adminUrl": "http://localhost:8080/customer-portal/j_admin_request",
- "useRealmMappings": true,
"credentials": [
{
"type": "totp",
@@ -77,7 +74,6 @@
"name": "product-portal",
"enabled": true,
"adminUrl": "http://localhost:8080/product-portal/j_admin_request",
- "useRealmMappings": true,
"credentials": [
{
"type": "totp",
@@ -87,4 +83,4 @@
]
}
]
-}
\ No newline at end of file
+}
testsuite/integration/pom.xml 10(+10 -0)
diff --git a/testsuite/integration/pom.xml b/testsuite/integration/pom.xml
index ffbe981..a246609 100755
--- a/testsuite/integration/pom.xml
+++ b/testsuite/integration/pom.xml
@@ -53,6 +53,16 @@
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
+ <artifactId>keycloak-model-jpa</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.keycloak</groupId>
+ <artifactId>keycloak-model-picketlink</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.keycloak</groupId>
<artifactId>keycloak-social-core</artifactId>
<version>${project.version}</version>
</dependency>
diff --git a/testsuite/integration/src/main/java/org/keycloak/testutils/KeycloakServer.java b/testsuite/integration/src/main/java/org/keycloak/testutils/KeycloakServer.java
index f07cb15..8f33252 100755
--- a/testsuite/integration/src/main/java/org/keycloak/testutils/KeycloakServer.java
+++ b/testsuite/integration/src/main/java/org/keycloak/testutils/KeycloakServer.java
@@ -262,8 +262,7 @@ public class KeycloakServer {
di.setDeploymentName("Keycloak");
di.setResourceManager(new KeycloakResourceManager(config.getResourcesHome()));
- Set<String> allowed = new HashSet<String>(Arrays.asList(new String[]{"js", "css", "png", "jpg", "gif", "html", "svg"}));
- di.setDefaultServletConfig(new DefaultServletConfig(false, allowed));
+ di.setDefaultServletConfig(new DefaultServletConfig(true));
di.addWelcomePage("index.html");
FilterInfo filter = Servlets.filter("SessionFilter", KeycloakSessionServletFilter.class);
@@ -272,7 +271,7 @@ public class KeycloakServer {
server.deploy(di);
- factory = KeycloakApplication.buildSessionFactory();
+ factory = KeycloakApplication.createSessionFactory();
setupDefaultRealm();
@@ -330,23 +329,21 @@ public class KeycloakServer {
@Override
public boolean isResourceChangeListenerSupported() {
- return false; //To change body of implemented methods use File | Settings | File Templates.
+ return false;
}
@Override
- public void registerResourceChangeListener(ResourceChangeListener resourceChangeListener) {
- //To change body of implemented methods use File | Settings | File Templates.
+ public void registerResourceChangeListener(ResourceChangeListener listener) {
}
@Override
- public void removeResourceChangeListener(ResourceChangeListener resourceChangeListener) {
- //To change body of implemented methods use File | Settings | File Templates.
+ public void removeResourceChangeListener(ResourceChangeListener listener) {
}
@Override
public void close() throws IOException {
- //To change body of implemented methods use File | Settings | File Templates.
}
+
}
private static File file(String... path) {
diff --git a/testsuite/integration/src/main/resources/META-INF/persistence.xml b/testsuite/integration/src/main/resources/META-INF/persistence.xml
index f299e7e..5a4df6c 100755
--- a/testsuite/integration/src/main/resources/META-INF/persistence.xml
+++ b/testsuite/integration/src/main/resources/META-INF/persistence.xml
@@ -32,5 +32,35 @@
</properties>
</persistence-unit>
+ <persistence-unit name="picketlink-keycloak-identity-store" transaction-type="RESOURCE_LOCAL">
+ <provider>org.hibernate.ejb.HibernatePersistence</provider>
+
+ <class>org.picketlink.idm.jpa.model.sample.simple.AttributedTypeEntity</class>
+ <class>org.picketlink.idm.jpa.model.sample.simple.AccountTypeEntity</class>
+ <class>org.picketlink.idm.jpa.model.sample.simple.RoleTypeEntity</class>
+ <class>org.picketlink.idm.jpa.model.sample.simple.GroupTypeEntity</class>
+ <class>org.picketlink.idm.jpa.model.sample.simple.IdentityTypeEntity</class>
+ <class>org.picketlink.idm.jpa.model.sample.simple.RelationshipTypeEntity</class>
+ <class>org.picketlink.idm.jpa.model.sample.simple.RelationshipIdentityTypeEntity</class>
+ <class>org.picketlink.idm.jpa.model.sample.simple.PartitionTypeEntity</class>
+ <class>org.picketlink.idm.jpa.model.sample.simple.PasswordCredentialTypeEntity</class>
+ <class>org.picketlink.idm.jpa.model.sample.simple.DigestCredentialTypeEntity</class>
+ <class>org.picketlink.idm.jpa.model.sample.simple.X509CredentialTypeEntity</class>
+ <class>org.picketlink.idm.jpa.model.sample.simple.OTPCredentialTypeEntity</class>
+ <class>org.picketlink.idm.jpa.model.sample.simple.AttributeTypeEntity</class>
+ <class>org.keycloak.models.picketlink.mappings.RealmEntity</class>
+ <class>org.keycloak.models.picketlink.mappings.ApplicationEntity</class>
+
+ <exclude-unlisted-classes>true</exclude-unlisted-classes>
+ <properties>
+ <property name="hibernate.connection.url" value="jdbc:h2:mem:test"/>
+ <property name="hibernate.connection.driver_class" value="org.h2.Driver"/>
+ <property name="hibernate.connection.username" value="sa"/>
+ <property name="hibernate.connection.password" value=""/>
+ <property name="hibernate.hbm2ddl.auto" value="create-drop" />
+ <property name="hibernate.show_sql" value="false" />
+ <property name="hibernate.format_sql" value="true" />
+ </properties>
+ </persistence-unit>
</persistence>
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/ProfileTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/ProfileTest.java
index 23ac614..e3fe2dd 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/ProfileTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/ProfileTest.java
@@ -12,7 +12,9 @@ import org.junit.Rule;
import org.junit.Test;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
+import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.testsuite.Constants;
import org.keycloak.testsuite.OAuthClient;
@@ -52,6 +54,16 @@ public class ProfileTest {
user.setAttribute("key2", "value2");
ApplicationModel accountApp = appRealm.getApplicationNameMap().get(org.keycloak.models.Constants.ACCOUNT_APPLICATION);
+ for (String r : accountApp.getDefaultRoles()) {
+ accountApp.grantRole(user, accountApp.getRole(r));
+ }
+
+ UserModel user2 = appRealm.addUser("test-user-no-access@localhost");
+ user2.setEnabled(true);
+ UserCredentialModel creds = new UserCredentialModel();
+ creds.setType(CredentialRepresentation.PASSWORD);
+ creds.setValue("password");
+ appRealm.updateCredential(user2, creds);
ApplicationModel app = appRealm.getApplicationNameMap().get("test-app");
accountApp.addScopeMapping(app.getApplicationUser(), org.keycloak.models.Constants.ACCOUNT_PROFILE_ROLE);
@@ -81,8 +93,6 @@ public class ProfileTest {
@WebResource
protected OAuthGrantPage grantPage;
- private List<String> defaultRoles;
-
@Test
public void getProfile() throws Exception {
oauth.doLogin("test-user@localhost", "password");
@@ -154,31 +164,13 @@ public class ProfileTest {
@Test
public void getProfileNoAccess() throws Exception {
- try {
- keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
- @Override
- public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
- ApplicationModel app = appRealm.getApplicationNameMap().get(org.keycloak.models.Constants.ACCOUNT_APPLICATION);
- defaultRoles = app.getDefaultRoles();
- app.updateDefaultRoles(new String[0]);
- }
- });
-
- oauth.doLogin("test-user@localhost", "password");
-
- String code = oauth.getCurrentQuery().get("code");
- String token = oauth.doAccessTokenRequest(code, "password").getAccessToken();
-
- HttpResponse response = doGetProfile(token, null);
- assertEquals(403, response.getStatusLine().getStatusCode());
- } finally {
- keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
- @Override
- public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
- appRealm.getApplicationNameMap().get(org.keycloak.models.Constants.ACCOUNT_APPLICATION).updateDefaultRoles((String[]) defaultRoles.toArray(new String[0]));
- }
- });
- }
+ oauth.doLogin("test-user-no-access@localhost", "password");
+
+ String code = oauth.getCurrentQuery().get("code");
+ String token = oauth.doAccessTokenRequest(code, "password").getAccessToken();
+
+ HttpResponse response = doGetProfile(token, null);
+ assertEquals(403, response.getStatusLine().getStatusCode());
}
@Test
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/AccountTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/AccountTest.java
index b38411e..4d0d3ca 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/AccountTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/AccountTest.java
@@ -48,7 +48,23 @@ import static org.junit.Assert.assertEquals;
public class AccountTest {
@ClassRule
- public static KeycloakRule keycloakRule = new KeycloakRule();
+ public static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakSetup() {
+ @Override
+ public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+ UserModel user = appRealm.getUser("test-user@localhost");
+ ApplicationModel accountApp = appRealm.getApplicationNameMap().get(org.keycloak.models.Constants.ACCOUNT_APPLICATION);
+ for (String r : accountApp.getDefaultRoles()) {
+ accountApp.grantRole(user, accountApp.getRole(r));
+ }
+
+ UserModel user2 = appRealm.addUser("test-user-no-access@localhost");
+ user2.setEnabled(true);
+ UserCredentialModel creds = new UserCredentialModel();
+ creds.setType(CredentialRepresentation.PASSWORD);
+ creds.setValue("password");
+ appRealm.updateCredential(user2, creds);
+ }
+ });
@Rule
public WebRule webRule = new WebRule(this);
@@ -79,8 +95,6 @@ public class AccountTest {
private TimeBasedOTP totp = new TimeBasedOTP();
- private List<String> defaultRoles;
-
@After
public void after() {
keycloakRule.configure(new KeycloakSetup() {
@@ -119,7 +133,7 @@ public class AccountTest {
loginPage.open();
loginPage.login("test-user@localhost", "password");
- Assert.assertEquals("Invalid username or password", loginPage.getError());
+ Assert.assertEquals("Invalid username or password.", loginPage.getError());
loginPage.open();
loginPage.login("test-user@localhost", "new-password");
@@ -176,7 +190,7 @@ public class AccountTest {
Assert.assertFalse(driver.getPageSource().contains("Remove Google"));
// Error with false code
- totpPage.configure(totp.generate(totpPage.getTotpSecret()+"123"));
+ totpPage.configure(totp.generate(totpPage.getTotpSecret() + "123"));
Assert.assertTrue(profilePage.isError());
@@ -189,29 +203,11 @@ public class AccountTest {
@Test
public void changeProfileNoAccess() throws Exception {
- try {
- keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
- @Override
- public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
- ApplicationModel app = appRealm.getApplicationNameMap().get(Constants.ACCOUNT_APPLICATION);
- defaultRoles = app.getDefaultRoles();
- app.updateDefaultRoles(new String[0]);
- }
- });
-
- profilePage.open();
- loginPage.login("test-user@localhost", "password");
-
- Assert.assertTrue(errorPage.isCurrent());
- Assert.assertEquals("No access", errorPage.getError());
- } finally {
- keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
- @Override
- public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
- appRealm.getApplicationNameMap().get(org.keycloak.models.Constants.ACCOUNT_APPLICATION).updateDefaultRoles((String[]) defaultRoles.toArray(new String[0]));
- }
- });
- }
+ profilePage.open();
+ loginPage.login("test-user-no-access@localhost", "password");
+
+ Assert.assertTrue(errorPage.isCurrent());
+ Assert.assertEquals("No access", errorPage.getError());
}
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTest.java
index d9628df..fab49b2 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTest.java
@@ -60,7 +60,7 @@ public class LoginTest {
loginPage.assertCurrent();
- Assert.assertEquals("Invalid username or password", loginPage.getError());
+ Assert.assertEquals("Invalid username or password.", loginPage.getError());
}
@Test
@@ -70,7 +70,7 @@ public class LoginTest {
loginPage.assertCurrent();
- Assert.assertEquals("Invalid username or password", loginPage.getError());
+ Assert.assertEquals("Invalid username or password.", loginPage.getError());
}
@Test
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java
index a86392b..a3ea179 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java
@@ -102,7 +102,7 @@ public class LoginTotpTest {
loginTotpPage.login("123456");
loginPage.assertCurrent();
- Assert.assertEquals("Invalid username or password", loginPage.getError());
+ Assert.assertEquals("Invalid username or password.", loginPage.getError());
}
@Test
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/RegisterTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/RegisterTest.java
index 93e773e..e82b31f 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/RegisterTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/RegisterTest.java
@@ -90,7 +90,7 @@ public class RegisterTest {
registerPage.register("firstName", "lastName", "email", "registerUserMissingPassword", null, null);
registerPage.assertCurrent();
- Assert.assertEquals("Please specify password", registerPage.getError());
+ Assert.assertEquals("Please specify password.", registerPage.getError());
}
@Test
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java
index 15f1cbf..0b25e48 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java
@@ -63,7 +63,7 @@ public class AccessTokenTest {
Assert.assertEquals(200, response.getStatusCode());
- Assert.assertTrue(response.getExpiresIn() <= 300 && response.getExpiresIn() >= 250);
+ Assert.assertTrue(response.getExpiresIn() <= 600 && response.getExpiresIn() >= 550);
Assert.assertEquals("bearer", response.getTokenType());
@@ -73,6 +73,9 @@ public class AccessTokenTest {
Assert.assertEquals(1, token.getRealmAccess().getRoles().size());
Assert.assertTrue(token.getRealmAccess().isUserInRole("user"));
+
+ Assert.assertEquals(1, token.getResourceAccess(oauth.getClientId()).getRoles().size());
+ Assert.assertTrue(token.getResourceAccess(oauth.getClientId()).isUserInRole("customer-user"));
}
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java
index c69208f..5b1118f 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java
@@ -145,6 +145,10 @@ public class OAuthClient {
}
}
+ public String getClientId() {
+ return clientId;
+ }
+
public String getCurrentRequest() {
return driver.getCurrentUrl().substring(0, driver.getCurrentUrl().indexOf('?'));
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/social/SocialLoginTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/social/SocialLoginTest.java
index f7af3c5..e4c3c6f 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/social/SocialLoginTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/social/SocialLoginTest.java
@@ -103,9 +103,6 @@ public class SocialLoginTest {
SkeletonKeyToken token = oauth.verifyToken(response.getAccessToken());
Assert.assertEquals("dummy-user", token.getPrincipal());
-
- Assert.assertEquals(1, token.getRealmAccess().getRoles().size());
- Assert.assertTrue(token.getRealmAccess().isUserInRole("user"));
}
@Test
diff --git a/testsuite/integration/src/test/resources/testrealm.json b/testsuite/integration/src/test/resources/testrealm.json
index f4ef0c5..112b8ce 100755
--- a/testsuite/integration/src/test/resources/testrealm.json
+++ b/testsuite/integration/src/test/resources/testrealm.json
@@ -2,8 +2,8 @@
"id": "test",
"realm": "test",
"enabled": true,
- "tokenLifespan": 300,
- "accessCodeLifespan": 10,
+ "tokenLifespan": 600,
+ "accessCodeLifespan": 600,
"accessCodeLifespanUserAction": 600,
"sslNotRequired": true,
"cookieLoginAllowed": true,
@@ -30,7 +30,9 @@
{ "type" : "password",
"value" : "password" }
]
- },
+ }
+ ],
+ "clients" : [
{
"username" : "third-party",
"enabled": true,
@@ -54,16 +56,16 @@
{
"username": "test-user@localhost",
"roles": ["user"]
- },
- {
- "username": "third-party",
- "roles": ["KEYCLOAK_IDENTITY_REQUESTER"]
}
],
"scopeMappings": [
{
"username": "third-party",
"roles": ["user"]
+ },
+ {
+ "username": "test-app",
+ "roles": ["user"]
}
],
"applications": [
@@ -71,7 +73,6 @@
"name": "test-app",
"enabled": true,
"adminUrl": "http://localhost:8081/app/logout",
- "useRealmMappings": true,
"credentials": [
{
"type": "password",
diff --git a/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/BaseJMeterPerformanceTest.java b/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/BaseJMeterPerformanceTest.java
index 882f8bb..eda2761 100755
--- a/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/BaseJMeterPerformanceTest.java
+++ b/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/BaseJMeterPerformanceTest.java
@@ -22,7 +22,7 @@ public class BaseJMeterPerformanceTest extends AbstractJavaSamplerClient {
@Override
public KeycloakSessionFactory call() throws Exception {
- return KeycloakApplication.buildSessionFactory();
+ return KeycloakApplication.createSessionFactory();
}
});