KEYCLOAK-1187 Admin console and endpoints

This commit is contained in:
Stian Thorgersen
2015-04-13 13:29:31 +02:00
parent 9a047eda36
commit 4fbbf39c51
117 changed files with 1523 additions and 1580 deletions

View File

@@ -4,14 +4,12 @@ import org.keycloak.broker.oidc.util.SimpleHttp;
import org.keycloak.constants.AdapterConstants;
import org.keycloak.events.EventBuilder;
import org.keycloak.jose.jws.JWSInput;
import org.keycloak.jose.jws.crypto.RSAProvider;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserSessionModel;
import org.keycloak.representations.adapters.action.AdminAction;
import org.keycloak.representations.adapters.action.LogoutAction;
import org.keycloak.services.managers.AuthenticationManager;
import org.keycloak.util.JsonSerialization;
import org.keycloak.util.PemUtils;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
@@ -90,7 +88,7 @@ public class KeycloakOIDCIdentityProvider extends OIDCIdentityProvider {
@Override
public SimpleHttp generateTokenRequest(String authorizationCode) {
return super.generateTokenRequest(authorizationCode)
.param(AdapterConstants.APPLICATION_SESSION_STATE, "n/a"); // hack to get backchannel logout to work
.param(AdapterConstants.CLIENT_SESSION_STATE, "n/a"); // hack to get backchannel logout to work
}

View File

@@ -19,13 +19,13 @@ public interface AdapterConstants {
String AUTH_DATA_PARAM_NAME = "org.keycloak.json.adapterConfig";
// Attribute passed in codeToToken request from adapter to Keycloak and saved in ClientSession. Contains ID of HttpSession on adapter
public static final String APPLICATION_SESSION_STATE = "application_session_state";
public static final String CLIENT_SESSION_STATE = "client_session_state";
// Attribute passed in codeToToken request from adapter to Keycloak and saved in ClientSession. Contains hostname of adapter where HttpSession is served
public static final String APPLICATION_SESSION_HOST = "application_session_host";
public static final String CLIENT_SESSION_HOST = "client_session_host";
// Attribute passed in registerNode request for register new application cluster node once he joined cluster
public static final String APPLICATION_CLUSTER_HOST = "application_cluster_host";
public static final String CLIENT_CLUSTER_HOST = "client_cluster_host";
// Cookie used on adapter side to store token info. Used only when tokenStore is 'COOKIE'
public static final String KEYCLOAK_ADAPTER_STATE_COOKIE = "KEYCLOAK_ADAPTER_STATE";

View File

@@ -54,7 +54,7 @@ public class ImportUtils {
if (Config.getAdminRealm().equals(realm.getId())) {
// Delete all masterAdmin apps due to foreign key constraints
for (RealmModel currRealm : model.getRealms()) {
currRealm.setMasterAdminApp(null);
currRealm.setMasterAdminClient(null);
}
}
// TODO: For migration between versions, it should be possible to delete just realm but keep it's users
@@ -83,7 +83,7 @@ public class ImportUtils {
for (RealmModel currentRealm : model.getRealms()) {
ClientModel masterApp = adminRealm.getClientByClientId(KeycloakModelUtils.getMasterRealmAdminApplicationName(currentRealm));
if (masterApp != null) {
currentRealm.setMasterAdminApp(masterApp);
currentRealm.setMasterAdminClient(masterApp);
} else {
setupMasterAdminManagement(model, currentRealm);
}
@@ -93,7 +93,7 @@ public class ImportUtils {
RealmModel adminRealm = model.getRealm(adminRealmId);
ClientModel masterApp = adminRealm.getClientByClientId(KeycloakModelUtils.getMasterRealmAdminApplicationName(realm));
if (masterApp != null) {
realm.setMasterAdminApp(masterApp);
realm.setMasterAdminClient(masterApp);
} else {
setupMasterAdminManagement(model, realm);
}
@@ -121,7 +121,7 @@ public class ImportUtils {
ClientModel realmAdminApp = KeycloakModelUtils.createClient(adminRealm, KeycloakModelUtils.getMasterRealmAdminApplicationName(realm));
realmAdminApp.setBearerOnly(true);
realm.setMasterAdminApp(realmAdminApp);
realm.setMasterAdminClient(realmAdminApp);
for (String r : AdminRoles.ALL_REALM_ROLES) {
RoleModel role = realmAdminApp.addRole(r);

View File

@@ -30,8 +30,7 @@
<script src="${resourceUrl}/js/app.js" type="text/javascript"></script>
<script src="${resourceUrl}/js/controllers/realm.js" type="text/javascript"></script>
<script src="${resourceUrl}/js/controllers/applications.js" type="text/javascript"></script>
<script src="${resourceUrl}/js/controllers/oauth-clients.js" type="text/javascript"></script>
<script src="${resourceUrl}/js/controllers/clients.js" type="text/javascript"></script>
<script src="${resourceUrl}/js/controllers/users.js" type="text/javascript"></script>
<script src="${resourceUrl}/js/loaders.js" type="text/javascript"></script>
<script src="${resourceUrl}/js/services.js" type="text/javascript"></script>

View File

@@ -212,8 +212,8 @@ module.config([ '$routeProvider', function($routeProvider) {
realm : function(RealmLoader) {
return RealmLoader();
},
applications : function(ApplicationListLoader) {
return ApplicationListLoader();
clients : function(ClientListLoader) {
return ClientListLoader();
},
roles : function(RoleListLoader) {
return RoleListLoader();
@@ -311,8 +311,8 @@ module.config([ '$routeProvider', function($routeProvider) {
user : function(UserLoader) {
return UserLoader();
},
applications : function(ApplicationListLoader) {
return ApplicationListLoader();
clients : function(ClientListLoader) {
return ClientListLoader();
}
},
controller : 'UserRoleMappingCtrl'
@@ -369,8 +369,8 @@ module.config([ '$routeProvider', function($routeProvider) {
roles : function(RoleListLoader) {
return RoleListLoader();
},
applications : function(ApplicationListLoader) {
return ApplicationListLoader();
clients : function(ClientListLoader) {
return ClientListLoader();
}
},
controller : 'RoleDetailCtrl'
@@ -387,8 +387,8 @@ module.config([ '$routeProvider', function($routeProvider) {
roles : function(RoleListLoader) {
return RoleListLoader();
},
applications : function(ApplicationListLoader) {
return ApplicationListLoader();
clients : function(ClientListLoader) {
return ClientListLoader();
}
},
controller : 'RoleDetailCtrl'
@@ -406,14 +406,14 @@ module.config([ '$routeProvider', function($routeProvider) {
controller : 'RoleListCtrl'
})
.when('/create/role/:realm/applications/:application', {
templateUrl : resourceUrl + '/partials/application-role-detail.html',
.when('/create/role/:realm/clients/:client', {
templateUrl : resourceUrl + '/partials/client-role-detail.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
application : function(ApplicationLoader) {
return ApplicationLoader();
client : function(ClientLoader) {
return ClientLoader();
},
role : function() {
return {};
@@ -421,56 +421,56 @@ module.config([ '$routeProvider', function($routeProvider) {
roles : function(RoleListLoader) {
return RoleListLoader();
},
applications : function(ApplicationListLoader) {
return ApplicationListLoader();
clients : function(ClientListLoader) {
return ClientListLoader();
}
},
controller : 'ApplicationRoleDetailCtrl'
controller : 'ClientRoleDetailCtrl'
})
.when('/realms/:realm/applications/:application/roles/:role', {
templateUrl : resourceUrl + '/partials/application-role-detail.html',
.when('/realms/:realm/clients/:client/roles/:role', {
templateUrl : resourceUrl + '/partials/client-role-detail.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
application : function(ApplicationLoader) {
return ApplicationLoader();
client : function(ClientLoader) {
return ClientLoader();
},
role : function(ApplicationRoleLoader) {
return ApplicationRoleLoader();
role : function(ClientRoleLoader) {
return ClientRoleLoader();
},
roles : function(RoleListLoader) {
return RoleListLoader();
},
applications : function(ApplicationListLoader) {
return ApplicationListLoader();
clients : function(ClientListLoader) {
return ClientListLoader();
}
},
controller : 'ApplicationRoleDetailCtrl'
controller : 'ClientRoleDetailCtrl'
})
.when('/realms/:realm/applications/:application/mappers', {
templateUrl : resourceUrl + '/partials/application-mappers.html',
.when('/realms/:realm/clients/:client/mappers', {
templateUrl : resourceUrl + '/partials/client-mappers.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
application : function(ApplicationLoader) {
return ApplicationLoader();
client : function(ClientLoader) {
return ClientLoader();
},
serverInfo : function(ServerInfoLoader) {
return ServerInfoLoader();
}
},
controller : 'ApplicationProtocolMapperListCtrl'
controller : 'ClientProtocolMapperListCtrl'
})
.when('/realms/:realm/applications/:application/add-mappers', {
templateUrl : resourceUrl + '/partials/application-mappers-add.html',
.when('/realms/:realm/clients/:client/add-mappers', {
templateUrl : resourceUrl + '/partials/client-mappers-add.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
application : function(ApplicationLoader) {
return ApplicationLoader();
client : function(ClientLoader) {
return ClientLoader();
},
serverInfo : function(ServerInfoLoader) {
return ServerInfoLoader();
@@ -478,26 +478,26 @@ module.config([ '$routeProvider', function($routeProvider) {
},
controller : 'AddBuiltinProtocolMapperCtrl'
})
.when('/realms/:realm/applications/:application/mappers/:id', {
.when('/realms/:realm/clients/:client/mappers/:id', {
templateUrl : resourceUrl + '/partials/protocol-mapper-detail.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
application : function(ApplicationLoader) {
return ApplicationLoader();
client : function(ClientLoader) {
return ClientLoader();
},
serverInfo : function(ServerInfoLoader) {
return ServerInfoLoader();
},
mapper : function(ApplicationProtocolMapperLoader) {
return ApplicationProtocolMapperLoader();
mapper : function(ClientProtocolMapperLoader) {
return ClientProtocolMapperLoader();
}
},
controller : 'ApplicationProtocolMapperCtrl'
controller : 'ClientProtocolMapperCtrl'
})
.when('/create/application/:realm/:application/mappers', {
.when('/create/client/:realm/:client/mappers', {
templateUrl : resourceUrl + '/partials/protocol-mapper-detail.html',
resolve : {
realm : function(RealmLoader) {
@@ -506,231 +506,231 @@ module.config([ '$routeProvider', function($routeProvider) {
serverInfo : function(ServerInfoLoader) {
return ServerInfoLoader();
},
application : function(ApplicationLoader) {
return ApplicationLoader();
client : function(ClientLoader) {
return ClientLoader();
}
},
controller : 'ApplicationProtocolMapperCreateCtrl'
controller : 'ClientProtocolMapperCreateCtrl'
})
.when('/realms/:realm/applications/:application/sessions', {
templateUrl : resourceUrl + '/partials/application-sessions.html',
.when('/realms/:realm/clients/:client/sessions', {
templateUrl : resourceUrl + '/partials/client-sessions.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
application : function(ApplicationLoader) {
return ApplicationLoader();
client : function(ClientLoader) {
return ClientLoader();
},
sessionCount : function(ApplicationSessionCountLoader) {
return ApplicationSessionCountLoader();
sessionCount : function(ClientSessionCountLoader) {
return ClientSessionCountLoader();
}
},
controller : 'ApplicationSessionsCtrl'
controller : 'ClientSessionsCtrl'
})
.when('/realms/:realm/applications/:application/credentials', {
templateUrl : resourceUrl + '/partials/application-credentials.html',
.when('/realms/:realm/clients/:client/credentials', {
templateUrl : resourceUrl + '/partials/client-credentials.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
application : function(ApplicationLoader) {
return ApplicationLoader();
client : function(ClientLoader) {
return ClientLoader();
}
},
controller : 'ApplicationCredentialsCtrl'
controller : 'ClientCredentialsCtrl'
})
.when('/realms/:realm/applications/:application/identity-provider', {
templateUrl : resourceUrl + '/partials/application-identity-provider.html',
.when('/realms/:realm/clients/:client/identity-provider', {
templateUrl : resourceUrl + '/partials/client-identity-provider.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
application : function(ApplicationLoader) {
return ApplicationLoader();
client : function(ClientLoader) {
return ClientLoader();
}
},
controller : 'ApplicationIdentityProviderCtrl'
controller : 'ClientIdentityProviderCtrl'
})
.when('/realms/:realm/applications/:application/clustering', {
templateUrl : resourceUrl + '/partials/application-clustering.html',
.when('/realms/:realm/clients/:client/clustering', {
templateUrl : resourceUrl + '/partials/client-clustering.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
application : function(ApplicationLoader) {
return ApplicationLoader();
client : function(ClientLoader) {
return ClientLoader();
}
},
controller : 'ApplicationClusteringCtrl'
controller : 'ClientClusteringCtrl'
})
.when('/register-node/realms/:realm/applications/:application/clustering', {
templateUrl : resourceUrl + '/partials/application-clustering-node.html',
.when('/register-node/realms/:realm/clients/:client/clustering', {
templateUrl : resourceUrl + '/partials/client-clustering-node.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
application : function(ApplicationLoader) {
return ApplicationLoader();
client : function(ClientLoader) {
return ClientLoader();
}
},
controller : 'ApplicationClusteringNodeCtrl'
controller : 'ClientClusteringNodeCtrl'
})
.when('/realms/:realm/applications/:application/clustering/:node', {
templateUrl : resourceUrl + '/partials/application-clustering-node.html',
.when('/realms/:realm/clients/:client/clustering/:node', {
templateUrl : resourceUrl + '/partials/client-clustering-node.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
application : function(ApplicationLoader) {
return ApplicationLoader();
client : function(ClientLoader) {
return ClientLoader();
}
},
controller : 'ApplicationClusteringNodeCtrl'
controller : 'ClientClusteringNodeCtrl'
})
.when('/realms/:realm/applications/:application/saml/keys', {
templateUrl : resourceUrl + '/partials/application-saml-keys.html',
.when('/realms/:realm/clients/:client/saml/keys', {
templateUrl : resourceUrl + '/partials/client-saml-keys.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
application : function(ApplicationLoader) {
return ApplicationLoader();
client : function(ClientLoader) {
return ClientLoader();
}
},
controller : 'ApplicationSamlKeyCtrl'
controller : 'ClientSamlKeyCtrl'
})
.when('/realms/:realm/applications/:application/saml/:keyType/import/:attribute', {
templateUrl : resourceUrl + '/partials/application-saml-key-import.html',
.when('/realms/:realm/clients/:client/saml/:keyType/import/:attribute', {
templateUrl : resourceUrl + '/partials/client-saml-key-import.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
application : function(ApplicationLoader) {
return ApplicationLoader();
client : function(ClientLoader) {
return ClientLoader();
}
},
controller : 'ApplicationCertificateImportCtrl'
controller : 'ClientCertificateImportCtrl'
})
.when('/realms/:realm/applications/:application/saml/:keyType/export/:attribute', {
templateUrl : resourceUrl + '/partials/application-saml-key-export.html',
.when('/realms/:realm/clients/:client/saml/:keyType/export/:attribute', {
templateUrl : resourceUrl + '/partials/client-saml-key-export.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
application : function(ApplicationLoader) {
return ApplicationLoader();
client : function(ClientLoader) {
return ClientLoader();
}
},
controller : 'ApplicationCertificateExportCtrl'
controller : 'ClientCertificateExportCtrl'
})
.when('/realms/:realm/applications/:application/roles', {
templateUrl : resourceUrl + '/partials/application-role-list.html',
.when('/realms/:realm/clients/:client/roles', {
templateUrl : resourceUrl + '/partials/client-role-list.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
application : function(ApplicationLoader) {
return ApplicationLoader();
client : function(ClientLoader) {
return ClientLoader();
},
roles : function(ApplicationRoleListLoader) {
return ApplicationRoleListLoader();
roles : function(ClientRoleListLoader) {
return ClientRoleListLoader();
}
},
controller : 'ApplicationRoleListCtrl'
controller : 'ClientRoleListCtrl'
})
.when('/realms/:realm/applications/:application/revocation', {
templateUrl : resourceUrl + '/partials/application-revocation.html',
.when('/realms/:realm/clients/:client/revocation', {
templateUrl : resourceUrl + '/partials/client-revocation.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
application : function(ApplicationLoader) {
return ApplicationLoader();
client : function(ClientLoader) {
return ClientLoader();
}
},
controller : 'ApplicationRevocationCtrl'
controller : 'ClientRevocationCtrl'
})
.when('/realms/:realm/applications/:application/scope-mappings', {
templateUrl : resourceUrl + '/partials/application-scope-mappings.html',
.when('/realms/:realm/clients/:client/scope-mappings', {
templateUrl : resourceUrl + '/partials/client-scope-mappings.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
application : function(ApplicationLoader) {
return ApplicationLoader();
client : function(ClientLoader) {
return ClientLoader();
},
applications : function(ApplicationListLoader) {
return ApplicationListLoader();
clients : function(ClientListLoader) {
return ClientListLoader();
}
},
controller : 'ApplicationScopeMappingCtrl'
controller : 'ClientScopeMappingCtrl'
})
.when('/realms/:realm/applications/:application/installation', {
templateUrl : resourceUrl + '/partials/application-installation.html',
.when('/realms/:realm/clients/:client/installation', {
templateUrl : resourceUrl + '/partials/client-installation.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
application : function(ApplicationLoader) {
return ApplicationLoader();
client : function(ClientLoader) {
return ClientLoader();
}
},
controller : 'ApplicationInstallationCtrl'
controller : 'ClientInstallationCtrl'
})
.when('/create/application/:realm', {
templateUrl : resourceUrl + '/partials/application-detail.html',
.when('/create/client/:realm', {
templateUrl : resourceUrl + '/partials/client-detail.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
applications : function(ApplicationListLoader) {
return ApplicationListLoader();
clients : function(ClientListLoader) {
return ClientListLoader();
},
application : function() {
client : function() {
return {};
},
serverInfo : function(ServerInfoLoader) {
return ServerInfoLoader();
}
},
controller : 'ApplicationDetailCtrl'
controller : 'ClientDetailCtrl'
})
.when('/realms/:realm/applications/:application', {
templateUrl : resourceUrl + '/partials/application-detail.html',
.when('/realms/:realm/clients/:client', {
templateUrl : resourceUrl + '/partials/client-detail.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
applications : function(ApplicationListLoader) {
return ApplicationListLoader();
clients : function(ClientListLoader) {
return ClientListLoader();
},
application : function(ApplicationLoader) {
return ApplicationLoader();
client : function(ClientLoader) {
return ClientLoader();
},
serverInfo : function(ServerInfoLoader) {
return ServerInfoLoader();
}
},
controller : 'ApplicationDetailCtrl'
controller : 'ClientDetailCtrl'
})
.when('/realms/:realm/applications', {
templateUrl : resourceUrl + '/partials/application-list.html',
.when('/realms/:realm/clients', {
templateUrl : resourceUrl + '/partials/client-list.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
applications : function(ApplicationListLoader) {
return ApplicationListLoader();
clients : function(ClientListLoader) {
return ClientListLoader();
},
serverInfo : function(ServerInfoLoader) {
return ServerInfoLoader();
}
},
controller : 'ApplicationListCtrl'
controller : 'ClientListCtrl'
})
.when('/import/application/:realm', {
templateUrl : resourceUrl + '/partials/application-import.html',
.when('/import/client/:realm', {
templateUrl : resourceUrl + '/partials/client-import.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
@@ -739,7 +739,7 @@ module.config([ '$routeProvider', function($routeProvider) {
return ServerInfoLoader();
}
},
controller : 'ApplicationImportCtrl'
controller : 'ClientImportCtrl'
})
.when('/', {
templateUrl : resourceUrl + '/partials/home.html',
@@ -772,8 +772,8 @@ module.config([ '$routeProvider', function($routeProvider) {
realm : function(RealmLoader) {
return RealmLoader();
},
stats : function(RealmApplicationSessionStatsLoader) {
return RealmApplicationSessionStatsLoader();
stats : function(RealmClientSessionStatsLoader) {
return RealmClientSessionStatsLoader();
}
},
controller : 'RealmSessionStatsCtrl'
@@ -1353,12 +1353,12 @@ module.directive('kcNavigation', function ($compile, Notifications) {
}
});
module.directive('kcNavigationApplication', function () {
module.directive('kcNavigationClient', function () {
return {
scope: true,
restrict: 'E',
replace: true,
templateUrl: resourceUrl + '/templates/kc-navigation-application.html'
templateUrl: resourceUrl + '/templates/kc-navigation-client.html'
}
});

View File

@@ -476,7 +476,7 @@ module.controller('RealmRequiredCredentialsCtrl', function($scope, Realm, realm,
};
});
module.controller('RealmDefaultRolesCtrl', function ($scope, Realm, realm, applications, roles, Notifications, ApplicationRole, Application) {
module.controller('RealmDefaultRolesCtrl', function ($scope, Realm, realm, clients, roles, Notifications, ClientRole, Client) {
console.log('RealmDefaultRolesCtrl');
@@ -486,17 +486,17 @@ module.controller('RealmDefaultRolesCtrl', function ($scope, Realm, realm, appli
$scope.selectedRealmRoles = [];
$scope.selectedRealmDefRoles = [];
$scope.applications = angular.copy(applications);
for (var i = 0; i < applications.length; i++) {
if (applications[i].name == 'account') {
$scope.application = $scope.applications[i];
$scope.clients = angular.copy(clients);
for (var i = 0; i < clients.length; i++) {
if (clients[i].name == 'account') {
$scope.client = $scope.clients[i];
break;
}
}
$scope.availableAppRoles = [];
$scope.selectedAppRoles = [];
$scope.selectedAppDefRoles = [];
$scope.availableClientRoles = [];
$scope.selectedClientRoles = [];
$scope.selectedClientDefRoles = [];
if (!$scope.realm.hasOwnProperty('defaultRoles') || $scope.realm.defaultRoles === null) {
$scope.realm.defaultRoles = [];
@@ -550,81 +550,81 @@ module.controller('RealmDefaultRolesCtrl', function ($scope, Realm, realm, appli
});
};
$scope.changeApplication = function () {
$scope.changeClient = function () {
$scope.selectedAppRoles = [];
$scope.selectedAppDefRoles = [];
$scope.selectedClientRoles = [];
$scope.selectedClientDefRoles = [];
// Populate available roles for selected application
if ($scope.application) {
var appDefaultRoles = ApplicationRole.query({realm: $scope.realm.realm, application: $scope.application.id}, function () {
// Populate available roles for selected client
if ($scope.client) {
var appDefaultRoles = ClientRole.query({realm: $scope.realm.realm, client: $scope.client.id}, function () {
if (!$scope.application.hasOwnProperty('defaultRoles') || $scope.application.defaultRoles === null) {
$scope.application.defaultRoles = [];
if (!$scope.client.hasOwnProperty('defaultRoles') || $scope.client.defaultRoles === null) {
$scope.client.defaultRoles = [];
}
$scope.availableAppRoles = [];
$scope.availableClientRoles = [];
for (var i = 0; i < appDefaultRoles.length; i++) {
var roleName = appDefaultRoles[i].name;
if ($scope.application.defaultRoles.indexOf(roleName) < 0) {
$scope.availableAppRoles.push(roleName);
if ($scope.client.defaultRoles.indexOf(roleName) < 0) {
$scope.availableClientRoles.push(roleName);
}
}
});
} else {
$scope.availableAppRoles = null;
$scope.availableClientRoles = null;
}
};
$scope.addAppDefaultRole = function () {
$scope.addClientDefaultRole = 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];
for (var i = 0; i < $scope.selectedClientRoles.length; i++) {
var role = $scope.selectedClientRoles[i];
var idx = $scope.application.defaultRoles.indexOf(role);
var idx = $scope.client.defaultRoles.indexOf(role);
if (idx < 0) {
$scope.application.defaultRoles.push(role);
$scope.client.defaultRoles.push(role);
}
idx = $scope.availableAppRoles.indexOf(role);
idx = $scope.availableClientRoles.indexOf(role);
if (idx != -1) {
$scope.availableAppRoles.splice(idx, 1);
$scope.availableClientRoles.splice(idx, 1);
}
}
// Update/save the selected application with new default roles.
Application.update({
// Update/save the selected client with new default roles.
Client.update({
realm: $scope.realm.realm,
application: $scope.application.id
}, $scope.application, function () {
Notifications.success("Your changes have been saved to the application.");
client: $scope.client.id
}, $scope.client, function () {
Notifications.success("Your changes have been saved to the client.");
});
};
$scope.rmAppDefaultRole = function () {
$scope.rmClientDefaultRole = 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);
for (var i = 0; i < $scope.selectedClientDefRoles.length; i++) {
var role = $scope.selectedClientDefRoles[i];
var idx = $scope.client.defaultRoles.indexOf(role);
if (idx != -1) {
$scope.application.defaultRoles.splice(idx, 1);
$scope.client.defaultRoles.splice(idx, 1);
}
idx = $scope.availableAppRoles.indexOf(role);
idx = $scope.availableClientRoles.indexOf(role);
if (idx < 0) {
$scope.availableAppRoles.push(role);
$scope.availableClientRoles.push(role);
}
}
// Update/save the selected application with new default roles.
Application.update({
// Update/save the selected client with new default roles.
Client.update({
realm: $scope.realm.realm,
application: $scope.application.id
}, $scope.application, function () {
Notifications.success("Your changes have been saved to the application.");
client: $scope.client.id
}, $scope.client, function () {
Notifications.success("Your changes have been saved to the client.");
});
};
@@ -848,7 +848,7 @@ module.controller('RealmIdentityProviderCtrl', function($scope, $filter, $upload
alias : $scope.identityProvider.alias
}, function() {
$location.url("/realms/" + realm.realm + "/identity-provider-settings");
Notifications.success("The application has been deleted.");
Notifications.success("The client has been deleted.");
});
});
};
@@ -1008,7 +1008,7 @@ module.controller('RealmKeysDetailCtrl', function($scope, Realm, realm, $http, $
};
});
module.controller('RealmSessionStatsCtrl', function($scope, realm, stats, RealmApplicationSessionStats, RealmLogoutAll, Notifications) {
module.controller('RealmSessionStatsCtrl', function($scope, realm, stats, RealmClientSessionStats, RealmLogoutAll, Notifications) {
$scope.realm = realm;
$scope.stats = stats;
@@ -1073,7 +1073,7 @@ module.controller('RealmRevocationCtrl', function($scope, Realm, RealmPushRevoca
var msgStart = successCount>0 ? 'Successfully push notBefore to: ' + globalReqResult.successRequests + ' . ' : '';
Notifications.error(msgStart + 'Failed to push notBefore to: ' + globalReqResult.failedRequests + '. Verify availability of failed hosts and try again');
} else {
Notifications.success('Successfully push notBefore to all configured applications');
Notifications.success('Successfully push notBefore to all configured clients');
}
});
}
@@ -1094,8 +1094,8 @@ module.controller('RoleListCtrl', function($scope, $location, realm, roles) {
});
module.controller('RoleDetailCtrl', function($scope, realm, role, roles, applications,
Role, ApplicationRole, RoleById, RoleRealmComposites, RoleApplicationComposites,
module.controller('RoleDetailCtrl', function($scope, realm, role, roles, clients,
Role, ClientRole, RoleById, RoleRealmComposites, RoleClientComposites,
$http, $location, Dialog, Notifications) {
$scope.realm = realm;
$scope.role = angular.copy(role);
@@ -1141,8 +1141,8 @@ module.controller('RoleDetailCtrl', function($scope, realm, role, roles, applica
roleControl($scope, realm, role, roles, applications,
ApplicationRole, RoleById, RoleRealmComposites, RoleApplicationComposites,
roleControl($scope, realm, role, roles, clients,
ClientRole, RoleById, RoleRealmComposites, RoleClientComposites,
$http, $location, Notifications, Dialog);
});

View File

@@ -1,17 +1,17 @@
module.controller('UserRoleMappingCtrl', function($scope, $http, realm, user, applications, Notifications, RealmRoleMapping,
ApplicationRoleMapping, AvailableRealmRoleMapping, AvailableApplicationRoleMapping,
CompositeRealmRoleMapping, CompositeApplicationRoleMapping) {
module.controller('UserRoleMappingCtrl', function($scope, $http, realm, user, clients, Notifications, RealmRoleMapping,
ClientRoleMapping, AvailableRealmRoleMapping, AvailableClientRoleMapping,
CompositeRealmRoleMapping, CompositeClientRoleMapping) {
$scope.realm = realm;
$scope.user = user;
$scope.selectedRealmRoles = [];
$scope.selectedRealmMappings = [];
$scope.realmMappings = [];
$scope.applications = applications;
$scope.applicationRoles = [];
$scope.applicationComposite = [];
$scope.selectedApplicationRoles = [];
$scope.selectedApplicationMappings = [];
$scope.applicationMappings = [];
$scope.clients = clients;
$scope.clientRoles = [];
$scope.clientComposite = [];
$scope.selectedClientRoles = [];
$scope.selectedClientMappings = [];
$scope.clientMappings = [];
$scope.dummymodel = [];
$scope.realmMappings = RealmRoleMapping.query({realm : realm.realm, userId : user.username});
@@ -26,13 +26,13 @@ module.controller('UserRoleMappingCtrl', function($scope, $http, realm, user, ap
$scope.realmComposite = CompositeRealmRoleMapping.query({realm : realm.realm, userId : user.username});
$scope.selectedRealmMappings = [];
$scope.selectRealmRoles = [];
if ($scope.application) {
if ($scope.client) {
console.log('load available');
$scope.applicationComposite = CompositeApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.id});
$scope.applicationRoles = AvailableApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.id});
$scope.applicationMappings = ApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.id});
$scope.selectedApplicationRoles = [];
$scope.selectedApplicationMappings = [];
$scope.clientComposite = CompositeClientRoleMapping.query({realm : realm.realm, userId : user.username, client : $scope.client.id});
$scope.clientRoles = AvailableClientRoleMapping.query({realm : realm.realm, userId : user.username, client : $scope.client.id});
$scope.clientMappings = ClientRoleMapping.query({realm : realm.realm, userId : user.username, client : $scope.client.id});
$scope.selectedClientRoles = [];
$scope.selectedClientMappings = [];
}
Notifications.success("Role mappings updated.");
@@ -47,57 +47,57 @@ module.controller('UserRoleMappingCtrl', function($scope, $http, realm, user, ap
$scope.realmComposite = CompositeRealmRoleMapping.query({realm : realm.realm, userId : user.username});
$scope.selectedRealmMappings = [];
$scope.selectRealmRoles = [];
if ($scope.application) {
if ($scope.client) {
console.log('load available');
$scope.applicationComposite = CompositeApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.id});
$scope.applicationRoles = AvailableApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.id});
$scope.applicationMappings = ApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.id});
$scope.selectedApplicationRoles = [];
$scope.selectedApplicationMappings = [];
$scope.clientComposite = CompositeClientRoleMapping.query({realm : realm.realm, userId : user.username, client : $scope.client.id});
$scope.clientRoles = AvailableClientRoleMapping.query({realm : realm.realm, userId : user.username, client : $scope.client.id});
$scope.clientMappings = ClientRoleMapping.query({realm : realm.realm, userId : user.username, client : $scope.client.id});
$scope.selectedClientRoles = [];
$scope.selectedClientMappings = [];
}
Notifications.success("Role mappings updated.");
});
};
$scope.addApplicationRole = function() {
$http.post(authUrl + '/admin/realms/' + realm.realm + '/users/' + user.username + '/role-mappings/applications-by-id/' + $scope.application.id,
$scope.selectedApplicationRoles).success(function() {
$scope.applicationMappings = ApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.id});
$scope.applicationRoles = AvailableApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.id});
$scope.applicationComposite = CompositeApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.id});
$scope.selectedApplicationRoles = [];
$scope.selectedApplicationMappings = [];
$scope.addClientRole = function() {
$http.post(authUrl + '/admin/realms/' + realm.realm + '/users/' + user.username + '/role-mappings/clients-by-id/' + $scope.client.id,
$scope.selectedClientRoles).success(function() {
$scope.clientMappings = ClientRoleMapping.query({realm : realm.realm, userId : user.username, client : $scope.client.id});
$scope.clientRoles = AvailableClientRoleMapping.query({realm : realm.realm, userId : user.username, client : $scope.client.id});
$scope.clientComposite = CompositeClientRoleMapping.query({realm : realm.realm, userId : user.username, client : $scope.client.id});
$scope.selectedClientRoles = [];
$scope.selectedClientMappings = [];
Notifications.success("Role mappings updated.");
});
};
$scope.deleteApplicationRole = function() {
$http.delete(authUrl + '/admin/realms/' + realm.realm + '/users/' + user.username + '/role-mappings/applications-by-id/' + $scope.application.id,
{data : $scope.selectedApplicationMappings, headers : {"content-type" : "application/json"}}).success(function() {
$scope.applicationMappings = ApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.id});
$scope.applicationRoles = AvailableApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.id});
$scope.applicationComposite = CompositeApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.id});
$scope.selectedApplicationRoles = [];
$scope.selectedApplicationMappings = [];
$scope.deleteClientRole = function() {
$http.delete(authUrl + '/admin/realms/' + realm.realm + '/users/' + user.username + '/role-mappings/clients-by-id/' + $scope.client.id,
{data : $scope.selectedClientMappings, headers : {"content-type" : "application/json"}}).success(function() {
$scope.clientMappings = ClientRoleMapping.query({realm : realm.realm, userId : user.username, client : $scope.client.id});
$scope.clientRoles = AvailableClientRoleMapping.query({realm : realm.realm, userId : user.username, client : $scope.client.id});
$scope.clientComposite = CompositeClientRoleMapping.query({realm : realm.realm, userId : user.username, client : $scope.client.id});
$scope.selectedClientRoles = [];
$scope.selectedClientMappings = [];
Notifications.success("Role mappings updated.");
});
};
$scope.changeApplication = function() {
console.log('changeApplication');
if ($scope.application) {
$scope.changeClient = function() {
console.log('changeClient');
if ($scope.client) {
console.log('load available');
$scope.applicationComposite = CompositeApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.id});
$scope.applicationRoles = AvailableApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.id});
$scope.applicationMappings = ApplicationRoleMapping.query({realm : realm.realm, userId : user.username, application : $scope.application.id});
$scope.clientComposite = CompositeClientRoleMapping.query({realm : realm.realm, userId : user.username, client : $scope.client.id});
$scope.clientRoles = AvailableClientRoleMapping.query({realm : realm.realm, userId : user.username, client : $scope.client.id});
$scope.clientMappings = ClientRoleMapping.query({realm : realm.realm, userId : user.username, client : $scope.client.id});
} else {
$scope.applicationRoles = null;
$scope.applicationMappings = null;
$scope.applicationComposite = null;
$scope.clientRoles = null;
$scope.clientMappings = null;
$scope.clientComposite = null;
}
$scope.selectedApplicationRoles = [];
$scope.selectedApplicationMappings = [];
$scope.selectedClientRoles = [];
$scope.selectedClientMappings = [];
};
@@ -111,7 +111,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');
Notifications.success('Logged out user in all clients');
UserSessions.query({realm: realm.realm, user: user.username}, function(updated) {
$scope.sessions = updated;
})

View File

@@ -71,19 +71,19 @@ module.factory('RealmSessionStatsLoader', function(Loader, RealmSessionStats, $r
});
});
module.factory('RealmApplicationSessionStatsLoader', function(Loader, RealmApplicationSessionStats, $route, $q) {
return Loader.query(RealmApplicationSessionStats, function() {
module.factory('RealmClientSessionStatsLoader', function(Loader, RealmClientSessionStats, $route, $q) {
return Loader.query(RealmClientSessionStats, function() {
return {
realm : $route.current.params.realm
}
});
});
module.factory('ApplicationProtocolMapperLoader', function(Loader, ApplicationProtocolMapper, $route, $q) {
return Loader.get(ApplicationProtocolMapper, function() {
module.factory('ClientProtocolMapperLoader', function(Loader, ClientProtocolMapper, $route, $q) {
return Loader.get(ClientProtocolMapper, function() {
return {
realm : $route.current.params.realm,
application : $route.current.params.application,
client : $route.current.params.client,
id: $route.current.params.id
}
});
@@ -164,74 +164,74 @@ module.factory('RoleListLoader', function(Loader, Role, $route, $q) {
});
});
module.factory('ApplicationRoleLoader', function(Loader, RoleById, $route, $q) {
module.factory('ClientRoleLoader', function(Loader, RoleById, $route, $q) {
return Loader.get(RoleById, function() {
return {
realm : $route.current.params.realm,
application : $route.current.params.application,
client : $route.current.params.client,
role : $route.current.params.role
}
});
});
module.factory('ApplicationSessionStatsLoader', function(Loader, ApplicationSessionStats, $route, $q) {
return Loader.get(ApplicationSessionStats, function() {
module.factory('ClientSessionStatsLoader', function(Loader, ClientSessionStats, $route, $q) {
return Loader.get(ClientSessionStats, function() {
return {
realm : $route.current.params.realm,
application : $route.current.params.application
client : $route.current.params.client
}
});
});
module.factory('ApplicationSessionCountLoader', function(Loader, ApplicationSessionCount, $route, $q) {
return Loader.get(ApplicationSessionCount, function() {
module.factory('ClientSessionCountLoader', function(Loader, ClientSessionCount, $route, $q) {
return Loader.get(ClientSessionCount, function() {
return {
realm : $route.current.params.realm,
application : $route.current.params.application
client : $route.current.params.client
}
});
});
module.factory('ApplicationClaimsLoader', function(Loader, ApplicationClaims, $route, $q) {
return Loader.get(ApplicationClaims, function() {
module.factory('ClientClaimsLoader', function(Loader, ClientClaims, $route, $q) {
return Loader.get(ClientClaims, function() {
return {
realm : $route.current.params.realm,
application : $route.current.params.application
client : $route.current.params.client
}
});
});
module.factory('ApplicationInstallationLoader', function(Loader, ApplicationInstallation, $route, $q) {
return Loader.get(ApplicationInstallation, function() {
module.factory('ClientInstallationLoader', function(Loader, ClientInstallation, $route, $q) {
return Loader.get(ClientInstallation, function() {
return {
realm : $route.current.params.realm,
application : $route.current.params.application
client : $route.current.params.client
}
});
});
module.factory('ApplicationRoleListLoader', function(Loader, ApplicationRole, $route, $q) {
return Loader.query(ApplicationRole, function() {
module.factory('ClientRoleListLoader', function(Loader, ClientRole, $route, $q) {
return Loader.query(ClientRole, function() {
return {
realm : $route.current.params.realm,
application : $route.current.params.application
client : $route.current.params.client
}
});
});
module.factory('ApplicationLoader', function(Loader, Application, $route, $q) {
return Loader.get(Application, function() {
module.factory('ClientLoader', function(Loader, Client, $route, $q) {
return Loader.get(Client, function() {
return {
realm : $route.current.params.realm,
application : $route.current.params.application
client : $route.current.params.client
}
});
});
module.factory('ApplicationListLoader', function(Loader, Application, $route, $q) {
return Loader.query(Application, function() {
module.factory('ClientListLoader', function(Loader, Client, $route, $q) {
return Loader.query(Client, function() {
return {
realm : $route.current.params.realm
}
@@ -240,7 +240,7 @@ module.factory('ApplicationListLoader', function(Loader, Application, $route, $q
module.factory('RoleMappingLoader', function(Loader, RoleMapping, $route, $q) {
var realm = $route.current.params.realm || $route.current.params.application;
var realm = $route.current.params.realm || $route.current.params.client;
return Loader.query(RoleMapping, function() {
return {

View File

@@ -190,10 +190,10 @@ module.factory('ServerInfo', function($resource) {
module.factory('ApplicationProtocolMapper', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/protocol-mappers/models/:id', {
module.factory('ClientProtocolMapper', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/protocol-mappers/models/:id', {
realm : '@realm',
application: '@application',
client: '@client',
id : "@id"
}, {
update : {
@@ -324,72 +324,72 @@ module.factory('AvailableRealmRoleMapping', function($resource) {
});
module.factory('ApplicationRoleMapping', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/users/:userId/role-mappings/applications-by-id/:application', {
module.factory('ClientRoleMapping', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/users/:userId/role-mappings/clients-by-id/:client', {
realm : '@realm',
userId : '@userId',
application : "@application"
client : "@client"
});
});
module.factory('AvailableApplicationRoleMapping', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/users/:userId/role-mappings/applications-by-id/:application/available', {
module.factory('AvailableClientRoleMapping', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/users/:userId/role-mappings/clients-by-id/:client/available', {
realm : '@realm',
userId : '@userId',
application : "@application"
client : "@client"
});
});
module.factory('CompositeApplicationRoleMapping', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/users/:userId/role-mappings/applications-by-id/:application/composite', {
module.factory('CompositeClientRoleMapping', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/users/:userId/role-mappings/clients-by-id/:client/composite', {
realm : '@realm',
userId : '@userId',
application : "@application"
client : "@client"
});
});
module.factory('ApplicationRealmScopeMapping', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/scope-mappings/realm', {
module.factory('ClientRealmScopeMapping', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/scope-mappings/realm', {
realm : '@realm',
application : '@application'
client : '@client'
});
});
module.factory('ApplicationAvailableRealmScopeMapping', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/scope-mappings/realm/available', {
module.factory('ClientAvailableRealmScopeMapping', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/scope-mappings/realm/available', {
realm : '@realm',
application : '@application'
client : '@client'
});
});
module.factory('ApplicationCompositeRealmScopeMapping', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/scope-mappings/realm/composite', {
module.factory('ClientCompositeRealmScopeMapping', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/scope-mappings/realm/composite', {
realm : '@realm',
application : '@application'
client : '@client'
});
});
module.factory('ApplicationApplicationScopeMapping', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/scope-mappings/applications-by-id/:targetApp', {
module.factory('ClientClientScopeMapping', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/scope-mappings/clients-by-id/:targetClient', {
realm : '@realm',
application : '@application',
targetApp : '@targetApp'
client : '@client',
targetClient : '@targetClient'
});
});
module.factory('ApplicationAvailableApplicationScopeMapping', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/scope-mappings/applications-by-id/:targetApp/available', {
module.factory('ClientAvailableClientScopeMapping', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/scope-mappings/clients-by-id/:targetClient/available', {
realm : '@realm',
application : '@application',
targetApp : '@targetApp'
client : '@client',
targetClient : '@targetClient'
});
});
module.factory('ApplicationCompositeApplicationScopeMapping', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/scope-mappings/applications-by-id/:targetApp/composite', {
module.factory('ClientCompositeClientScopeMapping', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/scope-mappings/clients-by-id/:targetClient/composite', {
realm : '@realm',
application : '@application',
targetApp : '@targetApp'
client : '@client',
targetClient : '@targetClient'
});
});
@@ -420,24 +420,24 @@ module.factory('RealmSessionStats', function($resource) {
});
});
module.factory('RealmApplicationSessionStats', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/application-by-id-session-stats', {
module.factory('RealmClientSessionStats', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/client-by-id-session-stats', {
realm : '@realm'
});
});
module.factory('RoleApplicationComposites', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/roles-by-id/:role/composites/applications-by-id/:application', {
module.factory('RoleClientComposites', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/roles-by-id/:role/composites/clients-by-id/:client', {
realm : '@realm',
role : '@role',
application : "@application"
client : "@client"
});
});
function roleControl($scope, realm, role, roles, applications,
ApplicationRole, RoleById, RoleRealmComposites, RoleApplicationComposites,
function roleControl($scope, realm, role, roles, clients,
ClientRole, RoleById, RoleRealmComposites, RoleClientComposites,
$http, $location, Notifications, Dialog) {
$scope.$watch(function () {
@@ -476,11 +476,11 @@ function roleControl($scope, realm, role, roles, applications,
$scope.selectedRealmRoles = [];
$scope.selectedRealmMappings = [];
$scope.realmMappings = [];
$scope.applications = applications;
$scope.applicationRoles = [];
$scope.selectedApplicationRoles = [];
$scope.selectedApplicationMappings = [];
$scope.applicationMappings = [];
$scope.clients = clients;
$scope.clientRoles = [];
$scope.selectedClientRoles = [];
$scope.selectedClientMappings = [];
$scope.clientMappings = [];
for (var j = 0; j < $scope.realmRoles.length; j++) {
if ($scope.realmRoles[j].id == role.id) {
@@ -540,61 +540,61 @@ function roleControl($scope, realm, role, roles, applications,
});
};
$scope.addApplicationRole = function() {
$scope.addClientRole = function() {
$scope.compositeSwitchDisabled=true;
$http.post(authUrl + '/admin/realms/' + realm.realm + '/roles-by-id/' + role.id + '/composites',
$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]);
$scope.selectedClientRoles).success(function() {
for (var i = 0; i < $scope.selectedClientRoles.length; i++) {
var role = $scope.selectedClientRoles[i];
var idx = $scope.clientRoles.indexOf($scope.selectedClientRoles[i]);
if (idx != -1) {
$scope.applicationRoles.splice(idx, 1);
$scope.applicationMappings.push(role);
$scope.clientRoles.splice(idx, 1);
$scope.clientMappings.push(role);
}
}
$scope.selectedApplicationRoles = [];
$scope.selectedClientRoles = [];
});
};
$scope.deleteApplicationRole = function() {
$scope.deleteClientRole = function() {
$scope.compositeSwitchDisabled=true;
$http.delete(authUrl + '/admin/realms/' + realm.realm + '/roles-by-id/' + role.id + '/composites',
{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]);
{data : $scope.selectedClientMappings, headers : {"content-type" : "application/json"}}).success(function() {
for (var i = 0; i < $scope.selectedClientMappings.length; i++) {
var role = $scope.selectedClientMappings[i];
var idx = $scope.clientMappings.indexOf($scope.selectedClientMappings[i]);
if (idx != -1) {
$scope.applicationMappings.splice(idx, 1);
$scope.applicationRoles.push(role);
$scope.clientMappings.splice(idx, 1);
$scope.clientRoles.push(role);
}
}
$scope.selectedApplicationMappings = [];
$scope.selectedClientMappings = [];
});
};
$scope.changeApplication = function() {
$scope.applicationRoles = ApplicationRole.query({realm : realm.realm, application : $scope.compositeApp.id}, function() {
$scope.applicationMappings = RoleApplicationComposites.query({realm : realm.realm, role : role.id, application : $scope.compositeApp.id}, 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];
$scope.changeClient = function() {
$scope.clientRoles = ClientRole.query({realm : realm.realm, client : $scope.compositeClient.id}, function() {
$scope.clientMappings = RoleClientComposites.query({realm : realm.realm, role : role.id, client : $scope.compositeClient.id}, function(){
for (var i = 0; i < $scope.clientMappings.length; i++) {
var role = $scope.clientMappings[i];
for (var j = 0; j < $scope.clientRoles.length; j++) {
var realmRole = $scope.clientRoles[j];
if (realmRole.id == role.id) {
var idx = $scope.applicationRoles.indexOf(realmRole);
var idx = $scope.clientRoles.indexOf(realmRole);
if (idx != -1) {
$scope.applicationRoles.splice(idx, 1);
$scope.clientRoles.splice(idx, 1);
break;
}
}
}
}
});
for (var j = 0; j < $scope.applicationRoles.length; j++) {
if ($scope.applicationRoles[j] == role.id) {
var appRole = $scope.applicationRoles[j];
var idx = $scope.applicationRoles.indexof(appRole);
$scope.applicationRoles.splice(idx, 1);
for (var j = 0; j < $scope.clientRoles.length; j++) {
if ($scope.clientRoles[j] == role.id) {
var appRole = $scope.clientRoles[j];
var idx = $scope.clientRoles.indexof(appRole);
$scope.clientRoles.splice(idx, 1);
break;
}
}
@@ -630,10 +630,10 @@ module.factory('RoleById', function($resource) {
});
});
module.factory('ApplicationRole', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/roles/:role', {
module.factory('ClientRole', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/roles/:role', {
realm : '@realm',
application : "@application",
client : "@client",
role : '@role'
}, {
update : {
@@ -642,10 +642,10 @@ module.factory('ApplicationRole', function($resource) {
});
});
module.factory('ApplicationClaims', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/claims', {
module.factory('ClientClaims', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/claims', {
realm : '@realm',
application : "@application"
client : "@client"
}, {
update : {
method : 'PUT'
@@ -653,52 +653,52 @@ module.factory('ApplicationClaims', function($resource) {
});
});
module.factory('ApplicationProtocolMappersByProtocol', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/protocol-mappers/protocol/:protocol', {
module.factory('ClientProtocolMappersByProtocol', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/protocol-mappers/protocol/:protocol', {
realm : '@realm',
application : "@application",
client : "@client",
protocol : "@protocol"
});
});
module.factory('ApplicationSessionStats', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/session-stats', {
module.factory('ClientSessionStats', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/session-stats', {
realm : '@realm',
application : "@application"
client : "@client"
});
});
module.factory('ApplicationSessionStatsWithUsers', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/session-stats?users=true', {
module.factory('ClientSessionStatsWithUsers', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/session-stats?users=true', {
realm : '@realm',
application : "@application"
client : "@client"
});
});
module.factory('ApplicationSessionCount', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/session-count', {
module.factory('ClientSessionCount', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/session-count', {
realm : '@realm',
application : "@application"
client : "@client"
});
});
module.factory('ApplicationUserSessions', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/user-sessions', {
module.factory('ClientUserSessions', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/user-sessions', {
realm : '@realm',
application : "@application"
client : "@client"
});
});
module.factory('ApplicationLogoutAll', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/logout-all', {
module.factory('ClientLogoutAll', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/logout-all', {
realm : '@realm',
application : "@application"
client : "@client"
});
});
module.factory('ApplicationLogoutUser', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/logout-user/:user', {
module.factory('ClientLogoutUser', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/logout-user/:user', {
realm : '@realm',
application : "@application",
client : "@client",
user : "@user"
});
});
@@ -708,39 +708,39 @@ module.factory('RealmLogoutAll', function($resource) {
});
});
module.factory('ApplicationPushRevocation', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/push-revocation', {
module.factory('ClientPushRevocation', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/push-revocation', {
realm : '@realm',
application : "@application"
client : "@client"
});
});
module.factory('ApplicationClusterNode', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/nodes/:node', {
module.factory('ClientClusterNode', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/nodes/:node', {
realm : '@realm',
application : "@application"
client : "@client"
});
});
module.factory('ApplicationTestNodesAvailable', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/test-nodes-available', {
module.factory('ClientTestNodesAvailable', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/test-nodes-available', {
realm : '@realm',
application : "@application"
client : "@client"
});
});
module.factory('ApplicationCertificate', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/certificates/:attribute', {
module.factory('ClientCertificate', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/certificates/:attribute', {
realm : '@realm',
application : "@application",
client : "@client",
attribute: "@attribute"
});
});
module.factory('ApplicationCertificateGenerate', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/certificates/:attribute/generate', {
module.factory('ClientCertificateGenerate', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/certificates/:attribute/generate', {
realm : '@realm',
application : "@application",
client : "@client",
attribute: "@attribute"
},
{
@@ -750,10 +750,10 @@ module.factory('ApplicationCertificateGenerate', function($resource) {
});
});
module.factory('ApplicationCertificateDownload', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/certificates/:attribute/download', {
module.factory('ClientCertificateDownload', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/certificates/:attribute/download', {
realm : '@realm',
application : "@application",
client : "@client",
attribute: "@attribute"
},
{
@@ -764,10 +764,10 @@ module.factory('ApplicationCertificateDownload', function($resource) {
});
});
module.factory('Application', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application', {
module.factory('Client', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client', {
realm : '@realm',
application : '@application'
client : '@client'
}, {
update : {
method : 'PUT'
@@ -775,29 +775,29 @@ module.factory('Application', function($resource) {
});
});
module.factory('ApplicationInstallation', function($resource) {
var url = authUrl + '/admin/realms/:realm/applications-by-id/:application/installation/json';
module.factory('ClientInstallation', function($resource) {
var url = authUrl + '/admin/realms/:realm/clients-by-id/:client/installation/json';
return {
url : function(parameters)
{
return url.replace(':realm', parameters.realm).replace(':application', parameters.application);
return url.replace(':realm', parameters.realm).replace(':client', parameters.client);
}
}
});
module.factory('ApplicationInstallationJBoss', function($resource) {
var url = authUrl + '/admin/realms/:realm/applications-by-id/:application/installation/jboss';
module.factory('ClientInstallationJBoss', function($resource) {
var url = authUrl + '/admin/realms/:realm/clients-by-id/:client/installation/jboss';
return {
url : function(parameters)
{
return url.replace(':realm', parameters.realm).replace(':application', parameters.application);
return url.replace(':realm', parameters.realm).replace(':client', parameters.client);
}
}
});
module.factory('ApplicationCredentials', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/client-secret', {
module.factory('ClientCredentials', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/client-secret', {
realm : '@realm',
application : '@application'
client : '@client'
}, {
update : {
method : 'POST'
@@ -805,10 +805,10 @@ module.factory('ApplicationCredentials', function($resource) {
});
});
module.factory('ApplicationOrigins', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/allowed-origins', {
module.factory('ClientOrigins', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/clients-by-id/:client/allowed-origins', {
realm : '@realm',
application : '@application'
client : '@client'
}, {
update : {
method : 'PUT',
@@ -822,8 +822,8 @@ module.factory('Current', function(Realm, $route) {
current.realms = {};
current.realm = null;
current.applications = {};
current.application = null;
current.clients = {};
current.client = null;
current.refresh = function() {
current.realm = null;

View File

@@ -1,59 +0,0 @@
<div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="resourceUrl + '/partials/realm-menu.html'"></div>
<div id="content-area" class="col-md-9" role="main">
<h2></h2>
<div id="content">
<h2><span>{{realm.realm}}</span> Applications <span tooltip-placement="right" tooltip="Applications are trusted browser apps and web services in a realm. These applications can request a login. You can also define application specific roles." class="fa fa-info-circle"></span></h2>
<table class="table table-striped table-bordered">
<thead>
<tr>
<th class="kc-table-actions" colspan="3">
<div class="search-comp clearfix">
<input type="text" placeholder="Search..." class="form-control search" data-ng-model="search.name"
onkeyup="if(event.keyCode == 13){$(this).next('button').click();}">
<button type="submit" class="kc-icon-search" tooltip-placement="right"
tooltip="Search by application name.">
Icon: search
</button>
</div>
<div class="pull-right">
<a class="btn btn-primary" href="#/import/application/{{realm.realm}}" data-ng-show="importButton">Import</a>
<a class="btn btn-primary" href="#/create/application/{{realm.realm}}">Create</a>
</div>
</th>
</tr>
<tr data-ng-hide="applications.length == 0">
<th>Application Name</th>
<th>Enabled</th>
<th>Base URL</th>
</tr>
</thead>
<!--<tfoot data-ng-show="applications && applications.length > 5">
<tr>
<td colspan="3">
<div class="table-nav">
<a href="#" class="first disabled">First page</a><a href="#" class="prev disabled">Previous
page</a><span><strong>1-8</strong> of <strong>10</strong></span><a href="#"
class="next">Next
page</a><a href="#" class="last">Last page</a>
</div>
</td>
</tr>
</tfoot>-->
<tbody>
<tr ng-repeat="app in applications | filter:search">
<td><a href="#/realms/{{realm.realm}}/applications/{{app.id}}">{{app.name}}</a></td>
<td>{{app.enabled}}</td>
<td ng-class="{'text-muted': !app.baseUrl}">
<a href="{{app.baseUrl}}" data-ng-show="app.baseUrl">{{app.baseUrl}}</a>
<span data-ng-hide="app.baseUrl">Not defined</span>
</tr>
<tr data-ng-show="applications.length == 0">
<td>No applications available</td>
</tr>
</tbody>
</table>
<div class="feedback warning inline" data-ng-show="search && applications.length == 0">
<p><strong>Your search returned no results.</strong><br>Try modifying the query and try again.</p>
</div>
</div>
</div>

View File

@@ -1,14 +1,14 @@
<div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="resourceUrl + '/partials/realm-menu.html'"></div>
<div id="content-area" class="col-md-9" role="main">
<kc-navigation-application></kc-navigation-application>
<kc-navigation-client></kc-navigation-client>
<div id="content">
<ol class="breadcrumb">
<li><a href="#/realms/{{realm.realm}}/applications">Applications</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}">{{application.name}}</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}/clustering">Clustering</a></li>
<li><a href="#/realms/{{realm.realm}}/clients">Clients</a></li>
<li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li>
<li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/clustering">Clustering</a></li>
<li class="active">{{node.host}}</li>
</ol>
<h2 data-ng-show="create || registered"><span>{{application.name}} Clustering</span></h2>
<h2 data-ng-show="create || registered"><span>{{client.clientId}} Clustering</span></h2>
<h2 data-ng-hide="create || registered">Cluster node on host <span>{{node.host}}</span> not registered!</h2>
<form class="form-horizontal" name="clusteringForm" novalidate kc-read-only="!access.manageClients" data-ng-show="create || registered">
<fieldset >

View File

@@ -1,13 +1,13 @@
<div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="resourceUrl + '/partials/realm-menu.html'"></div>
<div id="content-area" class="col-md-9" role="main">
<kc-navigation-application></kc-navigation-application>
<kc-navigation-client></kc-navigation-client>
<div id="content">
<ol class="breadcrumb" data-ng-hide="create">
<li><a href="#/realms/{{realm.realm}}/applications">Applications</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}">{{application.name}}</a></li>
<li><a href="#/realms/{{realm.realm}}/clients">Clients</a></li>
<li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li>
<li class="active">Clustering</li>
</ol>
<h2 data-ng-hide="create"><span>{{application.name}}</span> Clustering</h2>
<h2 data-ng-hide="create"><span>{{client.clientId}}</span> Clustering</h2>
<form class="form-horizontal" name="clusteringForm" novalidate kc-read-only="!access.manageClients">
<legend><span class="text">Basic configuration</span></legend>
<fieldset >
@@ -17,12 +17,12 @@
<div class="row">
<div class="col-sm-4">
<input class="form-control" type="number" required
max="31536000" data-ng-model="application.nodeReRegistrationTimeout"
max="31536000" data-ng-model="client.nodeReRegistrationTimeout"
id="nodeReRegistrationTimeout" name="nodeReRegistrationTimeout"/>
</div>
<div class="col-sm-4 select-kc">
<select name="nodeReRegistrationTimeoutUnit" data-ng-model="application.nodeReRegistrationTimeoutUnit" >
<option data-ng-selected="!application.nodeReRegistrationTimeoutUnit">Seconds</option>
<select name="nodeReRegistrationTimeoutUnit" data-ng-model="client.nodeReRegistrationTimeoutUnit" >
<option data-ng-selected="!client.nodeReRegistrationTimeoutUnit">Seconds</option>
<option>Minutes</option>
<option>Hours</option>
<option>Days</option>
@@ -30,7 +30,7 @@
</div>
</div>
</div>
<span tooltip-placement="right" tooltip="Interval to specify max time for registered application cluster nodes to re-register. If cluster node won't send re-registration request to Keycloak within this time, it will be unregistered from Keycloak" class="fa fa-info-circle"></span>
<span tooltip-placement="right" tooltip="Interval to specify max time for registered clients cluster nodes to re-register. If cluster node won't send re-registration request to Keycloak within this time, it will be unregistered from Keycloak" class="fa fa-info-circle"></span>
</div>
<div class="pull-right form-actions" data-ng-show="access.manageRealm">
<button data-kc-reset data-ng-show="changed">Clear changes</button>
@@ -46,7 +46,7 @@
<th class="kc-table-actions" colspan="3" data-ng-show="access.manageClients">
<div class="pull-right">
<a class="btn btn-primary" tooltip="Manually register cluster node. This is usually not needed as cluster node should be registered automatically by adapter"
tooltip-placement="bottom" href="#/register-node/realms/{{realm.realm}}/applications/{{application.id}}/clustering">Register node manually</a>
tooltip-placement="bottom" href="#/register-node/realms/{{realm.realm}}/clients/{{client.id}}/clustering">Register node manually</a>
</div>
</th>
</tr>
@@ -57,7 +57,7 @@
</thead>
<tbody>
<tr ng-repeat="node in nodeRegistrations">
<td><a href="#/realms/{{realm.realm}}/applications/{{application.id}}/clustering/{{node.host}}">{{node.host}}</a></td>
<td><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/clustering/{{node.host}}">{{node.host}}</a></td>
<td>{{node.lastRegistration}}</td>
</tr>
<tr data-ng-show="!nodeRegistrations || nodeRegistrations.length == 0">

View File

@@ -1,14 +1,14 @@
<div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="resourceUrl + '/partials/realm-menu.html'"></div>
<div id="content-area" class="col-md-9" role="main">
<kc-navigation-application></kc-navigation-application>
<kc-navigation-client></kc-navigation-client>
<div id="content">
<ol class="breadcrumb" data-ng-hide="create">
<li><a href="#/realms/{{realm.realm}}/applications">Applications</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}">{{application.name}}</a></li>
<li><a href="#/realms/{{realm.realm}}/clients">Clients</a></li>
<li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li>
<li class="active">Claims</li>
</ol>
<h2 data-ng-hide="create"><span>{{application.name}}</span> Credentials</h2>
<form class="form-horizontal" name="credentialForm" novalidate kc-read-only="!access.manageApplications">
<h2 data-ng-hide="create"><span>{{client.clientId}}</span> Credentials</h2>
<form class="form-horizontal" name="credentialForm" novalidate kc-read-only="!access.manageClients">
<fieldset >
<legend><span class="text">Client Secret</span></legend>
<div class="form-group">
@@ -18,7 +18,7 @@
</div>
</div>
</fieldset>
<div class="pull-right form-actions" data-ng-show="access.manageApplications">
<div class="pull-right form-actions" data-ng-show="access.manageClients">
<button type="submit" data-ng-click="changePassword()" class="btn btn-primary btn-lg">Regenerate Secret
</button>
</div>

View File

@@ -1,46 +1,46 @@
<div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="resourceUrl + '/partials/realm-menu.html'"></div>
<div id="content-area" class="col-md-9" role="main">
<kc-navigation-application></kc-navigation-application>
<kc-navigation-client></kc-navigation-client>
<div id="content">
<ol class="breadcrumb" data-ng-hide="create">
<li><a href="#/realms/{{realm.realm}}/applications">Applications</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}">{{application.name}}</a></li>
<li><a href="#/realms/{{realm.realm}}/clients">Clients</a></li>
<li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li>
<li class="active">Settings</li>
</ol>
<ol class="breadcrumb" data-ng-show="create">
<li><a href="#/realms/{{realm.realm}}/applications">Applications</a></li>
<li class="active">Add Application</li>
<li><a href="#/realms/{{realm.realm}}/clients">Clients</a></li>
<li class="active">Add Client</li>
</ol>
<h2 data-ng-hide="create"><span>{{application.name}}</span> Application Settings</h2>
<h2 data-ng-show="create" class="pull-left"><span>{{realm.realm}}</span> Add Application</h2>
<h2 data-ng-hide="create"><span>{{client.clientId}}</span> Client Settings</h2>
<h2 data-ng-show="create" class="pull-left"><span>{{realm.realm}}</span> Add Client</h2>
<p class="subtitle" data-ng-show="create"><span class="required">*</span> Required fields</p>
<form class="form-horizontal" name="applicationForm" novalidate kc-read-only="!access.manageClients">
<form class="form-horizontal" name="clientForm" novalidate kc-read-only="!access.manageClients">
<fieldset class="border-top">
<div class="form-group">
<label class="col-sm-2 control-label" for="name">Name <span class="required" data-ng-show="create">*</span></label>
<label class="col-sm-2 control-label" for="clientId">Client ID <span class="required" data-ng-show="create">*</span></label>
<div class="col-sm-4">
<input class="form-control" type="text" id="name" name="name" data-ng-model="application.name" autofocus required>
<input class="form-control" type="text" id="clientId" name="clientId" data-ng-model="client.clientId" autofocus required>
</div>
</div>
<div class="form-group clearfix block">
<label class="col-sm-2 control-label" for="enabled">Enabled</label>
<div class="col-sm-6">
<input ng-model="application.enabled" name="enabled" id="enabled" onoffswitch />
<input ng-model="client.enabled" name="enabled" id="enabled" onoffswitch />
</div>
<span tooltip-placement="right" tooltip="Disabled applications cannot initiate a login or have obtain access tokens." class="fa fa-info-circle"></span>
<span tooltip-placement="right" tooltip="Disabled clients cannot initiate a login or have obtain access tokens." class="fa fa-info-circle"></span>
</div>
<div class="form-group clearfix block">
<label class="col-sm-2 control-label" for="consentRequired">Consent Required</label>
<div class="col-sm-6">
<input ng-model="application.consentRequired" name="consentRequired" id="consentRequired" onoffswitch />
<input ng-model="client.consentRequired" name="consentRequired" id="consentRequired" onoffswitch />
</div>
<span tooltip-placement="right" tooltip="If enabled users have to consent to client access." class="fa fa-info-circle"></span>
</div>
<div class="form-group clearfix block">
<label class="col-sm-2 control-label" for="directGrantsOnly">Direct Grants Only</label>
<div class="col-sm-6">
<input ng-model="application.directGrantsOnly" name="directGrantsOnly" id="directGrantsOnly" onoffswitch />
<input ng-model="client.directGrantsOnly" name="directGrantsOnly" id="directGrantsOnly" onoffswitch />
</div>
<span tooltip-placement="right" tooltip="When enabled, client can only obtain grants from grant REST API." class="fa fa-info-circle"></span>
</div>
@@ -69,7 +69,7 @@
</select>
</div>
</div>
<span tooltip-placement="right" tooltip="'Confidential' applications require a secret to initiate login protocol. 'Public' clients do not require a secret. 'Bearer-only' applications are web services that never initiate a login." class="fa fa-info-circle"></span>
<span tooltip-placement="right" tooltip="'Confidential' clients require a secret to initiate login protocol. 'Public' clients do not require a secret. 'Bearer-only' clients are web services that never initiate a login." class="fa fa-info-circle"></span>
</div>
<div class="form-group clearfix block" data-ng-show="protocol == 'saml'">
<label class="col-sm-2 control-label" for="samlServerSignature">Include AuthnStatement</label>
@@ -129,9 +129,9 @@
<div class="form-group clearfix block" data-ng-show="protocol == 'saml'">
<label class="col-sm-2 control-label" for="frontchannelLogout">Front Channel Logout</label>
<div class="col-sm-6">
<input ng-model="application.frontchannelLogout" name="frontchannelLogout" id="frontchannelLogout" onoffswitch />
<input ng-model="client.frontchannelLogout" name="frontchannelLogout" id="frontchannelLogout" onoffswitch />
</div>
<span tooltip-placement="right" tooltip="When true, logout requires a browser redirect to application. When false, server performs a background invocation for logout." class="fa fa-info-circle"></span>
<span tooltip-placement="right" tooltip="When true, logout requires a browser redirect to client. When false, server performs a background invocation for logout." class="fa fa-info-circle"></span>
</div>
<div class="form-group clearfix block" data-ng-show="protocol == 'saml'">
<label class="col-sm-2 control-label" for="samlForceNameIdFormat">Force Name ID Format</label>
@@ -153,9 +153,9 @@
</div>
<span tooltip-placement="right" tooltip="The name ID format to use for the subject." class="fa fa-info-circle"></span>
</div>
<div class="form-group clearfix block" data-ng-show="!application.bearerOnly">
<div class="form-group clearfix block" data-ng-show="!client.bearerOnly">
<label class="col-sm-2 control-label" for="newRedirectUri">Valid Redirect URIs <span class="required" data-ng-show="create && protocol != 'saml'">*</span></label>
<div class="col-sm-6 multiple" ng-repeat="redirectUri in application.redirectUris">
<div class="col-sm-6 multiple" ng-repeat="redirectUri in client.redirectUris">
<div class="input-group kc-item-deletable">
<input class="form-control" type="text" data-ng-class="{'input-below':!$first}"
name="redirectUri" id="redirectUri" data-ng-model="redirectUri" readonly />
@@ -169,7 +169,7 @@
<div class="input-group">
<input class="form-control" type="text" name="newRedirectUri" id="newRedirectUri"
placeholder="New Redirect URI..." data-ng-model="newRedirectUri"
data-ng-class="{'input-below':application.redirectUris.length}" />
data-ng-class="{'input-below':client.redirectUris.length}" />
<span class="input-group-btn">
<button class="btn btn-default" data-ng-click="addRedirectUri()" ng-show="newRedirectUri.length > 0">Add</button>
</span>
@@ -177,33 +177,33 @@
</div>
<span tooltip-placement="right" tooltip="Valid URI pattern a browser can redirect to after a successful login or logout. Simple wildcards are allowed i.e. 'http://example.com/*'. Relative path can be specified too i.e. /my/relative/path/*. Relative paths will generate a redirect URI using the request's host and port. For SAML, you must set valid URI patterns if you are relying on the consumer service URL embedded with the login request." class="fa fa-info-circle"></span>
</div>
<div class="form-group" data-ng-show="!application.bearerOnly && !create">
<div class="form-group" data-ng-show="!client.bearerOnly && !create">
<label class="col-sm-2 control-label" for="baseUrl">Default Redirect URL</label>
<div class="col-sm-6">
<input class="form-control" type="text" name="baseUrl" id="baseUrl"
data-ng-model="application.baseUrl">
data-ng-model="client.baseUrl">
</div>
<span tooltip-placement="right" tooltip="Default URL to use when the auth server needs to redirect back to the application. This URL will also be used when the auth server needs to link to the application for any reason." class="fa fa-info-circle"></span>
<span tooltip-placement="right" tooltip="Default URL to use when the auth server needs to redirect back to the client. This URL will also be used when the auth server needs to link to the client for any reason." class="fa fa-info-circle"></span>
</div>
<div class="form-group" data-ng-hide="create || protocol == 'saml'">
<label class="col-sm-2 control-label" for="adminUrl">Admin URL</label>
<div class="col-sm-6">
<input class="form-control" type="text" name="adminUrl" id="adminUrl"
data-ng-model="application.adminUrl">
data-ng-model="client.adminUrl">
</div>
<span tooltip-placement="right" tooltip="URL to the admin interface of the application. Set this if the application supports the adapter REST API. This REST API allows the auth server to push revocation policies and other adminstrative tasks. Usually this is set to the base URL of the application." class="fa fa-info-circle"></span>
<span tooltip-placement="right" tooltip="URL to the admin interface of the client. Set this if the client supports the adapter REST API. This REST API allows the auth server to push revocation policies and other adminstrative tasks. Usually this is set to the base URL of the client." class="fa fa-info-circle"></span>
</div>
<div class="form-group" data-ng-show="protocol == 'saml'">
<label class="col-sm-2 control-label" for="masterSamlUrl">Master SAML Processing URL</label>
<div class="col-sm-6">
<input class="form-control" type="text" name="masterSamlUrl" id="masterSamlUrl"
data-ng-model="application.adminUrl">
data-ng-model="client.adminUrl">
</div>
<span tooltip-placement="right" tooltip="If configured, this URL will be used for every binding to both the SP's Assertion Consumer and Single Logout Services. This can be individually overiden for each binding and service in the Fine Grain SAML Endpoint Configuration." class="fa fa-info-circle"></span>
</div>
<div class="form-group" data-ng-show="!application.bearerOnly && !create && protocol == 'openid-connect'">
<div class="form-group" data-ng-show="!client.bearerOnly && !create && protocol == 'openid-connect'">
<label class="col-sm-2 control-label" for="newWebOrigin">Web Origin</label>
<div class="col-sm-6 multiple" ng-repeat="webOrigin in application.webOrigins">
<div class="col-sm-6 multiple" ng-repeat="webOrigin in client.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 />
@@ -217,7 +217,7 @@
<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}" />
data-ng-class="{'input-below':client.webOrigins.length}" />
<span class="input-group-btn">
<button class="btn btn-default" data-ng-click="addWebOrigin()" ng-show="newWebOrigin.length > 0">Add</button>
</span>
@@ -231,30 +231,30 @@
<div class="form-group clearfix block" data-ng-show="protocol == 'saml'">
<label class="col-sm-2 control-label" for="consumerServicePost">Assertion Consumer Service POST Binding URL</label>
<div class="col-sm-6">
<input ng-model="application.attributes.saml_assertion_consumer_url_post" class="form-control" type="text" name="consumerServicePost" id="consumerServicePost" />
<input ng-model="client.attributes.saml_assertion_consumer_url_post" class="form-control" type="text" name="consumerServicePost" id="consumerServicePost" />
</div>
<span tooltip-placement="right" tooltip="SAML POST Binding URL for the application's assertion consumer service (login responses). You can leave this blank if you do not have a URL for this binding." class="fa fa-info-circle"></span>
<span tooltip-placement="right" tooltip="SAML POST Binding URL for the client's assertion consumer service (login responses). You can leave this blank if you do not have a URL for this binding." class="fa fa-info-circle"></span>
</div>
<div class="form-group clearfix block" data-ng-show="protocol == 'saml'">
<label class="col-sm-2 control-label" for="consumerServiceRedirect">Assertion Consumer Service Redirect Binding URL</label>
<div class="col-sm-6">
<input ng-model="application.attributes.saml_assertion_consumer_url_redirect" class="form-control" type="text" name="consumerServiceRedirect" id="consumerServiceRedirect" />
<input ng-model="client.attributes.saml_assertion_consumer_url_redirect" class="form-control" type="text" name="consumerServiceRedirect" id="consumerServiceRedirect" />
</div>
<span tooltip-placement="right" tooltip="SAML Redirect Binding URL for the application's assertion consumer service (login responses). You can leave this blank if you do not have a URL for this binding." class="fa fa-info-circle"></span>
<span tooltip-placement="right" tooltip="SAML Redirect Binding URL for the client's assertion consumer service (login responses). You can leave this blank if you do not have a URL for this binding." class="fa fa-info-circle"></span>
</div>
<div class="form-group clearfix block" data-ng-show="protocol == 'saml'">
<label class="col-sm-2 control-label" for="logoutPostBinding">Logout Service POST Binding URL</label>
<div class="col-sm-6">
<input ng-model="application.attributes.saml_single_logout_service_url_post" class="form-control" type="text" name="logoutPostBinding" id="logoutPostBinding" />
<input ng-model="client.attributes.saml_single_logout_service_url_post" class="form-control" type="text" name="logoutPostBinding" id="logoutPostBinding" />
</div>
<span tooltip-placement="right" tooltip="SAML POST Binding URL for the application's single logout service. You can leave this blank if you are using a different binding" class="fa fa-info-circle"></span>
<span tooltip-placement="right" tooltip="SAML POST Binding URL for the client's single logout service. You can leave this blank if you are using a different binding" class="fa fa-info-circle"></span>
</div>
<div class="form-group clearfix block" data-ng-show="protocol == 'saml'">
<label class="col-sm-2 control-label" for="logoutPostBinding">Logout Service Redirect Binding URL</label>
<div class="col-sm-6">
<input ng-model="application.attributes.saml_single_logout_service_url_redirect" class="form-control" type="text" name="logoutRedirectBinding" id="logoutRedirectBinding" />
<input ng-model="client.attributes.saml_single_logout_service_url_redirect" class="form-control" type="text" name="logoutRedirectBinding" id="logoutRedirectBinding" />
</div>
<span tooltip-placement="right" tooltip="SAML Redirect Binding URL for the application's single logout service. You can leave this blank if you are using a different binding." class="fa fa-info-circle"></span>
<span tooltip-placement="right" tooltip="SAML Redirect Binding URL for the client's single logout service. You can leave this blank if you are using a different binding." class="fa fa-info-circle"></span>
</div>
</fieldset>
@@ -265,7 +265,7 @@
<div class="pull-right form-actions" data-ng-show="!create && access.manageClients">
<button kc-reset data-ng-show="changed">Clear changes</button>
<button kc-save data-ng-show="changed">Save</button>
<button kc-delete data-ng-click="remove()" data-ng-hide="changed">Delete Application</button>
<button kc-delete data-ng-click="remove()" data-ng-hide="changed">Delete Client</button>
</div>
</form>
</div>

View File

@@ -1,20 +1,20 @@
<div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="resourceUrl + '/partials/realm-menu.html'"></div>
<div id="content-area" class="col-md-9" role="main">
<kc-navigation-application></kc-navigation-application>
<kc-navigation-client></kc-navigation-client>
<div id="content">
<ol class="breadcrumb" data-ng-hide="create">
<li><a href="#/realms/{{realm.realm}}/applications">Applications</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}">{{application.name}}</a></li>
<li><a href="#/realms/{{realm.realm}}/clients">Clients</a></li>
<li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li>
<li class="active">Identity Provider</li>
</ol>
<h2 data-ng-hide="create"><span>{{application.name}}</span> Identity Provider Settings</h2>
<h2 data-ng-hide="create"><span>{{client.clientId}}</span> Identity Provider Settings</h2>
<form class="form-horizontal" name="identityProviderForm" novalidate>
<div class="form-group" ng-repeat="identityProvider in identityProviders">
<legend><span class="text">{{identityProvider.identityProvider.name}}</span></legend>
<div data-ng-show="application.identityProviders[$index].id">
<label class="col-sm-2 control-label" for="{{identityProvider.identityProvider.id}}retrieveToken">Can Retrieve Token&nbsp;<span tooltip-placement="right" tooltip="If disabled, the application can not retrieve tokens from the identity provider." class="fa fa-info-circle"></span></label>
<div data-ng-show="client.identityProviders[$index].id">
<label class="col-sm-2 control-label" for="{{identityProvider.identityProvider.id}}retrieveToken">Can Retrieve Token&nbsp;<span tooltip-placement="right" tooltip="If disabled, the client can not retrieve tokens from the identity provider." class="fa fa-info-circle"></span></label>
<div class="col-sm-4">
<input ng-model="application.identityProviders[$index].retrieveToken" name="identityProvider.identityProvider.id + 'retrieveToken'" id="identityProvider.identityProvider.id + 'retrieveToken'" value="true" onoffswitchmodel />
<input ng-model="client.identityProviders[$index].retrieveToken" name="identityProvider.identityProvider.id + 'retrieveToken'" id="identityProvider.identityProvider.id + 'retrieveToken'" value="true" onoffswitchmodel />
</div>
</div>
</div>

View File

@@ -1,11 +1,11 @@
<div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="resourceUrl + '/partials/realm-menu.html'"></div>
<div id="content-area" class="col-md-9" role="main">
<ul class="nav nav-tabs nav-tabs-pf">
<li class="active"><a href="">Application Import</a></li>
<li class="active"><a href="">Client Import</a></li>
</ul>
<h2></h2>
<div id="content">
<h2><span>{{application.name}}</span> Application Import <span tooltip-placement="right" tooltip="Helper utility for importing application definitions from various formats." class="fa fa-info-circle"></span></h2>
<h2><span>{{client.clientId}}</span> Client Import <span tooltip-placement="right" tooltip="Helper utility for importing client definitions from various formats." class="fa fa-info-circle"></span></h2>
<form class="form-horizontal" name="realmForm" novalidate>
<fieldset class="border-top">
<div class="form-group input-select">

View File

@@ -1,14 +1,14 @@
<div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="resourceUrl + '/partials/realm-menu.html'"></div>
<div id="content-area" class="col-md-9" role="main">
<kc-navigation-application></kc-navigation-application>
<kc-navigation-client></kc-navigation-client>
<div id="content">
<ol class="breadcrumb" data-ng-hide="create">
<li><a href="#/realms/{{realm.realm}}/applications">Applications</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}">{{application.name}}</a></li>
<li><a href="#/realms/{{realm.realm}}/clients">Clients</a></li>
<li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li>
<li class="active">Installation</li>
</ol>
<h2><span>{{application.name}}</span> Adapter Installation <span tooltip-placement="right" tooltip="Helper utility for generating various client adapter configuration formats which you can download or cut and paste to configure your client applications." class="fa fa-info-circle"></span></h2>
<h2><span>{{client.clientId}}</span> Adapter Installation <span tooltip-placement="right" tooltip="Helper utility for generating various client adapter configuration formats which you can download or cut and paste to configure your clients." class="fa fa-info-circle"></span></h2>
<form class="form-horizontal" name="realmForm" novalidate>
<fieldset class="border-top">
<div class="form-group input-select">

View File

@@ -1,13 +1,13 @@
<div class="bs-sidebar col-sm-3 " data-ng-include data-src="resourceUrl + '/partials/realm-menu.html'"></div>
<div id="content-area" class="col-sm-9" role="main">
<kc-navigation-application></kc-navigation-application>
<kc-navigation-client></kc-navigation-client>
<div id="content">
<ol class="breadcrumb" data-ng-hide="create">
<li><a href="#/realms/{{realm.realm}}/applications">Applications</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}">{{application.name}}</a></li>
<li><a href="#/realms/{{realm.realm}}/clients">Clients</a></li>
<li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li>
<li class="active">Keys</li>
</ol>
<h2><span>{{application.name}}</span> Key Pair and Certificate <span tooltip-placement="right" tooltip="Application's key pair and certificate. Used for more confidential interaction between application and auth server." class="fa fa-info-circle"></span></h2>
<h2><span>{{client.clientId}}</span> Key Pair and Certificate <span tooltip-placement="right" tooltip="Clients's key pair and certificate. Used for more confidential interaction between client and auth server." class="fa fa-info-circle"></span></h2>
<form class="form-horizontal" name="keyForm" novalidate kc-read-only="!access.manageRealm">
<fieldset>
<legend collapsed><span class="text">Import Keys and Cert</span> <span tooltip-placement="right" tooltip="Upload the client's key pair and cert." class="fa fa-info-circle"></span></legend>
@@ -62,7 +62,7 @@
</div>
</fieldset>
<fieldset class="form-group col-sm-10" data-ng-hide="!keyInfo.privateKey">
<legend collapsed><span class="text">Download Keys and Cert</span> <span tooltip-placement="right" tooltip="Client key pair, cert, and realm certificate will be stuffed into a PKCS12 or Java keystore that you can use in your applications." class="fa fa-info-circle"></span></legend>
<legend collapsed><span class="text">Download Keys and Cert</span> <span tooltip-placement="right" tooltip="Client key pair, cert, and realm certificate will be stuffed into a PKCS12 or Java keystore that you can use in your clients." class="fa fa-info-circle"></span></legend>
<div class="form-group">
<label class="col-sm-2 control-label" for="downloadKeyFormat">Archive Format</label>
<div class="col-sm-6">

View File

@@ -0,0 +1,47 @@
<div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="resourceUrl + '/partials/realm-menu.html'"></div>
<div id="content-area" class="col-md-9" role="main">
<h2></h2>
<div id="content">
<h2><span>{{realm.realm}}</span> Clients <span tooltip-placement="right" tooltip="Clients are trusted browser apps and web services in a realm. These clients can request a login. You can also define client specific roles." class="fa fa-info-circle"></span></h2>
<table class="table table-striped table-bordered">
<thead>
<tr>
<th class="kc-table-actions" colspan="3">
<div class="search-comp clearfix">
<input type="text" placeholder="Search..." class="form-control search" data-ng-model="search.clientId"
onkeyup="if(event.keyCode == 13){$(this).next('button').click();}">
<button type="submit" class="kc-icon-search" tooltip-placement="right"
tooltip="Search by client clientId.">
Icon: search
</button>
</div>
<div class="pull-right">
<a class="btn btn-primary" href="#/import/client/{{realm.realm}}" data-ng-show="importButton">Import</a>
<a class="btn btn-primary" href="#/create/client/{{realm.realm}}">Create</a>
</div>
</th>
</tr>
<tr data-ng-hide="clients.length == 0">
<th>Client ID</th>
<th>Enabled</th>
<th>Base URL</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="client in clients | filter:search">
<td><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></td>
<td>{{client.enabled}}</td>
<td ng-class="{'text-muted': !client.baseUrl}">
<a href="{{client.baseUrl}}" data-ng-show="client.baseUrl">{{client.baseUrl}}</a>
<span data-ng-hide="client.baseUrl">Not defined</span>
</tr>
<tr data-ng-show="clients.length == 0">
<td>No clients available</td>
</tr>
</tbody>
</table>
<div class="feedback warning inline" data-ng-show="search && clients.length == 0">
<p><strong>Your search returned no results.</strong><br>Try modifying the query and try again.</p>
</div>
</div>
</div>

View File

@@ -1,14 +1,14 @@
<div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="resourceUrl + '/partials/realm-menu.html'"></div>
<div id="content-area" class="col-md-9" role="main">
<kc-navigation-application></kc-navigation-application>
<kc-navigation-client></kc-navigation-client>
<div id="content">
<ol class="breadcrumb" data-ng-hide="create">
<li><a href="#/realms/{{realm.realm}}/applications">Applications</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}">{{application.name}}</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}/mappers">{{application.name}} Mappers</a></li>
<li><a href="#/realms/{{realm.realm}}/clients">Clients</a></li>
<li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li>
<li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/mappers">{{client.clientId}} Mappers</a></li>
<li class="active">Add Builtin Protocol Mappers</li>
</ol>
<h2><span>{{realm.realm}} </span>Add Builtin Protocol Mappers <span tooltip-placement="right" tooltip="Protocol mappers perform transformation on tokens and documents. They an do things like map user data into protocol claims, or just transform any requests going between the application and auth server." class="fa fa-info-circle"></span></h2>
<h2><span>{{realm.realm}} </span>Add Builtin Protocol Mappers <span tooltip-placement="right" tooltip="Protocol mappers perform transformation on tokens and documents. They an do things like map user data into protocol claims, or just transform any requests going between the client and auth server." class="fa fa-info-circle"></span></h2>
<table class="table table-striped table-bordered">
<thead>
<tr>

View File

@@ -1,13 +1,13 @@
<div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="resourceUrl + '/partials/realm-menu.html'"></div>
<div id="content-area" class="col-md-9" role="main">
<kc-navigation-application></kc-navigation-application>
<kc-navigation-client></kc-navigation-client>
<div id="content">
<ol class="breadcrumb" data-ng-hide="create">
<li><a href="#/realms/{{realm.realm}}/applications">Applications</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}">{{application.name}}</a></li>
<li><a href="#/realms/{{realm.realm}}/clients">Clients</a></li>
<li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li>
<li class="active">Protocol Mappers</li>
</ol>
<h2><span>{{realm.realm}} </span> {{application.name}} {{application.protocol}} Protocol Mappers <span tooltip-placement="right" tooltip="Protocol mappers perform transformation on tokens and documents. They an do things like map user data into protocol claims, or just transform any requests going between the application and auth server." class="fa fa-info-circle"></span></h2>
<h2><span>{{realm.realm}} </span> {{client.clientId}} {{client.protocol}} Protocol Mappers <span tooltip-placement="right" tooltip="Protocol mappers perform transformation on tokens and documents. They an do things like map user data into protocol claims, or just transform any requests going between the client and auth server." class="fa fa-info-circle"></span></h2>
<table class="table table-striped table-bordered">
<thead>
<tr>
@@ -21,8 +21,8 @@
</button>
</div>
<div class="pull-right">
<a class="btn btn-primary" href="#/create/application/{{realm.realm}}/{{application.id}}/mappers">Create</a>
<a class="btn btn-primary" href="#/realms/{{realm.realm}}/applications/{{application.id}}/add-mappers">Add Builtin</a>
<a class="btn btn-primary" href="#/create/client/{{realm.realm}}/{{client.id}}/mappers">Create</a>
<a class="btn btn-primary" href="#/realms/{{realm.realm}}/clients/{{client.id}}/add-mappers">Add Builtin</a>
</div>
</th>
</tr>
@@ -34,7 +34,7 @@
</thead>
<tbody>
<tr ng-repeat="mapper in mappers | filter:search">
<td><a href="#/realms/{{realm.realm}}/applications/{{application.id}}/mappers/{{mapper.id}}">{{mapper.name}}</a></td>
<td><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/mappers/{{mapper.id}}">{{mapper.name}}</a></td>
<td>{{mapperTypes[mapper.protocolMapper].category}}</td>
<td>{{mapperTypes[mapper.protocolMapper].name}}</td>
</tr>

View File

@@ -1,13 +1,13 @@
<div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="resourceUrl + '/partials/realm-menu.html'"></div>
<div id="content-area" class="col-md-9" role="main">
<kc-navigation-application></kc-navigation-application>
<kc-navigation-client></kc-navigation-client>
<div id="content">
<ol class="breadcrumb">
<li><a href="#/realms/{{realm.realm}}/applications">Applications</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}">{{application.name}}</a></li>
<li><a href="#/realms/{{realm.realm}}/clients">Clients</a></li>
<li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li>
<li class="active">Revocation</li>
</ol>
<h2 data-ng-hide="create"><span>{{application.name}}</span> Revocation Policies</h2>
<h2 data-ng-hide="create"><span>{{client.clientId}}</span> Revocation Policies</h2>
<form class="form-horizontal" name="credentialForm" novalidate kc-read-only="!access.manageRealm">
<fieldset class="border-top">
<div class="form-group">
@@ -15,7 +15,7 @@
<div class="col-sm-4">
<input ng-disabled="true" class="form-control" type="text" id="notBefore" name="notBefore" data-ng-model="notBefore" autofocus>
</div>
<span tooltip-placement="right" tooltip="Revoke any tokens issued before this date for this application." class="fa fa-info-circle"></span>
<span tooltip-placement="right" tooltip="Revoke any tokens issued before this date for this client." class="fa fa-info-circle"></span>
</div>
</fieldset>
<div class="pull-right form-actions" data-ng-show="access.manageClients">
@@ -23,7 +23,7 @@
</button>
<button type="submit" data-ng-click="setNotBeforeNow()" class="btn btn-primary btn-lg">Set To Now
</button>
<button type="submit" data-ng-click="pushRevocation()" class="btn btn-primary btn-lg" tooltip="If admin URL is configured for this application, push this policy to that application." tooltip-placement="bottom">Push
<button type="submit" data-ng-click="pushRevocation()" class="btn btn-primary btn-lg" tooltip="If admin URL is configured for this client, push this policy to that client." tooltip-placement="bottom">Push
</button>
</div>
</form>

View File

@@ -1,23 +1,23 @@
<div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="resourceUrl + '/partials/realm-menu.html'"></div>
<div id="content-area" class="col-md-9" role="main">
<kc-navigation-application></kc-navigation-application>
<kc-navigation-client></kc-navigation-client>
<div id="content">
<ol class="breadcrumb" data-ng-show="create">
<li><a href="#/realms/{{realm.realm}}/applications">Applications</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}">{{application.name}}</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}/roles">Roles</a></li>
<li><a href="#/realms/{{realm.realm}}/clients">Clients</a></li>
<li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li>
<li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/roles">Roles</a></li>
<li class="active">Add role</li>
</ol>
<ol class="breadcrumb" data-ng-hide="create">
<li><a href="#/realms/{{realm.realm}}/applications">Applications</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}">{{application.name}}</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}/roles">Roles</a></li>
<li><a href="#/realms/{{realm.realm}}/clients">Clients</a></li>
<li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li>
<li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/roles">Roles</a></li>
<li class="active">{{role.name}}</li>
</ol>
<h2 data-ng-hide="create" class="pull-left"><span>{{application.name}}</span> {{role.name}} Application Role</h2>
<h2 data-ng-show="create" class="pull-left"><span>{{application.name}}</span> Add Application Role</h2>
<h2 data-ng-hide="create" class="pull-left"><span>{{client.clientId}}</span> {{role.name}} Client Role</h2>
<h2 data-ng-show="create" class="pull-left"><span>{{client.clientId}}</span> Add Client Role</h2>
<p class="subtitle" data-ng-show="create"><span class="required">*</span> Required fields</p>
<form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageClients">
@@ -81,45 +81,45 @@
</div>
</fieldset>
<fieldset ng-show="applications.length > 0 && !create && (compositeSwitch || role.composite)">
<legend uncollapsed><span class="text">Composite Application Roles</span> </legend>
<fieldset ng-show="clients.length > 0 && !create && (compositeSwitch || role.composite)">
<legend uncollapsed><span class="text">Composite Client Roles</span> </legend>
<div class="form-group input-select">
<label class="col-sm-2 control-label" for="applications">Application <span tooltip-placement="right" tooltip="Select an application to view/modify roles associated with this composite." class="fa fa-info-circle"></span></label>
<label class="col-sm-2 control-label" for="clients">Client <span tooltip-placement="right" tooltip="Select an client to view/modify roles associated with this composite." class="fa fa-info-circle"></span></label>
<div class="col-sm-4">
<div class="input-group">
<div class="select-kc">
<select id="applications" name="applications" ng-change="changeApplication()" ng-model="compositeApp" ng-options="a.name for a in applications">
<option value="" selected> Select an Application...</option>
<select id="clients" name="clients" ng-change="changeClient()" ng-model="compositeClient" ng-options="c.clientId for c in clients">
<option value="" selected> Select a Client...</option>
</select>
</div>
</div>
</div>
</div>
<div class="form-group" ng-show="compositeApp">
<div class="controls changing-selectors application col-sm-10">
<div class="form-group" ng-show="compositeClient">
<div class="controls changing-selectors client col-sm-10">
<div class="select-title">
<label class="control-label" for="available-app">Available Roles <span tooltip-placement="right" tooltip="Roles from this application that you can associate to this composite role." class="fa fa-info-circle"></span></label>
<select id="available-app" class="form-control" multiple size="5"
<label class="control-label" for="available-client">Available Roles <span tooltip-placement="right" tooltip="Roles from this client that you can associate to this composite role." class="fa fa-info-circle"></span></label>
<select id="available-client" class="form-control" multiple size="5"
ng-multiple="true"
ng-model="selectedApplicationRoles"
ng-options="r.name for r in applicationRoles">
ng-model="selectedClientRoles"
ng-options="r.name for r in clientRoles">
</select>
</div>
<div class="middle-buttons kc-vertical">
<button class="btn btn-default" type="submit" ng-click="addApplicationRole()" tooltip="Associate role" tooltip-placement="right">
<button class="btn btn-default" type="submit" ng-click="addClientRole()" tooltip="Associate role" tooltip-placement="right">
<span class="kc-icon-arrow-right">Move right</span>
</button>
<button class="btn btn-default" type="submit" ng-click="deleteApplicationRole()" tooltip="Disassociate role" tooltip-placement="left">
<button class="btn btn-default" type="submit" ng-click="deleteClientRole()" tooltip="Disassociate role" tooltip-placement="left">
<span class="kc-icon-arrow-left">Move left</span>
</button>
</div>
<div class="select-title">
<label class="control-label" for="assigned-app">Associated Roles <span tooltip-placement="right" tooltip="Application roles associated with this composite role." class="fa fa-info-circle"></span></label>
<select id="assigned-app" class="form-control" multiple size=5
<label class="control-label" for="assigned-client">Associated Roles <span tooltip-placement="right" tooltip="Client roles associated with this composite role." class="fa fa-info-circle"></span></label>
<select id="assigned-client" class="form-control" multiple size=5
ng-multiple="true"
ng-model="selectedApplicationMappings"
ng-options="r.name for r in applicationMappings">
ng-model="selectedClientMappings"
ng-options="r.name for r in clientMappings">
</select>
</div>
</div>

View File

@@ -1,20 +1,20 @@
<div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="resourceUrl + '/partials/realm-menu.html'"></div>
<div id="content-area" class="col-md-9" role="main">
<kc-navigation-application></kc-navigation-application>
<kc-navigation-client></kc-navigation-client>
<div id="content">
<ol class="breadcrumb" data-ng-hide="create">
<li><a href="#/realms/{{realm.realm}}/applications">Applications</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}">{{application.name}}</a></li>
<li><a href="#/realms/{{realm.realm}}/clients">Clients</a></li>
<li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li>
<li class="active">Roles</li>
</ol>
<h2><span>{{application.name}}</span> Application Roles</h2>
<h2><span>{{client.clientId}}</span> Client Roles</h2>
<table class="table table-striped table-bordered">
<thead>
<tr>
<th class="kc-table-actions" colspan="3" data-ng-show="access.manageClients">
<div class="pull-right">
<a class="btn btn-primary" href="#/create/role/{{realm.realm}}/applications/{{application.id}}">Add Role</a>
<a class="btn btn-primary" href="#/create/role/{{realm.realm}}/clients/{{client.id}}">Add Role</a>
<!-- <button class="remove disabled">Remove</button> -->
</div>
</th>
@@ -52,12 +52,12 @@
-->
<tbody>
<tr ng-repeat="role in roles">
<td><a href="#/realms/{{realm.realm}}/applications/{{application.id}}/roles/{{role.id}}">{{role.name}}</a></td>
<td><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/roles/{{role.id}}">{{role.name}}</a></td>
<td>{{role.composite}}</td>
<td>{{role.description}}</td>
</tr>
<tr data-ng-show="!roles || roles.length == 0">
<td>No application roles available</td>
<td>No client roles available</td>
</tr>
</tbody>
</table>

View File

@@ -1,14 +1,14 @@
<div class="bs-sidebar col-sm-3 " data-ng-include data-src="resourceUrl + '/partials/realm-menu.html'"></div>
<div id="content-area" class="col-sm-9" role="main">
<kc-navigation-application></kc-navigation-application>
<kc-navigation-client></kc-navigation-client>
<div id="content">
<ol class="breadcrumb" data-ng-hide="create">
<li><a href="#/realms/{{realm.realm}}/applications">Applications</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}">{{application.name}}</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}/saml/keys">SAML Keys</a></li>
<li><a href="#/realms/{{realm.realm}}/clients">Clients</a></li>
<li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li>
<li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/saml/keys">SAML Keys</a></li>
<li class="active">SAML {{keyType}} Key Export</li>
</ol>
<h2><span>{{application.name}}</span> SAML {{keyType}} Key Export <span tooltip-placement="right" tooltip="Export Appliations key and certificate to file." class="fa fa-info-circle"></span></h2>
<h2><span>{{client.clientId}}</span> SAML {{keyType}} Key Export <span tooltip-placement="right" tooltip="Export Client key and certificate to file." class="fa fa-info-circle"></span></h2>
<form class="form-horizontal" name="keyForm" novalidate kc-read-only="!access.manageRealm">
<fieldset class="form-group col-sm-10">
<div class="form-group">

View File

@@ -1,14 +1,14 @@
<div class="bs-sidebar col-sm-3 " data-ng-include data-src="resourceUrl + '/partials/realm-menu.html'"></div>
<div id="content-area" class="col-sm-9" role="main">
<kc-navigation-application></kc-navigation-application>
<kc-navigation-client></kc-navigation-client>
<div id="content">
<ol class="breadcrumb" data-ng-hide="create">
<li><a href="#/realms/{{realm.realm}}/applications">Applications</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}">{{application.name}}</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}/saml/keys">SAML Keys</a></li>
<li><a href="#/realms/{{realm.realm}}/clients">Clients</a></li>
<li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li>
<li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/saml/keys">SAML Keys</a></li>
<li class="active">SAML {{keyType}} Key Import</li>
</ol>
<h2><span>{{application.name}}</span> SAML {{keyType}} Key Import <span tooltip-placement="right" tooltip="Upload Key." class="fa fa-info-circle"></span></h2>
<h2><span>{{client.clientId}}</span> SAML {{keyType}} Key Import <span tooltip-placement="right" tooltip="Upload Key." class="fa fa-info-circle"></span></h2>
<form class="form-horizontal" name="keyForm" novalidate kc-read-only="!access.manageRealm">
<fieldset>
<div class="form-group">

View File

@@ -1,15 +1,15 @@
<div class="bs-sidebar col-sm-3 " data-ng-include data-src="resourceUrl + '/partials/realm-menu.html'"></div>
<div id="content-area" class="col-sm-9" role="main">
<kc-navigation-application></kc-navigation-application>
<kc-navigation-client></kc-navigation-client>
<div id="content">
<ol class="breadcrumb" data-ng-hide="create">
<li><a href="#/realms/{{realm.realm}}/applications">Applications</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}">{{application.name}}</a></li>
<li><a href="#/realms/{{realm.realm}}/clients">Clients</a></li>
<li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li>
<li class="active">SAML Keys</li>
</ol>
<h2><span>{{application.name}}</span> SAML Keys <span tooltip-placement="right" tooltip="Application certificates used to sign and encrypt documents." class="fa fa-info-circle"></span></h2>
<h2><span>{{client.clientId}}</span> SAML Keys <span tooltip-placement="right" tooltip="Client certificates used to sign and encrypt documents." class="fa fa-info-circle"></span></h2>
<form class="form-horizontal" name="keyForm" novalidate kc-read-only="!access.manageRealm">
<fieldset class="form-group col-sm-10" data-ng-show="application.attributes['saml.client.signature'] == 'true'">
<fieldset class="form-group col-sm-10" data-ng-show="client.attributes['saml.client.signature'] == 'true'">
<legend uncollapsed><span class="text">Signing Key</span> <span tooltip-placement="right" tooltip="SAML Signing Key." class="fa fa-info-circle"></span></legend>
<div class="form-group" data-ng-hide="!signingKeyInfo.privateKey">
<label class="col-sm-2 control-label" for="signingPrivateKey">Private key</label>
@@ -35,7 +35,7 @@
</div>
</div>
</fieldset>
<fieldset class="form-group col-sm-10" data-ng-show="application.attributes['saml.encrypt'] == 'true'">
<fieldset class="form-group col-sm-10" data-ng-show="client.attributes['saml.encrypt'] == 'true'">
<legend uncollapsed><span class="text">Encryption Key</span> <span tooltip-placement="right" tooltip="SAML Encryption Key." class="fa fa-info-circle"></span></legend>
<div class="form-group" data-ng-hide="!encryptionKeyInfo.privateKey">
<label class="col-sm-2 control-label" for="encryptionPrivateKey">Private key</label>

View File

@@ -1,28 +1,28 @@
<div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="resourceUrl + '/partials/realm-menu.html'"></div>
<div id="content-area" class="col-md-9" role="main">
<kc-navigation-application></kc-navigation-application>
<kc-navigation-client></kc-navigation-client>
<div id="content">
<ol class="breadcrumb" data-ng-hide="create">
<li><a href="#/realms/{{realm.realm}}/applications">Applications</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}">{{application.name}}</a></li>
<li><a href="#/realms/{{realm.realm}}/clients">Clients</a></li>
<li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li>
<li class="active">Scope</li>
</ol>
<h2><span>{{application.name}}</span> Scope Mappings <span tooltip-placement="right" tooltip="Scope mappings allow you to restrict which user role mappings are included within the access token requested by the application." class="fa fa-info-circle"></span></h2>
<h2><span>{{client.clientId}}</span> Scope Mappings <span tooltip-placement="right" tooltip="Scope mappings allow you to restrict which user role mappings are included within the access token requested by the client." class="fa fa-info-circle"></span></h2>
<p class="subtitle"></p>
<form class="form-horizontal" name="allowScope" novalidate kc-read-only="!access.manageClients">
<fieldset class="border-top">
<div class="form-group">
<label class="col-sm-2 control-label" for="fullScopeAllowed">Full Scope Allowed</label>
<div class="col-sm-4">
<input ng-model="application.fullScopeAllowed" ng-click="changeFullScopeAllowed()" name="fullScopeAllowed" id="fullScopeAllowed" onoffswitch />
<input ng-model="client.fullScopeAllowed" ng-click="changeFullScopeAllowed()" name="fullScopeAllowed" id="fullScopeAllowed" onoffswitch />
</div>
<span tooltip-placement="right" tooltip="Allows you to disable all restrictions." class="fa fa-info-circle"></span>
</div>
</fieldset>
</form>
<form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageClients" data-ng-show="!application.fullScopeAllowed">
<form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageClients" data-ng-show="!client.fullScopeAllowed">
<fieldset>
<legend><span class="text">Realm Roles</span> <span tooltip-placement="right" tooltip="Realm level roles assigned to scope." class="fa fa-info-circle"></span></legend>
<div class="form-group col-sm-10">
@@ -66,56 +66,56 @@
</div>
</fieldset>
<fieldset ng-show="applications.length > 0">
<legend><span class="text">Application Roles</span> </legend>
<fieldset ng-show="clients.length > 0">
<legend><span class="text">Client Roles</span> </legend>
<div class="form-group input-select">
<label class="col-sm-2 control-label" for="applications">Application <span tooltip-placement="right" tooltip="Select an application to view or modify additional roles to assign." class="fa fa-info-circle"></span></label>
<label class="col-sm-2 control-label" for="clients">Client <span tooltip-placement="right" tooltip="Select a client to view or modify additional roles to assign." class="fa fa-info-circle"></span></label>
<div class="col-sm-4">
<div class="input-group">
<div class="select-kc">
<select id="applications" name="applications" ng-change="changeApplication()" ng-model="targetApp" ng-options="a.name for a in (applications|remove:application:'id')" ng-disabled="false">
<option value="" selected> Select an Application </option>
<select id="clients" name="clients" ng-change="changeClient()" ng-model="targetClient" ng-options="a.clientId for a in (clients|remove:client:'id')" ng-disabled="false">
<option value="" selected> Select a Client </option>
</select>
</div>
</div>
</div>
</div>
<div class="form-group" ng-show="targetApp">
<div class="form-group" ng-show="targetClient">
<div class="controls changing-selectors col-sm-10">
<div class="select-title">
<label class="control-label" for="app-available">Available Roles <span tooltip-placement="right" tooltip="Application roles available to be assigned." class="fa fa-info-circle"></span></label>
<select id="app-available" class="form-control" multiple size="5"
<label class="control-label" for="client-available">Available Roles <span tooltip-placement="right" tooltip="Client roles available to be assigned." class="fa fa-info-circle"></span></label>
<select id="client-available" class="form-control" multiple size="5"
ng-multiple="true"
ng-model="selectedApplicationRoles"
ng-options="r.name for r in applicationRoles">
ng-model="selectedClientRoles"
ng-options="r.name for r in clientRoles">
</select>
</div>
<div class="middle-buttons kc-vertical">
<button class="btn btn-default" type="submit" ng-click="addApplicationRole()" tooltip="Assign role" tooltip-placement="right">
<button class="btn btn-default" type="submit" ng-click="addClientRole()" tooltip="Assign role" tooltip-placement="right">
<span class="kc-icon-arrow-right">Move right</span>
</button>
<button class="btn btn-default" type="submit" ng-click="deleteApplicationRole()" tooltip="Unassign role" tooltip-placement="left">
<button class="btn btn-default" type="submit" ng-click="deleteClientRole()" tooltip="Unassign role" tooltip-placement="left">
<span class="kc-icon-arrow-left">Move left</span>
</button>
</div>
<div class="select-title">
<label class="control-label" for="app-assigned">Assigned Roles <span tooltip-placement="right" tooltip="Assigned application roles." class="fa fa-info-circle"></span></label>
<select id="app-assigned" class="form-control" multiple size=5
<label class="control-label" for="client-assigned">Assigned Roles <span tooltip-placement="right" tooltip="Assigned client roles." class="fa fa-info-circle"></span></label>
<select id="client-assigned" class="form-control" multiple size=5
ng-multiple="true"
ng-model="selectedApplicationMappings"
ng-options="r.name for r in applicationMappings">
ng-model="selectedClientMappings"
ng-options="r.name for r in clientMappings">
</select>
</div>
<div class="middle-buttons">
-
</div>
<div class="select-title">
<label class="control-label" for="app-composite">Effective Roles <span tooltip-placement="right" tooltip="Assigned application roles that may have been inherited from a composite role." class="fa fa-info-circle"></span></label>
<select id="app-composite" class="form-control" multiple size=5
<label class="control-label" for="client-composite">Effective Roles <span tooltip-placement="right" tooltip="Assigned client roles that may have been inherited from a composite role." class="fa fa-info-circle"></span></label>
<select id="client-composite" class="form-control" multiple size=5
ng-disabled="true"
ng-model="dummymodel"
ng-options="r.name for r in applicationComposite">
ng-options="r.name for r in clientComposite">
</select>
</div>
</div>

View File

@@ -1,13 +1,13 @@
<div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="resourceUrl + '/partials/realm-menu.html'"></div>
<div id="content-area" class="col-md-9" role="main">
<kc-navigation-application></kc-navigation-application>
<kc-navigation-client></kc-navigation-client>
<div id="content">
<ol class="breadcrumb" data-ng-hide="create">
<li><a href="#/realms/{{realm.realm}}/applications">Applications</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}">{{application.name}}</a></li>
<li class="active">Application Sessions</li>
<li><a href="#/realms/{{realm.realm}}/clients">Clients</a></li>
<li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li>
<li class="active">Client Sessions</li>
</ol>
<h2><span>{{application.name}}</span> Active Sessions <span tooltip-placement="right" tooltip="View active sessions for this application. Allows you to see which users are active and when they logged in." class="fa fa-info-circle"></span></h2>
<h2><span>{{client.clientId}}</span> Active Sessions <span tooltip-placement="right" tooltip="View active sessions for this client. Allows you to see which users are active and when they logged in." class="fa fa-info-circle"></span></h2>
<form class="form-horizontal" name="sessionStats">
<fieldset class="border-top">
<div class="form-group">
@@ -15,7 +15,7 @@
<div class="col-sm-4">
<input class="form-control" type="text" id="activeSessions" name="activeSessions" data-ng-model="count" ng-disabled="true">
</div>
<span tooltip-placement="right" tooltip="Total number of active user sessions for this application." class="fa fa-info-circle"></span>
<span tooltip-placement="right" tooltip="Total number of active user sessions for this client." class="fa fa-info-circle"></span>
</div>
</fieldset>
</form>

View File

@@ -1,18 +1,18 @@
<div class="bs-sidebar col-sm-3 " data-ng-include data-src="resourceUrl + '/partials/realm-menu.html'"></div>
<div id="content-area" class="col-sm-9" role="main">
<kc-navigation-application></kc-navigation-application>
<kc-navigation-client></kc-navigation-client>
<div id="content">
<ol class="breadcrumb" data-ng-show="create">
<li><a href="#/realms/{{realm.realm}}/applications">Applications</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}">{{application.name}}</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}/mappers">Protocol Mappers</a></li>
<li><a href="#/realms/{{realm.realm}}/clients">Clients</a></li>
<li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li>
<li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/mappers">Protocol Mappers</a></li>
<li class="active">Create Protocol Mapper</li>
</ol>
<ol class="breadcrumb" data-ng-hide="create">
<li><a href="#/realms/{{realm.realm}}/applications">Applications</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}">{{application.name}}</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}/mappers">Protocol Mappers</a></li>
<li><a href="#/realms/{{realm.realm}}/clients">Clients</a></li>
<li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li>
<li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/mappers">Protocol Mappers</a></li>
<li class="active">{{mapper.name}}</li>
</ol>
<h2 class="pull-left" data-ng-hide="create">{{mapper.name}} Protocol Mapper</h2>

View File

@@ -12,7 +12,7 @@
<div class="col-sm-4">
<input ng-model="realm.realmCacheEnabled" name="realmCacheEnabled" id="realmCacheEnabled" onoffswitch />
</div>
<span tooltip-placement="right" tooltip="Enable/disable cache for realm, application, oauth client, and role data." class="fa fa-info-circle"></span>
<span tooltip-placement="right" tooltip="Enable/disable cache for realm, client and role data." class="fa fa-info-circle"></span>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="userCacheEnabled">User Cache Enabled</label>

View File

@@ -40,45 +40,45 @@
</div>
</fieldset>
<fieldset ng-show="applications.length > 0">
<legend><span class="text">Application Default Roles</span> </legend>
<fieldset ng-show="clients.length > 0">
<legend><span class="text">Client Default Roles</span> </legend>
<div class="form-group input-select">
<label class="col-sm-2 control-label" for="applications">Application <span tooltip-placement="top" tooltip="Select an application to view/modify assigned default roles." class="fa fa-info-circle"></span></label>
<label class="col-sm-2 control-label" for="clients">Client <span tooltip-placement="top" tooltip="Select an client to view/modify assigned default roles." class="fa fa-info-circle"></span></label>
<div class="col-sm-4">
<div class="input-group">
<div class="select-kc">
<select id="applications" name="applications" ng-change="changeApplication()" ng-model="application" ng-options="a.name for a in applications" ng-disabled="false">
<option value="" selected> Select an Application...</option>
<select id="clients" name="clients" ng-change="changeClient()" ng-model="client" ng-options="a.clientId for a in clients" ng-disabled="false">
<option value="" selected> Select a Client...</option>
</select>
</div>
</div>
</div>
</div>
<div class="form-group" ng-show="application">
<div class="form-group" ng-show="client">
<div class="controls changing-selectors col-sm-10">
<div class="select-title">
<label class="control-label" for="available-app">Available Roles <span tooltip-placement="right" tooltip="Roles from this application that are assignable as a default." class="fa fa-info-circle"></span></label>
<select id="available-app" class="form-control" multiple size="5"
<label class="control-label" for="available-client">Available Roles <span tooltip-placement="right" tooltip="Roles from this client that are assignable as a default." class="fa fa-info-circle"></span></label>
<select id="available-client" class="form-control" multiple size="5"
ng-multiple="true"
ng-model="selectedAppRoles"
ng-options="r for r in availableAppRoles">
ng-model="selectedClientRoles"
ng-options="r for r in availableClientRoles">
</select>
</div>
<div class="middle-buttons">
<button class="btn btn-default" type="submit" ng-click="addAppDefaultRole()" tooltip="Assign role" tooltip-placement="right">
<button class="btn btn-default" type="submit" ng-click="addClientDefaultRole()" tooltip="Assign role" tooltip-placement="right">
<span class="kc-icon-arrow-right"><span>Move right</span></span>
</button>
<button class="btn btn-default" type="submit" ng-click="rmAppDefaultRole()" tooltip="Unassign role" tooltip-placement="left">
<button class="btn btn-default" type="submit" ng-click="rmClientDefaultRole()" tooltip="Unassign role" tooltip-placement="left">
<span class="kc-icon-arrow-left"><span>Move left</span></span>
</button>
</div>
<div class="select-title">
<label class="control-label" for="assigned-app">Application Default Roles <span tooltip-placement="right" tooltip="Roles from this application assigned as a default role." class="fa fa-info-circle"></span></label>
<select id="assigned-app" class="form-control" multiple size=5
<label class="control-label" for="assigned-client">Client Default Roles <span tooltip-placement="right" tooltip="Roles from this client assigned as a default role." class="fa fa-info-circle"></span></label>
<select id="assigned-client" class="form-control" multiple size=5
ng-multiple="true"
ng-model="selectedAppDefRoles"
ng-options="r for r in application.defaultRoles">
ng-model="selectedClientDefRoles"
ng-options="r for r in client.defaultRoles">
</select>
</div>
</div>

View File

@@ -17,7 +17,7 @@
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="enabled">Enabled</label>
<span tooltip="Users and applications can only access a realm if it's enabled" class="fa fa-info-circle"></span>
<span tooltip="Users and clients can only access a realm if it's enabled" class="fa fa-info-circle"></span>
<div class="col-sm-4">
<input ng-model="realm.enabled" name="enabled" id="enabled" onoffswitch />
</div>

View File

@@ -98,7 +98,7 @@
<div class="col-sm-4">
<input class="form-control" id="clientId" type="text" ng-model="identityProvider.config.clientId" required>
</div>
<span tooltip-placement="right" tooltip="The client or application identifier registered withing the identity provider." class="fa fa-info-circle"></span>
<span tooltip-placement="right" tooltip="The client or client identifier registered withing the identity provider." class="fa fa-info-circle"></span>
</div>
<div class="form-group clearfix">
<label class="col-sm-2 control-label" for="clientSecret">Client Secret <span class="required">*</span></label>
@@ -108,7 +108,7 @@
<a href="" ng-click="showPassword(false)" class="link" ng-show="hidePassword">Show Secret</a>
<a href="" ng-click="showPassword(true);" ng-show="!hidePassword">Hide Secret</a>
</div>
<span tooltip-placement="right" tooltip="The client or application secret registered withing the identity provider." class="fa fa-info-circle"></span>
<span tooltip-placement="right" tooltip="The client or client secret registered withing the identity provider." class="fa fa-info-circle"></span>
</div>
<div class="form-group clearfix">
<label class="col-sm-2 control-label" for="issuer">Issuer </label>

View File

@@ -25,7 +25,7 @@
<div class="col-sm-4">
<input class="form-control" id="clientId" type="text" ng-model="identityProvider.config.clientId" required>
</div>
<span tooltip-placement="right" tooltip="The client or application identifier registered withing the identity provider." class="fa fa-info-circle"></span>
<span tooltip-placement="right" tooltip="The client identifier registered withing the identity provider." class="fa fa-info-circle"></span>
</div>
<div class="form-group clearfix">
<label class="col-sm-2 control-label" for="clientSecret">Client Secret <span class="required">*</span></label>
@@ -35,7 +35,7 @@
<a href="" ng-click="showPassword(false)" class="link" ng-show="hidePassword">Show Secret</a>
<a href="" ng-click="showPassword(true);" ng-show="!hidePassword">Hide Secret</a>
</div>
<span tooltip-placement="right" tooltip="The client or application secret registered withing the identity provider." class="fa fa-info-circle"></span>
<span tooltip-placement="right" tooltip="The client secret registered withing the identity provider." class="fa fa-info-circle"></span>
</div>
<div data-ng-include data-src="resourceUrl + '/partials/realm-identity-provider-' + identityProvider.providerId + '-ext.html'"></div>
<div class="form-group clearfix">

View File

@@ -3,5 +3,5 @@
<div class="col-sm-4">
<input class="form-control" id="clientId" type="text" ng-model="identityProvider.config.key" required>
</div>
<span tooltip-placement="right" tooltip="The Key obtained from Stack Overflow application registration." class="fa fa-info-circle"></span>
<span tooltip-placement="right" tooltip="The Key obtained from Stack Overflow client registration." class="fa fa-info-circle"></span>
</div>

View File

@@ -4,12 +4,12 @@
|| path[2] == 'login-settings'
|| path[2] == 'theme-settings'
|| path[2] == 'cache-settings'
|| path[2] == 'keys-settings' || path[2] == 'smtp-settings' || path[2] == 'ldap-settings' || path[2] == 'auth-settings') && path[3] != 'applications') && 'active'">
|| path[2] == 'keys-settings' || path[2] == 'smtp-settings' || path[2] == 'ldap-settings' || path[2] == 'auth-settings') && path[3] != 'clients') && 'active'">
<a href="#/realms/{{realm.realm}}">Settings</a>
</li>
<li data-ng-show="access.viewUsers" data-ng-class="(path[2] == 'users' || path[1] == 'user') && 'active'"><a href="#/realms/{{realm.realm}}/users">Users</a></li>
<li data-ng-show="access.viewClients" data-ng-class="(path[2] == 'applications' || path[1] == 'application' || path[3] == 'applications') && 'active'"><a href="#/realms/{{realm.realm}}/applications">Clients</a></li>
<li data-ng-show="access.viewRealm" data-ng-class="(path[2] == 'roles' || (path[1] == 'role' && path[3] != 'applications')) && 'active'"><a href="#/realms/{{realm.realm}}/roles">Roles</a></li>
<li data-ng-show="access.viewClients" data-ng-class="(path[2] == 'clients' || path[1] == 'client' || path[3] == 'clients') && 'active'"><a href="#/realms/{{realm.realm}}/clients">Clients</a></li>
<li data-ng-show="access.viewRealm" data-ng-class="(path[2] == 'roles' || (path[1] == 'role' && path[3] != 'clients')) && 'active'"><a href="#/realms/{{realm.realm}}/roles">Roles</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.viewRealm" data-ng-class="(path[2] == 'defense') && 'active'"><a href="#/realms/{{realm.realm}}/defense/headers">Security Defenses</a></li>
<li data-ng-show="access.viewEvents" data-ng-class="(path[2] == 'events' || path[2] == 'events-settings') && 'active'"><a href="#/realms/{{realm.realm}}/events">Events</a></li>

View File

@@ -90,8 +90,7 @@
</div>
</div>
</div>
<span tooltip-placement="right" tooltip="Max time an application or oauth client has to finish the access token protocol. This should normally be 1 minute." class="fa fa-info-circle"></span>
</div>
<span tooltip-placement="right" tooltip="Max time an client has to finish the access token protocol. This should normally be 1 minute." class="fa fa-info-circle"></span> </div>
<div class="form-group input-select">
<label class="col-sm-2 control-label" for="accessCodeLifespanLogin" class="two-lines">Login lifespan</label>
<div class="col-sm-5">

View File

@@ -74,45 +74,45 @@
</div>
</fieldset>
<fieldset ng-show="applications.length > 0 && !create && (compositeSwitch || role.composite)">
<legend uncollapsed class="collapsible"><span class="text">Composite Application Roles</span> </legend>
<fieldset ng-show="clients.length > 0 && !create && (compositeSwitch || role.composite)">
<legend uncollapsed class="collapsible"><span class="text">Composite Client Roles</span> </legend>
<div class="form-group input-select">
<label class="col-sm-2 control-label" for="applications">Application <span tooltip-placement="right" tooltip="Select an application to view/modify roles associated with this composite." class="fa fa-info-circle"></span>
<label class="col-sm-2 control-label" for="clients">Client <span tooltip-placement="right" tooltip="Select a client to view/modify roles associated with this composite." class="fa fa-info-circle"></span>
</label>
<div class="col-sm-4">
<div class="input-group">
<div class="select-kc">
<select id="applications" name="applications" ng-change="changeApplication()" ng-model="compositeApp" ng-options="a.name for a in applications" ng-disabled="false">
<option value="" selected> Select an Application...</option>
<select id="clients" name="clients" ng-change="changeClient()" ng-model="compositeClient" ng-options="a.clientId for a in clients" ng-disabled="false">
<option value="" selected> Select a Client...</option>
</select>
</div>
</div>
</div>
</div>
<div class="form-group" ng-show="compositeApp">
<div class="form-group" ng-show="compositeClient">
<div class="controls changing-selectors col-sm-10">
<div class="select-title">
<label class="control-label" for="available-app">Available Roles <span tooltip-placement="right" tooltip="Roles from this application that you can associate to this composite role." class="fa fa-info-circle"></span></label>
<select id="available-app" class="form-control" multiple size="5"
<label class="control-label" for="available-client">Available Roles <span tooltip-placement="right" tooltip="Roles from this client that you can associate to this composite role." class="fa fa-info-circle"></span></label>
<select id="available-client" class="form-control" multiple size="5"
ng-multiple="true"
ng-model="selectedApplicationRoles"
ng-options="r.name for r in applicationRoles">
ng-model="selectedClientRoles"
ng-options="r.name for r in clientRoles">
</select>
</div>
<div class="middle-buttons kc-vertical">
<button class="btn btn-default" type="submit" ng-click="addApplicationRole()" tooltip="Associate role" tooltip-placement="right">
<button class="btn btn-default" type="submit" ng-click="addClientRole()" tooltip="Associate role" tooltip-placement="right">
<span class="kc-icon-arrow-right">Move right</span>
</button>
<button class="btn btn-default" type="submit" ng-click="deleteApplicationRole()" tooltip="Disassociate role" tooltip-placement="left">
<button class="btn btn-default" type="submit" ng-click="deleteClientRole()" tooltip="Disassociate role" tooltip-placement="left">
<span class="kc-icon-arrow-left">Move left</span>
</button>
</div>
<div class="select-title">
<label class="control-label" for="assigned-app">Associated Roles <span tooltip-placement="right" tooltip="Application roles associated with this composite role." class="fa fa-info-circle"></span></label>
<select id="assigned-app" class="form-control" multiple size=5
<label class="control-label" for="assigned-client">Associated Roles <span tooltip-placement="right" tooltip="Client roles associated with this composite role." class="fa fa-info-circle"></span></label>
<select id="assigned-client" class="form-control" multiple size=5
ng-multiple="true"
ng-model="selectedApplicationMappings"
ng-options="r.name for r in applicationMappings">
ng-model="selectedClientMappings"
ng-options="r.name for r in clientMappings">
</select>
</div>
</div>

View File

@@ -63,56 +63,56 @@
</div>
</fieldset>
<fieldset ng-show="applications.length > 0">
<legend><span class="text">Application Roles</span> </legend>
<fieldset ng-show="clients.length > 0">
<legend><span class="text">Client Roles</span> </legend>
<div class="form-group input-select">
<label class="col-sm-2 control-label" for="applications">Application <span tooltip-placement="right" tooltip="Select an application to view or modify additional roles to map." class="fa fa-info-circle"></span></label>
<label class="col-sm-2 control-label" for="clients">Client <span tooltip-placement="right" tooltip="Select a client to view or modify additional roles to map." class="fa fa-info-circle"></span></label>
<div class="col-sm-4">
<div class="input-group">
<div class="select-kc">
<select id="applications" name="applications" ng-change="changeApplication()" ng-model="application" ng-options="a.name for a in applications" ng-disabled="false">
<option value="" selected> Select an Application...</option>
<select id="clients" name="clients" ng-change="changeClient()" ng-model="client" ng-options="a.clientId for a in clients" ng-disabled="false">
<option value="" selected> Select a Client...</option>
</select>
</div>
</div>
</div>
</div>
<div class="form-group" ng-show="application">
<div class="form-group" ng-show="client">
<div class="controls changing-selectors col-sm-10">
<div class="select-title">
<label class="control-label" for="available-app">Available Roles <span tooltip-placement="right" tooltip="Assignable roles from this application." class="fa fa-info-circle"></span></label>
<select id="available-app" class="form-control" multiple size="5"
<label class="control-label" for="available-client">Available Roles <span tooltip-placement="right" tooltip="Assignable roles from this client." class="fa fa-info-circle"></span></label>
<select id="available-client" class="form-control" multiple size="5"
ng-multiple="true"
ng-model="selectedApplicationRoles"
ng-options="r.name for r in applicationRoles">
ng-model="selectedClientRoles"
ng-options="r.name for r in clientRoles">
</select>
</div>
<div class="middle-buttons">
<button class="btn btn-default" type="submit" ng-click="addApplicationRole()" tooltip="Assign role" tooltip-placement="right">
<button class="btn btn-default" type="submit" ng-click="addClientRole()" tooltip="Assign role" tooltip-placement="right">
<span class="kc-icon-arrow-right">Move right</span>
</button>
<button class="btn btn-default" type="submit" ng-click="deleteApplicationRole()" tooltip="Unassign role" tooltip-placement="left">
<button class="btn btn-default" type="submit" ng-click="deleteClientRole()" tooltip="Unassign role" tooltip-placement="left">
<span class="kc-icon-arrow-left">Move left</span>
</button>
</div>
<div class="select-title">
<label class="control-label" for="assigned-app">Assigned Roles <span tooltip-placement="right" tooltip="Role mappings for this application." class="fa fa-info-circle"></span></label>
<select id="assigned-app" class="form-control" multiple size=5
<label class="control-label" for="assigned-client">Assigned Roles <span tooltip-placement="right" tooltip="Role mappings for this client." class="fa fa-info-circle"></span></label>
<select id="assigned-client" class="form-control" multiple size=5
ng-multiple="true"
ng-model="selectedApplicationMappings"
ng-options="r.name for r in applicationMappings">
ng-model="selectedClientMappings"
ng-options="r.name for r in clientMappings">
</select>
</div>
<div class="middle-buttons">
-
</div>
<div class="select-title">
<label class="control-label" for="app-composite">Effective Roles <span tooltip-placement="right" tooltip="Role mappings for this application. Some roles here might be inherited from a mapped composite role." class="fa fa-info-circle"></span></label>
<select id="app-composite" class="form-control" multiple size=5
<label class="control-label" for="client-composite">Effective Roles <span tooltip-placement="right" tooltip="Role mappings for this client. Some roles here might be inherited from a mapped composite role." class="fa fa-info-circle"></span></label>
<select id="client-composite" class="form-control" multiple size=5
ng-disabled="true"
ng-model="dummymodel"
ng-options="r.name for r in applicationComposite">
ng-options="r.name for r in clientComposite">
</select>
</div>
</div>

View File

@@ -18,13 +18,13 @@
</th>
</tr>
<tr>
<th>Application</th>
<th>Client</th>
<th>Active Sessions</th>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="data in stats">
<td><a href="#/realms/{{realm.realm}}/applications/{{data.id}}/sessions">{{data.name}}</a></td>
<td><a href="#/realms/{{realm.realm}}/clients/{{data.id}}/sessions">{{data.clientId}}</a></td>
<td>{{data.active}}</td>
</tr>
</tbody>

View File

@@ -23,7 +23,7 @@
</button>
<button type="submit" data-ng-click="setNotBeforeNow()" class="btn btn-primary btn-lg">Set To Now
</button>
<button type="submit" data-ng-click="pushRevocation()" class="btn btn-primary btn-lg" tooltip="For every application that has an admin URL, notify them of the new revocation policy." tooltip-placement="bottom">Push
<button type="submit" data-ng-click="pushRevocation()" class="btn btn-primary btn-lg" tooltip="For every client that has an admin URL, notify them of the new revocation policy." tooltip-placement="bottom">Push
</button>
</div>
</form>

View File

@@ -27,8 +27,7 @@
<th>IP Address</th>
<th>Started</th>
<th>Last Access</th>
<th>Applications</th>
<th>OAuth Clients</th>
<th>Clients</th>
<th>Action</th>
</tr>
</thead>
@@ -38,16 +37,11 @@
<td>{{session.start | date:'medium'}}</td>
<td>{{session.lastAccess | date:'medium'}}</td>
<td>
<div data-ng-repeat="(id, name) in session.applications">
<a href="#/realms/{{realm.realm}}/applications/{{id}}">{{name}}</a>
<div data-ng-repeat="(id, clientId) in session.clients">
<a href="#/realms/{{realm.realm}}/clients/{{id}}">{{clientId}}</a>
</div>
</ul>
</td>
<td>
<div data-ng-repeat="(clientId, clientName) in session.clients">
<a href="#/realms/{{realm.realm}}/oauth-clients/{{clientId}}">{{clientName}}</a>
</div>
</td>
<td><a href="" ng-click="logoutSession(session.id)">logout</a> </td>
</tr>
</tbody>

View File

@@ -1,13 +0,0 @@
<ul class="nav nav-tabs nav-tabs-pf" data-ng-hide="create && !path[4]">
<li ng-class="{active: !path[4]}"><a href="#/realms/{{realm.realm}}/applications/{{application.id}}">Settings</a></li>
<li ng-class="{active: path[4] == 'credentials'}" data-ng-show="!application.publicClient && application.protocol != 'saml'"><a href="#/realms/{{realm.realm}}/applications/{{application.id}}/credentials">Credentials</a></li>
<li ng-class="{active: path[4] == 'saml'}" data-ng-show="application.protocol == 'saml' && (application.attributes['saml.client.signature'] == 'true' || application.attributes['saml.encrypt'] == 'true')"><a href="#/realms/{{realm.realm}}/applications/{{application.id}}/saml/keys">SAML Keys</a></li>
<li ng-class="{active: path[4] == 'roles'}"><a href="#/realms/{{realm.realm}}/applications/{{application.id}}/roles">Roles</a></li>
<li ng-class="{active: path[4] == 'mappers'}" data-ng-show="!application.bearerOnly"><a href="#/realms/{{realm.realm}}/applications/{{application.id}}/mappers">Mappers</a></li>
<li ng-class="{active: path[4] == 'scope-mappings'}" data-ng-show="!application.bearerOnly"><a href="#/realms/{{realm.realm}}/applications/{{application.id}}/scope-mappings">Scope</a></li>
<li ng-class="{active: path[4] == 'revocation'}"><a href="#/realms/{{realm.realm}}/applications/{{application.id}}/revocation">Revocation</a></li>
<!-- <li ng-class="{active: path[4] == 'identity-provider'}" data-ng-show="realm.identityFederationEnabled"><a href="#/realms/{{realm.realm}}/applications/{{application.id}}/identity-provider">Identity Provider</a></li> -->
<li ng-class="{active: path[4] == 'sessions'}" data-ng-show="!application.bearerOnly"><a href="#/realms/{{realm.realm}}/applications/{{application.id}}/sessions">Sessions</a></li>
<li ng-class="{active: path[4] == 'clustering'}" data-ng-show="!application.publicClient"><a href="#/realms/{{realm.realm}}/applications/{{application.id}}/clustering">Clustering</a></li>
<li ng-class="{active: path[4] == 'installation'}" data-ng-show="application.protocol != 'saml'"><a href="#/realms/{{realm.realm}}/applications/{{application.id}}/installation">Installation</a></li>
</ul>

View File

@@ -0,0 +1,13 @@
<ul class="nav nav-tabs nav-tabs-pf" data-ng-hide="create && !path[4]">
<li ng-class="{active: !path[4]}"><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">Settings</a></li>
<li ng-class="{active: path[4] == 'credentials'}" data-ng-show="!client.publicClient && client.protocol != 'saml'"><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/credentials">Credentials</a></li>
<li ng-class="{active: path[4] == 'saml'}" data-ng-show="client.protocol == 'saml' && (client.attributes['saml.client.signature'] == 'true' || client.attributes['saml.encrypt'] == 'true')"><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/saml/keys">SAML Keys</a></li>
<li ng-class="{active: path[4] == 'roles'}"><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/roles">Roles</a></li>
<li ng-class="{active: path[4] == 'mappers'}" data-ng-show="!client.bearerOnly"><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/mappers">Mappers</a></li>
<li ng-class="{active: path[4] == 'scope-mappings'}" data-ng-show="!client.bearerOnly"><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/scope-mappings">Scope</a></li>
<li ng-class="{active: path[4] == 'revocation'}"><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/revocation">Revocation</a></li>
<!-- <li ng-class="{active: path[4] == 'identity-provider'}" data-ng-show="realm.identityFederationEnabled"><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/identity-provider">Identity Provider</a></li> -->
<li ng-class="{active: path[4] == 'sessions'}" data-ng-show="!client.bearerOnly"><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/sessions">Sessions</a></li>
<li ng-class="{active: path[4] == 'clustering'}" data-ng-show="!client.publicClient"><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/clustering">Clustering</a></li>
<li ng-class="{active: path[4] == 'installation'}" data-ng-show="client.protocol != 'saml'"><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/installation">Installation</a></li>
</ul>

View File

@@ -102,8 +102,8 @@ public class ServerRequest {
formparams.add(new BasicNameValuePair(OAuth2Constants.CODE, code));
formparams.add(new BasicNameValuePair(OAuth2Constants.REDIRECT_URI, redirectUri));
if (sessionId != null) {
formparams.add(new BasicNameValuePair(AdapterConstants.APPLICATION_SESSION_STATE, sessionId));
formparams.add(new BasicNameValuePair(AdapterConstants.APPLICATION_SESSION_HOST, HostUtils.getHostName()));
formparams.add(new BasicNameValuePair(AdapterConstants.CLIENT_SESSION_STATE, sessionId));
formparams.add(new BasicNameValuePair(AdapterConstants.CLIENT_SESSION_HOST, HostUtils.getHostName()));
}
HttpResponse response = null;
HttpPost post = new HttpPost(tokenUrl);
@@ -237,7 +237,7 @@ public class ServerRequest {
}
List<NameValuePair> formparams = new ArrayList<NameValuePair>();
formparams.add(new BasicNameValuePair(AdapterConstants.APPLICATION_CLUSTER_HOST, host));
formparams.add(new BasicNameValuePair(AdapterConstants.CLIENT_CLUSTER_HOST, host));
HttpPost post = new HttpPost(endpointUrl);

View File

@@ -62,7 +62,7 @@ public interface ClientModel extends RoleContainerModel {
void updateDefaultRoles(String[] defaultRoles);
Set<RoleModel> getApplicationScopeMappings(ClientModel client);
Set<RoleModel> getClientScopeMappings(ClientModel client);
boolean isBearerOnly();
void setBearerOnly(boolean only);

View File

@@ -5,9 +5,9 @@ package org.keycloak.models;
* @version $Revision: 1 $
*/
public interface Constants {
String ADMIN_CONSOLE_APPLICATION = "security-admin-console";
String ADMIN_CONSOLE_CLIENT_ID = "security-admin-console";
String ACCOUNT_MANAGEMENT_APP = "account";
String ACCOUNT_MANAGEMENT_CLIENT_ID = "account";
String INSTALLED_APP_URN = "urn:ietf:wg:oauth:2.0:oob";
String INSTALLED_APP_URL = "http://localhost";

View File

@@ -232,9 +232,9 @@ public interface RealmModel extends RoleContainerModel {
void setEnabledEventTypes(Set<String> enabledEventTypes);
ClientModel getMasterAdminApp();
ClientModel getMasterAdminClient();
void setMasterAdminApp(ClientModel app);
void setMasterAdminClient(ClientModel client);
boolean isIdentityFederationEnabled();

View File

@@ -66,7 +66,7 @@ public interface UserModel {
void updateCredentialDirectly(UserCredentialValueModel cred);
Set<RoleModel> getRealmRoleMappings();
Set<RoleModel> getApplicationRoleMappings(ClientModel app);
Set<RoleModel> getClientRoleMappings(ClientModel app);
boolean hasRole(RoleModel role);
void grantRole(RoleModel role);
Set<RoleModel> getRoleMappings();

View File

@@ -533,7 +533,7 @@ public class RepresentationToModel {
if (resourceRep.isFullScopeAllowed() != null) {
client.setFullScopeAllowed(resourceRep.isFullScopeAllowed());
} else {
client.setFullScopeAllowed(true);
client.setFullScopeAllowed(!client.isConsentRequired());
}
if (resourceRep.getNodeReRegistrationTimeout() != null) {
client.setNodeReRegistrationTimeout(resourceRep.getNodeReRegistrationTimeout());

View File

@@ -152,8 +152,8 @@ public class UserModelDelegate implements UserModel {
}
@Override
public Set<RoleModel> getApplicationRoleMappings(ClientModel app) {
return delegate.getApplicationRoleMappings(app);
public Set<RoleModel> getClientRoleMappings(ClientModel app) {
return delegate.getClientRoleMappings(app);
}
@Override

View File

@@ -565,7 +565,7 @@ public class ClientAdapter implements ClientModel {
}
@Override
public Set<RoleModel> getApplicationScopeMappings(ClientModel client) {
public Set<RoleModel> getClientScopeMappings(ClientModel client) {
Set<RoleModel> allScopes = client.getScopeMappings();
Set<RoleModel> appRoles = new HashSet<RoleModel>();

View File

@@ -959,22 +959,22 @@ public class RealmAdapter implements RealmModel {
}
@Override
public ClientModel getMasterAdminApp() {
public ClientModel getMasterAdminClient() {
return this.masterAdminApp;
}
@Override
public void setMasterAdminApp(ClientModel app) {
if (app == null) {
public void setMasterAdminClient(ClientModel client) {
if (client == null) {
realm.setAdminAppId(null);
this.masterAdminApp = null;
} else {
String appId = app.getId();
String appId = client.getId();
if (appId == null) {
throw new IllegalStateException("Master Admin app not initialized.");
}
realm.setAdminAppId(appId);
this.masterAdminApp = app;
this.masterAdminApp = client;
}
}

View File

@@ -325,7 +325,7 @@ public class UserAdapter implements UserModel, Comparable {
}
@Override
public Set<RoleModel> getApplicationRoleMappings(ClientModel app) {
public Set<RoleModel> getClientRoleMappings(ClientModel app) {
Set<RoleModel> result = new HashSet<RoleModel>();
for (RoleModel role : allRoles) {

View File

@@ -377,7 +377,7 @@ public class ClientAdapter implements ClientModel {
}
@Override
public Set<RoleModel> getApplicationScopeMappings(ClientModel client) {
public Set<RoleModel> getClientScopeMappings(ClientModel client) {
Set<RoleModel> roleMappings = client.getScopeMappings();
Set<RoleModel> appRoles = new HashSet<RoleModel>();

View File

@@ -11,7 +11,6 @@ import org.keycloak.models.RequiredCredentialModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.models.cache.entities.CachedRealm;
import org.keycloak.models.entities.IdentityProviderMapperEntity;
import org.keycloak.models.utils.KeycloakModelUtils;
import java.security.Key;
@@ -752,14 +751,14 @@ public class RealmAdapter implements RealmModel {
}
@Override
public ClientModel getMasterAdminApp() {
public ClientModel getMasterAdminClient() {
return cacheSession.getRealm(Config.getAdminRealm()).getClientById(cached.getMasterAdminApp());
}
@Override
public void setMasterAdminApp(ClientModel app) {
public void setMasterAdminClient(ClientModel client) {
getDelegateForUpdate();
updated.setMasterAdminApp(app);
updated.setMasterAdminClient(client);
}
@Override

View File

@@ -219,8 +219,8 @@ public class UserAdapter implements UserModel {
}
@Override
public Set<RoleModel> getApplicationRoleMappings(ClientModel app) {
if (updated != null) return updated.getApplicationRoleMappings(app);
public Set<RoleModel> getClientRoleMappings(ClientModel app) {
if (updated != null) return updated.getClientRoleMappings(app);
Set<RoleModel> roleMappings = getRoleMappings();
Set<RoleModel> appMappings = new HashSet<RoleModel>();
for (RoleModel role : roleMappings) {

View File

@@ -155,7 +155,7 @@ public class CachedRealm {
eventsListeners.addAll(model.getEventsListeners());
enabledEventTypes.addAll(model.getEnabledEventTypes());
defaultRoles.addAll(model.getDefaultRoles());
masterAdminApp = model.getMasterAdminApp().getId();
masterAdminApp = model.getMasterAdminClient().getId();
for (RoleModel role : model.getRoles()) {
realmRoles.put(role.getName(), role.getId());

View File

@@ -625,7 +625,7 @@ public class ClientAdapter implements ClientModel {
}
@Override
public Set<RoleModel> getApplicationScopeMappings(ClientModel client) {
public Set<RoleModel> getClientScopeMappings(ClientModel client) {
Set<RoleModel> roleMappings = client.getScopeMappings();
Set<RoleModel> appRoles = new HashSet<RoleModel>();

View File

@@ -1065,13 +1065,13 @@ public class RealmAdapter implements RealmModel {
}
@Override
public ClientModel getMasterAdminApp() {
public ClientModel getMasterAdminClient() {
return new ClientAdapter(this, em, session, realm.getMasterAdminApp());
}
@Override
public void setMasterAdminApp(ClientModel app) {
ClientEntity appEntity = app!=null ? em.getReference(ClientEntity.class, app.getId()) : null;
public void setMasterAdminClient(ClientModel client) {
ClientEntity appEntity = client !=null ? em.getReference(ClientEntity.class, client.getId()) : null;
realm.setMasterAdminApp(appEntity);
em.flush();
}

View File

@@ -363,7 +363,7 @@ public class UserAdapter implements UserModel {
}
@Override
public Set<RoleModel> getApplicationRoleMappings(ClientModel app) {
public Set<RoleModel> getClientRoleMappings(ClientModel app) {
Set<RoleModel> roleMappings = getRoleMappings();
Set<RoleModel> roles = new HashSet<RoleModel>();

View File

@@ -575,7 +575,7 @@ public class ClientAdapter extends AbstractMongoAdapter<MongoClientEntity> imple
}
@Override
public Set<RoleModel> getApplicationScopeMappings(ClientModel client) {
public Set<RoleModel> getClientScopeMappings(ClientModel client) {
Set<RoleModel> result = new HashSet<RoleModel>();
List<MongoRoleEntity> roles = MongoModelUtils.getAllScopesOfClient(client, invocationContext);

View File

@@ -978,14 +978,14 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
}
@Override
public ClientModel getMasterAdminApp() {
public ClientModel getMasterAdminClient() {
MongoClientEntity appData = getMongoStore().loadEntity(MongoClientEntity.class, realm.getAdminAppId(), invocationContext);
return appData != null ? new ClientAdapter(session, this, appData, invocationContext) : null;
}
@Override
public void setMasterAdminApp(ClientModel app) {
String adminAppId = app != null ? app.getId() : null;
public void setMasterAdminClient(ClientModel client) {
String adminAppId = client != null ? client.getId() : null;
realm.setAdminAppId(adminAppId);
updateRealm();
}

View File

@@ -316,7 +316,7 @@ public class UserAdapter extends AbstractMongoAdapter<MongoUserEntity> implement
}
@Override
public Set<RoleModel> getApplicationRoleMappings(ClientModel app) {
public Set<RoleModel> getClientRoleMappings(ClientModel app) {
Set<RoleModel> result = new HashSet<RoleModel>();
List<MongoRoleEntity> roles = MongoModelUtils.getAllRolesOfUser(this, invocationContext);

View File

@@ -1,6 +1,6 @@
package org.keycloak.protocol.saml;
import org.keycloak.exportimport.ApplicationImporter;
import org.keycloak.exportimport.ClientImporter;
import org.keycloak.models.RealmModel;
import org.keycloak.services.resources.admin.RealmAuth;
@@ -8,7 +8,7 @@ import org.keycloak.services.resources.admin.RealmAuth;
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class EntityDescriptorImporter implements ApplicationImporter {
public class EntityDescriptorImporter implements ClientImporter {
@Override
public Object createJaxrsService(RealmModel realm, RealmAuth auth) {
return new EntityDescriptorImporterService(realm, auth);

View File

@@ -1,8 +1,8 @@
package org.keycloak.protocol.saml;
import org.keycloak.Config;
import org.keycloak.exportimport.ApplicationImporter;
import org.keycloak.exportimport.ApplicationImporterFactory;
import org.keycloak.exportimport.ClientImporter;
import org.keycloak.exportimport.ClientImporterFactory;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
@@ -10,14 +10,14 @@ import org.keycloak.models.KeycloakSessionFactory;
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class EntityDescriptorImporterFactory implements ApplicationImporterFactory {
public class EntityDescriptorImporterFactory implements ClientImporterFactory {
@Override
public String getDisplayName() {
return "SAML 2.0 Entity Descriptor";
}
@Override
public ApplicationImporter create(KeycloakSession session) {
public ClientImporter create(KeycloakSession session) {
return new EntityDescriptorImporter();
}

View File

@@ -7,20 +7,20 @@ import org.keycloak.provider.Spi;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class ApplicationImportSpi implements Spi {
public class ClientImportSpi implements Spi {
@Override
public String getName() {
return "application-import";
return "client-import";
}
@Override
public Class<? extends Provider> getProviderClass() {
return ApplicationImporter.class;
return ClientImporter.class;
}
@Override
public Class<? extends ProviderFactory> getProviderFactoryClass() {
return ApplicationImporterFactory.class;
return ClientImporterFactory.class;
}
}

View File

@@ -5,11 +5,11 @@ import org.keycloak.provider.Provider;
import org.keycloak.services.resources.admin.RealmAuth;
/**
* Provider plugin interface for importing applications from an arbitrary configuration format
* Provider plugin interface for importing clients from an arbitrary configuration format
*
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public interface ApplicationImporter extends Provider {
public interface ClientImporter extends Provider {
public Object createJaxrsService(RealmModel realm, RealmAuth auth);
}

View File

@@ -3,11 +3,11 @@ package org.keycloak.exportimport;
import org.keycloak.provider.ProviderFactory;
/**
* Provider plugin interface for importing applications from an arbitrary configuration format
* Provider plugin interface for importing clients from an arbitrary configuration format
*
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public interface ApplicationImporterFactory extends ProviderFactory<ApplicationImporter> {
public interface ClientImporterFactory extends ProviderFactory<ClientImporter> {
public String getDisplayName();
}

View File

@@ -260,12 +260,12 @@ public class TokenManager {
for (Map.Entry<String, AccessToken.Access> entry : token.getResourceAccess().entrySet()) {
AccessToken.Access appAccess = newToken.getResourceAccess(entry.getKey());
if (appAccess == null && !entry.getValue().getRoles().isEmpty()) {
throw new OAuthErrorException(OAuthErrorException.INVALID_SCOPE, "User or application no longer has role permissions for application key: " + entry.getKey());
throw new OAuthErrorException(OAuthErrorException.INVALID_SCOPE, "User or client no longer has role permissions for client key: " + entry.getKey());
}
for (String roleName : entry.getValue().getRoles()) {
if (!appAccess.getRoles().contains(roleName)) {
throw new OAuthErrorException(OAuthErrorException.INVALID_SCOPE, "User no long has permission for application role " + roleName);
throw new OAuthErrorException(OAuthErrorException.INVALID_SCOPE, "User no long has permission for client role " + roleName);
}
}
}

View File

@@ -145,9 +145,9 @@ public class LogoutEndpoint {
* authenticate the client if it is not public.
*
* If the client is a confidential client
* you must include the client-id (application name or oauth client name) and secret in an Basic Auth Authorization header.
* you must include the client-id and secret in an Basic Auth Authorization header.
*
* If the client is a public client, then you must include a "client_id" form parameter with the app's or oauth client's name.
* If the client is a public client, then you must include a "client_id" form parameter.
*
* returns 204 if successful, 400 if not with a json error response.
*

View File

@@ -231,15 +231,15 @@ public class TokenEndpoint {
throw new ErrorResponseException("invalid_grant", "Session not active", Response.Status.BAD_REQUEST);
}
String adapterSessionId = formParams.getFirst(AdapterConstants.APPLICATION_SESSION_STATE);
String adapterSessionId = formParams.getFirst(AdapterConstants.CLIENT_SESSION_STATE);
if (adapterSessionId != null) {
String adapterSessionHost = formParams.getFirst(AdapterConstants.APPLICATION_SESSION_HOST);
String adapterSessionHost = formParams.getFirst(AdapterConstants.CLIENT_SESSION_HOST);
logger.debugf("Adapter Session '%s' saved in ClientSession for client '%s'. Host is '%s'", adapterSessionId, client.getClientId(), adapterSessionHost);
event.detail(AdapterConstants.APPLICATION_SESSION_STATE, adapterSessionId);
clientSession.setNote(AdapterConstants.APPLICATION_SESSION_STATE, adapterSessionId);
event.detail(AdapterConstants.APPLICATION_SESSION_HOST, adapterSessionHost);
clientSession.setNote(AdapterConstants.APPLICATION_SESSION_HOST, adapterSessionHost);
event.detail(AdapterConstants.CLIENT_SESSION_STATE, adapterSessionId);
clientSession.setNote(AdapterConstants.CLIENT_SESSION_STATE, adapterSessionId);
event.detail(AdapterConstants.CLIENT_SESSION_HOST, adapterSessionHost);
clientSession.setNote(AdapterConstants.CLIENT_SESSION_HOST, adapterSessionHost);
}
AccessToken token = tokenManager.createClientAccessToken(session, accessCode.getRequestedRoles(), realm, client, user, userSession, clientSession);

View File

@@ -88,7 +88,7 @@ public class ValidateTokenEndpoint {
error.put(OAuth2Constants.ERROR, e.getError());
if (e.getDescription() != null) error.put(OAuth2Constants.ERROR_DESCRIPTION, e.getDescription());
event.error(Errors.INVALID_TOKEN);
return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build();
return Response.status(Response.Status.BAD_REQUEST).entity(error).type(MediaType.APPLICATION_JSON_TYPE).build();
}
event.success();

View File

@@ -30,7 +30,7 @@ public class HardcodedRole extends AbstractOIDCProtocolMapper implements OIDCAcc
property = new ConfigProperty();
property.setName(ROLE_CONFIG);
property.setLabel("Role");
property.setHelpText("Role you want added to the token. To specify an application role the syntax is appname.approle, i.e. myapp.myrole");
property.setHelpText("Role you want added to the token. To specify a client role the syntax is clientId.clientRole, i.e. myapp.myrole");
property.setType(ConfigProperty.STRING_TYPE);
configProperties.add(property);
}

View File

@@ -33,7 +33,7 @@ public class RoleNameMapper extends AbstractOIDCProtocolMapper implements OIDCAc
property = new ConfigProperty();
property.setName(ROLE_CONFIG);
property.setLabel("Role");
property.setHelpText("Role name you want changed. To reference an application role the syntax is appname.approle, i.e. myapp.myrole");
property.setHelpText("Role name you want changed. To reference an client role the syntax is clientId.clientRole, i.e. myapp.myrole");
property.setType(ConfigProperty.STRING_TYPE);
configProperties.add(property);
property = new ConfigProperty();

View File

@@ -10,6 +10,7 @@ import org.keycloak.models.RealmModel;
import org.keycloak.util.BasicAuthHelper;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import java.util.HashMap;
@@ -39,7 +40,7 @@ public class AuthorizeClientUtil {
Map<String, String> error = new HashMap<String, String>();
error.put(OAuth2Constants.ERROR, "invalid_client");
error.put(OAuth2Constants.ERROR_DESCRIPTION, "Could not find client");
throw new BadRequestException("Could not find client", Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build());
throw new BadRequestException("Could not find client", Response.status(Response.Status.BAD_REQUEST).entity(error).type(MediaType.APPLICATION_JSON_TYPE).build());
}
event.client(client_id);
@@ -50,7 +51,7 @@ public class AuthorizeClientUtil {
error.put(OAuth2Constants.ERROR, "invalid_client");
error.put(OAuth2Constants.ERROR_DESCRIPTION, "Could not find client");
event.error(Errors.CLIENT_NOT_FOUND);
throw new BadRequestException("Could not find client", Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build());
throw new BadRequestException("Could not find client", Response.status(Response.Status.BAD_REQUEST).entity(error).type(MediaType.APPLICATION_JSON_TYPE).build());
}
if (!client.isEnabled()) {
@@ -58,7 +59,7 @@ public class AuthorizeClientUtil {
error.put(OAuth2Constants.ERROR, "invalid_client");
error.put(OAuth2Constants.ERROR_DESCRIPTION, "Client is not enabled");
event.error(Errors.CLIENT_DISABLED);
throw new BadRequestException("Client is not enabled", Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build());
throw new BadRequestException("Client is not enabled", Response.status(Response.Status.BAD_REQUEST).entity(error).type(MediaType.APPLICATION_JSON_TYPE).build());
}
if (!client.isPublicClient()) {
@@ -66,7 +67,7 @@ public class AuthorizeClientUtil {
Map<String, String> error = new HashMap<String, String>();
error.put(OAuth2Constants.ERROR, "unauthorized_client");
event.error(Errors.INVALID_CLIENT_CREDENTIALS);
throw new BadRequestException("Unauthorized Client", Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build());
throw new BadRequestException("Unauthorized Client", Response.status(Response.Status.BAD_REQUEST).entity(error).type(MediaType.APPLICATION_JSON_TYPE).build());
}
}

View File

@@ -6,6 +6,7 @@ import org.keycloak.models.RealmModel;
import org.keycloak.services.resources.flows.Flows;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import java.util.HashMap;
@@ -33,7 +34,7 @@ public class ErrorResponseException extends WebApplicationException {
if (errorDescription != null) {
e.put(OAuth2Constants.ERROR_DESCRIPTION, errorDescription);
}
return Response.status(status).entity(e).type("application/json").build();
return Response.status(status).entity(e).type(MediaType.APPLICATION_JSON_TYPE).build();
}
}

View File

@@ -71,7 +71,7 @@ public class ApplianceBootstrap {
RoleModel adminRole = realm.getRole(AdminRoles.ADMIN);
adminUser.grantRole(adminRole);
ClientModel accountApp = realm.getClientNameMap().get(Constants.ACCOUNT_MANAGEMENT_APP);
ClientModel accountApp = realm.getClientNameMap().get(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID);
for (String r : accountApp.getDefaultRoles()) {
adminUser.grantRole(accountApp.getRole(r));
}

View File

@@ -80,7 +80,7 @@ public class Auth {
return false;
}
public boolean hasAppRole(ClientModel app, String role) {
public boolean hasClientRole(ClientModel app, String role) {
if (cookie) {
return user.hasRole(app.getRole(role));
} else {
@@ -91,7 +91,7 @@ public class Auth {
public boolean hasOneOfAppRole(ClientModel app, String... roles) {
for (String r : roles) {
if (hasAppRole(app, r)) {
if (hasClientRole(app, r)) {
return true;
}
}

View File

@@ -18,7 +18,7 @@ import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionProvider;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.models.utils.RepresentationToModel;
import org.keycloak.representations.idm.ApplicationRepresentation;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.RealmEventsConfigRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.timer.TimerProvider;
@@ -90,8 +90,8 @@ public class RealmManager {
}
protected void setupAdminConsole(RealmModel realm) {
ClientModel adminConsole = realm.getClientByClientId(Constants.ADMIN_CONSOLE_APPLICATION);
if (adminConsole == null) adminConsole = new ClientManager(this).createClient(realm, Constants.ADMIN_CONSOLE_APPLICATION);
ClientModel adminConsole = realm.getClientByClientId(Constants.ADMIN_CONSOLE_CLIENT_ID);
if (adminConsole == null) adminConsole = new ClientManager(this).createClient(realm, Constants.ADMIN_CONSOLE_CLIENT_ID);
String baseUrl = contextPath + "/admin/" + realm.getName() + "/console";
adminConsole.setBaseUrl(baseUrl + "/index.html");
adminConsole.setEnabled(true);
@@ -103,18 +103,18 @@ public class RealmManager {
if (realm.getName().equals(Config.getAdminRealm())) {
adminRole = realm.getRole(AdminRoles.ADMIN);
} else {
String realmAdminApplicationName = getRealmAdminApplicationName(realm);
ClientModel realmAdminApp = realm.getClientByClientId(realmAdminApplicationName);
String realmAdminApplicationClientId = getRealmAdminClientId(realm);
ClientModel realmAdminApp = realm.getClientByClientId(realmAdminApplicationClientId);
adminRole = realmAdminApp.getRole(AdminRoles.REALM_ADMIN);
}
adminConsole.addScopeMapping(adminRole);
}
public String getRealmAdminApplicationName(RealmModel realm) {
public String getRealmAdminClientId(RealmModel realm) {
return "realm-management";
}
public String getRealmAdminApplicationName(RealmRepresentation realm) {
public String getRealmAdminClientId(RealmRepresentation realm) {
return "realm-management";
}
@@ -139,7 +139,7 @@ public class RealmManager {
boolean removed = model.removeRealm(realm.getId());
if (removed) {
new ClientManager(this).removeClient(getKeycloakAdminstrationRealm(), realm.getMasterAdminApp());
new ClientManager(this).removeClient(getKeycloakAdminstrationRealm(), realm.getMasterAdminClient());
UserSessionProvider sessions = session.sessions();
if (sessions != null) {
@@ -176,18 +176,18 @@ public class RealmManager {
ClientManager clientManager = new ClientManager(new RealmManager(session));
String realmAdminApplicationName = getRealmAdminApplicationName(realm);
ClientModel realmAdminApp = realm.getClientByClientId(realmAdminApplicationName);
if (realmAdminApp == null) {
realmAdminApp = clientManager.createClient(realm, realmAdminApplicationName);
String realmAdminClientId = getRealmAdminClientId(realm);
ClientModel realmAdminClient = realm.getClientByClientId(realmAdminClientId);
if (realmAdminClient == null) {
realmAdminClient = clientManager.createClient(realm, realmAdminClientId);
}
RoleModel adminRole = realmAdminApp.addRole(AdminRoles.REALM_ADMIN);
adminRole.setDescription("${role_"+AdminRoles.REALM_ADMIN+"}");
realmAdminApp.setBearerOnly(true);
realmAdminApp.setFullScopeAllowed(false);
RoleModel adminRole = realmAdminClient.addRole(AdminRoles.REALM_ADMIN);
adminRole.setDescription("${role_" + AdminRoles.REALM_ADMIN + "}");
realmAdminClient.setBearerOnly(true);
realmAdminClient.setFullScopeAllowed(false);
for (String r : AdminRoles.ALL_REALM_ROLES) {
RoleModel role = realmAdminApp.addRole(r);
RoleModel role = realmAdminClient.addRole(r);
role.setDescription("${role_"+r+"}");
adminRole.addCompositeRole(role);
}
@@ -195,19 +195,19 @@ public class RealmManager {
private void setupAccountManagement(RealmModel realm) {
ClientModel application = realm.getClientNameMap().get(Constants.ACCOUNT_MANAGEMENT_APP);
if (application == null) {
application = new ClientManager(this).createClient(realm, Constants.ACCOUNT_MANAGEMENT_APP);
application.setEnabled(true);
application.setFullScopeAllowed(false);
ClientModel client = realm.getClientNameMap().get(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID);
if (client == null) {
client = new ClientManager(this).createClient(realm, Constants.ACCOUNT_MANAGEMENT_CLIENT_ID);
client.setEnabled(true);
client.setFullScopeAllowed(false);
String base = contextPath + "/realms/" + realm.getName() + "/account";
String redirectUri = base + "/*";
application.addRedirectUri(redirectUri);
application.setBaseUrl(base);
client.addRedirectUri(redirectUri);
client.setBaseUrl(base);
for (String role : AccountRoles.ALL) {
application.addDefaultRole(role);
application.getRole(role).setDescription("${role_"+role+"}");
client.addDefaultRole(role);
client.getRole(role).setDescription("${role_"+role+"}");
}
}
}
@@ -224,9 +224,9 @@ public class RealmManager {
setupRealmDefaults(realm);
setupMasterAdminManagement(realm);
if (!hasRealmAdminManagementApp(rep)) setupRealmAdminManagement(realm);
if (!hasAccountManagementApp(rep)) setupAccountManagement(realm);
if (!hasAdminConsoleApp(rep)) setupAdminConsole(realm);
if (!hasRealmAdminManagementClient(rep)) setupRealmAdminManagement(realm);
if (!hasAccountManagementClient(rep)) setupAccountManagement(realm);
if (!hasAdminConsoleClient(rep)) setupAdminConsole(realm);
RepresentationToModel.importRealm(session, rep, realm);
@@ -239,30 +239,30 @@ public class RealmManager {
return realm;
}
private boolean hasRealmAdminManagementApp(RealmRepresentation rep) {
if (rep.getApplications() == null) return false;
for (ApplicationRepresentation app : rep.getApplications()) {
if (app.getName().equals(getRealmAdminApplicationName(rep))) {
private boolean hasRealmAdminManagementClient(RealmRepresentation rep) {
if (rep.getClients() == null) return false;
for (ClientRepresentation clientRep : rep.getClients()) {
if (clientRep.getClientId().equals(getRealmAdminClientId(rep))) {
return true;
}
}
return false;
}
private boolean hasAccountManagementApp(RealmRepresentation rep) {
if (rep.getApplications() == null) return false;
for (ApplicationRepresentation app : rep.getApplications()) {
if (app.getName().equals(Constants.ACCOUNT_MANAGEMENT_APP)) {
private boolean hasAccountManagementClient(RealmRepresentation rep) {
if (rep.getClients() == null) return false;
for (ClientRepresentation clientRep : rep.getClients()) {
if (clientRep.getClientId().equals(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID)) {
return true;
}
}
return false;
}
private boolean hasAdminConsoleApp(RealmRepresentation rep) {
if (rep.getApplications() == null) return false;
for (ApplicationRepresentation app : rep.getApplications()) {
if (app.getName().equals(Constants.ADMIN_CONSOLE_APPLICATION)) {
private boolean hasAdminConsoleClient(RealmRepresentation rep) {
if (rep.getClients() == null) return false;
for (ClientRepresentation clientRep : rep.getClients()) {
if (clientRep.getClientId().equals(Constants.ADMIN_CONSOLE_CLIENT_ID)) {
return true;
}
}

View File

@@ -42,7 +42,7 @@ import java.util.Set;
*/
public class ResourceAdminManager {
protected static Logger logger = Logger.getLogger(ResourceAdminManager.class);
private static final String APPLICATION_SESSION_HOST_PROPERTY = "${application.session.host}";
private static final String CLIENT_SESSION_HOST_PROPERTY = "${application.session.host}";
public static ApacheHttpClient4Executor createExecutor() {
HttpClient client = new HttpClientBuilder()
@@ -57,13 +57,13 @@ public class ResourceAdminManager {
}
public static String getManagementUrl(URI requestUri, ClientModel application) {
String mgmtUrl = application.getManagementUrl();
public static String getManagementUrl(URI requestUri, ClientModel client) {
String mgmtUrl = client.getManagementUrl();
if (mgmtUrl == null || mgmtUrl.equals("")) {
return null;
}
// this is to support relative admin urls when keycloak and applications are deployed on the same machine
// this is to support relative admin urls when keycloak and clients are deployed on the same machine
String absoluteURI = ResolveRelative.resolveRelativeUri(requestUri, mgmtUrl);
// this is for resolving URI like "http://${jboss.host.name}:8080/..." in order to send request to same machine and avoid request to LB in cluster environment
@@ -72,13 +72,13 @@ public class ResourceAdminManager {
// For non-cluster setup, return just single configured managementUrls
// For cluster setup, return the management Urls corresponding to all registered cluster nodes
private List<String> getAllManagementUrls(URI requestUri, ClientModel application) {
String baseMgmtUrl = getManagementUrl(requestUri, application);
private List<String> getAllManagementUrls(URI requestUri, ClientModel client) {
String baseMgmtUrl = getManagementUrl(requestUri, client);
if (baseMgmtUrl == null) {
return Collections.emptyList();
}
Set<String> registeredNodesHosts = new ClientManager().validateRegisteredNodes(application);
Set<String> registeredNodesHosts = new ClientManager().validateRegisteredNodes(client);
// No-cluster setup
if (registeredNodesHosts.isEmpty()) {
@@ -128,7 +128,7 @@ public class ResourceAdminManager {
}
}
public void logoutUserFromApplication(URI requestUri, RealmModel realm, ClientModel resource, UserModel user, KeycloakSession session) {
public void logoutUserFromClient(URI requestUri, RealmModel realm, ClientModel resource, UserModel user, KeycloakSession session) {
ApacheHttpClient4Executor executor = createExecutor();
try {
@@ -163,9 +163,9 @@ public class ResourceAdminManager {
if (clientSessions != null && clientSessions.size() > 0) {
adapterSessionIds = new MultivaluedHashMap<String, String>();
for (ClientSessionModel clientSession : clientSessions) {
String adapterSessionId = clientSession.getNote(AdapterConstants.APPLICATION_SESSION_STATE);
String adapterSessionId = clientSession.getNote(AdapterConstants.CLIENT_SESSION_STATE);
if (adapterSessionId != null) {
String host = clientSession.getNote(AdapterConstants.APPLICATION_SESSION_HOST);
String host = clientSession.getNote(AdapterConstants.CLIENT_SESSION_HOST);
adapterSessionIds.add(host, adapterSessionId);
}
if (clientSession.getUserSession() != null) userSessions.add(clientSession.getUserSession().getId());
@@ -177,13 +177,13 @@ public class ResourceAdminManager {
return false;
}
if (managementUrl.contains(APPLICATION_SESSION_HOST_PROPERTY)) {
if (managementUrl.contains(CLIENT_SESSION_HOST_PROPERTY)) {
boolean allPassed = true;
// Send logout separately to each host (needed for single-sign-out in cluster for non-distributable apps - KEYCLOAK-748)
for (Map.Entry<String, List<String>> entry : adapterSessionIds.entrySet()) {
String host = entry.getKey();
List<String> sessionIds = entry.getValue();
String currentHostMgmtUrl = managementUrl.replace(APPLICATION_SESSION_HOST_PROPERTY, host);
String currentHostMgmtUrl = managementUrl.replace(CLIENT_SESSION_HOST_PROPERTY, host);
allPassed = sendLogoutRequest(realm, resource, sessionIds, userSessions, client, 0, currentHostMgmtUrl) && allPassed;
}
@@ -215,7 +215,7 @@ public class ResourceAdminManager {
GlobalRequestResult finalResult = new GlobalRequestResult();
for (ClientModel resource : resources) {
GlobalRequestResult currentResult = logoutApplication(requestUri, realm, resource, executor, realm.getNotBefore());
GlobalRequestResult currentResult = logoutClient(requestUri, realm, resource, executor, realm.getNotBefore());
finalResult.addAll(currentResult);
}
return finalResult;
@@ -224,25 +224,25 @@ public class ResourceAdminManager {
}
}
public GlobalRequestResult logoutApplication(URI requestUri, RealmModel realm, ClientModel resource) {
public GlobalRequestResult logoutClient(URI requestUri, RealmModel realm, ClientModel resource) {
ApacheHttpClient4Executor executor = createExecutor();
try {
resource.setNotBefore(Time.currentTime());
return logoutApplication(requestUri, realm, resource, executor, resource.getNotBefore());
return logoutClient(requestUri, realm, resource, executor, resource.getNotBefore());
} finally {
executor.getHttpClient().getConnectionManager().shutdown();
}
}
protected GlobalRequestResult logoutApplication(URI requestUri, RealmModel realm, ClientModel resource, ApacheHttpClient4Executor executor, int notBefore) {
protected GlobalRequestResult logoutClient(URI requestUri, RealmModel realm, ClientModel resource, ApacheHttpClient4Executor executor, int notBefore) {
List<String> mgmtUrls = getAllManagementUrls(requestUri, resource);
if (mgmtUrls.isEmpty()) {
logger.debug("No management URL or no registered cluster nodes for the application " + resource.getClientId());
logger.debug("No management URL or no registered cluster nodes for the client " + resource.getClientId());
return new GlobalRequestResult();
}
if (logger.isDebugEnabled()) logger.debug("Send logoutApplication for URLs: " + mgmtUrls);
if (logger.isDebugEnabled()) logger.debug("Send logoutClient for URLs: " + mgmtUrls);
// Propagate this to all hosts
GlobalRequestResult result = new GlobalRequestResult();
@@ -265,7 +265,7 @@ public class ResourceAdminManager {
try {
response = request.body(MediaType.TEXT_PLAIN_TYPE, token).post();
} catch (Exception e) {
logger.warn("Logout for application '" + resource.getClientId() + "' failed", e);
logger.warn("Logout for client '" + resource.getClientId() + "' failed", e);
return false;
}
try {
@@ -282,8 +282,8 @@ public class ResourceAdminManager {
try {
GlobalRequestResult finalResult = new GlobalRequestResult();
for (ClientModel application : realm.getClients()) {
GlobalRequestResult currentResult = pushRevocationPolicy(requestUri, realm, application, realm.getNotBefore(), executor);
for (ClientModel client : realm.getClients()) {
GlobalRequestResult currentResult = pushRevocationPolicy(requestUri, realm, client, realm.getNotBefore(), executor);
finalResult.addAll(currentResult);
}
return finalResult;
@@ -292,11 +292,11 @@ public class ResourceAdminManager {
}
}
public GlobalRequestResult pushApplicationRevocationPolicy(URI requestUri, RealmModel realm, ClientModel application) {
public GlobalRequestResult pushClientRevocationPolicy(URI requestUri, RealmModel realm, ClientModel client) {
ApacheHttpClient4Executor executor = createExecutor();
try {
return pushRevocationPolicy(requestUri, realm, application, application.getNotBefore(), executor);
return pushRevocationPolicy(requestUri, realm, client, client.getNotBefore(), executor);
} finally {
executor.getHttpClient().getConnectionManager().shutdown();
}
@@ -306,7 +306,7 @@ public class ResourceAdminManager {
protected GlobalRequestResult pushRevocationPolicy(URI requestUri, RealmModel realm, ClientModel resource, int notBefore, ApacheHttpClient4Executor executor) {
List<String> mgmtUrls = getAllManagementUrls(requestUri, resource);
if (mgmtUrls.isEmpty()) {
logger.debugf("No management URL or no registered cluster nodes for the application %s", resource.getClientId());
logger.debugf("No management URL or no registered cluster nodes for the client %s", resource.getClientId());
return new GlobalRequestResult();
}
@@ -345,10 +345,10 @@ public class ResourceAdminManager {
}
}
public GlobalRequestResult testNodesAvailability(URI requestUri, RealmModel realm, ClientModel application) {
List<String> mgmtUrls = getAllManagementUrls(requestUri, application);
public GlobalRequestResult testNodesAvailability(URI requestUri, RealmModel realm, ClientModel client) {
List<String> mgmtUrls = getAllManagementUrls(requestUri, client);
if (mgmtUrls.isEmpty()) {
logger.debug("No management URL or no registered cluster nodes for the application " + application.getClientId());
logger.debug("No management URL or no registered cluster nodes for the application " + client.getClientId());
return new GlobalRequestResult();
}
@@ -360,7 +360,7 @@ public class ResourceAdminManager {
// Propagate this to all hosts
GlobalRequestResult result = new GlobalRequestResult();
for (String mgmtUrl : mgmtUrls) {
if (sendTestNodeAvailabilityRequest(realm, application, executor, mgmtUrl)) {
if (sendTestNodeAvailabilityRequest(realm, client, executor, mgmtUrl)) {
result.addSuccessRequest(mgmtUrl);
} else {
result.addFailedRequest(mgmtUrl);
@@ -372,11 +372,11 @@ public class ResourceAdminManager {
}
}
protected boolean sendTestNodeAvailabilityRequest(RealmModel realm, ClientModel application, ApacheHttpClient4Executor client, String managementUrl) {
TestAvailabilityAction adminAction = new TestAvailabilityAction(TokenIdGenerator.generateId(), Time.currentTime() + 30, application.getClientId());
protected boolean sendTestNodeAvailabilityRequest(RealmModel realm, ClientModel client, ApacheHttpClient4Executor httpClient, String managementUrl) {
TestAvailabilityAction adminAction = new TestAvailabilityAction(TokenIdGenerator.generateId(), Time.currentTime() + 30, client.getClientId());
String token = new TokenManager().encodeToken(realm, adminAction);
logger.debugv("testNodes availability resource: {0} url: {1}", application.getClientId(), managementUrl);
ClientRequest request = client.createRequest(UriBuilder.fromUri(managementUrl).path(AdapterConstants.K_TEST_AVAILABLE).build().toString());
logger.debugv("testNodes availability resource: {0} url: {1}", client.getClientId(), managementUrl);
ClientRequest request = httpClient.createRequest(UriBuilder.fromUri(managementUrl).path(AdapterConstants.K_TEST_AVAILABLE).build().toString());
ClientResponse response;
try {
response = request.body(MediaType.TEXT_PLAIN_TYPE, token).post();

View File

@@ -131,16 +131,16 @@ public class AccountService {
private KeycloakSession session;
private final AppAuthManager authManager;
private final ClientModel application;
private final ClientModel client;
private EventBuilder event;
private AccountProvider account;
private Auth auth;
private EventStoreProvider eventStore;
private String stateChecker;
public AccountService(RealmModel realm, ClientModel application, EventBuilder event) {
public AccountService(RealmModel realm, ClientModel client, EventBuilder event) {
this.realm = realm;
this.application = application;
this.client = client;
this.event = event;
this.authManager = new AppAuthManager();
}
@@ -152,11 +152,11 @@ public class AccountService {
AuthenticationManager.AuthResult authResult = authManager.authenticateBearerToken(session, realm, uriInfo, clientConnection, headers);
if (authResult != null) {
auth = new Auth(realm, authResult.getToken(), authResult.getUser(), application, authResult.getSession(), false);
auth = new Auth(realm, authResult.getToken(), authResult.getUser(), client, authResult.getSession(), false);
} else {
authResult = authManager.authenticateIdentityCookie(session, realm, uriInfo, clientConnection, headers);
if (authResult != null) {
auth = new Auth(realm, authResult.getToken(), authResult.getUser(), application, authResult.getSession(), true);
auth = new Auth(realm, authResult.getToken(), authResult.getUser(), client, authResult.getSession(), true);
Cookie cookie = headers.getCookies().get(KEYCLOAK_STATE_CHECKER);
if (cookie != null) {
stateChecker = cookie.getValue();
@@ -193,14 +193,14 @@ public class AccountService {
if (userSession != null) {
boolean associated = false;
for (ClientSessionModel c : userSession.getClientSessions()) {
if (c.getClient().equals(application)) {
if (c.getClient().equals(client)) {
auth.setClientSession(c);
associated = true;
break;
}
}
if (!associated) {
ClientSessionModel clientSession = session.sessions().createClientSession(realm, application);
ClientSessionModel clientSession = session.sessions().createClientSession(realm, client);
clientSession.setUserSession(userSession);
auth.setClientSession(clientSession);
}
@@ -737,7 +737,7 @@ public class AccountService {
logger.debug("realm not enabled");
throw new ForbiddenException();
}
if (!application.isEnabled()) {
if (!client.isEnabled()) {
logger.debug("account management app not enabled");
throw new ForbiddenException();
}
@@ -766,7 +766,7 @@ public class AccountService {
String authUrl = OIDCLoginProtocolService.authUrl(uriInfo).build(realm.getName()).toString();
oauth.setAuthUrl(authUrl);
oauth.setClientId(Constants.ACCOUNT_MANAGEMENT_APP);
oauth.setClientId(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID);
UriBuilder uriBuilder = Urls.accountPageBuilder(uriInfo.getBaseUri()).path(AccountService.class, "loginRedirect");
@@ -813,21 +813,21 @@ public class AccountService {
String referrerUri = uriInfo.getQueryParameters().getFirst("referrer_uri");
ClientModel application = realm.getClientByClientId(referrer);
if (application != null) {
ClientModel referrerClient = realm.getClientByClientId(referrer);
if (referrerClient != null) {
if (referrerUri != null) {
referrerUri = RedirectUtils.verifyRedirectUri(uriInfo, referrerUri, realm, application);
referrerUri = RedirectUtils.verifyRedirectUri(uriInfo, referrerUri, realm, referrerClient);
} else {
referrerUri = ResolveRelative.resolveRelativeUri(uriInfo.getRequestUri(), application.getBaseUrl());
referrerUri = ResolveRelative.resolveRelativeUri(uriInfo.getRequestUri(), referrerClient.getBaseUrl());
}
if (referrerUri != null) {
return new String[]{referrer, referrerUri};
}
} else if (referrerUri != null) {
ClientModel client = realm.getClientByClientId(referrer);
referrerClient = realm.getClientByClientId(referrer);
if (client != null) {
referrerUri = RedirectUtils.verifyRedirectUri(uriInfo, referrerUri, realm, application);
referrerUri = RedirectUtils.verifyRedirectUri(uriInfo, referrerUri, realm, referrerClient);
if (referrerUri != null) {
return new String[]{referrer, referrerUri};
@@ -843,7 +843,7 @@ public class AccountService {
throw new ForbiddenException();
}
if (!auth.hasAppRole(application, role)) {
if (!auth.hasClientRole(client, role)) {
throw new ForbiddenException();
}
}
@@ -853,7 +853,7 @@ public class AccountService {
throw new ForbiddenException();
}
if (!auth.hasOneOfAppRole(application, roles)) {
if (!auth.hasOneOfAppRole(client, roles)) {
throw new ForbiddenException();
}
}

View File

@@ -24,6 +24,7 @@ import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
@@ -81,7 +82,7 @@ public class ClientsManagementService {
}
/**
* URL invoked by adapter to register new application cluster node. Each application cluster node will invoke this URL once it joins cluster
* URL invoked by adapter to register new client cluster node. Each application cluster node will invoke this URL once it joins cluster
*
* @param authorizationHeader
* @param formData
@@ -89,7 +90,7 @@ public class ClientsManagementService {
*/
@Path("register-node")
@POST
@Produces("application/json")
@Produces(MediaType.APPLICATION_JSON)
public Response registerNode(@HeaderParam(HttpHeaders.AUTHORIZATION) String authorizationHeader, final MultivaluedMap<String, String> formData) {
if (!checkSsl()) {
throw new ForbiddenException("HTTPS required");
@@ -102,13 +103,13 @@ public class ClientsManagementService {
throw new UnauthorizedException("Realm not enabled");
}
ClientModel application = authorizeApplication(authorizationHeader, formData);
String nodeHost = getApplicationClusterHost(formData);
ClientModel client = authorizeClient(authorizationHeader, formData);
String nodeHost = getClientClusterHost(formData);
event.client(application).detail(Details.NODE_HOST, nodeHost);
logger.debugf("Registering cluster host '%s' for client '%s'", nodeHost, application.getClientId());
event.client(client).detail(Details.NODE_HOST, nodeHost);
logger.debugf("Registering cluster host '%s' for client '%s'", nodeHost, client.getClientId());
application.registerNode(nodeHost, Time.currentTime());
client.registerNode(nodeHost, Time.currentTime());
event.success();
@@ -117,7 +118,7 @@ public class ClientsManagementService {
/**
* URL invoked by adapter to register new application cluster node. Each application cluster node will invoke this URL once it joins cluster
* URL invoked by adapter to register new client cluster node. Each application cluster node will invoke this URL once it joins cluster
*
* @param authorizationHeader
* @param formData
@@ -125,7 +126,7 @@ public class ClientsManagementService {
*/
@Path("unregister-node")
@POST
@Produces("application/json")
@Produces(MediaType.APPLICATION_JSON)
public Response unregisterNode(@HeaderParam(HttpHeaders.AUTHORIZATION) String authorizationHeader, final MultivaluedMap<String, String> formData) {
if (!checkSsl()) {
throw new ForbiddenException("HTTPS required");
@@ -138,20 +139,20 @@ public class ClientsManagementService {
throw new UnauthorizedException("Realm not enabled");
}
ClientModel application = authorizeApplication(authorizationHeader, formData);
String nodeHost = getApplicationClusterHost(formData);
ClientModel client = authorizeClient(authorizationHeader, formData);
String nodeHost = getClientClusterHost(formData);
event.client(application).detail(Details.NODE_HOST, nodeHost);
logger.debugf("Unregistering cluster host '%s' for client '%s'", nodeHost, application.getClientId());
event.client(client).detail(Details.NODE_HOST, nodeHost);
logger.debugf("Unregistering cluster host '%s' for client '%s'", nodeHost, client.getClientId());
application.unregisterNode(nodeHost);
client.unregisterNode(nodeHost);
event.success();
return Response.noContent().build();
}
protected ClientModel authorizeApplication(String authorizationHeader, MultivaluedMap<String, String> formData) {
protected ClientModel authorizeClient(String authorizationHeader, MultivaluedMap<String, String> formData) {
ClientModel client = AuthorizeClientUtil.authorizeClient(authorizationHeader, formData, event, realm);
if (client.isPublicClient()) {
@@ -159,31 +160,23 @@ public class ClientsManagementService {
error.put(OAuth2Constants.ERROR, "invalid_client");
error.put(OAuth2Constants.ERROR_DESCRIPTION, "Public clients not allowed");
event.error(Errors.INVALID_CLIENT);
throw new BadRequestException("Public clients not allowed", javax.ws.rs.core.Response.status(javax.ws.rs.core.Response.Status.BAD_REQUEST).entity(error).type("application/json").build());
throw new BadRequestException("Public clients not allowed", javax.ws.rs.core.Response.status(javax.ws.rs.core.Response.Status.BAD_REQUEST).entity(error).type(MediaType.APPLICATION_JSON_TYPE).build());
}
if (!(client instanceof ClientModel)) {
Map<String, String> error = new HashMap<String, String>();
error.put(OAuth2Constants.ERROR, "invalid_client");
error.put(OAuth2Constants.ERROR_DESCRIPTION, "Just applications are allowed");
event.error(Errors.INVALID_CLIENT);
throw new BadRequestException("ust applications are allowed", javax.ws.rs.core.Response.status(javax.ws.rs.core.Response.Status.BAD_REQUEST).entity(error).type("application/json").build());
}
return (ClientModel)client;
return client;
}
protected String getApplicationClusterHost(MultivaluedMap<String, String> formData) {
String applicationClusterHost = formData.getFirst(AdapterConstants.APPLICATION_CLUSTER_HOST);
if (applicationClusterHost == null || applicationClusterHost.length() == 0) {
protected String getClientClusterHost(MultivaluedMap<String, String> formData) {
String clientClusterHost = formData.getFirst(AdapterConstants.CLIENT_CLUSTER_HOST);
if (clientClusterHost == null || clientClusterHost.length() == 0) {
Map<String, String> error = new HashMap<String, String>();
error.put(OAuth2Constants.ERROR, "invalid_request");
error.put(OAuth2Constants.ERROR_DESCRIPTION, "application cluster host not specified");
error.put(OAuth2Constants.ERROR_DESCRIPTION, "Client cluster host not specified");
event.error(Errors.INVALID_CODE);
throw new BadRequestException("Cluster host not specified", javax.ws.rs.core.Response.status(javax.ws.rs.core.Response.Status.BAD_REQUEST).entity(error).type("application/json").build());
throw new BadRequestException("Cluster host not specified", javax.ws.rs.core.Response.status(javax.ws.rs.core.Response.Status.BAD_REQUEST).entity(error).type(MediaType.APPLICATION_JSON_TYPE).build());
}
return applicationClusterHost;
return clientClusterHost;
}

View File

@@ -73,7 +73,7 @@ import java.util.Map;
import static org.keycloak.models.AccountRoles.MANAGE_ACCOUNT;
import static org.keycloak.models.ClientSessionModel.Action.AUTHENTICATE;
import static org.keycloak.models.Constants.ACCOUNT_MANAGEMENT_APP;
import static org.keycloak.models.Constants.ACCOUNT_MANAGEMENT_CLIENT_ID;
import static org.keycloak.models.UserModel.RequiredAction.UPDATE_PROFILE;
/**
@@ -327,7 +327,7 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
return redirectToErrorPage(Messages.ACCOUNT_DISABLED);
}
if (!authenticatedUser.hasRole(this.realmModel.getClientByClientId(ACCOUNT_MANAGEMENT_APP).getRole(MANAGE_ACCOUNT))) {
if (!authenticatedUser.hasRole(this.realmModel.getClientByClientId(ACCOUNT_MANAGEMENT_CLIENT_ID).getRole(MANAGE_ACCOUNT))) {
fireErrorEvent(Errors.NOT_ALLOWED);
return redirectToErrorPage(Messages.INSUFFICIENT_PERMISSION);
}
@@ -382,7 +382,7 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
return clientCode;
}
throw new IdentityBrokerException("Invalid code, please login again through your application.");
throw new IdentityBrokerException("Invalid code, please login again through your client.");
}
private AuthenticationRequest createAuthenticationRequest(String providerId, ClientSessionCode clientSessionCode) {

View File

@@ -14,6 +14,7 @@ import javax.ws.rs.OPTIONS;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
@@ -59,7 +60,7 @@ public class PublicRealmResource {
*/
@GET
@NoCache
@Produces("application/json")
@Produces(MediaType.APPLICATION_JSON)
public PublishedRealmRepresentation getRealm() {
Cors.add(request).allowedOrigins(Cors.ACCESS_CONTROL_ALLOW_ORIGIN_WILDCARD).auth().build(response);
return realmRep(realm, uriInfo);

View File

@@ -157,16 +157,15 @@ public class RealmsResource {
RealmManager realmManager = new RealmManager(session);
RealmModel realm = locateRealm(name, realmManager);
ClientModel application = realm.getClientNameMap().get(Constants.ACCOUNT_MANAGEMENT_APP);
if (application == null || !application.isEnabled()) {
ClientModel client = realm.getClientNameMap().get(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID);
if (client == null || !client.isEnabled()) {
logger.debug("account management not enabled");
throw new NotFoundException("account management not enabled");
}
EventBuilder event = new EventBuilder(realm, session, clientConnection);
AccountService accountService = new AccountService(realm, application, event);
AccountService accountService = new AccountService(realm, client, event);
ResteasyProviderFactory.getInstance().injectProperties(accountService);
//resourceContext.initResource(accountService);
accountService.init();
return accountService;
}
@@ -177,7 +176,6 @@ public class RealmsResource {
RealmModel realm = locateRealm(name, realmManager);
PublicRealmResource realmResource = new PublicRealmResource(realm);
ResteasyProviderFactory.getInstance().injectProperties(realmResource);
//resourceContext.initResource(realmResource);
return realmResource;
}
@@ -188,7 +186,6 @@ public class RealmsResource {
IdentityBrokerService brokerService = new IdentityBrokerService(realm);
ResteasyProviderFactory.getInstance().injectProperties(brokerService);
//resourceContext.initResource(brokerService);
brokerService.init();

View File

@@ -151,12 +151,12 @@ public class AdminConsole {
*/
@Path("config")
@GET
@Produces("application/json")
@Produces(MediaType.APPLICATION_JSON)
@NoCache
public ClientManager.InstallationAdapterConfig config() {
ClientModel consoleApp = realm.getClientByClientId(Constants.ADMIN_CONSOLE_APPLICATION);
ClientModel consoleApp = realm.getClientByClientId(Constants.ADMIN_CONSOLE_CLIENT_ID);
if (consoleApp == null) {
throw new NotFoundException("Could not find admin console application");
throw new NotFoundException("Could not find admin console client");
}
return new ClientManager().toInstallationRepresentation(realm, consoleApp, keycloak.getBaseUri(uriInfo));
@@ -170,7 +170,7 @@ public class AdminConsole {
*/
@Path("whoami")
@GET
@Produces("application/json")
@Produces(MediaType.APPLICATION_JSON)
@NoCache
public Response whoAmI(final @Context HttpHeaders headers) {
RealmManager realmManager = new RealmManager(session);
@@ -208,7 +208,7 @@ public class AdminConsole {
private void addRealmAccess(RealmModel realm, UserModel user, Map<String, Set<String>> realmAdminAccess) {
RealmManager realmManager = new RealmManager(session);
ClientModel realmAdminApp = realm.getClientByClientId(realmManager.getRealmAdminApplicationName(realm));
ClientModel realmAdminApp = realm.getClientByClientId(realmManager.getRealmAdminClientId(realm));
Set<RoleModel> roles = realmAdminApp.getRoles();
for (RoleModel role : roles) {
if (!user.hasRole(role)) continue;
@@ -223,7 +223,7 @@ public class AdminConsole {
private void addMasterRealmAccess(RealmModel masterRealm, UserModel user, Map<String, Set<String>> realmAdminAccess) {
List<RealmModel> realms = session.realms().getRealms();
for (RealmModel realm : realms) {
ClientModel realmAdminApp = realm.getMasterAdminApp();
ClientModel realmAdminApp = realm.getMasterAdminClient();
Set<RoleModel> roles = realmAdminApp.getRoles();
for (RoleModel role : roles) {
if (!user.hasRole(role)) continue;

View File

@@ -16,7 +16,6 @@ import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.models.utils.ModelToRepresentation;
import org.keycloak.models.utils.RepresentationToModel;
import org.keycloak.representations.adapters.action.GlobalRequestResult;
import org.keycloak.representations.idm.ApplicationRepresentation;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.UserSessionRepresentation;
@@ -49,7 +48,7 @@ import java.util.Map;
import java.util.Set;
/**
* Base resource class for managing one particular application of a realm.
* Base resource class for managing one particular client of a realm.
*
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
@@ -88,7 +87,7 @@ public class ClientResource {
}
/**
* Update the application.
* Update the client.
* @param rep
* @return
*/
@@ -107,7 +106,7 @@ public class ClientResource {
/**
* Get representation of the application.
* Get representation of the client.
*
* @return
*/
@@ -132,7 +131,7 @@ public class ClientResource {
/**
* Return keycloak.json file for this application to be used to configure the adapter of that application.
* Return keycloak.json file for this client to be used to configure the adapter of that client.
*
* @return
* @throws IOException
@@ -152,7 +151,7 @@ public class ClientResource {
}
/**
* Return XML that can be included in the JBoss/Wildfly Keycloak subsystem to configure the adapter of that application.
* Return XML that can be included in the JBoss/Wildfly Keycloak subsystem to configure the adapter of that client.
*
* @return
* @throws IOException
@@ -169,26 +168,26 @@ public class ClientResource {
}
/**
* Delete this application.
* Delete this client.
*
*/
@DELETE
@NoCache
public void deleteApplication() {
public void deleteClient() {
auth.requireManage();
new ClientManager(new RealmManager(session)).removeClient(realm, client);
}
/**
* Generates a new secret for this application
* Generates a new secret for this client
*
* @return
*/
@Path("client-secret")
@POST
@Produces("application/json")
@Consumes("application/json")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public CredentialRepresentation regenerateSecret() {
auth.requireManage();
@@ -199,25 +198,25 @@ public class ClientResource {
}
/**
* Get the secret of this application
* Get the secret of this client
*
* @return
*/
@Path("client-secret")
@GET
@NoCache
@Produces("application/json")
@Produces(MediaType.APPLICATION_JSON)
public CredentialRepresentation getClientSecret() {
auth.requireView();
logger.debug("getClientSecret");
UserCredentialModel model = UserCredentialModel.secret(client.getSecret());
if (model == null) throw new NotFoundException("Application does not have a secret");
if (model == null) throw new NotFoundException("Client does not have a secret");
return ModelToRepresentation.toRepresentation(model);
}
/**
* Base path for managing the scope mappings for this application
* Base path for managing the scope mappings for this client
*
* @return
*/
@@ -233,14 +232,14 @@ public class ClientResource {
/**
* Returns set of allowed origin. This is used for CORS requests. Access tokens will have
* their allowedOrigins claim set to this value for tokens created for this application.
* their allowedOrigins claim set to this value for tokens created for this client.
*
* @return
*/
@Path("allowed-origins")
@GET
@NoCache
@Produces("application/json")
@Produces(MediaType.APPLICATION_JSON)
public Set<String> getAllowedOrigins()
{
auth.requireView();
@@ -250,13 +249,13 @@ public class ClientResource {
/**
* Change the set of allowed origins. This is used for CORS requests. Access tokens will have
* their allowedOrigins claim set to this value for tokens created for this application.
* their allowedOrigins claim set to this value for tokens created for this client.
*
* @param allowedOrigins
*/
@Path("allowed-origins")
@PUT
@Consumes("application/json")
@Consumes(MediaType.APPLICATION_JSON)
public void updateAllowedOrigins(Set<String> allowedOrigins)
{
auth.requireManage();
@@ -266,13 +265,13 @@ public class ClientResource {
/**
* Remove set of allowed origins from current allowed origins list. This is used for CORS requests. Access tokens will have
* their allowedOrigins claim set to this value for tokens created for this application.
* their allowedOrigins claim set to this value for tokens created for this client.
*
* @param allowedOrigins
*/
@Path("allowed-origins")
@DELETE
@Consumes("application/json")
@Consumes(MediaType.APPLICATION_JSON)
public void deleteAllowedOrigins(Set<String> allowedOrigins)
{
auth.requireManage();
@@ -283,18 +282,18 @@ public class ClientResource {
}
/**
* If the application has an admin URL, push the application's revocation policy to it.
* If the client has an admin URL, push the client's revocation policy to it.
*
*/
@Path("push-revocation")
@POST
public GlobalRequestResult pushRevocation() {
auth.requireManage();
return new ResourceAdminManager().pushApplicationRevocationPolicy(uriInfo.getRequestUri(), realm, client);
return new ResourceAdminManager().pushClientRevocationPolicy(uriInfo.getRequestUri(), realm, client);
}
/**
* Number of user sessions associated with this application
* Number of user sessions associated with this client
*
* {
* "count": number
@@ -314,7 +313,7 @@ public class ClientResource {
}
/**
* Return a list of user sessions associated with this application
* Return a list of user sessions associated with this client
*
* @return
*/
@@ -335,18 +334,18 @@ public class ClientResource {
}
/**
* If the application has an admin URL, invalidate all sessions associated with that application directly.
* If the client has an admin URL, invalidate all sessions associated with that client directly.
*
*/
@Path("logout-all")
@POST
public GlobalRequestResult logoutAll() {
auth.requireManage();
return new ResourceAdminManager().logoutApplication(uriInfo.getRequestUri(), realm, client);
return new ResourceAdminManager().logoutClient(uriInfo.getRequestUri(), realm, client);
}
/**
* If the application has an admin URL, invalidate the sessions for a particular user directly.
* If the client has an admin URL, invalidate the sessions for a particular user directly.
*
*/
@Path("logout-user/{username}")
@@ -357,18 +356,18 @@ public class ClientResource {
if (user == null) {
throw new NotFoundException("User not found");
}
new ResourceAdminManager().logoutUserFromApplication(uriInfo.getRequestUri(), realm, client, user, session);
new ResourceAdminManager().logoutUserFromClient(uriInfo.getRequestUri(), realm, client, user, session);
}
/**
* Manually register cluster node to this application - usually it's not needed to call this directly as adapter should handle
* Manually register cluster node to this client - usually it's not needed to call this directly as adapter should handle
* by sending registration request to Keycloak
*
* @param formParams
*/
@Path("nodes")
@POST
@Consumes("application/json")
@Consumes(MediaType.APPLICATION_JSON)
public void registerNode(Map<String, String> formParams) {
auth.requireManage();
String node = formParams.get("node");
@@ -380,7 +379,7 @@ public class ClientResource {
}
/**
* Unregister cluster node from this application
* Unregister cluster node from this client
*
* @param node
*/
@@ -393,7 +392,7 @@ public class ClientResource {
Integer time = client.getRegisteredNodes().get(node);
if (time == null) {
throw new NotFoundException("Application does not have a node " + node);
throw new NotFoundException("Client does not have a node " + node);
}
client.unregisterNode(node);

View File

@@ -27,7 +27,7 @@ import java.util.ArrayList;
import java.util.List;
/**
* Base resource class for managing a realm's applications.
* Base resource class for managing a realm's clients.
*
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
@@ -48,7 +48,7 @@ public class ClientsResource {
}
/**
* List of applications belonging to this realm.
* List of clients belonging to this realm.
*
* @return
*/
@@ -100,7 +100,7 @@ public class ClientsResource {
}
/**
* Base path for managing a specific application.
* Base path for managing a specific client.
*
* @param name
* @return

View File

@@ -27,6 +27,7 @@ import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import java.util.ArrayList;
@@ -53,7 +54,7 @@ public class IdentityProviderResource {
@GET
@NoCache
@Produces("application/json")
@Produces(MediaType.APPLICATION_JSON)
public IdentityProviderRepresentation getIdentityProvider() {
IdentityProviderRepresentation rep = ModelToRepresentation.toRepresentation(this.identityProviderModel);
@@ -73,7 +74,7 @@ public class IdentityProviderResource {
}
@PUT
@Consumes("application/json")
@Consumes(MediaType.APPLICATION_JSON)
public Response update(IdentityProviderRepresentation providerRep) {
try {
this.auth.requireManage();

View File

@@ -57,7 +57,7 @@ public class IdentityProvidersResource {
@Path("/providers/{provider_id}")
@GET
@NoCache
@Produces("application/json")
@Produces(MediaType.APPLICATION_JSON)
public Response getIdentityProviders(@PathParam("provider_id") String providerId) {
this.auth.requireView();
IdentityProviderFactory providerFactory = getProviderFactorytById(providerId);
@@ -108,7 +108,7 @@ public class IdentityProvidersResource {
@GET
@Path("instances")
@NoCache
@Produces("application/json")
@Produces(MediaType.APPLICATION_JSON)
public List<IdentityProviderRepresentation> getIdentityProviders() {
this.auth.requireView();

View File

@@ -19,6 +19,7 @@ import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import java.util.LinkedList;
@@ -59,7 +60,7 @@ public class ProtocolMappersResource {
@GET
@NoCache
@Path("protocol/{protocol}")
@Produces("application/json")
@Produces(MediaType.APPLICATION_JSON)
public List<ProtocolMapperRepresentation> getMappersPerProtocol(@PathParam("protocol") String protocol) {
auth.requireView();
List<ProtocolMapperRepresentation> mappers = new LinkedList<ProtocolMapperRepresentation>();
@@ -77,7 +78,7 @@ public class ProtocolMappersResource {
@Path("models")
@POST
@NoCache
@Consumes("application/json")
@Consumes(MediaType.APPLICATION_JSON)
public Response createMapper(ProtocolMapperRepresentation rep) {
auth.requireManage();
ProtocolMapperModel model = RepresentationToModel.toModel(rep);
@@ -91,7 +92,7 @@ public class ProtocolMappersResource {
@Path("add-models")
@POST
@NoCache
@Consumes("application/json")
@Consumes(MediaType.APPLICATION_JSON)
public void createMapper(List<ProtocolMapperRepresentation> reps) {
auth.requireManage();
for (ProtocolMapperRepresentation rep : reps) {
@@ -103,7 +104,7 @@ public class ProtocolMappersResource {
@GET
@NoCache
@Path("models")
@Produces("application/json")
@Produces(MediaType.APPLICATION_JSON)
public List<ProtocolMapperRepresentation> getMappers() {
auth.requireView();
List<ProtocolMapperRepresentation> mappers = new LinkedList<ProtocolMapperRepresentation>();
@@ -116,7 +117,7 @@ public class ProtocolMappersResource {
@GET
@NoCache
@Path("models/{id}")
@Produces("application/json")
@Produces(MediaType.APPLICATION_JSON)
public ProtocolMapperRepresentation getMapperById(@PathParam("id") String id) {
auth.requireView();
ProtocolMapperModel model = client.getProtocolMapperById(id);
@@ -127,7 +128,7 @@ public class ProtocolMappersResource {
@PUT
@NoCache
@Path("models/{id}")
@Consumes("application/json")
@Consumes(MediaType.APPLICATION_JSON)
public void update(@PathParam("id") String id, ProtocolMapperRepresentation rep) {
auth.requireManage();
ProtocolMapperModel model = client.getProtocolMapperById(id);

View File

@@ -9,7 +9,7 @@ import org.keycloak.events.Event;
import org.keycloak.events.EventQuery;
import org.keycloak.events.EventStoreProvider;
import org.keycloak.events.EventType;
import org.keycloak.exportimport.ApplicationImporter;
import org.keycloak.exportimport.ClientImporter;
import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ModelDuplicateException;
@@ -85,40 +85,38 @@ public class RealmAdminResource {
}
/**
* Base path for importing applications under this realm.
* Base path for importing clients under this realm.
*
* @return
*/
@Path("application-importers/{formatId}")
public Object getApplicationImporter(@PathParam("formatId") String formatId) {
ApplicationImporter importer = session.getProvider(ApplicationImporter.class, formatId);
@Path("client-importers/{formatId}")
public Object getClientImporter(@PathParam("formatId") String formatId) {
ClientImporter importer = session.getProvider(ClientImporter.class, formatId);
return importer.createJaxrsService(realm, auth);
}
/**
* Base path for managing applications under this realm.
* Base path for managing clients under this realm.
*
* @return
*/
@Path("applications")
public ClientsResource getApplications() {
@Path("clients")
public ClientsResource getClients() {
ClientsResource clientsResource = new ClientsResource(realm, auth);
ResteasyProviderFactory.getInstance().injectProperties(clientsResource);
//resourceContext.initResource(applicationsResource);
return clientsResource;
}
/**
* Base path for managing applications under this realm.
* Base path for managing clients under this realm.
*
* @return
*/
@Path("applications-by-id")
public ClientsByIdResource getApplicationsById() {
ClientsByIdResource applicationsResource = new ClientsByIdResource(realm, auth);
ResteasyProviderFactory.getInstance().injectProperties(applicationsResource);
//resourceContext.initResource(applicationsResource);
return applicationsResource;
@Path("clients-by-id")
public ClientsByIdResource getClientsById() {
ClientsByIdResource clientsResource = new ClientsByIdResource(realm, auth);
ResteasyProviderFactory.getInstance().injectProperties(clientsResource);
return clientsResource;
}
/**
@@ -132,14 +130,13 @@ public class RealmAdminResource {
}
/**
* Get the top-level representation of the realm. It will not include nested information like User, Application, or OAuth
* Client representations.
* Get the top-level representation of the realm. It will not include nested information like User and Client representations.
*
* @return
*/
@GET
@NoCache
@Produces("application/json")
@Produces(MediaType.APPLICATION_JSON)
public RealmRepresentation getRealm() {
if (auth.hasView()) {
RealmRepresentation rep = ModelToRepresentation.toRepresentation(realm, false);
@@ -162,14 +159,14 @@ public class RealmAdminResource {
}
/**
* Update the top-level information of this realm. Any user, roles, application, or oauth client information in the representation
* Update the top-level information of this realm. Any user, roles or client information in the representation
* will be ignored. This will only update top-level attributes of the realm.
*
* @param rep
* @return
*/
@PUT
@Consumes("application/json")
@Consumes(MediaType.APPLICATION_JSON)
public Response updateRealm(final RealmRepresentation rep) {
auth.requireManage();
@@ -237,7 +234,7 @@ public class RealmAdminResource {
}
/**
* Path for managing all realm-level or application-level roles defined in this realm by it's id.
* Path for managing all realm-level or client-level roles defined in this realm by it's id.
*
* @return
*/
@@ -250,7 +247,7 @@ public class RealmAdminResource {
}
/**
* Push the realm's revocation policy to any application that has an admin url associated with it.
* Push the realm's revocation policy to any client that has an admin url associated with it.
*
*/
@Path("push-revocation")
@@ -261,7 +258,7 @@ public class RealmAdminResource {
}
/**
* Removes all user sessions. Any application that has an admin url will also be told to invalidate any sessions
* Removes all user sessions. Any client that has an admin url will also be told to invalidate any sessions
* they have.
*
*/
@@ -273,7 +270,7 @@ public class RealmAdminResource {
}
/**
* Remove a specific user session. Any application that has an admin url will also be told to invalidate this
* Remove a specific user session. Any client that has an admin url will also be told to invalidate this
* particular session.
*
* @param sessionId
@@ -287,46 +284,46 @@ public class RealmAdminResource {
}
/**
* Returns a JSON map. The key is the application name, the value is the number of sessions that currently are active
* with that application. Only application's that actually have a session associated with them will be in this map.
* Returns a JSON map. The key is the client name, the value is the number of sessions that currently are active
* with that client. Only client's that actually have a session associated with them will be in this map.
*
* @return
*/
@Path("application-session-stats")
@Path("client-session-stats")
@GET
@NoCache
@Produces(MediaType.APPLICATION_JSON)
@Deprecated
public Map<String, Integer> getApplicationSessionStats() {
public Map<String, Integer> getClientSessionStats() {
auth.requireView();
Map<String, Integer> stats = new HashMap<String, Integer>();
for (ClientModel application : realm.getClients()) {
int size = session.sessions().getActiveUserSessions(application.getRealm(), application);
for (ClientModel client : realm.getClients()) {
int size = session.sessions().getActiveUserSessions(client.getRealm(), client);
if (size == 0) continue;
stats.put(application.getClientId(), size);
stats.put(client.getClientId(), size);
}
return stats;
}
/**
* Returns a JSON map. The key is the application id, the value is the number of sessions that currently are active
* with that application. Only application's that actually have a session associated with them will be in this map.
* Returns a JSON map. The key is the client id, the value is the number of sessions that currently are active
* with that client. Only client's that actually have a session associated with them will be in this map.
*
* @return
*/
@Path("application-by-id-session-stats")
@Path("client-by-id-session-stats")
@GET
@NoCache
@Produces(MediaType.APPLICATION_JSON)
public List<Map<String, String>> getApplicationByIdSessionStats() {
public List<Map<String, String>> getClientByIdSessionStats() {
auth.requireView();
List<Map<String, String>> data = new LinkedList<Map<String, String>>();
for (ClientModel application : realm.getClients()) {
int size = session.sessions().getActiveUserSessions(application.getRealm(), application);
for (ClientModel client : realm.getClients()) {
int size = session.sessions().getActiveUserSessions(client.getRealm(), client);
if (size == 0) continue;
Map<String, String> map = new HashMap<String, String>();
map.put("id", application.getId());
map.put("name", application.getClientId());
map.put("id", client.getId());
map.put("clientId", client.getClientId());
map.put("active", size + "");
data.add(map);
}
@@ -341,7 +338,7 @@ public class RealmAdminResource {
@GET
@NoCache
@Path("events/config")
@Produces("application/json")
@Produces(MediaType.APPLICATION_JSON)
public RealmEventsConfigRepresentation getRealmEventsConfig() {
auth.init(RealmAuth.Resource.EVENTS).requireView();
@@ -355,7 +352,7 @@ public class RealmAdminResource {
*/
@PUT
@Path("events/config")
@Consumes("application/json")
@Consumes(MediaType.APPLICATION_JSON)
public void updateRealmEventsConfig(final RealmEventsConfigRepresentation rep) {
auth.init(RealmAuth.Resource.EVENTS).requireManage();

View File

@@ -74,27 +74,27 @@ public class RealmsAdminResource {
*/
@GET
@NoCache
@Produces("application/json")
@Produces(MediaType.APPLICATION_JSON)
public List<RealmRepresentation> getRealms() {
RealmManager realmManager = new RealmManager(session);
List<RealmRepresentation> reps = new ArrayList<RealmRepresentation>();
if (auth.getRealm().equals(realmManager.getKeycloakAdminstrationRealm())) {
List<RealmModel> realms = session.realms().getRealms();
for (RealmModel realm : realms) {
addRealmRep(reps, realm, realm.getMasterAdminApp());
addRealmRep(reps, realm, realm.getMasterAdminClient());
}
} else {
ClientModel adminApp = auth.getRealm().getClientByClientId(realmManager.getRealmAdminApplicationName(auth.getRealm()));
ClientModel adminApp = auth.getRealm().getClientByClientId(realmManager.getRealmAdminClientId(auth.getRealm()));
addRealmRep(reps, auth.getRealm(), adminApp);
}
logger.debug(("getRealms()"));
return reps;
}
protected void addRealmRep(List<RealmRepresentation> reps, RealmModel realm, ClientModel realmManagementApplication) {
if (auth.hasAppRole(realmManagementApplication, AdminRoles.MANAGE_REALM)) {
protected void addRealmRep(List<RealmRepresentation> reps, RealmModel realm, ClientModel realmManagementClient) {
if (auth.hasAppRole(realmManagementClient, AdminRoles.MANAGE_REALM)) {
reps.add(ModelToRepresentation.toRepresentation(realm, false));
} else if (auth.hasOneOfAppRole(realmManagementApplication, AdminRoles.ALL_REALM_ROLES)) {
} else if (auth.hasOneOfAppRole(realmManagementClient, AdminRoles.ALL_REALM_ROLES)) {
RealmRepresentation rep = new RealmRepresentation();
rep.setRealm(realm.getName());
reps.add(rep);
@@ -109,7 +109,7 @@ public class RealmsAdminResource {
* @return
*/
@POST
@Consumes("application/json")
@Consumes(MediaType.APPLICATION_JSON)
public Response importRealm(@Context final UriInfo uriInfo, final RealmRepresentation rep) {
RealmManager realmManager = new RealmManager(session);
realmManager.setContextPath(keycloak.getContextPath());
@@ -186,7 +186,7 @@ public class RealmsAdminResource {
}
RealmModel adminRealm = new RealmManager(session).getKeycloakAdminstrationRealm();
ClientModel realmAdminApp = realm.getMasterAdminApp();
ClientModel realmAdminApp = realm.getMasterAdminClient();
for (String r : AdminRoles.ALL_REALM_ROLES) {
RoleModel role = realmAdminApp.getRole(r);
auth.getUser().grantRole(role);
@@ -214,9 +214,9 @@ public class RealmsAdminResource {
RealmAuth realmAuth;
if (auth.getRealm().equals(realmManager.getKeycloakAdminstrationRealm())) {
realmAuth = new RealmAuth(auth, realm.getMasterAdminApp());
realmAuth = new RealmAuth(auth, realm.getMasterAdminClient());
} else {
realmAuth = new RealmAuth(auth, realm.getClientByClientId(realmManager.getRealmAdminApplicationName(auth.getRealm())));
realmAuth = new RealmAuth(auth, realm.getClientByClientId(realmManager.getRealmAdminClientId(auth.getRealm())));
}
RealmAdminResource adminResource = new RealmAdminResource(realmAuth, realm, tokenManager);

View File

@@ -19,6 +19,7 @@ import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import java.util.List;
import java.util.Set;
@@ -52,7 +53,7 @@ public class RoleByIdResource extends RoleResource {
@Path("{role-id}")
@GET
@NoCache
@Produces("application/json")
@Produces(MediaType.APPLICATION_JSON)
public RoleRepresentation getRole(final @PathParam("role-id") String id) {
RoleModel roleModel = getRoleModel(id);
auth.requireView();
@@ -101,7 +102,7 @@ public class RoleByIdResource extends RoleResource {
*/
@Path("{role-id}")
@PUT
@Consumes("application/json")
@Consumes(MediaType.APPLICATION_JSON)
public void updateRole(final @PathParam("role-id") String id, final RoleRepresentation rep) {
RoleModel role = getRoleModel(id);
auth.requireManage();
@@ -116,7 +117,7 @@ public class RoleByIdResource extends RoleResource {
*/
@Path("{role-id}/composites")
@POST
@Consumes("application/json")
@Consumes(MediaType.APPLICATION_JSON)
public void addComposites(final @PathParam("role-id") String id, List<RoleRepresentation> roles) {
RoleModel role = getRoleModel(id);
auth.requireManage();
@@ -132,7 +133,7 @@ public class RoleByIdResource extends RoleResource {
@Path("{role-id}/composites")
@GET
@NoCache
@Produces("application/json")
@Produces(MediaType.APPLICATION_JSON)
public Set<RoleRepresentation> getRoleComposites(final @PathParam("role-id") String id) {
if (logger.isDebugEnabled()) logger.debug("*** getRoleComposites: '" + id + "'");
@@ -150,7 +151,7 @@ public class RoleByIdResource extends RoleResource {
@Path("{role-id}/composites/realm")
@GET
@NoCache
@Produces("application/json")
@Produces(MediaType.APPLICATION_JSON)
public Set<RoleRepresentation> getRealmRoleComposites(final @PathParam("role-id") String id) {
RoleModel role = getRoleModel(id);
auth.requireView();
@@ -158,49 +159,49 @@ public class RoleByIdResource extends RoleResource {
}
/**
* Return a set of application-level roles for a specific app that are in the role's composite
* Return a set of client-level roles for a specific client that are in the role's composite
*
* @param id
* @param appName
* @return
*/
@Path("{role-id}/composites/applications/{app}")
@Path("{role-id}/composites/clients/{app}")
@GET
@NoCache
@Produces("application/json")
public Set<RoleRepresentation> getApplicationRoleComposites(final @PathParam("role-id") String id,
@Produces(MediaType.APPLICATION_JSON)
public Set<RoleRepresentation> getClientRoleComposites(final @PathParam("role-id") String id,
final @PathParam("app") String appName) {
RoleModel role = getRoleModel(id);
auth.requireView();
ClientModel app = realm.getClientByClientId(appName);
if (app == null) {
throw new NotFoundException("Could not find application: " + appName);
throw new NotFoundException("Could not find client: " + appName);
}
return getApplicationRoleComposites(app, role);
return getClientRoleComposites(app, role);
}
/**
* Return a set of application-level roles for a specific app that are in the role's composite
* Return a set of client-level roles for a specific client that are in the role's composite
*
* @param id
* @param appId
* @return
*/
@Path("{role-id}/composites/applications-by-id/{appId}")
@Path("{role-id}/composites/clients-by-id/{appId}")
@GET
@NoCache
@Produces("application/json")
public Set<RoleRepresentation> getApplicationByIdRoleComposites(final @PathParam("role-id") String id,
@Produces(MediaType.APPLICATION_JSON)
public Set<RoleRepresentation> getClientByIdRoleComposites(final @PathParam("role-id") String id,
final @PathParam("appId") String appId) {
RoleModel role = getRoleModel(id);
auth.requireView();
ClientModel app = realm.getClientById(appId);
if (app == null) {
throw new NotFoundException("Could not find application: " + appId);
throw new NotFoundException("Could not find client: " + appId);
}
return getApplicationRoleComposites(app, role);
return getClientRoleComposites(app, role);
}
/**
@@ -211,7 +212,7 @@ public class RoleByIdResource extends RoleResource {
*/
@Path("{role-id}/composites")
@DELETE
@Consumes("application/json")
@Consumes(MediaType.APPLICATION_JSON)
public void deleteComposites(final @PathParam("role-id") String id, List<RoleRepresentation> roles) {
RoleModel role = getRoleModel(id);
auth.requireManage();

View File

@@ -20,6 +20,7 @@ import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import java.util.ArrayList;
@@ -43,13 +44,13 @@ public class RoleContainerResource extends RoleResource {
}
/**
* List all roles for this realm or application
* List all roles for this realm or client
*
* @return
*/
@GET
@NoCache
@Produces("application/json")
@Produces(MediaType.APPLICATION_JSON)
public List<RoleRepresentation> getRoles() {
auth.requireAny();
@@ -62,14 +63,14 @@ public class RoleContainerResource extends RoleResource {
}
/**
* Create a new role for this realm or application
* Create a new role for this realm or client
*
* @param uriInfo
* @param rep
* @return
*/
@POST
@Consumes("application/json")
@Consumes(MediaType.APPLICATION_JSON)
public Response createRole(final @Context UriInfo uriInfo, final RoleRepresentation rep) {
auth.requireManage();
@@ -91,7 +92,7 @@ public class RoleContainerResource extends RoleResource {
@Path("{role-name}")
@GET
@NoCache
@Produces("application/json")
@Produces(MediaType.APPLICATION_JSON)
public RoleRepresentation getRole(final @PathParam("role-name") String roleName) {
auth.requireView();
@@ -131,7 +132,7 @@ public class RoleContainerResource extends RoleResource {
*/
@Path("{role-name}")
@PUT
@Consumes("application/json")
@Consumes(MediaType.APPLICATION_JSON)
public Response updateRole(final @PathParam("role-name") String roleName, final RoleRepresentation rep) {
auth.requireManage();
@@ -155,7 +156,7 @@ public class RoleContainerResource extends RoleResource {
*/
@Path("{role-name}/composites")
@POST
@Consumes("application/json")
@Consumes(MediaType.APPLICATION_JSON)
public void addComposites(final @PathParam("role-name") String roleName, List<RoleRepresentation> roles) {
auth.requireManage();
@@ -175,7 +176,7 @@ public class RoleContainerResource extends RoleResource {
@Path("{role-name}/composites")
@GET
@NoCache
@Produces("application/json")
@Produces(MediaType.APPLICATION_JSON)
public Set<RoleRepresentation> getRoleComposites(final @PathParam("role-name") String roleName) {
auth.requireManage();
@@ -195,7 +196,7 @@ public class RoleContainerResource extends RoleResource {
@Path("{role-name}/composites/realm")
@GET
@NoCache
@Produces("application/json")
@Produces(MediaType.APPLICATION_JSON)
public Set<RoleRepresentation> getRealmRoleComposites(final @PathParam("role-name") String roleName) {
auth.requireManage();
@@ -207,30 +208,30 @@ public class RoleContainerResource extends RoleResource {
}
/**
* An app-level roles for a specific app for this role's composite
* An client-level roles for a specific client for this role's composite
*
* @param roleName role's name (not id!)
* @param appName
* @param clientId
* @return
*/
@Path("{role-name}/composites/application/{app}")
@Path("{role-name}/composites/client/{clientId}")
@GET
@NoCache
@Produces("application/json")
public Set<RoleRepresentation> getApplicationRoleComposites(final @PathParam("role-name") String roleName,
final @PathParam("app") String appName) {
@Produces(MediaType.APPLICATION_JSON)
public Set<RoleRepresentation> getClientRoleComposites(final @PathParam("role-name") String roleName,
final @PathParam("clientId") String clientId) {
auth.requireManage();
RoleModel role = roleContainer.getRole(roleName);
if (role == null) {
throw new NotFoundException("Could not find role: " + roleName);
}
ClientModel app = realm.getClientByClientId(appName);
ClientModel app = realm.getClientByClientId(clientId);
if (app == null) {
throw new NotFoundException("Could not find application: " + appName);
throw new NotFoundException("Could not find client: " + clientId);
}
return getApplicationRoleComposites(app, role);
return getClientRoleComposites(app, role);
}
@@ -238,27 +239,27 @@ public class RoleContainerResource extends RoleResource {
* An app-level roles for a specific app for this role's composite
*
* @param roleName role's name (not id!)
* @param appId
* @param id
* @return
*/
@Path("{role-name}/composites/application-by-id/{appId}")
@Path("{role-name}/composites/client-by-id/{id}")
@GET
@NoCache
@Produces("application/json")
public Set<RoleRepresentation> getApplicationByIdRoleComposites(final @PathParam("role-name") String roleName,
final @PathParam("appId") String appId) {
@Produces(MediaType.APPLICATION_JSON)
public Set<RoleRepresentation> getClientByIdRoleComposites(final @PathParam("role-name") String roleName,
final @PathParam("id") String id) {
auth.requireManage();
RoleModel role = roleContainer.getRole(roleName);
if (role == null) {
throw new NotFoundException("Could not find role: " + roleName);
}
ClientModel app = realm.getClientById(appId);
if (app == null) {
throw new NotFoundException("Could not find application: " + appId);
ClientModel client = realm.getClientById(id);
if (client == null) {
throw new NotFoundException("Could not find client: " + id);
}
return getApplicationRoleComposites(app, role);
return getClientRoleComposites(client, role);
}
@@ -270,7 +271,7 @@ public class RoleContainerResource extends RoleResource {
*/
@Path("{role-name}/composites")
@DELETE
@Consumes("application/json")
@Consumes(MediaType.APPLICATION_JSON)
public void deleteComposites(final @PathParam("role-name") String roleName, List<RoleRepresentation> roles) {
auth.requireManage();

View File

@@ -69,7 +69,7 @@ public abstract class RoleResource {
return composites;
}
protected Set<RoleRepresentation> getApplicationRoleComposites(ClientModel app, RoleModel role) {
protected Set<RoleRepresentation> getClientRoleComposites(ClientModel app, RoleModel role) {
if (!role.isComposite() || role.getComposites().size() == 0) return Collections.emptySet();
Set<RoleRepresentation> composites = new HashSet<RoleRepresentation>(role.getComposites().size());

Some files were not shown because too many files have changed in this diff Show More