Merge pull request #1179 from mposolda/master
KEYCLOAK-1070 Improve Applications page and add available roles. Add tes...
This commit is contained in:
commit
b8d23829aa
11 changed files with 438 additions and 170 deletions
|
@ -20,7 +20,7 @@ import javax.ws.rs.core.UriInfo;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
import org.keycloak.account.AccountPages;
|
import org.keycloak.account.AccountPages;
|
||||||
import org.keycloak.account.AccountProvider;
|
import org.keycloak.account.AccountProvider;
|
||||||
import org.keycloak.account.freemarker.model.ConsentBean;
|
import org.keycloak.account.freemarker.model.ApplicationsBean;
|
||||||
import org.keycloak.account.freemarker.model.AccountBean;
|
import org.keycloak.account.freemarker.model.AccountBean;
|
||||||
import org.keycloak.account.freemarker.model.AccountFederatedIdentityBean;
|
import org.keycloak.account.freemarker.model.AccountFederatedIdentityBean;
|
||||||
import org.keycloak.account.freemarker.model.FeaturesBean;
|
import org.keycloak.account.freemarker.model.FeaturesBean;
|
||||||
|
@ -186,7 +186,7 @@ public class FreeMarkerAccountProvider implements AccountProvider {
|
||||||
attributes.put("sessions", new SessionsBean(realm, sessions));
|
attributes.put("sessions", new SessionsBean(realm, sessions));
|
||||||
break;
|
break;
|
||||||
case APPLICATIONS:
|
case APPLICATIONS:
|
||||||
attributes.put("consent", new ConsentBean(user));
|
attributes.put("applications", new ApplicationsBean(realm, user));
|
||||||
attributes.put("advancedMsg", new AdvancedMessageFormatterMethod(locale, messagesBundle));
|
attributes.put("advancedMsg", new AdvancedMessageFormatterMethod(locale, messagesBundle));
|
||||||
break;
|
break;
|
||||||
case PASSWORD:
|
case PASSWORD:
|
||||||
|
|
|
@ -0,0 +1,154 @@
|
||||||
|
package org.keycloak.account.freemarker.model;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.keycloak.models.ClientModel;
|
||||||
|
import org.keycloak.models.UserConsentModel;
|
||||||
|
import org.keycloak.models.ProtocolMapperModel;
|
||||||
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.RoleModel;
|
||||||
|
import org.keycloak.models.UserModel;
|
||||||
|
import org.keycloak.protocol.oidc.TokenManager;
|
||||||
|
import org.keycloak.util.MultivaluedHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
public class ApplicationsBean {
|
||||||
|
|
||||||
|
private List<ApplicationEntry> applications = new LinkedList<ApplicationEntry>();
|
||||||
|
|
||||||
|
public ApplicationsBean(RealmModel realm, UserModel user) {
|
||||||
|
List<ClientModel> realmClients = realm.getClients();
|
||||||
|
for (ClientModel client : realmClients) {
|
||||||
|
// Don't show bearerOnly clients
|
||||||
|
if (client.isBearerOnly()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<RoleModel> availableRoles = TokenManager.getAccess(null, client, user);
|
||||||
|
// Don't show applications, which user doesn't have access into (any available roles)
|
||||||
|
if (availableRoles.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
List<RoleModel> realmRolesAvailable = new LinkedList<RoleModel>();
|
||||||
|
MultivaluedHashMap<String, ClientRoleEntry> resourceRolesAvailable = new MultivaluedHashMap<String, ClientRoleEntry>();
|
||||||
|
processRoles(availableRoles, realmRolesAvailable, resourceRolesAvailable);
|
||||||
|
|
||||||
|
List<RoleModel> realmRolesGranted = new LinkedList<RoleModel>();
|
||||||
|
MultivaluedHashMap<String, ClientRoleEntry> resourceRolesGranted = new MultivaluedHashMap<String, ClientRoleEntry>();
|
||||||
|
List<String> claimsGranted = new LinkedList<String>();
|
||||||
|
if (client.isConsentRequired()) {
|
||||||
|
UserConsentModel consent = user.getConsentByClient(client.getId());
|
||||||
|
|
||||||
|
if (consent != null) {
|
||||||
|
processRoles(consent.getGrantedRoles(), realmRolesGranted, resourceRolesGranted);
|
||||||
|
|
||||||
|
for (ProtocolMapperModel protocolMapper : consent.getGrantedProtocolMappers()) {
|
||||||
|
claimsGranted.add(protocolMapper.getConsentText());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ApplicationEntry appEntry = new ApplicationEntry(realmRolesAvailable, resourceRolesAvailable, realmRolesGranted, resourceRolesGranted, client, claimsGranted);
|
||||||
|
applications.add(appEntry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processRoles(Set<RoleModel> inputRoles, List<RoleModel> realmRoles, MultivaluedHashMap<String, ClientRoleEntry> clientRoles) {
|
||||||
|
for (RoleModel role : inputRoles) {
|
||||||
|
if (role.getContainer() instanceof RealmModel) {
|
||||||
|
realmRoles.add(role);
|
||||||
|
} else {
|
||||||
|
ClientModel currentClient = (ClientModel) role.getContainer();
|
||||||
|
ClientRoleEntry clientRole = new ClientRoleEntry(currentClient.getClientId(), currentClient.getName(),
|
||||||
|
role.getName(), role.getDescription());
|
||||||
|
clientRoles.add(currentClient.getClientId(), clientRole);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ApplicationEntry> getApplications() {
|
||||||
|
return applications;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ApplicationEntry {
|
||||||
|
|
||||||
|
private final List<RoleModel> realmRolesAvailable;
|
||||||
|
private final MultivaluedHashMap<String, ClientRoleEntry> resourceRolesAvailable;
|
||||||
|
private final List<RoleModel> realmRolesGranted;
|
||||||
|
private final MultivaluedHashMap<String, ClientRoleEntry> resourceRolesGranted;
|
||||||
|
private final ClientModel client;
|
||||||
|
private final List<String> claimsGranted;
|
||||||
|
|
||||||
|
public ApplicationEntry(List<RoleModel> realmRolesAvailable, MultivaluedHashMap<String, ClientRoleEntry> resourceRolesAvailable,
|
||||||
|
List<RoleModel> realmRolesGranted, MultivaluedHashMap<String, ClientRoleEntry> resourceRolesGranted,
|
||||||
|
ClientModel client, List<String> claimsGranted) {
|
||||||
|
this.realmRolesAvailable = realmRolesAvailable;
|
||||||
|
this.resourceRolesAvailable = resourceRolesAvailable;
|
||||||
|
this.realmRolesGranted = realmRolesGranted;
|
||||||
|
this.resourceRolesGranted = resourceRolesGranted;
|
||||||
|
this.client = client;
|
||||||
|
this.claimsGranted = claimsGranted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<RoleModel> getRealmRolesAvailable() {
|
||||||
|
return realmRolesAvailable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MultivaluedHashMap<String, ClientRoleEntry> getResourceRolesAvailable() {
|
||||||
|
return resourceRolesAvailable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<RoleModel> getRealmRolesGranted() {
|
||||||
|
return realmRolesGranted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MultivaluedHashMap<String, ClientRoleEntry> getResourceRolesGranted() {
|
||||||
|
return resourceRolesGranted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClientModel getClient() {
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getClaimsGranted() {
|
||||||
|
return claimsGranted;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Same class used in OAuthGrantBean as well. Maybe should be merged into common-freemarker...
|
||||||
|
public static class ClientRoleEntry {
|
||||||
|
|
||||||
|
private final String clientId;
|
||||||
|
private final String clientName;
|
||||||
|
private final String roleName;
|
||||||
|
private final String roleDescription;
|
||||||
|
|
||||||
|
public ClientRoleEntry(String clientId, String clientName, String roleName, String roleDescription) {
|
||||||
|
this.clientId = clientId;
|
||||||
|
this.clientName = clientName;
|
||||||
|
this.roleName = roleName;
|
||||||
|
this.roleDescription = roleDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getClientId() {
|
||||||
|
return clientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getClientName() {
|
||||||
|
return clientName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRoleName() {
|
||||||
|
return roleName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRoleDescription() {
|
||||||
|
return roleDescription;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,117 +0,0 @@
|
||||||
package org.keycloak.account.freemarker.model;
|
|
||||||
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.keycloak.models.ClientModel;
|
|
||||||
import org.keycloak.models.UserConsentModel;
|
|
||||||
import org.keycloak.models.ProtocolMapperModel;
|
|
||||||
import org.keycloak.models.RealmModel;
|
|
||||||
import org.keycloak.models.RoleModel;
|
|
||||||
import org.keycloak.models.UserModel;
|
|
||||||
import org.keycloak.util.MultivaluedHashMap;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
|
||||||
*/
|
|
||||||
public class ConsentBean {
|
|
||||||
|
|
||||||
private List<ClientGrantBean> clientGrants = new LinkedList<ClientGrantBean>();
|
|
||||||
|
|
||||||
public ConsentBean(UserModel user) {
|
|
||||||
List<UserConsentModel> grantedConsents = user.getConsents();
|
|
||||||
for (UserConsentModel consent : grantedConsents) {
|
|
||||||
ClientModel client = consent.getClient();
|
|
||||||
|
|
||||||
List<RoleModel> realmRolesGranted = new LinkedList<RoleModel>();
|
|
||||||
MultivaluedHashMap<String, ClientRoleEntry> resourceRolesGranted = new MultivaluedHashMap<String, ClientRoleEntry>();
|
|
||||||
for (RoleModel role : consent.getGrantedRoles()) {
|
|
||||||
if (role.getContainer() instanceof RealmModel) {
|
|
||||||
realmRolesGranted.add(role);
|
|
||||||
} else {
|
|
||||||
ClientModel currentClient = (ClientModel) role.getContainer();
|
|
||||||
ClientRoleEntry clientRole = new ClientRoleEntry(currentClient.getClientId(), currentClient.getName(),
|
|
||||||
role.getName(), role.getDescription());
|
|
||||||
resourceRolesGranted.add(currentClient.getClientId(), clientRole);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
List<String> claimsGranted = new LinkedList<String>();
|
|
||||||
for (ProtocolMapperModel protocolMapper : consent.getGrantedProtocolMappers()) {
|
|
||||||
claimsGranted.add(protocolMapper.getConsentText());
|
|
||||||
}
|
|
||||||
|
|
||||||
ClientGrantBean clientGrant = new ClientGrantBean(realmRolesGranted, resourceRolesGranted, client, claimsGranted);
|
|
||||||
clientGrants.add(clientGrant);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ClientGrantBean> getClientGrants() {
|
|
||||||
return clientGrants;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class ClientGrantBean {
|
|
||||||
|
|
||||||
private final List<RoleModel> realmRolesGranted;
|
|
||||||
private final MultivaluedHashMap<String, ClientRoleEntry> resourceRolesGranted;
|
|
||||||
private final ClientModel client;
|
|
||||||
private final List<String> claimsGranted;
|
|
||||||
|
|
||||||
public ClientGrantBean(List<RoleModel> realmRolesGranted, MultivaluedHashMap<String, ClientRoleEntry> resourceRolesGranted,
|
|
||||||
ClientModel client, List<String> claimsGranted) {
|
|
||||||
this.realmRolesGranted = realmRolesGranted;
|
|
||||||
this.resourceRolesGranted = resourceRolesGranted;
|
|
||||||
this.client = client;
|
|
||||||
this.claimsGranted = claimsGranted;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<RoleModel> getRealmRolesGranted() {
|
|
||||||
return realmRolesGranted;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MultivaluedHashMap<String, ClientRoleEntry> getResourceRolesGranted() {
|
|
||||||
return resourceRolesGranted;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ClientModel getClient() {
|
|
||||||
return client;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getClaimsGranted() {
|
|
||||||
return claimsGranted;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Same class used in OAuthGrantBean as well. Maybe should be merged into common-freemarker...
|
|
||||||
public static class ClientRoleEntry {
|
|
||||||
|
|
||||||
private final String clientId;
|
|
||||||
private final String clientName;
|
|
||||||
private final String roleName;
|
|
||||||
private final String roleDescription;
|
|
||||||
|
|
||||||
public ClientRoleEntry(String clientId, String clientName, String roleName, String roleDescription) {
|
|
||||||
this.clientId = clientId;
|
|
||||||
this.clientName = clientName;
|
|
||||||
this.roleName = roleName;
|
|
||||||
this.roleDescription = roleDescription;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getClientId() {
|
|
||||||
return clientId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getClientName() {
|
|
||||||
return clientName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRoleName() {
|
|
||||||
return roleName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRoleDescription() {
|
|
||||||
return roleDescription;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -13,42 +13,71 @@
|
||||||
<table class="table table-striped table-bordered">
|
<table class="table table-striped table-bordered">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<td>${msg("client")}</td>
|
<td>${msg("application")}</td>
|
||||||
<td>${msg("grantedPersonalInfo")}</td>
|
<td>${msg("availablePermissions")}</td>
|
||||||
<td>${msg("grantedPermissions")}</td>
|
<td>${msg("grantedPermissions")}</td>
|
||||||
|
<td>${msg("grantedPersonalInfo")}</td>
|
||||||
<td>${msg("action")}</td>
|
<td>${msg("action")}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
<#list consent.clientGrants as clientGrant>
|
<#list applications.applications as application>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<#if clientGrant.client.baseUrl??><a href="${clientGrant.client.baseUrl}"></#if>
|
<#if application.client.baseUrl??><a href="${application.client.baseUrl}"></#if>
|
||||||
<#if clientGrant.client.name??>${advancedMsg(clientGrant.client.name)}<#else>${clientGrant.client.clientId}</#if>
|
<#if application.client.name??>${advancedMsg(application.client.name)}<#else>${application.client.clientId}</#if>
|
||||||
<#if clientGrant.client.baseUrl??></a></#if>
|
<#if application.client.baseUrl??></a></#if>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<#list clientGrant.claimsGranted as claim>
|
<#list application.realmRolesAvailable as role>
|
||||||
${advancedMsg(claim)}<#if claim_has_next>, </#if>
|
|
||||||
</#list>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<#list clientGrant.realmRolesGranted as role>
|
|
||||||
<#if role.description??>${advancedMsg(role.description)}<#else>${advancedMsg(role.name)}</#if>
|
<#if role.description??>${advancedMsg(role.description)}<#else>${advancedMsg(role.name)}</#if>
|
||||||
<#if role_has_next>, </#if>
|
<#if role_has_next>, </#if>
|
||||||
</#list>
|
</#list>
|
||||||
<#list clientGrant.resourceRolesGranted?keys as resource>
|
<#list application.resourceRolesAvailable?keys as resource>
|
||||||
<#if clientGrant.realmRolesGranted?has_content>, </#if>
|
<#if application.realmRolesAvailable?has_content>, </#if>
|
||||||
<#list clientGrant.resourceRolesGranted[resource] as clientRole>
|
<#list application.resourceRolesAvailable[resource] as clientRole>
|
||||||
<#if clientRole.roleDescription??>${advancedMsg(clientRole.roleDescription)}<#else>${advancedMsg(clientRole.roleName)}</#if>
|
<#if clientRole.roleDescription??>${advancedMsg(clientRole.roleDescription)}<#else>${advancedMsg(clientRole.roleName)}</#if>
|
||||||
${msg("inResource")} <strong><#if clientRole.clientName??>${advancedMsg(clientRole.clientName)}<#else>${clientRole.clientId}</#if></strong>
|
${msg("inResource")} <strong><#if clientRole.clientName??>${advancedMsg(clientRole.clientName)}<#else>${clientRole.clientId}</#if></strong>
|
||||||
<#if clientRole_has_next>, </#if>
|
<#if clientRole_has_next>, </#if>
|
||||||
</#list>
|
</#list>
|
||||||
</#list>
|
</#list>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<button type='submit' class='btn btn-primary' id='revoke-${clientGrant.client.clientId}' name='clientId' value="${clientGrant.client.id}">${msg("revoke")}</button>
|
<#if application.client.consentRequired>
|
||||||
|
<#list application.realmRolesGranted as role>
|
||||||
|
<#if role.description??>${advancedMsg(role.description)}<#else>${advancedMsg(role.name)}</#if>
|
||||||
|
<#if role_has_next>, </#if>
|
||||||
|
</#list>
|
||||||
|
<#list application.resourceRolesGranted?keys as resource>
|
||||||
|
<#if application.realmRolesGranted?has_content>, </#if>
|
||||||
|
<#list application.resourceRolesGranted[resource] as clientRole>
|
||||||
|
<#if clientRole.roleDescription??>${advancedMsg(clientRole.roleDescription)}<#else>${advancedMsg(clientRole.roleName)}</#if>
|
||||||
|
${msg("inResource")} <strong><#if clientRole.clientName??>${advancedMsg(clientRole.clientName)}<#else>${clientRole.clientId}</#if></strong>
|
||||||
|
<#if clientRole_has_next>, </#if>
|
||||||
|
</#list>
|
||||||
|
</#list>
|
||||||
|
<#else>
|
||||||
|
<strong>${msg("fullAccess")}</strong>
|
||||||
|
</#if>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<#if application.client.consentRequired>
|
||||||
|
<#list application.claimsGranted as claim>
|
||||||
|
${advancedMsg(claim)}<#if claim_has_next>, </#if>
|
||||||
|
</#list>
|
||||||
|
<#else>
|
||||||
|
<strong>${msg("fullAccess")}</strong>
|
||||||
|
</#if>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<#if application.client.consentRequired>
|
||||||
|
<button type='submit' class='btn btn-primary' id='revoke-${application.client.clientId}' name='clientId' value="${application.client.id}">${msg("revoke")}</button>
|
||||||
|
</#if>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</#list>
|
</#list>
|
||||||
|
|
|
@ -12,7 +12,7 @@ changePasswordHtmlTitle=Change Password
|
||||||
sessionsHtmlTitle=Sessions
|
sessionsHtmlTitle=Sessions
|
||||||
accountManagementTitle=Keycloak Account Management
|
accountManagementTitle=Keycloak Account Management
|
||||||
authenticatorTitle=Authenticator
|
authenticatorTitle=Authenticator
|
||||||
applicationsHtmlTitle=Manage Granted Permissions
|
applicationsHtmlTitle=Applications
|
||||||
|
|
||||||
authenticatorCode=One-time code
|
authenticatorCode=One-time code
|
||||||
email=Email
|
email=Email
|
||||||
|
@ -32,7 +32,7 @@ region=State, Province, or Region
|
||||||
postal_code=Zip or Postal code
|
postal_code=Zip or Postal code
|
||||||
country=Country
|
country=Country
|
||||||
emailVerified=Email verified
|
emailVerified=Email verified
|
||||||
gssDelegationCredential=gss delegation credential
|
gssDelegationCredential=GSS Delegation Credential
|
||||||
|
|
||||||
role_admin=Admin
|
role_admin=Admin
|
||||||
role_realm-admin=Realm Admin
|
role_realm-admin=Realm Admin
|
||||||
|
@ -50,6 +50,7 @@ role_manage-identity-providers=Manage identity providers
|
||||||
role_manage-clients=Manage clients
|
role_manage-clients=Manage clients
|
||||||
role_manage-events=Manage events
|
role_manage-events=Manage events
|
||||||
role_view-profile=View profile
|
role_view-profile=View profile
|
||||||
|
role_manage-account=Manage account
|
||||||
client_account=Account
|
client_account=Account
|
||||||
client_security-admin-console=Security Admin Console
|
client_security-admin-console=Security Admin Console
|
||||||
client_realm-management=Realm Management
|
client_realm-management=Realm Management
|
||||||
|
@ -78,10 +79,13 @@ authenticator=Authenticator
|
||||||
sessions=Sessions
|
sessions=Sessions
|
||||||
log=Log
|
log=Log
|
||||||
|
|
||||||
grantedPersonalInfo=Granted Personal Info
|
application=Application
|
||||||
|
availablePermissions=Available Permissions
|
||||||
grantedPermissions=Granted Permissions
|
grantedPermissions=Granted Permissions
|
||||||
|
grantedPersonalInfo=Granted Personal Info
|
||||||
action=Action
|
action=Action
|
||||||
inResource=in
|
inResource=in
|
||||||
|
fullAccess=Full Access
|
||||||
revoke=Revoke Grant
|
revoke=Revoke Grant
|
||||||
|
|
||||||
configureAuthenticators=Configured Authenticators
|
configureAuthenticators=Configured Authenticators
|
||||||
|
|
|
@ -76,10 +76,10 @@ public interface UserModel {
|
||||||
void setFederationLink(String link);
|
void setFederationLink(String link);
|
||||||
|
|
||||||
void addConsent(UserConsentModel consent);
|
void addConsent(UserConsentModel consent);
|
||||||
UserConsentModel getConsentByClient(String clientId);
|
UserConsentModel getConsentByClient(String clientInternalId);
|
||||||
List<UserConsentModel> getConsents();
|
List<UserConsentModel> getConsents();
|
||||||
void updateConsent(UserConsentModel consent);
|
void updateConsent(UserConsentModel consent);
|
||||||
boolean revokeConsentForClient(String clientId);
|
boolean revokeConsentForClient(String clientInternalId);
|
||||||
|
|
||||||
public static enum RequiredAction {
|
public static enum RequiredAction {
|
||||||
VERIFY_EMAIL, UPDATE_PROFILE, CONFIGURE_TOTP, UPDATE_PASSWORD
|
VERIFY_EMAIL, UPDATE_PROFILE, CONFIGURE_TOTP, UPDATE_PASSWORD
|
||||||
|
|
|
@ -370,7 +370,7 @@ public class MongoUserProvider implements UserProvider {
|
||||||
.and("grantedProtocolMappers").is(protocolMapper.getId())
|
.and("grantedProtocolMappers").is(protocolMapper.getId())
|
||||||
.get();
|
.get();
|
||||||
DBObject pull = new BasicDBObject("$pull", query);
|
DBObject pull = new BasicDBObject("$pull", query);
|
||||||
getMongoStore().updateEntities(MongoUserEntity.class, query, pull, invocationContext);
|
getMongoStore().updateEntities(MongoUserConsentEntity.class, query, pull, invocationContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -52,7 +52,7 @@ public class ApplicationServlet extends HttpServlet {
|
||||||
PrintWriter pw = resp.getWriter();
|
PrintWriter pw = resp.getWriter();
|
||||||
pw.printf("<html><head><title>%s</title></head><body>", title);
|
pw.printf("<html><head><title>%s</title></head><body>", title);
|
||||||
UriBuilder base = UriBuilder.fromUri("http://localhost:8081/auth");
|
UriBuilder base = UriBuilder.fromUri("http://localhost:8081/auth");
|
||||||
pw.printf(LINK, RealmsResource.accountUrl(base), "account", "account");
|
pw.printf(LINK, RealmsResource.accountUrl(base).build("test"), "account", "account");
|
||||||
|
|
||||||
pw.print("</body></html>");
|
pw.print("</body></html>");
|
||||||
pw.flush();
|
pw.flush();
|
||||||
|
|
|
@ -28,6 +28,7 @@ import org.junit.BeforeClass;
|
||||||
import org.junit.ClassRule;
|
import org.junit.ClassRule;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.keycloak.account.freemarker.model.ApplicationsBean;
|
||||||
import org.keycloak.events.Details;
|
import org.keycloak.events.Details;
|
||||||
import org.keycloak.events.Event;
|
import org.keycloak.events.Event;
|
||||||
import org.keycloak.events.EventType;
|
import org.keycloak.events.EventType;
|
||||||
|
@ -43,6 +44,7 @@ import org.keycloak.services.resources.AccountService;
|
||||||
import org.keycloak.services.resources.RealmsResource;
|
import org.keycloak.services.resources.RealmsResource;
|
||||||
import org.keycloak.testsuite.AssertEvents;
|
import org.keycloak.testsuite.AssertEvents;
|
||||||
import org.keycloak.testsuite.OAuthClient;
|
import org.keycloak.testsuite.OAuthClient;
|
||||||
|
import org.keycloak.testsuite.pages.AccountApplicationsPage;
|
||||||
import org.keycloak.testsuite.pages.AccountLogPage;
|
import org.keycloak.testsuite.pages.AccountLogPage;
|
||||||
import org.keycloak.testsuite.pages.AccountPasswordPage;
|
import org.keycloak.testsuite.pages.AccountPasswordPage;
|
||||||
import org.keycloak.testsuite.pages.AccountSessionsPage;
|
import org.keycloak.testsuite.pages.AccountSessionsPage;
|
||||||
|
@ -63,6 +65,7 @@ import org.openqa.selenium.WebDriver;
|
||||||
import javax.ws.rs.core.UriBuilder;
|
import javax.ws.rs.core.UriBuilder;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
|
@ -129,6 +132,9 @@ public class AccountTest {
|
||||||
@WebResource
|
@WebResource
|
||||||
protected AccountSessionsPage sessionsPage;
|
protected AccountSessionsPage sessionsPage;
|
||||||
|
|
||||||
|
@WebResource
|
||||||
|
protected AccountApplicationsPage applicationsPage;
|
||||||
|
|
||||||
@WebResource
|
@WebResource
|
||||||
protected ErrorPage errorPage;
|
protected ErrorPage errorPage;
|
||||||
|
|
||||||
|
@ -517,4 +523,38 @@ public class AccountTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// More tests (including revoke) are in OAuthGrantTest
|
||||||
|
@Test
|
||||||
|
public void applications() {
|
||||||
|
applicationsPage.open();
|
||||||
|
loginPage.login("test-user@localhost", "password");
|
||||||
|
|
||||||
|
events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=applications").assertEvent();
|
||||||
|
Assert.assertTrue(applicationsPage.isCurrent());
|
||||||
|
|
||||||
|
Map<String, AccountApplicationsPage.AppEntry> apps = applicationsPage.getApplications();
|
||||||
|
Assert.assertEquals(3, apps.size());
|
||||||
|
|
||||||
|
AccountApplicationsPage.AppEntry accountEntry = apps.get("Account");
|
||||||
|
Assert.assertEquals(2, accountEntry.getRolesAvailable().size());
|
||||||
|
Assert.assertTrue(accountEntry.getRolesAvailable().contains("Manage account in Account"));
|
||||||
|
Assert.assertTrue(accountEntry.getRolesAvailable().contains("View profile in Account"));
|
||||||
|
Assert.assertEquals(1, accountEntry.getRolesGranted().size());
|
||||||
|
Assert.assertTrue(accountEntry.getRolesGranted().contains("Full Access"));
|
||||||
|
Assert.assertEquals(1, accountEntry.getProtocolMappersGranted().size());
|
||||||
|
Assert.assertTrue(accountEntry.getProtocolMappersGranted().contains("Full Access"));
|
||||||
|
|
||||||
|
AccountApplicationsPage.AppEntry testAppEntry = apps.get("test-app");
|
||||||
|
Assert.assertEquals(4, testAppEntry.getRolesAvailable().size());
|
||||||
|
Assert.assertTrue(testAppEntry.getRolesGranted().contains("Full Access"));
|
||||||
|
Assert.assertTrue(testAppEntry.getProtocolMappersGranted().contains("Full Access"));
|
||||||
|
|
||||||
|
AccountApplicationsPage.AppEntry thirdPartyEntry = apps.get("third-party");
|
||||||
|
Assert.assertEquals(2, thirdPartyEntry.getRolesAvailable().size());
|
||||||
|
Assert.assertTrue(thirdPartyEntry.getRolesAvailable().contains("Have User privileges"));
|
||||||
|
Assert.assertTrue(thirdPartyEntry.getRolesAvailable().contains("Have Customer User privileges in test-app"));
|
||||||
|
Assert.assertEquals(0, thirdPartyEntry.getRolesGranted().size());
|
||||||
|
Assert.assertEquals(0, thirdPartyEntry.getProtocolMappersGranted().size());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,11 +26,24 @@ import org.junit.ClassRule;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.keycloak.OAuth2Constants;
|
import org.keycloak.OAuth2Constants;
|
||||||
|
import org.keycloak.constants.KerberosConstants;
|
||||||
import org.keycloak.events.Details;
|
import org.keycloak.events.Details;
|
||||||
import org.keycloak.events.Event;
|
import org.keycloak.events.Event;
|
||||||
|
import org.keycloak.events.EventType;
|
||||||
|
import org.keycloak.models.ClientModel;
|
||||||
|
import org.keycloak.models.ProtocolMapperModel;
|
||||||
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.RoleModel;
|
||||||
|
import org.keycloak.models.UserModel;
|
||||||
|
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
||||||
|
import org.keycloak.protocol.oidc.OIDCLoginProtocolFactory;
|
||||||
|
import org.keycloak.protocol.oidc.mappers.UserSessionNoteMapper;
|
||||||
import org.keycloak.representations.AccessToken;
|
import org.keycloak.representations.AccessToken;
|
||||||
|
import org.keycloak.services.managers.RealmManager;
|
||||||
import org.keycloak.testsuite.AssertEvents;
|
import org.keycloak.testsuite.AssertEvents;
|
||||||
import org.keycloak.testsuite.OAuthClient;
|
import org.keycloak.testsuite.OAuthClient;
|
||||||
|
import org.keycloak.testsuite.pages.AccountApplicationsPage;
|
||||||
|
import org.keycloak.testsuite.pages.AppPage;
|
||||||
import org.keycloak.testsuite.pages.LoginPage;
|
import org.keycloak.testsuite.pages.LoginPage;
|
||||||
import org.keycloak.testsuite.pages.OAuthGrantPage;
|
import org.keycloak.testsuite.pages.OAuthGrantPage;
|
||||||
import org.keycloak.testsuite.rule.KeycloakRule;
|
import org.keycloak.testsuite.rule.KeycloakRule;
|
||||||
|
@ -69,11 +82,17 @@ public class OAuthGrantTest {
|
||||||
@WebResource
|
@WebResource
|
||||||
protected OAuthGrantPage grantPage;
|
protected OAuthGrantPage grantPage;
|
||||||
|
|
||||||
|
@WebResource
|
||||||
|
protected AccountApplicationsPage accountAppsPage;
|
||||||
|
|
||||||
|
@WebResource
|
||||||
|
protected AppPage appPage;
|
||||||
|
|
||||||
private static String ROLE_USER = "Have User privileges";
|
private static String ROLE_USER = "Have User privileges";
|
||||||
private static String ROLE_CUSTOMER = "Have Customer User privileges";
|
private static String ROLE_CUSTOMER = "Have Customer User privileges";
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void oauthGrantAcceptTest() throws IOException {
|
public void oauthGrantAcceptTest() {
|
||||||
oauth.clientId("third-party");
|
oauth.clientId("third-party");
|
||||||
oauth.doLoginGrant("test-user@localhost", "password");
|
oauth.doLoginGrant("test-user@localhost", "password");
|
||||||
|
|
||||||
|
@ -106,10 +125,16 @@ public class OAuthGrantTest {
|
||||||
Assert.assertTrue(resourceAccess.get("test-app").isUserInRole("customer-user"));
|
Assert.assertTrue(resourceAccess.get("test-app").isUserInRole("customer-user"));
|
||||||
|
|
||||||
events.expectCodeToToken(codeId, loginEvent.getSessionId()).client("third-party").assertEvent();
|
events.expectCodeToToken(codeId, loginEvent.getSessionId()).client("third-party").assertEvent();
|
||||||
|
|
||||||
|
accountAppsPage.open();
|
||||||
|
accountAppsPage.revokeGrant("third-party");
|
||||||
|
|
||||||
|
events.expect(EventType.REVOKE_GRANT)
|
||||||
|
.client("account").detail(Details.REVOKED_CLIENT, "third-party").assertEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void oauthGrantCancelTest() throws IOException {
|
public void oauthGrantCancelTest() {
|
||||||
oauth.clientId("third-party");
|
oauth.clientId("third-party");
|
||||||
oauth.doLoginGrant("test-user@localhost", "password");
|
oauth.doLoginGrant("test-user@localhost", "password");
|
||||||
|
|
||||||
|
@ -125,4 +150,118 @@ public class OAuthGrantTest {
|
||||||
events.expectLogin().client("third-party").error("rejected_by_user").assertEvent();
|
events.expectLogin().client("third-party").error("rejected_by_user").assertEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void oauthGrantNotShownWhenAlreadyGranted() {
|
||||||
|
// Grant permissions on grant screen
|
||||||
|
oauth.clientId("third-party");
|
||||||
|
oauth.doLoginGrant("test-user@localhost", "password");
|
||||||
|
|
||||||
|
grantPage.assertCurrent();
|
||||||
|
grantPage.accept();
|
||||||
|
|
||||||
|
events.expectLogin().client("third-party").assertEvent();
|
||||||
|
|
||||||
|
// Assert permissions granted on Account mgmt. applications page
|
||||||
|
accountAppsPage.open();
|
||||||
|
AccountApplicationsPage.AppEntry thirdPartyEntry = accountAppsPage.getApplications().get("third-party");
|
||||||
|
Assert.assertTrue(thirdPartyEntry.getRolesGranted().contains(ROLE_USER));
|
||||||
|
Assert.assertTrue(thirdPartyEntry.getRolesGranted().contains("Have Customer User privileges in test-app"));
|
||||||
|
Assert.assertTrue(thirdPartyEntry.getProtocolMappersGranted().contains("Full name"));
|
||||||
|
Assert.assertTrue(thirdPartyEntry.getProtocolMappersGranted().contains("Email"));
|
||||||
|
|
||||||
|
// Open login form and assert grantPage not shown
|
||||||
|
oauth.openLoginForm();
|
||||||
|
appPage.assertCurrent();
|
||||||
|
events.expectLogin().detail(Details.AUTH_METHOD, "sso").removeDetail(Details.USERNAME).client("third-party").assertEvent();
|
||||||
|
|
||||||
|
// Revoke grant in account mgmt.
|
||||||
|
accountAppsPage.open();
|
||||||
|
accountAppsPage.revokeGrant("third-party");
|
||||||
|
|
||||||
|
events.expect(EventType.REVOKE_GRANT)
|
||||||
|
.client("account").detail(Details.REVOKED_CLIENT, "third-party").assertEvent();
|
||||||
|
|
||||||
|
// Open login form again and assert grant Page is shown
|
||||||
|
oauth.openLoginForm();
|
||||||
|
grantPage.assertCurrent();
|
||||||
|
Assert.assertTrue(driver.getPageSource().contains(ROLE_USER));
|
||||||
|
Assert.assertTrue(driver.getPageSource().contains(ROLE_CUSTOMER));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void oauthGrantAddAnotherRoleAndMapper() {
|
||||||
|
// Grant permissions on grant screen
|
||||||
|
oauth.clientId("third-party");
|
||||||
|
oauth.doLoginGrant("test-user@localhost", "password");
|
||||||
|
|
||||||
|
// Add new protocolMapper and role before showing grant page
|
||||||
|
keycloakRule.update(new KeycloakRule.KeycloakSetup() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
||||||
|
ProtocolMapperModel protocolMapper = UserSessionNoteMapper.createClaimMapper(KerberosConstants.GSS_DELEGATION_CREDENTIAL_DISPLAY_NAME,
|
||||||
|
KerberosConstants.GSS_DELEGATION_CREDENTIAL,
|
||||||
|
KerberosConstants.GSS_DELEGATION_CREDENTIAL, "String",
|
||||||
|
true, KerberosConstants.GSS_DELEGATION_CREDENTIAL_DISPLAY_NAME,
|
||||||
|
true, false);
|
||||||
|
|
||||||
|
ClientModel thirdPartyApp = appRealm.getClientByClientId("third-party");
|
||||||
|
thirdPartyApp.addProtocolMapper(protocolMapper);
|
||||||
|
|
||||||
|
RoleModel newRole = appRealm.addRole("new-role");
|
||||||
|
thirdPartyApp.addScopeMapping(newRole);
|
||||||
|
UserModel testUser = manager.getSession().users().getUserByUsername("test-user@localhost", appRealm);
|
||||||
|
testUser.grantRole(newRole);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// Confirm grant page
|
||||||
|
grantPage.assertCurrent();
|
||||||
|
grantPage.accept();
|
||||||
|
events.expectLogin().client("third-party").assertEvent();
|
||||||
|
|
||||||
|
// Assert new role and protocol mapper not in account mgmt.
|
||||||
|
accountAppsPage.open();
|
||||||
|
AccountApplicationsPage.AppEntry appEntry = accountAppsPage.getApplications().get("third-party");
|
||||||
|
Assert.assertFalse(appEntry.getRolesGranted().contains("new-role"));
|
||||||
|
Assert.assertFalse(appEntry.getProtocolMappersGranted().contains(KerberosConstants.GSS_DELEGATION_CREDENTIAL_DISPLAY_NAME));
|
||||||
|
|
||||||
|
// Show grant page another time. Just new role and protocol mapper are on the page
|
||||||
|
oauth.openLoginForm();
|
||||||
|
grantPage.assertCurrent();
|
||||||
|
Assert.assertFalse(driver.getPageSource().contains(ROLE_USER));
|
||||||
|
Assert.assertFalse(driver.getPageSource().contains("Full name"));
|
||||||
|
Assert.assertTrue(driver.getPageSource().contains("new-role"));
|
||||||
|
Assert.assertTrue(driver.getPageSource().contains(KerberosConstants.GSS_DELEGATION_CREDENTIAL_DISPLAY_NAME));
|
||||||
|
grantPage.accept();
|
||||||
|
events.expectLogin().client("third-party").assertEvent();
|
||||||
|
|
||||||
|
// Go to account mgmt. Everything is granted now
|
||||||
|
accountAppsPage.open();
|
||||||
|
appEntry = accountAppsPage.getApplications().get("third-party");
|
||||||
|
Assert.assertTrue(appEntry.getRolesGranted().contains("new-role"));
|
||||||
|
Assert.assertTrue(appEntry.getProtocolMappersGranted().contains(KerberosConstants.GSS_DELEGATION_CREDENTIAL_DISPLAY_NAME));
|
||||||
|
|
||||||
|
// Revoke
|
||||||
|
accountAppsPage.revokeGrant("third-party");
|
||||||
|
events.expect(EventType.REVOKE_GRANT)
|
||||||
|
.client("account").detail(Details.REVOKED_CLIENT, "third-party").assertEvent();
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
keycloakRule.update(new KeycloakRule.KeycloakSetup() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
||||||
|
ClientModel thirdPartyApp = appRealm.getClientByClientId("third-party");
|
||||||
|
ProtocolMapperModel gssMapper = thirdPartyApp.getProtocolMapperByName(OIDCLoginProtocol.LOGIN_PROTOCOL, KerberosConstants.GSS_DELEGATION_CREDENTIAL_DISPLAY_NAME);
|
||||||
|
thirdPartyApp.removeProtocolMapper(gssMapper);
|
||||||
|
|
||||||
|
RoleModel newRole = appRealm.getRole("new-role");
|
||||||
|
appRealm.removeRole(newRole);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,62 +37,81 @@ public class AccountApplicationsPage extends AbstractAccountPage {
|
||||||
driver.findElement(By.id("revoke-" + clientId)).click();
|
driver.findElement(By.id("revoke-" + clientId)).click();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, ClientGrant> getClientGrants() {
|
public Map<String, AppEntry> getApplications() {
|
||||||
Map<String, ClientGrant> table = new HashMap<String, ClientGrant>();
|
Map<String, AppEntry> table = new HashMap<String, AppEntry>();
|
||||||
for (WebElement r : driver.findElements(By.tagName("tr"))) {
|
for (WebElement r : driver.findElements(By.tagName("tr"))) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
ClientGrant currentGrant = null;
|
AppEntry currentEntry = null;
|
||||||
|
|
||||||
for (WebElement col : r.findElements(By.tagName("td"))) {
|
for (WebElement col : r.findElements(By.tagName("td"))) {
|
||||||
count++;
|
count++;
|
||||||
switch (count) {
|
switch (count) {
|
||||||
case 1:
|
case 1:
|
||||||
currentGrant = new ClientGrant();
|
currentEntry = new AppEntry();
|
||||||
String clientId = col.getText();
|
String client = col.getText();
|
||||||
table.put(clientId, currentGrant);
|
table.put(client, currentEntry);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
String protMappersStr = col.getText();
|
|
||||||
String[] protMappers = protMappersStr.split(",");
|
|
||||||
for (String protMapper : protMappers) {
|
|
||||||
protMapper = protMapper.trim();
|
|
||||||
currentGrant.addMapper(protMapper);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
String rolesStr = col.getText();
|
String rolesStr = col.getText();
|
||||||
String[] roles = rolesStr.split(",");
|
String[] roles = rolesStr.split(",");
|
||||||
for (String role : roles) {
|
for (String role : roles) {
|
||||||
role = role.trim();
|
role = role.trim();
|
||||||
currentGrant.addRole(role);
|
currentEntry.addAvailableRole(role);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
rolesStr = col.getText();
|
||||||
|
if (rolesStr.isEmpty()) break;
|
||||||
|
roles = rolesStr.split(",");
|
||||||
|
for (String role : roles) {
|
||||||
|
role = role.trim();
|
||||||
|
currentEntry.addGrantedRole(role);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
String protMappersStr = col.getText();
|
||||||
|
if (protMappersStr.isEmpty()) break;
|
||||||
|
String[] protMappers = protMappersStr.split(",");
|
||||||
|
for (String protMapper : protMappers) {
|
||||||
|
protMapper = protMapper.trim();
|
||||||
|
currentEntry.addMapper(protMapper);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
table.remove("Client");
|
table.remove("Application");
|
||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ClientGrant {
|
public static class AppEntry {
|
||||||
|
|
||||||
private final List<String> protocolMapperDescriptions = new ArrayList<String>();
|
private final List<String> rolesAvailable = new ArrayList<String>();
|
||||||
private final List<String> roleDescriptions = new ArrayList<String>();
|
private final List<String> rolesGranted = new ArrayList<String>();
|
||||||
|
private final List<String> protocolMappersGranted = new ArrayList<String>();
|
||||||
|
|
||||||
|
private void addAvailableRole(String role) {
|
||||||
|
rolesAvailable.add(role);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addGrantedRole(String role) {
|
||||||
|
rolesGranted.add(role);
|
||||||
|
}
|
||||||
|
|
||||||
private void addMapper(String protocolMapper) {
|
private void addMapper(String protocolMapper) {
|
||||||
protocolMapperDescriptions.add(protocolMapper);
|
protocolMappersGranted.add(protocolMapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addRole(String role) {
|
public List<String> getRolesGranted() {
|
||||||
roleDescriptions.add(role);
|
return rolesGranted;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getProtocolMapperDescriptions() {
|
public List<String> getRolesAvailable() {
|
||||||
return protocolMapperDescriptions;
|
return rolesAvailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getRoleDescriptions() {
|
public List<String> getProtocolMappersGranted() {
|
||||||
return roleDescriptions;
|
return protocolMappersGranted;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue