keycloak-uncached
Changes
export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ModelImporter.java 4(+2 -2)
forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/applications.js 219(+42 -177)
forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/oauth-clients.js 40(+22 -18)
forms/common-themes/src/main/resources/theme/admin/base/resources/partials/application-detail.html 40(+17 -23)
forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-detail.html 34(+16 -18)
forms/common-themes/src/main/resources/theme/admin/base/resources/partials/user-sessions.html 15(+7 -8)
pom.xml 41(+25 -16)
Details
diff --git a/examples/js-console/example-realm.json b/examples/js-console/example-realm.json
index 7cb5485..42d291e 100755
--- a/examples/js-console/example-realm.json
+++ b/examples/js-console/example-realm.json
@@ -48,12 +48,12 @@
"name": "js-console",
"enabled": true,
"publicClient": true,
- "baseUrl": "http://localhost/js-console",
+ "baseUrl": "http://localhost:8080/js-console",
"redirectUris": [
- "http://localhost/js-console/*"
+ "http://localhost:8080/js-console/*"
],
"webOrigins": [
- "http://localhost"
+ "http://localhost:8080"
]
}
],
diff --git a/examples/js-console/src/main/webapp/index.html b/examples/js-console/src/main/webapp/index.html
index 499c928..45f7665 100644
--- a/examples/js-console/src/main/webapp/index.html
+++ b/examples/js-console/src/main/webapp/index.html
@@ -1,13 +1,13 @@
<html>
<head>
- <script src="//localhost:8081/auth/js/keycloak.js"></script>
+ <script src="//localhost:8080/auth/js/keycloak.js"></script>
</head>
<body>
<div>
<button onclick="keycloak.login()">Login</button>
<button onclick="keycloak.logout()">Logout</button>
- <button onclick="refreshToken()">Refresh Token</button>
+ <button onclick="refreshToken(9999)">Refresh Token</button>
<button onclick="refreshToken(30)">Refresh Token (if <30s validity)</button>
<button onclick="loadProfile()">Get Profile</button>
<button onclick="output(keycloak.tokenParsed)">Show Token</button>
diff --git a/examples/js-console/src/main/webapp/keycloak.json b/examples/js-console/src/main/webapp/keycloak.json
index 66434b9..286d87b 100644
--- a/examples/js-console/src/main/webapp/keycloak.json
+++ b/examples/js-console/src/main/webapp/keycloak.json
@@ -1,8 +1,8 @@
{
"realm" : "example",
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
- "auth-server-url" : "http://localhost:8081/auth",
+ "auth-server-url" : "http://localhost:8080/auth",
"ssl-not-required" : true,
"resource" : "js-console",
"public-client" : true
-}
\ No newline at end of file
+}
diff --git a/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ModelImporter.java b/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ModelImporter.java
index 15f9fae..be78099 100755
--- a/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ModelImporter.java
+++ b/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ModelImporter.java
@@ -151,7 +151,7 @@ public class ModelImporter {
}
}
- logger.infof("%d roles imported: ", roles);
+ logger.infof("%d roles imported: ", roles.size());
if (logger.isDebugEnabled()) {
logger.debug("Imported roles: " + roles);
}
@@ -225,7 +225,7 @@ public class ModelImporter {
addScopes(realm, client, clientEntity);
}
- logger.infof("OAuth clients imported: " + clients);
+ logger.info("OAuth clients imported: " + clients);
}
protected ApplicationModel findApplicationById(KeycloakSession keycloakSession, String applicationId) {
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/index.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/index.html
index eca1170..459751c 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/index.html
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/index.html
@@ -38,7 +38,7 @@
</style>
</head>
-<body class="admin-console" data-ng-controller="GlobalCtrl" data-ng-cloak>
+<body class="admin-console" data-ng-controller="GlobalCtrl" data-ng-cloak data-ng-show="auth.user">
<div id="idletimeout">
You will be logged off in <strong><span></span> seconds</strong> due to inactivity.
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/app.js b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/app.js
index e633dca..3438d6b 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/app.js
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/app.js
@@ -1,6 +1,5 @@
'use strict';
-var indexUrl = window.location.href;
var consoleBaseUrl = window.location.href;
consoleBaseUrl = consoleBaseUrl.substring(0, consoleBaseUrl.indexOf("/console"));
consoleBaseUrl = consoleBaseUrl + "/console";
@@ -23,14 +22,12 @@ var loadingTimer = -1;
angular.element(document).ready(function ($http) {
var keycloakAuth = new Keycloak(configUrl);
- auth.loggedIn = false;
keycloakAuth.onAuthLogout = function() {
location.reload();
}
keycloakAuth.init({ onLoad: 'login-required' }).success(function () {
- auth.loggedIn = true;
auth.authz = keycloakAuth;
module.factory('Auth', function() {
return auth;
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/applications.js b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/applications.js
index 6c492d4..0f9d457 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/applications.js
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/applications.js
@@ -195,7 +195,7 @@ module.controller('ApplicationInstallationCtrl', function($scope, realm, applica
});
-module.controller('ApplicationDetailCtrl', function($scope, $document, realm, application, Application, $location, Dialog, Notifications) {
+module.controller('ApplicationDetailCtrl', function($scope, realm, application, Application, $location, Dialog, Notifications) {
console.log('ApplicationDetailCtrl');
$scope.clientTypes = [
@@ -263,21 +263,10 @@ module.controller('ApplicationDetailCtrl', function($scope, $document, realm, ap
}
$scope.save = function() {
- if ($scope.create) {
- if (!$scope.application.bearerOnly && (!$scope.application.redirectUris || $scope.application.redirectUris.length == 0)) {
- Notifications.error("You must specify at least one redirect uri");
- } else {
- // automatically add redirects to web origins
- var parser = document.createElement('a');
- var originSet = {};
- for (var i = 0; i < $scope.application.redirectUris.length; i++) {
- parser.href = $scope.application.redirectUris[i];
- var origin = parser.protocol + "//" + parser.host;
- originSet[origin] = true;
- }
- for (var key in originSet) {
- $scope.application.webOrigins.push(key);
- }
+ if (!$scope.application.bearerOnly && (!$scope.application.redirectUris || $scope.application.redirectUris.length == 0)) {
+ Notifications.error("You must specify at least one redirect uri");
+ } else {
+ if ($scope.create) {
Application.save({
realm: realm.realm,
application: ''
@@ -288,16 +277,16 @@ module.controller('ApplicationDetailCtrl', function($scope, $document, realm, ap
$location.url("/realms/" + realm.realm + "/applications/" + id);
Notifications.success("The application has been created.");
});
+ } else {
+ Application.update({
+ realm : realm.realm,
+ application : application.name
+ }, $scope.application, function() {
+ $scope.changed = false;
+ application = angular.copy($scope.application);
+ Notifications.success("Your changes have been saved to the application.");
+ });
}
- } else {
- Application.update({
- realm : realm.realm,
- application : application.name
- }, $scope.application, function() {
- $scope.changed = false;
- application = angular.copy($scope.application);
- Notifications.success("Your changes have been saved to the application.");
- });
}
};
@@ -342,195 +331,71 @@ module.controller('ApplicationScopeMappingCtrl', function($scope, $http, realm,
$scope.applicationMappings = [];
$scope.dummymodel = [];
+ function updateRealmRoles() {
+ $scope.realmRoles = ApplicationAvailableRealmScopeMapping.query({realm : realm.realm, application : application.name});
+ $scope.realmMappings = ApplicationRealmScopeMapping.query({realm : realm.realm, application : application.name});
+ $scope.realmComposite = ApplicationCompositeRealmScopeMapping.query({realm : realm.realm, application : application.name});
+ }
-
- $scope.realmMappings = ApplicationRealmScopeMapping.query({realm : realm.realm, application : application.name}, function(){
- for (var i = 0; i < $scope.realmMappings.length; i++) {
- var role = $scope.realmMappings[i];
- for (var j = 0; j < $scope.realmRoles.length; j++) {
- var realmRole = $scope.realmRoles[j];
- if (realmRole.id == role.id) {
- var idx = $scope.realmRoles.indexOf(realmRole);
- if (idx != -1) {
- $scope.realmRoles.splice(idx, 1);
- break;
- }
- }
- }
+ function updateAppRoles() {
+ if ($scope.targetApp) {
+ console.debug($scope.targetApp.name);
+ $scope.applicationRoles = ApplicationAvailableApplicationScopeMapping.query({realm : realm.realm, application : application.name, targetApp : $scope.targetApp.name});
+ $scope.applicationMappings = ApplicationApplicationScopeMapping.query({realm : realm.realm, application : application.name, targetApp : $scope.targetApp.name});
+ $scope.applicationComposite = ApplicationCompositeApplicationScopeMapping.query({realm : realm.realm, application : application.name, targetApp : $scope.targetApp.name});
+ } else {
+ $scope.applicationRoles = null;
+ $scope.applicationMappings = null;
+ $scope.applicationComposite = null;
}
- });
+ }
$scope.addRealmRole = function() {
- $http.post(authUrl + '/admin/realms/' + realm.realm + '/applications/' + application.name + '/scope-mappings/realm',
- $scope.selectedRealmRoles).success(function() {
- for (var i = 0; i < $scope.selectedRealmRoles.length; i++) {
- var role = $scope.selectedRealmRoles[i];
- var idx = $scope.realmRoles.indexOf($scope.selectedRealmRoles[i]);
- if (idx != -1) {
- $scope.realmRoles.splice(idx, 1);
- $scope.realmMappings.push(role);
- }
- }
- $scope.selectRealmRoles = [];
- });
+ $http.post(authUrl + '/admin/realms/' + realm.realm + '/applications/' + application.name + '/scope-mappings/realm', $scope.selectedRealmRoles)
+ .success(updateRealmRoles);
};
$scope.deleteRealmRole = function() {
$http.delete(authUrl + '/admin/realms/' + realm.realm + '/applications/' + application.name + '/scope-mappings/realm',
- {data : $scope.selectedRealmMappings, headers : {"content-type" : "application/json"}}).success(function() {
- for (var i = 0; i < $scope.selectedRealmMappings.length; i++) {
- var role = $scope.selectedRealmMappings[i];
- var idx = $scope.realmMappings.indexOf($scope.selectedRealmMappings[i]);
- if (idx != -1) {
- $scope.realmMappings.splice(idx, 1);
- $scope.realmRoles.push(role);
- }
- }
- $scope.selectedRealmMappings = [];
- });
+ {data : $scope.selectedRealmMappings, headers : {"content-type" : "application/json"}})
+ .success(updateRealmRoles);
};
$scope.addApplicationRole = function() {
$http.post(authUrl + '/admin/realms/' + realm.realm + '/applications/' + application.name + '/scope-mappings/applications/' + $scope.targetApp.name,
- $scope.selectedApplicationRoles).success(function() {
- for (var i = 0; i < $scope.selectedApplicationRoles.length; i++) {
- var role = $scope.selectedApplicationRoles[i];
- var idx = $scope.applicationRoles.indexOf($scope.selectedApplicationRoles[i]);
- if (idx != -1) {
- $scope.applicationRoles.splice(idx, 1);
- $scope.applicationMappings.push(role);
- }
- }
- $scope.selectedApplicationRoles = [];
- });
+ $scope.selectedApplicationRoles).success(updateAppRoles);
};
$scope.deleteApplicationRole = function() {
$http.delete(authUrl + '/admin/realms/' + realm.realm + '/applications/' + application.name + '/scope-mappings/applications/' + $scope.targetApp.name,
- {data : $scope.selectedApplicationMappings, headers : {"content-type" : "application/json"}}).success(function() {
- for (var i = 0; i < $scope.selectedApplicationMappings.length; i++) {
- var role = $scope.selectedApplicationMappings[i];
- var idx = $scope.applicationMappings.indexOf($scope.selectedApplicationMappings[i]);
- if (idx != -1) {
- $scope.applicationMappings.splice(idx, 1);
- $scope.applicationRoles.push(role);
- }
- }
- $scope.selectedApplicationMappings = [];
- });
+ {data : $scope.selectedApplicationMappings, headers : {"content-type" : "application/json"}}).success(updateAppRoles);
};
-
$scope.changeApplication = function() {
- if ($scope.targetApp) {
- $scope.applicationRoles = ApplicationRole.query({realm : realm.realm, application : $scope.targetApp.name}, function() {
- $scope.applicationMappings = ApplicationApplicationScopeMapping.query({realm : realm.realm, application : application.name, targetApp : $scope.targetApp.name}, function(){
- for (var i = 0; i < $scope.applicationMappings.length; i++) {
- var role = $scope.applicationMappings[i];
- for (var j = 0; j < $scope.applicationRoles.length; j++) {
- var realmRole = $scope.applicationRoles[j];
- if (realmRole.id == role.id) {
- var idx = $scope.applicationRoles.indexOf(realmRole);
- if (idx != -1) {
- $scope.applicationRoles.splice(idx, 1);
- break;
- }
- }
- }
- }
- });
-
- }
- );
- } else {
- $scope.applicationRoles = null;
- }
+ updateAppRoles();
};
- $scope.realmMappings = ApplicationRealmScopeMapping.query({realm : realm.realm, application : application.name});
- $scope.realmRoles = ApplicationAvailableRealmScopeMapping.query({realm : realm.realm, application : application.name});
- $scope.realmComposite = ApplicationCompositeRealmScopeMapping.query({realm : realm.realm, application : application.name});
-
$scope.addRealmRole = function() {
$http.post(authUrl + '/admin/realms/' + realm.realm + '/applications/' + application.name + '/scope-mappings/realm',
- $scope.selectedRealmRoles).success(function() {
- $scope.realmMappings = ApplicationRealmScopeMapping.query({realm : realm.realm, application : application.name});
- $scope.realmRoles = ApplicationAvailableRealmScopeMapping.query({realm : realm.realm, application : application.name});
- $scope.realmComposite = ApplicationCompositeRealmScopeMapping.query({realm : realm.realm, application : application.name});
- $scope.selectedRealmMappings = [];
- $scope.selectRealmRoles = [];
- if ($scope.targetApp) {
- console.log('load available');
- $scope.applicationMappings = ApplicationApplicationScopeMapping.query({realm : realm.realm, application : application.name, targetApp : $scope.targetApp.name});
- $scope.applicationRoles = ApplicationAvailableApplicationScopeMapping.query({realm : realm.realm, application : application.name, targetApp : $scope.targetApp.name});
- $scope.applicationComposite = ApplicationCompositeApplicationScopeMapping.query({realm : realm.realm, application : application.name, targetApp : $scope.targetApp.name});
- $scope.selectedApplicationRoles = [];
- $scope.selectedApplicationMappings = [];
- }
- });
+ $scope.selectedRealmRoles).success(updateRealmRoles);
};
$scope.deleteRealmRole = function() {
$http.delete(authUrl + '/admin/realms/' + realm.realm + '/applications/' + application.name + '/scope-mappings/realm',
- {data : $scope.selectedRealmMappings, headers : {"content-type" : "application/json"}}).success(function() {
- $scope.realmMappings = ApplicationRealmScopeMapping.query({realm : realm.realm, application : application.name});
- $scope.realmRoles = ApplicationAvailableRealmScopeMapping.query({realm : realm.realm, application : application.name});
- $scope.realmComposite = ApplicationCompositeRealmScopeMapping.query({realm : realm.realm, application : application.name});
- $scope.selectedRealmMappings = [];
- $scope.selectRealmRoles = [];
- if ($scope.targetApp) {
- console.log('load available');
- $scope.applicationMappings = ApplicationApplicationScopeMapping.query({realm : realm.realm, application : application.name, targetApp : $scope.targetApp.name});
- $scope.applicationRoles = ApplicationAvailableApplicationScopeMapping.query({realm : realm.realm, application : application.name, targetApp : $scope.targetApp.name});
- $scope.applicationComposite = ApplicationCompositeApplicationScopeMapping.query({realm : realm.realm, application : application.name, targetApp : $scope.targetApp.name});
- $scope.selectedApplicationRoles = [];
- $scope.selectedApplicationMappings = [];
- }
- });
+ {data : $scope.selectedRealmMappings, headers : {"content-type" : "application/json"}}).success(updateRealmRoles);
};
$scope.addApplicationRole = function() {
$http.post(authUrl + '/admin/realms/' + realm.realm + '/applications/' + application.name + '/scope-mappings/applications/' + $scope.targetApp.name,
- $scope.selectedApplicationRoles).success(function() {
- $scope.applicationMappings = ApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.name});
- $scope.applicationRoles = AvailableApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.name});
- $scope.applicationComposite = CompositeApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.name});
- $scope.selectedApplicationRoles = [];
- $scope.selectedApplicationMappings = [];
- });
+ $scope.selectedApplicationRoles).success(updateAppRoles);
};
$scope.deleteApplicationRole = function() {
$http.delete(authUrl + '/admin/realms/' + realm.realm + '/applications/' + application.name + '/scope-mappings/applications/' + $scope.targetApp.name,
- {data : $scope.selectedApplicationMappings, headers : {"content-type" : "application/json"}}).success(function() {
- $scope.applicationMappings = ApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.name});
- $scope.applicationRoles = AvailableApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.name});
- $scope.applicationComposite = CompositeApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.name});
- $scope.selectedApplicationRoles = [];
- $scope.selectedApplicationMappings = [];
- });
+ {data : $scope.selectedApplicationMappings, headers : {"content-type" : "application/json"}}).success(updateAppRoles);
};
-
- $scope.changeApplication = function() {
- console.log('changeApplication');
- if ($scope.targetApp) {
- console.log('load available');
- $scope.applicationMappings = ApplicationApplicationScopeMapping.query({realm : realm.realm, application : application.name, targetApp : $scope.targetApp.name});
- $scope.applicationRoles = ApplicationAvailableApplicationScopeMapping.query({realm : realm.realm, application : application.name, targetApp : $scope.targetApp.name});
- $scope.applicationComposite = ApplicationCompositeApplicationScopeMapping.query({realm : realm.realm, application : application.name, targetApp : $scope.targetApp.name});
- } else {
- $scope.applicationRoles = null;
- $scope.applicationMappings = null;
- $scope.applicationComposite = null;
- }
- $scope.selectedApplicationRoles = [];
- $scope.selectedApplicationMappings = [];
- };
-
-
-
-
+ updateRealmRoles();
});
module.controller('ApplicationRevocationCtrl', function($scope, realm, application, Application, ApplicationPushRevocation, $location, Dialog, Notifications) {
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/oauth-clients.js b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/oauth-clients.js
index aabb96e..6fb9744 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/oauth-clients.js
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/oauth-clients.js
@@ -133,25 +133,29 @@ module.controller('OAuthClientDetailCtrl', function($scope, realm, oauth, OAuthC
}
$scope.save = function() {
- if ($scope.create) {
- OAuthClient.save({
- realm: realm.realm
- }, $scope.oauth, function (data, headers) {
- $scope.changed = false;
- var l = headers().location;
- var id = l.substring(l.lastIndexOf("/") + 1);
- $location.url("/realms/" + realm.realm + "/oauth-clients/" + id);
- Notifications.success("The oauth client has been created.");
- });
+ if (!$scope.oauth.redirectUris || $scope.oauth.redirectUris.length == 0) {
+ Notifications.error("You must specify at least one redirect uri");
} else {
- OAuthClient.update({
- realm : realm.realm,
- id : oauth.id
- }, $scope.oauth, function() {
- $scope.changed = false;
- oauth = angular.copy($scope.oauth);
- Notifications.success("Your changes have been saved to the oauth client.");
- });
+ if ($scope.create) {
+ OAuthClient.save({
+ realm: realm.realm
+ }, $scope.oauth, function (data, headers) {
+ $scope.changed = false;
+ var l = headers().location;
+ var id = l.substring(l.lastIndexOf("/") + 1);
+ $location.url("/realms/" + realm.realm + "/oauth-clients/" + id);
+ Notifications.success("The oauth client has been created.");
+ });
+ } else {
+ OAuthClient.update({
+ realm : realm.realm,
+ id : oauth.id
+ }, $scope.oauth, function() {
+ $scope.changed = false;
+ oauth = angular.copy($scope.oauth);
+ Notifications.success("Your changes have been saved to the oauth client.");
+ });
+ }
}
};
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/users.js b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/users.js
index 35e4fb0..e38b4e1 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/users.js
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/users.js
@@ -107,7 +107,7 @@ module.controller('UserSessionsCtrl', function($scope, realm, user, sessions, Us
$scope.logoutAll = function() {
UserLogout.save({realm : realm.realm, user: user.username}, function () {
Notifications.success('Logged out user in all applications');
- UserSessions.get({realm: realm.realm, user: user.username}, function(updated) {
+ UserSessions.query({realm: realm.realm, user: user.username}, function(updated) {
$scope.sessions = updated;
})
});
@@ -116,9 +116,9 @@ module.controller('UserSessionsCtrl', function($scope, realm, user, sessions, Us
$scope.logoutSession = function(sessionId) {
console.log('here in logoutSession');
UserSessionLogout.delete({realm : realm.realm, session: sessionId}, function() {
- Notifications.success('Logged out session');
- UserSessions.get({realm: realm.realm, user: user.username}, function(updated) {
+ UserSessions.query({realm: realm.realm, user: user.username}, function(updated) {
$scope.sessions = updated;
+ Notifications.success('Logged out session');
})
});
}
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/services.js b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/services.js
index b827960..3a48af6 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/services.js
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/services.js
@@ -77,8 +77,6 @@ module.service('Dialog', function($modal) {
}
dialog.confirm = function(title, message, success, cancel) {
- var title = title;
- var msg = '<span class="primary">' + message + '"</span>';
var btns = {
ok: {
label: title,
@@ -90,7 +88,7 @@ module.service('Dialog', function($modal) {
}
}
- openDialog(title, msg, btns).then(success).reject(cancel);
+ openDialog(title, message, btns).then(success, cancel);
}
return dialog
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/application-detail.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/application-detail.html
index defcdcd..9496bf3 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/application-detail.html
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/application-detail.html
@@ -92,30 +92,24 @@
</div>
<div class="form-group" data-ng-show="!application.bearerOnly && !create">
<label class="col-sm-2 control-label" for="newWebOrigin">Web Origin</label>
- <div class="col-sm-6">
- <div ng-repeat="webOrigin in application.webOrigins" class="row kc-item-deletable">
- <div class="col-sm-8">
- <input class="form-control kc-button-control"
- type="text" data-ng-class="{'input-below':!$first}"
- name="webOrigin" id="webOrigin"
- data-ng-model="webOrigin" readonly/>
- </div>
- <div class="col-sm-2">
- <button class="btn btn-danger"
- type="button" data-ng-click="deleteWebOrigin($index)">Delete</button>
- </div>
+ <div class="col-sm-4 multiple" ng-repeat="webOrigin in application.webOrigins">
+ <div class="input-group kc-item-deletable">
+ <input class="form-control" type="text" data-ng-class="{'input-below':!$first}"
+ name="webOrigin" id="webOrigin" data-ng-model="webOrigin" readonly />
+ <span class="input-group-btn">
+ <button class="btn btn-default" type="button" data-ng-click="deleteWebOrigin($index)">
+ Delete</button>
+ </span>
</div>
- <div class="row">
- <div class="col-sm-8">
- <input class="form-control kc-button-control"
- type="text" name="newWebOrigin" id="newWebOrigin"
- placeholder="New Web Origin..." data-ng-model="newWebOrigin"
- data-ng-class="{'input-below':application.webOrigins.length}"/>
- </div>
- <div class="col-sm-2">
- <button class="btn btn-primary"
- data-ng-click="addWebOrigin()" ng-show="newWebOrigin.length > 0">Add</button>
- </div>
+ </div>
+ <div class="col-sm-4 multiple">
+ <div class="input-group">
+ <input class="form-control" type="text" name="newWebOrigin" id="newWebOrigin"
+ placeholder="New Web Origin..." data-ng-model="newWebOrigin"
+ data-ng-class="{'input-below':application.webOrigins.length}" />
+ <span class="input-group-btn">
+ <button class="btn btn-default" data-ng-click="addWebOrigin()" ng-show="newWebOrigin.length > 0">Add</button>
+ </span>
</div>
</div>
</div>
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/menu.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/menu.html
index 40dc702..03830e9 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/menu.html
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/menu.html
@@ -12,7 +12,7 @@
</div>
<div class="collapse navbar-collapse navbar-collapse-1">
<div class="container">
- <ul class="nav navbar-nav navbar-utility" data-ng-show="auth.loggedIn">
+ <ul class="nav navbar-nav navbar-utility" data-ng-show="auth.user">
<li class="dropdown">
<a data-toggle="dropdown" class="dropdown-toggle" href="#">
<span class="pficon pficon-user"></span>
@@ -36,9 +36,9 @@
</li>
</ul>
</li>
- <li class="active pull-right" data-ng-show="auth.loggedIn && access.createRealm">
+ <li class="active pull-right" data-ng-show="auth.user && access.createRealm">
<a class="button primary" href="#/create/realm" data-ng-class="path[0] == 'create' && path[1] == 'realm' && 'active'"
- data-ng-show="auth.loggedIn">Add Realm</a>
+ data-ng-show="auth.user">Add Realm</a>
</li>
</ul>
</div>
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-detail.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-detail.html
index e5ea613..f1ed7f8 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-detail.html
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-detail.html
@@ -77,26 +77,24 @@
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="newWebOrigin">Web Origin</label>
- <div class="col-sm-6">
- <div ng-repeat="webOrigin in oauth.webOrigins" class="kc-item-deletable row">
- <div class="col-sm-8">
- <input class="form-control" type="text" data-ng-class="{'input-below':!$first}"
- name="webOrigin" id="webOrigin" data-ng-model="webOrigin" readonly />
- </div>
- <div class="col-sm-2">
- <button class="btn btn-danger" type="button" data-ng-click="deleteWebOrigin($index)">
+ <div class="col-sm-4 multiple" ng-repeat="webOrigin in oauth.webOrigins">
+ <div class="input-group kc-item-deletable">
+ <input class="form-control" type="text" data-ng-class="{'input-below':!$first}"
+ name="webOrigin" id="webOrigin" data-ng-model="webOrigin" readonly />
+ <span class="input-group-btn">
+ <button class="btn btn-default" type="button" data-ng-click="deleteWebOrigin($index)">
Delete</button>
- </div>
+ </span>
</div>
- <div class="row">
- <div class="col-sm-8">
- <input class="form-control" type="text" name="newWebOrigin" id="newWebOrigin"
- placeholder="New Web Origin..." data-ng-model="newWebOrigin"
- data-ng-class="{'input-below':oauth.webOrigins.length}" />
- </div>
- <div class="col-sm-2">
- <button class="btn btn-primary" data-ng-click="addWebOrigin()" ng-show="newWebOrigin.length > 0">Add</button>
- </div>
+ </div>
+ <div class="col-sm-4 multiple">
+ <div class="input-group">
+ <input class="form-control" type="text" name="newWebOrigin" id="newWebOrigin"
+ placeholder="New Web Origin..." data-ng-model="newWebOrigin"
+ data-ng-class="{'input-below':oauth.webOrigins.length}" />
+ <span class="input-group-btn">
+ <button class="btn btn-default" data-ng-click="addWebOrigin()" ng-show="newWebOrigin.length > 0">Add</button>
+ </span>
</div>
</div>
</div>
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-menu.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-menu.html
index 7725e35..1bc9c6b 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-menu.html
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-menu.html
@@ -1,5 +1,5 @@
<ul data-ng-hide="createRealm">
- <li data-ng-show="access.viewRealm" data-ng-class="((!path[2] || path[1] == 'role' || path[2] == 'roles' || path[2] == 'token-settings' ||
+ <li data-ng-show="access.viewRealm" data-ng-class="((!path[2] || path[1] == 'role' || path[2] == 'roles' ||
path[2] == 'social-settings' || path[2] == 'required-credentials' || path[2] == 'default-roles' || path[2] == 'registration-settings' ||
path[2] == 'keys-settings' || path[2] == 'smtp-settings' || path[2] == 'ldap-settings' || path[2] == 'auth-settings') && path[3] != 'applications') && 'active'">
<a href="#/realms/{{realm.realm}}">Settings</a>
@@ -8,6 +8,6 @@
</li>
<li data-ng-show="access.viewApplications" data-ng-class="(path[2] == 'applications' || path[1] == 'application' || path[3] == 'applications') && 'active'"><a href="#/realms/{{realm.realm}}/applications">Applications</a></li>
<li data-ng-show="access.viewClients" data-ng-class="(path[2] == 'oauth-clients' || path[1] == 'oauth-client') && 'active'"><a href="#/realms/{{realm.realm}}/oauth-clients">OAuth Clients</a></li>
- <li data-ng-show="access.viewRealm" data-ng-class="(path[2] == 'sessions') && 'active'"><a href="#/realms/{{realm.realm}}/sessions/realm">Sessions and Tokens</a></li>
+ <li data-ng-show="access.viewRealm" data-ng-class="(path[2] == 'sessions' || path[2] == 'token-settings') && 'active'"><a href="#/realms/{{realm.realm}}/sessions/realm">Sessions and Tokens</a></li>
<li data-ng-show="access.viewAudit" data-ng-class="(path[2] == 'audit' || path[2] == 'audit-settings') && 'active'"><a href="#/realms/{{realm.realm}}/audit">Audit</a></li>
</ul>
\ No newline at end of file
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/user-sessions.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/user-sessions.html
index 844efc0..e19e8dd 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/user-sessions.html
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/user-sessions.html
@@ -38,19 +38,18 @@
<td>{{session.ipAddress}}</td>
<td>{{session.start | date:'medium'}}</td>
<td>{{session.lastAccess | date:'medium'}}</td>
- <td><ul style="list-style: none; ">
- <li data-ng-repeat="app in session.applications">
+ <td>
+ <div data-ng-repeat="app in session.applications">
<a href="#/realms/{{realm.realm}}/applications/{{app}}/sessions">{{app}}</a>
- </li>
+ </div>
</ul>
</td>
- <td><ul style="list-style: none; ">
- <li data-ng-repeat="(clientId, clientName) in session.clients">
+ <td>
+ <div data-ng-repeat="(clientId, clientName) in session.clients">
<a href="#/realms/{{realm.realm}}/oauth-clients/{{clientId}}">{{clientName}}</a>
- </li>
- </ul>
+ </div>
</td>
- <td><a ng-click="logoutSession(session.id)">logout</a> </td>
+ <td><a href="" ng-click="logoutSession(session.id)">logout</a> </td>
</tr>
</tbody>
</table>
diff --git a/integration/js/src/main/resources/keycloak.js b/integration/js/src/main/resources/keycloak.js
index b05761d..1cfba81 100755
--- a/integration/js/src/main/resources/keycloak.js
+++ b/integration/js/src/main/resources/keycloak.js
@@ -29,6 +29,10 @@ var Keycloak = function (config) {
if (initOptions.checkLoginIframeInterval) {
loginIframe.interval = initOptions.checkLoginIframeInterval;
}
+
+ if (initOptions.onLoad === 'login-required') {
+ kc.loginRequired = true;
+ }
}
var promise = createPromise();
@@ -374,6 +378,9 @@ var Keycloak = function (config) {
if (kc.token) {
setToken(null, null);
kc.onAuthLogout && kc.onAuthLogout();
+ if (kc.loginRequired) {
+ kc.login();
+ }
}
}
@@ -531,7 +538,7 @@ var Keycloak = function (config) {
loginIframe.iframe = iframe;
}
- var src = getRealmUrl() + '/login-status-iframe.html?client_id=' + encodeURIComponent(kc.clientId);
+ var src = getRealmUrl() + '/login-status-iframe.html?client_id=' + encodeURIComponent(kc.clientId) + '&origin=' + window.location.origin;
iframe.setAttribute('src', src );
iframe.style.display = 'none';
document.body.appendChild(iframe);
pom.xml 41(+25 -16)
diff --git a/pom.xml b/pom.xml
index 0aa3dff..655ed16 100755
--- a/pom.xml
+++ b/pom.xml
@@ -12,6 +12,8 @@
<packaging>pom</packaging>
<properties>
+ <bouncycastle.version>1.46</bouncycastle.version>
+ <jackson.version>1.9.12</jackson.version>
<keycloak.apache.httpcomponents.version>4.1.2</keycloak.apache.httpcomponents.version>
<resteasy.version>2.3.7.Final</resteasy.version>
<resteasy.version.eap.6.3>2.3.7.Final</resteasy.version.eap.6.3>
@@ -33,6 +35,13 @@
<slf4j.version>1.5.10</slf4j.version>
<jboss.version>7.1.1.Final</jboss.version>
<wildfly.version>8.0.0.Final</wildfly.version>
+ <servlet.api.30.version>1.0.1.Final</servlet.api.30.version>
+ <google.zxing.version>2.2</google.zxing.version>
+ <google.client.version>1.14.1-beta</google.client.version>
+ <winzipaes.version>1.0.1</winzipaes.version>
+ <freemarker.version>2.3.19</freemarker.version>
+ <twitter4j.version>3.0.5</twitter4j.version>
+ <selenium.version>2.35.0</selenium.version>
<!-- maven-compiler-plugin -->
<maven.compiler.target>1.6</maven.compiler.target>
@@ -109,12 +118,12 @@
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
- <version>1.46</version>
+ <version>${bouncycastle.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcmail-jdk16</artifactId>
- <version>1.46</version>
+ <version>${bouncycastle.version}</version>
</dependency>
<dependency>
<groupId>net.iharder</groupId>
@@ -179,27 +188,27 @@
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
- <version>1.9.12</version>
+ <version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
- <version>1.9.12</version>
+ <version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-xc</artifactId>
- <version>1.9.12</version>
+ <version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-jaxrs</artifactId>
- <version>1.9.12</version>
+ <version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.servlet</groupId>
<artifactId>jboss-servlet-api_3.0_spec</artifactId>
- <version>1.0.1.Final</version>
+ <version>${servlet.api.30.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.servlet</groupId>
@@ -282,19 +291,19 @@
<dependency>
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client</artifactId>
- <version>1.14.1-beta</version>
+ <version>${google.client.version}</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
- <version>2.3.19</version>
+ <version>${freemarker.version}</version>
</dependency>
<!-- Google+ -->
<dependency>
<groupId>com.google.http-client</groupId>
<artifactId>google-http-client-jackson</artifactId>
- <version>1.14.1-beta</version>
+ <version>${google.client.version}</version>
</dependency>
<dependency>
<groupId>com.google.apis</groupId>
@@ -306,19 +315,19 @@
<dependency>
<groupId>org.twitter4j</groupId>
<artifactId>twitter4j-core</artifactId>
- <version>3.0.5</version>
+ <version>${twitter4j.version}</version>
</dependency>
<!-- QR Code Generator -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
- <version>2.2</version>
+ <version>${google.zxing.version}</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
- <version>2.2</version>
+ <version>${google.zxing.version}</version>
</dependency>
<!-- Email Test Servers -->
@@ -332,19 +341,19 @@
<dependency>
<groupId>de.idyl</groupId>
<artifactId>winzipaes</artifactId>
- <version>1.0.1</version>
+ <version>${winzipaes.version}</version>
</dependency>
<!-- Selenium -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
- <version>2.35.0</version>
+ <version>${selenium.version}</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-chrome-driver</artifactId>
- <version>2.35.0</version>
+ <version>${selenium.version}</version>
<scope>test</scope>
</dependency>
<dependency>
diff --git a/server/src/main/resources/META-INF/keycloak-server.json b/server/src/main/resources/META-INF/keycloak-server.json
index aa44676..06efa79 100644
--- a/server/src/main/resources/META-INF/keycloak-server.json
+++ b/server/src/main/resources/META-INF/keycloak-server.json
@@ -20,7 +20,9 @@
"theme": {
"default": "keycloak",
- "dir": "${jboss.server.config.dir}/themes"
+ "folder": {
+ "dir": "${jboss.server.config.dir}/themes"
+ }
},
"login-forms": {
diff --git a/server/src/main/resources/META-INF/persistence.xml b/server/src/main/resources/META-INF/persistence.xml
index 90b1742..a75390a 100755
--- a/server/src/main/resources/META-INF/persistence.xml
+++ b/server/src/main/resources/META-INF/persistence.xml
@@ -25,7 +25,6 @@
<properties>
<property name="hibernate.hbm2ddl.auto" value="update" />
- <property name="jboss.as.jpa.managed" value="false" />
</properties>
</persistence-unit>
@@ -37,7 +36,6 @@
<properties>
<property name="hibernate.hbm2ddl.auto" value="update" />
- <property name="jboss.as.jpa.managed" value="false" />
</properties>
</persistence-unit>
diff --git a/services/src/main/java/org/keycloak/services/managers/AppAuthManager.java b/services/src/main/java/org/keycloak/services/managers/AppAuthManager.java
index 2b2aa08..64adc30 100755
--- a/services/src/main/java/org/keycloak/services/managers/AppAuthManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/AppAuthManager.java
@@ -3,7 +3,6 @@ package org.keycloak.services.managers;
import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.UnauthorizedException;
import org.keycloak.models.RealmModel;
-import org.keycloak.models.UserModel;
import org.keycloak.provider.ProviderSession;
import javax.ws.rs.core.Cookie;
@@ -21,18 +20,16 @@ public class AppAuthManager extends AuthenticationManager {
super(providerSession);
}
- public AuthResult authenticateRequest(RealmModel realm, UriInfo uriInfo, HttpHeaders headers) {
- AuthResult authResult = authenticateIdentityCookie(realm, uriInfo, headers);
- if (authResult != null) {
- Cookie remember = headers.getCookies().get(AuthenticationManager.KEYCLOAK_REMEMBER_ME);
- boolean rememberMe = remember != null;
- // refresh the cookies!
- createLoginCookie(realm, authResult.getUser(), authResult.getSession(), uriInfo, rememberMe);
- if (rememberMe) createRememberMeCookie(realm, uriInfo);
- return authResult;
- } else {
- return authenticateBearerToken(realm, uriInfo, headers);
- }
+ @Override
+ public AuthResult authenticateIdentityCookie(RealmModel realm, UriInfo uriInfo, HttpHeaders headers) {
+ AuthResult authResult = super.authenticateIdentityCookie(realm, uriInfo, headers);
+ if (authResult == null) return null;
+ Cookie remember = headers.getCookies().get(AuthenticationManager.KEYCLOAK_REMEMBER_ME);
+ boolean rememberMe = remember != null;
+ // refresh the cookies!
+ createLoginCookie(realm, authResult.getUser(), authResult.getSession(), uriInfo, rememberMe);
+ if (rememberMe) createRememberMeCookie(realm, uriInfo);
+ return authResult;
}
public String extractAuthorizationHeaderToken(HttpHeaders headers) {
diff --git a/services/src/main/java/org/keycloak/services/managers/Auth.java b/services/src/main/java/org/keycloak/services/managers/Auth.java
index d549aa2..f13cfb2 100755
--- a/services/src/main/java/org/keycloak/services/managers/Auth.java
+++ b/services/src/main/java/org/keycloak/services/managers/Auth.java
@@ -17,26 +17,8 @@ public class Auth {
private final UserModel user;
private final ClientModel client;
- public Auth(RealmModel realm, UserModel user, ClientModel client) {
- this.cookie = true;
- this.realm = realm;
- this.token = null;
-
- this.user = user;
- this.client = client;
- }
-
- public Auth(AccessToken token, UserModel user, ClientModel client) {
- this.cookie = false;
- this.token = token;
- this.realm = null;
-
- this.user = user;
- this.client = client;
- }
-
- public Auth(RealmModel realm, AccessToken token, UserModel user, ClientModel client) {
- this.cookie = false;
+ public Auth(RealmModel realm, AccessToken token, UserModel user, ClientModel client, boolean cookie) {
+ this.cookie = cookie;
this.token = token;
this.realm = realm;
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 d641441..b232de5 100755
--- a/services/src/main/java/org/keycloak/services/resources/AccountService.java
+++ b/services/src/main/java/org/keycloak/services/resources/AccountService.java
@@ -145,9 +145,16 @@ public class AccountService {
account = providers.getProvider(AccountProvider.class).setRealm(realm).setUriInfo(uriInfo);
boolean passwordUpdateSupported = false;
- AuthenticationManager.AuthResult authResult = authManager.authenticateRequest(realm, uriInfo, headers);
+ AuthenticationManager.AuthResult authResult = authManager.authenticateIdentityCookie(realm, uriInfo, headers);
+ if (authResult != null) {
+ auth = new Auth(realm, authResult.getToken(), authResult.getUser(), application, true);
+ } else {
+ authResult = authManager.authenticateBearerToken(realm, uriInfo, headers);
+ if (authResult != null) {
+ auth = new Auth(realm, authResult.getToken(), authResult.getUser(), application, false);
+ }
+ }
if (authResult != null) {
- auth = new Auth(realm, authResult.getUser(), application);
if (authResult.getSession() != null) {
authResult.getSession().associateClient(application);
}
@@ -208,7 +215,7 @@ public class AccountService {
} else if (types.contains(MediaType.APPLICATION_JSON_TYPE)) {
requireOneOf(AccountRoles.MANAGE_ACCOUNT, AccountRoles.VIEW_PROFILE);
- return Cors.add(request, Response.ok(ModelToRepresentation.toRepresentation(auth.getUser()))).auth().allowedOrigins(auth.getClient()).build();
+ return Cors.add(request, Response.ok(ModelToRepresentation.toRepresentation(auth.getUser()))).auth().allowedOrigins(auth.getToken()).build();
} else {
return Response.notAcceptable(Variant.VariantListBuilder.newInstance().mediaTypes(MediaType.TEXT_HTML_TYPE, MediaType.APPLICATION_JSON_TYPE).build()).build();
}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AdminAuth.java b/services/src/main/java/org/keycloak/services/resources/admin/AdminAuth.java
new file mode 100755
index 0000000..dcfad7c
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/admin/AdminAuth.java
@@ -0,0 +1,83 @@
+package org.keycloak.services.resources.admin;
+
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.representations.AccessToken;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public class AdminAuth {
+
+ private final RealmModel realm;
+ private final AccessToken token;
+ private final UserModel user;
+ private final ClientModel client;
+
+ public AdminAuth(RealmModel realm, AccessToken token, UserModel user, ClientModel client) {
+ this.token = token;
+ this.realm = realm;
+
+ this.user = user;
+ this.client = client;
+ }
+
+ public RealmModel getRealm() {
+ return realm;
+ }
+
+ public UserModel getUser() {
+ return user;
+ }
+
+ public ClientModel getClient() {
+ return client;
+ }
+
+ public AccessToken getToken() {
+ return token;
+ }
+
+
+ public boolean hasRealmRole(String role) {
+ if (client instanceof ApplicationModel) {
+ RoleModel roleModel = realm.getRole(role);
+ return realm.hasRole(user, roleModel) && realm.hasScope(client, roleModel);
+ } else {
+ AccessToken.Access access = token.getRealmAccess();
+ return access != null && access.isUserInRole(role);
+ }
+ }
+
+ public boolean hasOneOfRealmRole(String... roles) {
+ for (String r : roles) {
+ if (hasRealmRole(r)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean hasAppRole(ApplicationModel app, String role) {
+ if (client instanceof ApplicationModel) {
+ RoleModel roleModel = app.getRole(role);
+ return realm.hasRole(user, roleModel) && realm.hasScope(client, roleModel);
+ } else {
+ AccessToken.Access access = token.getResourceAccess(app.getName());
+ return access != null && access.isUserInRole(role);
+ }
+ }
+
+ public boolean hasOneOfAppRole(ApplicationModel app, String... roles) {
+ for (String r : roles) {
+ if (hasAppRole(app, r)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AdminRoot.java b/services/src/main/java/org/keycloak/services/resources/admin/AdminRoot.java
index 43fecc8..1c36506 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/AdminRoot.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/AdminRoot.java
@@ -9,6 +9,7 @@ import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.jboss.resteasy.spi.UnauthorizedException;
import org.keycloak.jose.jws.JWSInput;
import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
@@ -112,7 +113,7 @@ public class AdminRoot {
}
- protected Auth authenticateRealmAdminRequest(HttpHeaders headers) {
+ protected AdminAuth authenticateRealmAdminRequest(HttpHeaders headers) {
String tokenString = authManager.extractAuthorizationHeaderToken(headers);
if (tokenString == null) throw new UnauthorizedException("Bearer");
JWSInput input = new JWSInput(tokenString);
@@ -134,14 +135,13 @@ public class AdminRoot {
throw new UnauthorizedException("Bearer");
}
- ApplicationModel consoleApp = realm.getApplicationByName(Constants.ADMIN_CONSOLE_APPLICATION);
- if (consoleApp == null) {
- throw new NotFoundException("Could not find admin console application");
- }
- Auth auth = new Auth(realm, token, authResult.getUser(), consoleApp);
- return auth;
+ ClientModel client = realm.findClient(token.getIssuedFor());
+ if (client == null) {
+ throw new NotFoundException("Could not find client for authorization");
+ }
+ return new AdminAuth(realm, authResult.getToken(), authResult.getUser(), client);
}
public static UriBuilder realmsUrl(UriInfo uriInfo) {
@@ -155,11 +155,12 @@ public class AdminRoot {
@Path("realms")
public RealmsAdminResource getRealmsAdmin(@Context final HttpHeaders headers) {
if (request.getHttpMethod().equalsIgnoreCase("OPTIONS")) {
- Response response = Cors.add(request, Response.ok()).allowedMethods("GET", "PUT", "POST", "DELETE").auth().build();
+ logger.info("*** CORS ADMIN PREFLIGHT!!!!");
+ Response response = Cors.add(request, Response.ok()).preflight().allowedMethods("GET", "PUT", "POST", "DELETE").auth().build();
throw new WebApplicationException(response);
}
- Auth auth = authenticateRealmAdminRequest(headers);
+ AdminAuth auth = authenticateRealmAdminRequest(headers);
if (auth != null) {
logger.info("authenticated admin access for: " + auth.getUser().getLoginName());
}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmAuth.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmAuth.java
index fc0d174..89d9ef3 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RealmAuth.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmAuth.java
@@ -1,95 +1,95 @@
-package org.keycloak.services.resources.admin;
-
-import org.keycloak.models.AdminRoles;
-import org.keycloak.models.ApplicationModel;
-import org.keycloak.services.ForbiddenException;
-import org.keycloak.services.managers.Auth;
-
-import javax.ws.rs.WebApplicationException;
-
-
-/**
- * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
- */
-public class RealmAuth {
-
- private Resource resource;
-
- public enum Resource {
- APPLICATION, CLIENT, USER, REALM, AUDIT
- }
-
- private Auth auth;
- private ApplicationModel realmAdminApp;
-
- public RealmAuth(Auth auth, ApplicationModel realmAdminApp) {
- this.auth = auth;
- this.realmAdminApp = realmAdminApp;
- }
-
- public RealmAuth init(Resource resource) {
- this.resource = resource;
- return this;
- }
-
- public void requireAny() {
- if (!auth.hasOneOfAppRole(realmAdminApp, AdminRoles.ALL_REALM_ROLES)) {
- throw new ForbiddenException();
- }
- }
-
- public boolean hasView() {
- return auth.hasOneOfAppRole(realmAdminApp, getViewRole(resource), getManageRole(resource));
- }
-
- public boolean hasManage() {
- return auth.hasOneOfAppRole(realmAdminApp, getManageRole(resource));
- }
-
- public void requireView() {
- if (!hasView()) {
- throw new ForbiddenException();
- }
- }
-
- public void requireManage() {
- if (!hasManage()) {
- throw new ForbiddenException();
- }
- }
-
- private String getViewRole(Resource resource) {
- switch (resource) {
- case APPLICATION:
- return AdminRoles.VIEW_APPLICATIONS;
- case CLIENT:
- return AdminRoles.VIEW_CLIENTS;
- case USER:
- return AdminRoles.VIEW_USERS;
- case REALM:
- return AdminRoles.VIEW_REALM;
- case AUDIT:
- return AdminRoles.VIEW_AUDIT;
- default:
- throw new IllegalStateException();
- }
- }
-
- private String getManageRole(Resource resource) {
- switch (resource) {
- case APPLICATION:
- return AdminRoles.MANAGE_APPLICATIONS;
- case CLIENT:
- return AdminRoles.MANAGE_CLIENTS;
- case USER:
- return AdminRoles.MANAGE_USERS;
- case REALM:
- return AdminRoles.MANAGE_REALM;
- case AUDIT:
- return AdminRoles.MANAGE_AUDIT;
- default:
- throw new IllegalStateException();
- }
- }
-
-}
+package org.keycloak.services.resources.admin;
+
+import org.keycloak.models.AdminRoles;
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.services.ForbiddenException;
+import org.keycloak.services.managers.Auth;
+
+import javax.ws.rs.WebApplicationException;
+
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public class RealmAuth {
+
+ private Resource resource;
+
+ public enum Resource {
+ APPLICATION, CLIENT, USER, REALM, AUDIT
+ }
+
+ private AdminAuth auth;
+ private ApplicationModel realmAdminApp;
+
+ public RealmAuth(AdminAuth auth, ApplicationModel realmAdminApp) {
+ this.auth = auth;
+ this.realmAdminApp = realmAdminApp;
+ }
+
+ public RealmAuth init(Resource resource) {
+ this.resource = resource;
+ return this;
+ }
+
+ public void requireAny() {
+ if (!auth.hasOneOfAppRole(realmAdminApp, AdminRoles.ALL_REALM_ROLES)) {
+ throw new ForbiddenException();
+ }
+ }
+
+ public boolean hasView() {
+ return auth.hasOneOfAppRole(realmAdminApp, getViewRole(resource), getManageRole(resource));
+ }
+
+ public boolean hasManage() {
+ return auth.hasOneOfAppRole(realmAdminApp, getManageRole(resource));
+ }
+
+ public void requireView() {
+ if (!hasView()) {
+ throw new ForbiddenException();
+ }
+ }
+
+ public void requireManage() {
+ if (!hasManage()) {
+ throw new ForbiddenException();
+ }
+ }
+
+ private String getViewRole(Resource resource) {
+ switch (resource) {
+ case APPLICATION:
+ return AdminRoles.VIEW_APPLICATIONS;
+ case CLIENT:
+ return AdminRoles.VIEW_CLIENTS;
+ case USER:
+ return AdminRoles.VIEW_USERS;
+ case REALM:
+ return AdminRoles.VIEW_REALM;
+ case AUDIT:
+ return AdminRoles.VIEW_AUDIT;
+ default:
+ throw new IllegalStateException();
+ }
+ }
+
+ private String getManageRole(Resource resource) {
+ switch (resource) {
+ case APPLICATION:
+ return AdminRoles.MANAGE_APPLICATIONS;
+ case CLIENT:
+ return AdminRoles.MANAGE_CLIENTS;
+ case USER:
+ return AdminRoles.MANAGE_USERS;
+ case REALM:
+ return AdminRoles.MANAGE_REALM;
+ case AUDIT:
+ return AdminRoles.MANAGE_AUDIT;
+ default:
+ throw new IllegalStateException();
+ }
+ }
+
+}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java
index 681eb89..efecbf9 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java
@@ -46,10 +46,10 @@ import java.util.Map;
*/
public class RealmsAdminResource {
protected static final Logger logger = Logger.getLogger(RealmsAdminResource.class);
- protected Auth auth;
+ protected AdminAuth auth;
protected TokenManager tokenManager;
- public RealmsAdminResource(Auth auth, TokenManager tokenManager) {
+ public RealmsAdminResource(AdminAuth auth, TokenManager tokenManager) {
this.auth = auth;
this.tokenManager = tokenManager;
}
diff --git a/services/src/main/java/org/keycloak/services/resources/Cors.java b/services/src/main/java/org/keycloak/services/resources/Cors.java
index dcf3499..c77b001 100755
--- a/services/src/main/java/org/keycloak/services/resources/Cors.java
+++ b/services/src/main/java/org/keycloak/services/resources/Cors.java
@@ -8,6 +8,7 @@ import java.util.concurrent.TimeUnit;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
+import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.HttpRequest;
import org.jboss.resteasy.spi.HttpResponse;
import org.keycloak.models.ClientModel;
@@ -18,6 +19,7 @@ import org.keycloak.util.CollectionUtil;
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class Cors {
+ protected static final Logger logger = Logger.getLogger(Cors.class);
public static final long DEFAULT_MAX_AGE = TimeUnit.HOURS.toSeconds(1);
public static final String DEFAULT_ALLOW_METHODS = "GET, HEAD, OPTIONS";
@@ -128,15 +130,18 @@ public class Cors {
return builder.build();
}
public void build(HttpResponse response) {
+ logger.info("build CORS");
String origin = request.getHttpHeaders().getRequestHeaders().getFirst(ORIGIN_HEADER);
if (origin == null) {
+ logger.info("No origin returning");
return;
}
if (!preflight && (allowedOrigins == null || !allowedOrigins.contains(origin))) {
+ logger.info("!preflight and no origin");
return;
}
-
+ logger.info("build CORS headers and return");
response.getOutputHeaders().add(ACCESS_CONTROL_ALLOW_ORIGIN, origin);
if (allowedMethods != null) {
diff --git a/services/src/main/java/org/keycloak/services/resources/RealmsResource.java b/services/src/main/java/org/keycloak/services/resources/RealmsResource.java
index 18c6caa..23359d5 100755
--- a/services/src/main/java/org/keycloak/services/resources/RealmsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/RealmsResource.java
@@ -2,6 +2,7 @@ package org.keycloak.services.resources;
import org.jboss.logging.Logger;
import org.jboss.resteasy.annotations.cache.NoCache;
+import org.jboss.resteasy.spi.BadRequestException;
import org.jboss.resteasy.spi.NotFoundException;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.jboss.resteasy.spi.UnauthorizedException;
@@ -98,7 +99,8 @@ public class RealmsResource {
@Produces(MediaType.TEXT_HTML)
@NoCache
public String getLoginStatusIframe(final @PathParam("realm") String name,
- @QueryParam("client_id") String client_id) {
+ @QueryParam("client_id") String client_id,
+ @QueryParam("origin") String origin) {
logger.info("getLoginStatusIframe");
AuthenticationManager auth = new AuthenticationManager(providers);
@@ -116,31 +118,33 @@ public class RealmsResource {
InputStream is = getClass().getClassLoader().getResourceAsStream("login-status-iframe.html");
if (is == null) throw new NotFoundException("Could not find login-status-iframe.html ");
- Set<String> redirectUris = TokenService.resolveValidRedirects(uriInfo, client.getRedirectUris());
- String origin = null;
- for (String redirect : redirectUris) {
-
- int index = redirect.indexOf("://");
- if (index == -1) continue;
- index = redirect.indexOf('/', index + 3);
- if (index == -1) {
- origin = redirect;
- } else {
- origin = redirect.substring(0, index);
+
+ boolean valid = false;
+ for (String o : client.getWebOrigins()) {
+ if (o.equals("*") || o.equals(origin)) {
+ valid = true;
+ break;
}
- break;
+ }
+ for (String r : TokenService.resolveValidRedirects(uriInfo, client.getRedirectUris())) {
+ r = r.substring(0, r.indexOf('/', 8));
+ if (r.equals(origin)) {
+ valid = true;
+ break;
+ }
}
- String file = null;
+
+ if (!valid) {
+ throw new BadRequestException("Invalid origin");
+ }
+
try {
- file = StreamUtil.readString(is);
+ String file = StreamUtil.readString(is);
+ return file.replace("ORIGIN", origin);
} catch (IOException e) {
throw new RuntimeException(e);
}
- file = file.replace("ORIGIN", origin);
- //System.out.println(file);
- return file;
-
}
@Path("{realm}/tokens")
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java
index 7c8705b..7bec7a7 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java
@@ -158,10 +158,12 @@ public class AccountTest {
});
}
+ /*
@Test
public void forever() throws Exception{
while (true) Thread.sleep(5000);
}
+ */
@Test
public void returnToAppFromQueryParam() {