keycloak-uncached

Changes

Details

diff --git a/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.RC1.xml b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.RC1.xml
index bc808bc..f435ffc 100755
--- a/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.RC1.xml
+++ b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.RC1.xml
@@ -83,17 +83,19 @@
         <addForeignKeyConstraint baseColumnNames="USER_CONSENT_ID" baseTableName="USER_CONSENT_PROT_MAPPER" constraintName="FK_GRNTCSNT_PRM_GR" referencedColumnNames="ID" referencedTableName="USER_CONSENT"/>
         <addForeignKeyConstraint baseColumnNames="CLIENT_SESSION" baseTableName="CLIENT_SESSION_PROT_MAPPER" constraintName="FK_33A8SGQW18I532811V7O2DK89" referencedColumnNames="ID" referencedTableName="CLIENT_SESSION"/>
 
+        <renameColumn tableName="CLIENT" newColumnName="CLIENT_ID" oldColumnName="NAME"/>
         <addColumn tableName="CLIENT">
             <column name="CONSENT_REQUIRED" type="BOOLEAN" defaultValueBoolean="false">
                 <constraints nullable="false"/>
             </column>
+            <column name="NAME" type="VARCHAR(255)" />
         </addColumn>
         <update tableName="CLIENT">
             <column name="CONSENT_REQUIRED" valueBoolean="true"/>
             <where>DTYPE = 'OAuthClientEntity'</where>
         </update>
         <dropColumn tableName="CLIENT" columnName="DTYPE"/>
-        <renameColumn tableName="CLIENT" newColumnName="CLIENT_ID" oldColumnName="NAME"/>
+
         <renameColumn tableName="REALM" newColumnName="MASTER_ADMIN_CLIENT" oldColumnName="MASTER_ADMIN_APP"/>
 
         <renameTable oldTableName="REALM_APPLICATION" newTableName="REALM_CLIENT"/>
diff --git a/core/src/main/java/org/keycloak/representations/idm/ClientRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/ClientRepresentation.java
index de40f10..4137196 100755
--- a/core/src/main/java/org/keycloak/representations/idm/ClientRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/ClientRepresentation.java
@@ -10,6 +10,7 @@ import java.util.Map;
 public class ClientRepresentation {
     protected String id;
     protected String clientId;
+    protected String name;
     protected String adminUrl;
     protected String baseUrl;
     protected Boolean surrogateAuthRequired;
@@ -40,6 +41,14 @@ public class ClientRepresentation {
         this.id = id;
     }
 
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
     public String getClientId() {
         return clientId;
     }
diff --git a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ImportUtils.java b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ImportUtils.java
index 66b106c..fbd909d 100755
--- a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ImportUtils.java
+++ b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ImportUtils.java
@@ -120,6 +120,8 @@ public class ImportUtils {
         adminRole.setDescription("${role_"+AdminRoles.ADMIN+"}");
 
         ClientModel realmAdminApp = KeycloakModelUtils.createClient(adminRealm, KeycloakModelUtils.getMasterRealmAdminApplicationClientId(realm));
+        // No localized name for now
+        realmAdminApp.setName(realm.getName() + " Realm");
         realmAdminApp.setBearerOnly(true);
         realm.setMasterAdminClient(realmAdminApp);
 
diff --git a/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/FreeMarkerAccountProvider.java b/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/FreeMarkerAccountProvider.java
index ba95348..b721503 100755
--- a/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/FreeMarkerAccountProvider.java
+++ b/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/FreeMarkerAccountProvider.java
@@ -20,7 +20,7 @@ import javax.ws.rs.core.UriInfo;
 import org.jboss.logging.Logger;
 import org.keycloak.account.AccountPages;
 import org.keycloak.account.AccountProvider;
-import org.keycloak.account.freemarker.model.AccessBean;
+import org.keycloak.account.freemarker.model.ConsentBean;
 import org.keycloak.account.freemarker.model.AccountBean;
 import org.keycloak.account.freemarker.model.AccountFederatedIdentityBean;
 import org.keycloak.account.freemarker.model.FeaturesBean;
@@ -186,7 +186,7 @@ public class FreeMarkerAccountProvider implements AccountProvider {
                 attributes.put("sessions", new SessionsBean(realm, sessions));
                 break;
             case ACCESS:
-                attributes.put("access", new AccessBean(realm, user, uriInfo.getBaseUri(), stateChecker));
+                attributes.put("consent", new ConsentBean(user));
                 attributes.put("advancedMsg", new AdvancedMessageFormatterMethod(locale, messagesBundle));
                 break;
             case PASSWORD:
diff --git a/forms/common-themes/src/main/resources/theme/base/account/messages/messages_de.properties b/forms/common-themes/src/main/resources/theme/base/account/messages/messages_de.properties
index a846d54..80fb02f 100644
--- a/forms/common-themes/src/main/resources/theme/base/account/messages/messages_de.properties
+++ b/forms/common-themes/src/main/resources/theme/base/account/messages/messages_de.properties
@@ -16,16 +16,40 @@ authenticatorTitle=Authenticator
 authenticatorCode=One-time code
 email=E-Mail
 firstName=Vorname
+givenName=Vorname
+fullName=voller Name
 lastName=Nachname
+familyName=Nachname
 password=Passwort
 passwordConfirm=Passwortbest\u00E4tigung
 passwordNew=Neues Passwort
 username=Benutzernamen
+address=Adresse
 street=Strasse
 region=Staat, Provinz, Region
 postal_code=PLZ
 locality=Stadt oder Ortschaft
 country=Land
+emailVerified=E-Mail verifiziert
+gssDelegationCredential=GSS delegierte Berechtigung
+
+role_admin=Admin
+role_realm-admin=Realm Admin
+role_create-realm=Realm erstellen
+role_view-realm=Realm ansehen
+role_view-users=Benutzer ansehen
+role_view-applications=Applicationen ansehen
+role_view-clients=Clients ansehen
+role_view-events=Events ansehen
+role_view-identity-providers=Identity Providers ansehen
+role_manage-realm=Realm verwalten
+role_manage-users=Benutzer verwalten
+role_manage-applications=Applikationen verwalten
+role_manage-identity-providers=Identity Provider verwalten
+role_manage-clients=Clients verwalten
+role_manage-events=Events verwalten
+role_view-profile=Profile ansehen
+role_manage-account=Profile verwalten
 
 requiredFields=Erforderliche Felder
 allFieldsRequired=Alle Felder sind Erforderlich
diff --git a/forms/common-themes/src/main/resources/theme/base/account/messages/messages_en.properties b/forms/common-themes/src/main/resources/theme/base/account/messages/messages_en.properties
index d0bbb37..6179483 100755
--- a/forms/common-themes/src/main/resources/theme/base/account/messages/messages_en.properties
+++ b/forms/common-themes/src/main/resources/theme/base/account/messages/messages_en.properties
@@ -50,6 +50,9 @@ role_manage-identity-providers=Manage identity providers
 role_manage-clients=Manage clients
 role_manage-events=Manage events
 role_view-profile=View profile
+client_account=Account
+client_security-admin-console=Security Admin Console
+client_realm-management=Realm Management
 
 
 requiredFields=Required fields
@@ -79,7 +82,7 @@ access=Access
 grantedPersonalInfo=Granted Personal Info
 grantedPermissions=Granted Permissions
 action=Action
-inResource=in <strong>{0}</strong>
+inResource=in
 revoke=Revoke Access
 
 configureAuthenticators=Configured Authenticators
diff --git a/forms/common-themes/src/main/resources/theme/base/account/messages/messages_it.properties b/forms/common-themes/src/main/resources/theme/base/account/messages/messages_it.properties
index d22b935..99eff0c 100755
--- a/forms/common-themes/src/main/resources/theme/base/account/messages/messages_it.properties
+++ b/forms/common-themes/src/main/resources/theme/base/account/messages/messages_it.properties
@@ -16,16 +16,40 @@ authenticatorTitle=Authenticator
 authenticatorCode=Codice One-time
 email=Email
 firstName=Nome
+givenName=Nome
+fullName=Nome Completo
 lastName=Cognome
+familyName=Cognome
 password=Password
 passwordConfirm=Conferma Password
 passwordNew=Nuova Password
 username=Username
+address=Indirizzo
 street=Via
 locality=Citta'' o Localita''
 region=Stato, Provincia, o Regione
 postal_code=Cap
 country=Paese
+emailVerified=Email verificata
+gssDelegationCredential=credenziali gss delegation
+
+role_admin=Admin
+role_realm-admin=Realm Admin
+role_create-realm=Crea realm
+role_view-realm=Visualizza realm
+role_view-users=Visualizza utenti
+role_view-applications=Visualizza applicazioni
+role_view-clients=Visualizza client
+role_view-events=Visualizza eventi
+role_view-identity-providers=Visualizza identity provider
+role_manage-realm=Gestisci realm
+role_manage-users=Gestisci utenti
+role_manage-applications=Gestisci applicazioni
+role_manage-identity-providers=Gestisci identity provider
+role_manage-clients=Gestisci client
+role_manage-events=Gestisci eventi
+role_view-profile=Visualizza profilo
+role_manage-account=Gestisci account
 
 requiredFields=Campi obbligatori
 allFieldsRequired=Tutti campi obbligatori
diff --git a/forms/common-themes/src/main/resources/theme/base/account/messages/messages_pt_BR.properties b/forms/common-themes/src/main/resources/theme/base/account/messages/messages_pt_BR.properties
index 367be5f..a29d60d 100644
--- a/forms/common-themes/src/main/resources/theme/base/account/messages/messages_pt_BR.properties
+++ b/forms/common-themes/src/main/resources/theme/base/account/messages/messages_pt_BR.properties
@@ -16,16 +16,40 @@ authenticatorTitle=Autenticator
 authenticatorCode=C\u00F3digo autenticador
 email=Email
 firstName=Primeiro nome
+givenName=Primeiro nome
+fullName=Nome completo
 lastName=Sobrenome
+familyName=Sobrenome
 password=Senha
 passwordConfirm=Confirma\u00E7\u00E3o
 passwordNew=Nova senha
 username=Nome de us\u00FAario
+address=Endere\u00E7o
 street=Logradouro
 locality=Cidade ou Localidade
 region=Estado
 postal_code=CEP
 country=Pa\u00EDs
+emailVerified=Email verificado
+gssDelegationCredential=gss delega\u00E7\u00E3o credencial
+
+role_admin=Admin
+role_realm-admin=Realm Admin
+role_create-realm=Cria realm
+role_view-realm=Visualiza realm
+role_view-users=Visualiza usu\u00E1rios
+role_view-applications=Visualiza aplica\u00E7\u00F5es
+role_view-clients=Visualiza clientes
+role_view-events=Visualiza eventos
+role_view-identity-providers=Visualiza provedores de identidade
+role_manage-realm=Gerencia realm
+role_manage-users=Gerencia usu\u00E1rios
+role_manage-applications=Gerencia aplica\u00E7\u00F5es
+role_manage-identity-providers=Gerencia provedores de identidade
+role_manage-clients=Gerencia clientes
+role_manage-events=Gerencia eventos
+role_view-profile=Visualiza perfil
+role_manage-account=Gerencia contas
 
 requiredFields=Campos obrigat\u00F3rios
 allFieldsRequired=Todos os campos s\u00E3o obrigat\u00F3rios
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-detail.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-detail.html
index ebfca94..69dd012 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-detail.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-detail.html
@@ -19,9 +19,17 @@
             <fieldset class="border-top">
                 <div class="form-group">
                     <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">
+                    <div class="col-sm-6">
                         <input class="form-control" type="text" id="clientId" name="clientId" data-ng-model="client.clientId" autofocus required>
                     </div>
+                    <span tooltip-placement="right" tooltip="Specifies ID referenced in URI and tokens. For example 'my-client'" class="fa fa-info-circle"></span>
+                </div>
+                <div class="form-group">
+                    <label class="col-sm-2 control-label" for="name">Name </label>
+                    <div class="col-sm-6">
+                        <input class="form-control" type="text" id="name" name="name" data-ng-model="client.name" autofocus>
+                    </div>
+                    <span tooltip-placement="right" tooltip="Specifies display name of the client. For example 'My Client'. Supports keys for localized values as well. For example: ${my_client}" class="fa fa-info-circle"></span>
                 </div>
                 <div class="form-group clearfix block">
                     <label class="col-sm-2 control-label" for="enabled">Enabled</label>
diff --git a/forms/common-themes/src/main/resources/theme/base/login/login-oauth-grant.ftl b/forms/common-themes/src/main/resources/theme/base/login/login-oauth-grant.ftl
index 6136e8b..30d55c3 100755
--- a/forms/common-themes/src/main/resources/theme/base/login/login-oauth-grant.ftl
+++ b/forms/common-themes/src/main/resources/theme/base/login/login-oauth-grant.ftl
@@ -3,7 +3,7 @@
     <#if section = "title">
         ${msg("oauthGrantTitle")}
     <#elseif section = "header">
-        ${msg("oauthGrantTitleHtml",(realm.name!''), (client.clientId!''))}
+        ${msg("oauthGrantTitleHtml",(realm.name!''))} <strong><#if client.name??>${advancedMsg(client.name)}<#else>${client.clientId}</#if></strong>.
     <#elseif section = "form">
         <div id="kc-oauth" class="content-area">
             <h3>${msg("oauthGrantRequest")}</h3>
@@ -34,10 +34,10 @@
                 </#if>
                 <#if oauth.resourceRolesRequested??>
                     <#list oauth.resourceRolesRequested?keys as resource>
-                        <#list oauth.resourceRolesRequested[resource] as role>
+                        <#list oauth.resourceRolesRequested[resource] as clientRole>
                             <li>
-                                <span class="kc-role"><#if role.description??>${advancedMsg(role.description)}<#else>${advancedMsg(role.name)}</#if></span>
-                                <span class="kc-resource">${msg("inResource", resource)}</span>
+                                <span class="kc-role"><#if clientRole.roleDescription??>${advancedMsg(clientRole.roleDescription)}<#else>${advancedMsg(clientRole.roleName)}</#if></span>
+                                <span class="kc-resource">${msg("inResource")} <strong><#if clientRole.clientName??>${advancedMsg(clientRole.clientName)}<#else>${clientRole.clientId}</#if></strong> </span>
                             </li>
                         </#list>
                     </#list>
diff --git a/forms/common-themes/src/main/resources/theme/base/login/messages/messages_de.properties b/forms/common-themes/src/main/resources/theme/base/login/messages/messages_de.properties
index ca45f53..5999681 100644
--- a/forms/common-themes/src/main/resources/theme/base/login/messages/messages_de.properties
+++ b/forms/common-themes/src/main/resources/theme/base/login/messages/messages_de.properties
@@ -16,7 +16,7 @@ loginOauthTitleHtml=Tempor\u00E4rer zugriff auf <strong>{0}</strong> angefordert
 loginTotpTitle=Mobile Authentifizierung Einrichten
 loginProfileTitle=Benutzerkonto Informationen aktualisieren
 oauthGrantTitle=OAuth gew\u00E4hren
-oauthGrantTitleHtml=Tempor\u00E4rer zugriff auf <strong>{0}</strong> angefordert von <strong>{1}</strong>.
+oauthGrantTitleHtml=Tempor\u00E4rer zugriff auf <strong>{0}</strong> angefordert von
 errorTitle=Es tut uns leid...
 errorTitleHtml=Es tut uns leid...
 emailVerifyTitle=E-Mail verifizieren
@@ -55,7 +55,7 @@ loginTotpStep3=Geben Sie den One-time Code welcher die Applikation generiert hat
 loginTotpOneTime=One-time Code
 
 oauthGrantRequest=Wollen Sie diese Zugriffsreche gew\u00E4hren?
-inResource=in <strong>{0}</strong>
+inResource=in
 
 emailVerifyInstruction1=Ein E-Mail mit weitern Anweisungen wurde an Sie versendet.
 emailVerifyInstruction2=Falls Sie kein E-Mail erhalten haben, dann k\u00F6nnen Sie
diff --git a/forms/common-themes/src/main/resources/theme/base/login/messages/messages_en.properties b/forms/common-themes/src/main/resources/theme/base/login/messages/messages_en.properties
index 006883f..a1f76ee 100755
--- a/forms/common-themes/src/main/resources/theme/base/login/messages/messages_en.properties
+++ b/forms/common-themes/src/main/resources/theme/base/login/messages/messages_en.properties
@@ -14,7 +14,7 @@ loginTitleHtml=Log in to <strong>{0}</strong>
 loginTotpTitle=Mobile Authenticator Setup
 loginProfileTitle=Update Account Information
 oauthGrantTitle=OAuth Grant
-oauthGrantTitleHtml=Temporary access for <strong>{0}</strong> requested by <strong>{1}</strong>.
+oauthGrantTitleHtml=Temporary access for <strong>{0}</strong> requested by
 errorTitle=We''re sorry...
 errorTitleHtml=We''re <strong>sorry</strong> ...
 emailVerifyTitle=Email verification
@@ -45,7 +45,7 @@ region=State, Province, or Region
 postal_code=Zip or Postal code
 country=Country
 emailVerified=Email verified
-gssDelegationCredential=gss delegation credential
+gssDelegationCredential=GSS Delegation Credential
 
 loginTotpStep1=Install <a href="https://fedorahosted.org/freeotp/" target="_blank">FreeOTP</a> or Google Authenticator on your mobile. Both applications are available in <a href="https://play.google.com">Google Play</a> and Apple App Store.
 loginTotpStep2=Open the application and scan the barcode or enter the key
@@ -53,7 +53,7 @@ loginTotpStep3=Enter the one-time code provided by the application and click Sub
 loginTotpOneTime=One-time code
 
 oauthGrantRequest=Do you grant these access privileges?
-inResource=in <strong>{0}</strong>
+inResource=in
 
 emailVerifyInstruction1=An email with instructions to verify your email address has been sent to you.
 emailVerifyInstruction2=Haven''t received a verification code in your email?
@@ -84,6 +84,9 @@ role_manage-clients=Manage clients
 role_manage-events=Manage events
 role_view-profile=View profile
 role_manage-account=Manage account
+client_account=Account
+client_security-admin-console=Security Admin Console
+client_realm-management=Realm Management
 
 invalidUserMessage=Invalid username or password.
 invalidEmailMessage=Invalid email address.
diff --git a/forms/common-themes/src/main/resources/theme/base/login/messages/messages_it.properties b/forms/common-themes/src/main/resources/theme/base/login/messages/messages_it.properties
index f7296b9..b019d6c 100755
--- a/forms/common-themes/src/main/resources/theme/base/login/messages/messages_it.properties
+++ b/forms/common-themes/src/main/resources/theme/base/login/messages/messages_it.properties
@@ -14,7 +14,7 @@ loginTitleHtml=Accedi a <strong>{0}</strong>
 loginTotpTitle=Configura Autenticazione Mobile
 loginProfileTitle=Aggiorna Profilo
 oauthGrantTitle=OAuth Grant
-oauthGrantTitleHtml=Accesso temporaneo per <strong>{0}</strong> richiesto da <strong>{1}</strong>.
+oauthGrantTitleHtml=Accesso temporaneo per <strong>{0}</strong> richiesto da
 errorTitle=Siamo spiacenti...
 errorTitleHtml=Siamo <strong>spiacenti</strong> ...
 emailVerifyTitle=Verifica Email
@@ -53,7 +53,7 @@ loginTotpStep3=Scrivi il codice one-time fornito dall''applicazione e premi Invi
 loginTotpOneTime=Codice one-time
 
 oauthGrantRequest=Vuoi assegnare questi privilegi di accesso?
-inResource=per <strong>{0}</strong>
+inResource=per
 
 emailVerifyInstruction1=Ti e'' stata inviata una email con le istruzioni per la verifica della tua email.
 emailVerifyInstruction2=Non hai ricevuto un codice di verifica nella tua email?
diff --git a/forms/common-themes/src/main/resources/theme/base/login/messages/messages_pt_BR.properties b/forms/common-themes/src/main/resources/theme/base/login/messages/messages_pt_BR.properties
index 896f83f..8d50d3e 100644
--- a/forms/common-themes/src/main/resources/theme/base/login/messages/messages_pt_BR.properties
+++ b/forms/common-themes/src/main/resources/theme/base/login/messages/messages_pt_BR.properties
@@ -14,7 +14,7 @@ loginTitleHtml=Entrar em <strong>{0}</strong>
 loginTotpTitle=Configura\u00E7\u00E3o do autenticador mobile
 loginProfileTitle=Atualiza\u00E7\u00E3o de Informa\u00E7\u00F5es da Conta
 oauthGrantTitle=Concess\u00E3o OAuth
-oauthGrantTitleHtml=Acesso tempor\u00E1rio para <strong>{0}</strong> solicitado pela <strong>{1}</strong>.
+oauthGrantTitleHtml=Acesso tempor\u00E1rio para <strong>{0}</strong> solicitado pela
 errorTitle=N\u00F3s lamentamos...
 errorTitleHtml=N\u00F3s <strong>lamentamos</strong> ...
 emailVerifyTitle=Verifica\u00E7\u00E3o de e-mail
@@ -53,7 +53,7 @@ loginTotpStep3=Digite o c\u00F3digo fornecido pelo aplicativo e clique em Enviar
 loginTotpOneTime=C\u00F3digo autenticador
 
 oauthGrantRequest=Voc\u00EA concede esses privil\u00E9gios de acesso?
-inResource=em <strong>{0}</strong>
+inResource=em
 
 emailVerifyInstruction1=Um e-mail com instru\u00E7\u00F5es para verificar o seu endere\u00E7o de e-mail foi enviado para voc\u00EA.
 emailVerifyInstruction2=Voc\u00EA n\u00E3o recebeu um c\u00F3digo de verifica\u00E7\u00E3o em seu e-mail?
diff --git a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/ClientBean.java b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/ClientBean.java
index 53f7937..d945c38 100755
--- a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/ClientBean.java
+++ b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/ClientBean.java
@@ -18,6 +18,10 @@ public class ClientBean {
         return client.getClientId();
     }
 
+    public String getName() {
+        return client.getName();
+    }
+
     public String getBaseUrl() {
         return client.getBaseUrl();
     }
diff --git a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/OAuthGrantBean.java b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/OAuthGrantBean.java
index 98cd164..6032587 100755
--- a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/OAuthGrantBean.java
+++ b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/OAuthGrantBean.java
@@ -21,6 +21,7 @@
  */
 package org.keycloak.login.freemarker.model;
 
+import org.jboss.resteasy.specimpl.MultivaluedMapImpl;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.ClientSessionModel;
 import org.keycloak.models.ProtocolMapperModel;
@@ -29,6 +30,7 @@ import org.keycloak.models.RoleModel;
 import javax.ws.rs.core.MultivaluedMap;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 
 /**
  * @author <a href="mailto:vrockai@redhat.com">Viliam Rockai</a>
@@ -37,7 +39,7 @@ public class OAuthGrantBean {
 
     private final String accessRequestMessage;
     private List<RoleModel> realmRolesRequested;
-    private MultivaluedMap<String, RoleModel> resourceRolesRequested;
+    private MultivaluedMap<String, ClientRoleEntry> resourceRolesRequested;
     private String code;
     private ClientModel client;
     private List<String> claimsRequested;
@@ -47,7 +49,17 @@ public class OAuthGrantBean {
         this.code = code;
         this.client = client;
         this.realmRolesRequested = realmRolesRequested;
-        this.resourceRolesRequested = resourceRolesRequested;
+        if (resourceRolesRequested != null) {
+            this.resourceRolesRequested = new MultivaluedMapImpl<String, ClientRoleEntry>();
+            for (List<RoleModel> clientRoles : resourceRolesRequested.values()) {
+                for (RoleModel role : clientRoles) {
+                    ClientModel currentClient = (ClientModel) role.getContainer();
+                    ClientRoleEntry roleEntry = new ClientRoleEntry(currentClient.getClientId(), currentClient.getName(), role.getName(), role.getDescription());
+                    this.resourceRolesRequested.add(currentClient.getClientId(), roleEntry);
+                }
+            }
+        }
+
         this.accessRequestMessage = accessRequestMessage;
 
         List<String> claims = new LinkedList<String>();
@@ -63,7 +75,7 @@ public class OAuthGrantBean {
         return code;
     }
 
-    public MultivaluedMap<String, RoleModel> getResourceRolesRequested() {
+    public MultivaluedMap<String, ClientRoleEntry> getResourceRolesRequested() {
         return resourceRolesRequested;
     }
 
@@ -82,4 +94,36 @@ public class OAuthGrantBean {
     public String getAccessRequestMessage() {
         return this.accessRequestMessage;
     }
+
+    // Same class used in ConsentBean in account 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;
+        }
+    }
 }
diff --git a/model/api/src/main/java/org/keycloak/models/ClientModel.java b/model/api/src/main/java/org/keycloak/models/ClientModel.java
index 2382f55..5fae169 100755
--- a/model/api/src/main/java/org/keycloak/models/ClientModel.java
+++ b/model/api/src/main/java/org/keycloak/models/ClientModel.java
@@ -24,6 +24,10 @@ public interface ClientModel extends RoleContainerModel {
 
     void setClientId(String clientId);
 
+    String getName();
+
+    void setName(String name);
+
     boolean isEnabled();
 
     void setEnabled(boolean enabled);
diff --git a/model/api/src/main/java/org/keycloak/models/entities/ClientEntity.java b/model/api/src/main/java/org/keycloak/models/entities/ClientEntity.java
index 699c6d6..513c4ef 100644
--- a/model/api/src/main/java/org/keycloak/models/entities/ClientEntity.java
+++ b/model/api/src/main/java/org/keycloak/models/entities/ClientEntity.java
@@ -11,6 +11,7 @@ import java.util.Map;
 public class ClientEntity extends AbstractIdentifiableEntity {
 
     private String clientId;
+    private String name;
     private String realmId;
     private boolean enabled;
     private String secret;
@@ -49,6 +50,14 @@ public class ClientEntity extends AbstractIdentifiableEntity {
         this.clientId = clientId;
     }
 
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
     public boolean isEnabled() {
         return enabled;
     }
diff --git a/model/api/src/main/java/org/keycloak/models/RealmModel.java b/model/api/src/main/java/org/keycloak/models/RealmModel.java
index 17c88ea..9c29604 100755
--- a/model/api/src/main/java/org/keycloak/models/RealmModel.java
+++ b/model/api/src/main/java/org/keycloak/models/RealmModel.java
@@ -145,6 +145,7 @@ public interface RealmModel extends RoleContainerModel {
 
     void updateDefaultRoles(String[] defaultRoles);
 
+    // Key is clientId
     Map<String, ClientModel> getClientNameMap();
 
     List<ClientModel> getClients();
diff --git a/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java b/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java
index 63be7f0..e10cbed 100755
--- a/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java
@@ -226,6 +226,7 @@ public class ModelToRepresentation {
         ClientRepresentation rep = new ClientRepresentation();
         rep.setId(clientModel.getId());
         rep.setClientId(clientModel.getClientId());
+        rep.setName(clientModel.getName());
         rep.setEnabled(clientModel.isEnabled());
         rep.setAdminUrl(clientModel.getManagementUrl());
         rep.setPublicClient(clientModel.isPublicClient());
diff --git a/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java b/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
index 7043611..d5983cd 100755
--- a/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
@@ -523,6 +523,7 @@ public class RepresentationToModel {
         logger.debug("Create client: {0}" + resourceRep.getClientId());
 
         ClientModel client = resourceRep.getId()!=null ? realm.addClient(resourceRep.getId(), resourceRep.getClientId()) : realm.addClient(resourceRep.getClientId());
+        if (resourceRep.getName() != null) client.setName(resourceRep.getName());
         if (resourceRep.isEnabled() != null) client.setEnabled(resourceRep.isEnabled());
         client.setManagementUrl(resourceRep.getAdminUrl());
         if (resourceRep.isSurrogateAuthRequired() != null)
@@ -614,6 +615,7 @@ public class RepresentationToModel {
 
     public static void updateClient(ClientRepresentation rep, ClientModel resource) {
         if (rep.getClientId() != null) resource.setClientId(rep.getClientId());
+        if (rep.getName() != null) resource.setName(rep.getName());
         if (rep.isEnabled() != null) resource.setEnabled(rep.isEnabled());
         if (rep.isBearerOnly() != null) resource.setBearerOnly(rep.isBearerOnly());
         if (rep.isConsentRequired() != null) resource.setConsentRequired(rep.isConsentRequired());
diff --git a/model/file/src/main/java/org/keycloak/models/file/adapter/ClientAdapter.java b/model/file/src/main/java/org/keycloak/models/file/adapter/ClientAdapter.java
index 7068a26..e7847e2 100755
--- a/model/file/src/main/java/org/keycloak/models/file/adapter/ClientAdapter.java
+++ b/model/file/src/main/java/org/keycloak/models/file/adapter/ClientAdapter.java
@@ -69,6 +69,16 @@ public class ClientAdapter implements ClientModel {
     }
 
     @Override
+    public String getName() {
+        return entity.getName();
+    }
+
+    @Override
+    public void setName(String name) {
+       entity.setName(name);
+    }
+
+    @Override
     public Set<String> getWebOrigins() {
         Set<String> result = new HashSet<String>();
         if (entity.getWebOrigins() != null) {
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ClientAdapter.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ClientAdapter.java
index 4dc4a03..48089bd 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ClientAdapter.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ClientAdapter.java
@@ -293,7 +293,7 @@ public class ClientAdapter implements ClientModel {
     @Override
     public String getClientId() {
         if (updated != null) return updated.getClientId();
-        return cached.getName();
+        return cached.getClientId();
     }
 
     @Override
@@ -304,6 +304,18 @@ public class ClientAdapter implements ClientModel {
     }
 
     @Override
+    public String getName() {
+        if (updated != null) return updated.getName();
+        return cached.getName();
+    }
+
+    @Override
+    public void setName(String name) {
+        getDelegateForUpdate();
+        updated.setName(name);
+    }
+
+    @Override
     public boolean isSurrogateAuthRequired() {
         if (updated != null) return updated.isSurrogateAuthRequired();
         return cached.isSurrogateAuthRequired();
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedClient.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedClient.java
index 58d3cb0..8b8c045 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedClient.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedClient.java
@@ -21,6 +21,7 @@ import java.util.TreeMap;
  */
 public class CachedClient {
     private String id;
+    private String clientId;
     private String name;
     private String realm;
     private Set<String> redirectUris = new HashSet<String>();
@@ -49,7 +50,8 @@ public class CachedClient {
     public CachedClient(RealmCache cache, RealmProvider delegate, RealmModel realm, ClientModel model) {
         id = model.getId();
         secret = model.getSecret();
-        name = model.getClientId();
+        clientId = model.getClientId();
+        name = model.getName();
         this.realm = realm.getId();
         enabled = model.isEnabled();
         protocol = model.getProtocol();
@@ -85,6 +87,10 @@ public class CachedClient {
         return id;
     }
 
+    public String getClientId() {
+        return clientId;
+    }
+
     public String getName() {
         return name;
     }
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
index b290e48..7e4906a 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
@@ -55,6 +55,16 @@ public class ClientAdapter implements ClientModel {
     }
 
     @Override
+    public String getName() {
+        return entity.getName();
+    }
+
+    @Override
+    public void setName(String name) {
+        entity.setName(name);
+    }
+
+    @Override
     public boolean isEnabled() {
         return entity.isEnabled();
     }
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java
index 26322d4..ff6f14c 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java
@@ -32,6 +32,8 @@ public class ClientEntity {
     @Id
     @Column(name="ID", length = 36)
     private String id;
+    @Column(name = "NAME")
+    private String name;
     @Column(name = "CLIENT_ID")
     private String clientId;
     @Column(name="ENABLED")
@@ -125,6 +127,14 @@ public class ClientEntity {
         this.id = id;
     }
 
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
     public boolean isEnabled() {
         return enabled;
     }
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java
index 9eae9f0..b0784f5 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java
@@ -27,20 +27,20 @@ import java.util.Set;
  */
 public class ClientAdapter extends AbstractMongoAdapter<MongoClientEntity> implements ClientModel {
 
-    protected final MongoClientEntity applicationEntity;
+    protected final MongoClientEntity clientEntity;
     private final RealmModel realm;
     protected  KeycloakSession session;
 
-    public ClientAdapter(KeycloakSession session, RealmModel realm, MongoClientEntity applicationEntity, MongoStoreInvocationContext invContext) {
+    public ClientAdapter(KeycloakSession session, RealmModel realm, MongoClientEntity clientEntity, MongoStoreInvocationContext invContext) {
         super(invContext);
         this.session = session;
         this.realm = realm;
-        this.applicationEntity = applicationEntity;
+        this.clientEntity = clientEntity;
     }
 
     @Override
     public MongoClientEntity getMongoEntity() {
-        return applicationEntity;
+        return clientEntity;
     }
 
     @Override
@@ -60,6 +60,17 @@ public class ClientAdapter extends AbstractMongoAdapter<MongoClientEntity> imple
     }
 
     @Override
+    public String getName() {
+        return getMongoEntity().getName();
+    }
+
+    @Override
+    public void setName(String name) {
+        getMongoEntity().setName(name);
+        updateMongoEntity();
+    }
+
+    @Override
     public void setClientId(String clientId) {
         getMongoEntity().setClientId(clientId);
         updateMongoEntity();
@@ -84,12 +95,12 @@ public class ClientAdapter extends AbstractMongoAdapter<MongoClientEntity> imple
 
     @Override
     public void addWebOrigin(String webOrigin) {
-        getMongoStore().pushItemToList(applicationEntity, "webOrigins", webOrigin, true, invocationContext);
+        getMongoStore().pushItemToList(clientEntity, "webOrigins", webOrigin, true, invocationContext);
     }
 
     @Override
     public void removeWebOrigin(String webOrigin) {
-        getMongoStore().pullItemFromList(applicationEntity, "webOrigins", webOrigin, invocationContext);
+        getMongoStore().pullItemFromList(clientEntity, "webOrigins", webOrigin, invocationContext);
     }
 
     @Override
@@ -111,12 +122,12 @@ public class ClientAdapter extends AbstractMongoAdapter<MongoClientEntity> imple
 
     @Override
     public void addRedirectUri(String redirectUri) {
-        getMongoStore().pushItemToList(applicationEntity, "redirectUris", redirectUri, true, invocationContext);
+        getMongoStore().pushItemToList(clientEntity, "redirectUris", redirectUri, true, invocationContext);
     }
 
     @Override
     public void removeRedirectUri(String redirectUri) {
-        getMongoStore().pullItemFromList(applicationEntity, "redirectUris", redirectUri, invocationContext);
+        getMongoStore().pullItemFromList(clientEntity, "redirectUris", redirectUri, invocationContext);
     }
 
     @Override
diff --git a/services/src/main/java/org/keycloak/services/managers/RealmManager.java b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
index 8493397..3d56a2a 100755
--- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
@@ -94,6 +94,7 @@ public class RealmManager {
     protected void setupAdminConsole(RealmModel realm) {
         ClientModel adminConsole = realm.getClientByClientId(Constants.ADMIN_CONSOLE_CLIENT_ID);
         if (adminConsole == null) adminConsole = new ClientManager(this).createClient(realm, Constants.ADMIN_CONSOLE_CLIENT_ID);
+        adminConsole.setName("${client_" + Constants.ADMIN_CONSOLE_CLIENT_ID + "}");
         String baseUrl = contextPath + "/admin/" + realm.getName() + "/console";
         adminConsole.setBaseUrl(baseUrl + "/index.html");
         adminConsole.setEnabled(true);
@@ -184,6 +185,7 @@ public class RealmManager {
         ClientModel realmAdminClient = realm.getClientByClientId(realmAdminClientId);
         if (realmAdminClient == null) {
             realmAdminClient = clientManager.createClient(realm, realmAdminClientId);
+            realmAdminClient.setName("${client_" + realmAdminClientId + "}");
         }
         RoleModel adminRole = realmAdminClient.addRole(AdminRoles.REALM_ADMIN);
         adminRole.setDescription("${role_" + AdminRoles.REALM_ADMIN + "}");
@@ -202,6 +204,7 @@ public class RealmManager {
         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.setName("${client_" + Constants.ACCOUNT_MANAGEMENT_CLIENT_ID + "}");
             client.setEnabled(true);
             client.setFullScopeAllowed(false);
             String base = contextPath + "/realms/" + realm.getName() + "/account";
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java
index 0312446..afee212 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java
@@ -167,6 +167,7 @@ public class AdminAPITest {
 
     protected void checkAppUpdate(ClientRepresentation appRep, ClientRepresentation storedApp) {
         if (appRep.getClientId() != null) Assert.assertEquals(appRep.getClientId(), storedApp.getClientId());
+        if (appRep.getName() != null) Assert.assertEquals(appRep.getName(), storedApp.getName());
         if (appRep.isEnabled() != null) Assert.assertEquals(appRep.isEnabled(), storedApp.isEnabled());
         if (appRep.isBearerOnly() != null) Assert.assertEquals(appRep.isBearerOnly(), storedApp.isBearerOnly());
         if (appRep.isPublicClient() != null) Assert.assertEquals(appRep.isPublicClient(), storedApp.isPublicClient());
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ClientModelTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ClientModelTest.java
index e56d462..efbefa6 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ClientModelTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ClientModelTest.java
@@ -31,6 +31,7 @@ public class ClientModelTest extends AbstractModelTest {
 
         realm = realmManager.createRealm("original");
         client = realm.addClient("application");
+        client.setName("Application");
         client.setBaseUrl("http://base");
         client.setManagementUrl("http://management");
         client.setClientId("app-name");
@@ -85,6 +86,7 @@ public class ClientModelTest extends AbstractModelTest {
 
     public static void assertEquals(ClientModel expected, ClientModel actual) {
         Assert.assertEquals(expected.getClientId(), actual.getClientId());
+        Assert.assertEquals(expected.getName(), actual.getName());
         Assert.assertEquals(expected.getBaseUrl(), actual.getBaseUrl());
         Assert.assertEquals(expected.getManagementUrl(), actual.getManagementUrl());
         Assert.assertEquals(expected.getDefaultRoles(), actual.getDefaultRoles());
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java
index bea52c4..317c101 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java
@@ -99,6 +99,7 @@ public class ImportTest extends AbstractModelTest {
         Assert.assertTrue(clients.values().contains(accountApp));
         realm.getClients().containsAll(clients.values());
 
+        Assert.assertEquals("Applicationn", application.getName());
         Assert.assertEquals(50, application.getNodeReRegistrationTimeout());
         Map<String, Integer> appRegisteredNodes = application.getRegisteredNodes();
         Assert.assertEquals(2, appRegisteredNodes.size());
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/OAuthGrantTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/OAuthGrantTest.java
index 6985e88..65f6198 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/OAuthGrantTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/OAuthGrantTest.java
@@ -73,6 +73,16 @@ public class OAuthGrantTest {
     private static String ROLE_CUSTOMER = "Have Customer User privileges";
 
     @Test
+    public void sleepTest() throws IOException {
+        try {
+            Thread.sleep(10000000);
+        } catch (InterruptedException ie) {
+            throw new RuntimeException(ie);
+        }
+    }
+
+
+    @Test
     public void oauthGrantAcceptTest() throws IOException {
         oauth.clientId("third-party");
         oauth.doLoginGrant("test-user@localhost", "password");
diff --git a/testsuite/integration/src/test/resources/model/testrealm.json b/testsuite/integration/src/test/resources/model/testrealm.json
index 1c0b7e6..e6d4d18 100755
--- a/testsuite/integration/src/test/resources/model/testrealm.json
+++ b/testsuite/integration/src/test/resources/model/testrealm.json
@@ -107,9 +107,10 @@
             ]
         }
     ],
-    "applications": [
+    "clients": [
         {
-            "name": "Application",
+            "clientId": "Application",
+            "name": "Applicationn",
             "enabled": true,
             "nodeReRegistrationTimeout": 50,
             "registeredNodes": {
@@ -118,7 +119,8 @@
             }
         },
         {
-            "name": "OtherApp",
+            "clientId": "OtherApp",
+            "name": "Other Application",
             "enabled": true,
             "protocolMappers" : [
                 {