keycloak-memoizeit

Changes

services/src/main/java/org/keycloak/protocol/oidc/endpoints/ValidateTokenEndpoint.java 105(+0 -105)

Details

diff --git a/docbook/auth-server-docs/reference/en/en-US/modules/client-registration.xml b/docbook/auth-server-docs/reference/en/en-US/modules/client-registration.xml
index 35f73a3..79b035a 100755
--- a/docbook/auth-server-docs/reference/en/en-US/modules/client-registration.xml
+++ b/docbook/auth-server-docs/reference/en/en-US/modules/client-registration.xml
@@ -106,23 +106,23 @@ Authorization: bearer eyJhbGciOiJSUzI1NiJ9.eyJqdGkiOiJmMjJmNzQyYy04ZjNlLTQ2M....
         </para>
         <para>
             To create a client create a Client Representation (JSON) then do a HTTP POST to:
-            <literal>&lt;KEYCLOAK URL&gt;/realms/&lt;realm&gt;/clients/&lt;provider&gt;/default</literal>. It will return a Client Representation
+            <literal>&lt;KEYCLOAK URL&gt;/realms/&lt;realm&gt;/clients/default</literal>. It will return a Client Representation
             that also includes the registration access token. You should save the registration access token somewhere
             if you want to retrieve the config, update or delete the client later.
         </para>
         <para>
             To retrieve the Client Representation then do a HTTP GET to:
-            <literal>&lt;KEYCLOAK URL&gt;/realms/&lt;realm&gt;clients/&lt;provider&gt;/default/&lt;client id&gt;</literal>. It will also
+            <literal>&lt;KEYCLOAK URL&gt;/realms/&lt;realm&gt;/clients/default/&lt;client id&gt;</literal>. It will also
             return a new registration access token.
         </para>
         <para>
             To update the Client Representation then do a HTTP PUT to with the updated Client Representation to:
-            <literal>&lt;KEYCLOAK URL&gt;/realms/&lt;realm&gt;/clients/&lt;provider&gt;/default/&lt;client id&gt;</literal>. It will also
+            <literal>&lt;KEYCLOAK URL&gt;/realms/&lt;realm&gt;/clients/default/&lt;client id&gt;</literal>. It will also
             return a new registration access token.
         </para>
         <para>
             To delete the Client Representation then do a HTTP DELETE to:
-            <literal>&lt;KEYCLOAK URL&gt;/realms/&lt;realm&gt;/clients/&lt;provider&gt;/default/&lt;client id&gt;</literal>
+            <literal>&lt;KEYCLOAK URL&gt;/realms/&lt;realm&gt;/clients/default/&lt;client id&gt;</literal>
         </para>
     </section>
 
@@ -138,7 +138,7 @@ Authorization: basic BASE64(client-id + ':' + client-secret)
         </para>
         <para>
             To retrieve the Adapter Configuration then do a HTTP GET to:
-            <literal>&lt;KEYCLOAK URL&gt;//realms/&lt;realm&gt;clients/&lt;provider&gt;/installation/&lt;client id&gt;</literal>
+            <literal>&lt;KEYCLOAK URL&gt;//realms/&lt;realm&gt;/clients/installation/&lt;client id&gt;</literal>
         </para>
         <para>
             No authentication is required for public clients. This means that for the JavaScript adapter you can
@@ -155,7 +155,7 @@ Authorization: basic BASE64(client-id + ':' + client-secret)
         </para>
         <para>
             The endpoint to use these specifications to register clients in Keycloak is:
-            <literal>&lt;KEYCLOAK URL&gt;/realms/&lt;realm&gt;/clients/&lt;provider&gt;/oidc[/&lt;client id&gt;]</literal>.
+            <literal>&lt;KEYCLOAK URL&gt;/realms/&lt;realm&gt;/clients/oidc[/&lt;client id&gt;]</literal>.
         </para>
         <para>
             This endpoints can also be found in the OpenID Connect Discovery endpoint for the realm:
@@ -173,7 +173,7 @@ Authorization: basic BASE64(client-id + ':' + client-secret)
         </para>
         <para>
             To create a client do a HTTP POST with the SAML Entity Descriptor to:
-            <literal>&lt;KEYCLOAK URL&gt;/realms/&lt;realm&gt;/clients/&lt;provider&gt;/saml2-entity-descriptor</literal>.
+            <literal>&lt;KEYCLOAK URL&gt;/realms/&lt;realm&gt;/clients/saml2-entity-descriptor</literal>.
         </para>
     </section>
 
diff --git a/docbook/auth-server-docs/reference/en/en-US/modules/MigrationFromOlderVersions.xml b/docbook/auth-server-docs/reference/en/en-US/modules/MigrationFromOlderVersions.xml
index 998a93d..f950ead 100755
--- a/docbook/auth-server-docs/reference/en/en-US/modules/MigrationFromOlderVersions.xml
+++ b/docbook/auth-server-docs/reference/en/en-US/modules/MigrationFromOlderVersions.xml
@@ -80,6 +80,23 @@
     <section>
         <title>Version specific migration</title>
         <section>
+            <title>Migrating to 1.9.0</title>
+            <simplesect>
+                <title>Deprecated OpenID Connect endpoints</title>
+                <para>
+                    In 1.2 we deprecated a number of endpoints that where not consistent with the OpenID Connect
+                    specifications, these have now been removed. This also applies to the validate token endpoints that
+                    was replaced with the new introspect endpoint in 1.8.
+                </para>
+            </simplesect>
+            <simplesect>
+                <title>Updates to theme templates</title>
+                <para>
+                    Feedback in template.ftl has been moved and format has changed slightly.
+                </para>
+            </simplesect>
+        </section>
+        <section>
             <title>Migrating to 1.8.0</title>
             <simplesect>
             <title>Admin account</title>
diff --git a/forms/account-freemarker/src/main/java/org/keycloak/forms/account/freemarker/model/RealmBean.java b/forms/account-freemarker/src/main/java/org/keycloak/forms/account/freemarker/model/RealmBean.java
index 68c7b78..a926a05 100755
--- a/forms/account-freemarker/src/main/java/org/keycloak/forms/account/freemarker/model/RealmBean.java
+++ b/forms/account-freemarker/src/main/java/org/keycloak/forms/account/freemarker/model/RealmBean.java
@@ -36,6 +36,28 @@ public class RealmBean {
         realm = realmModel;
     }
 
+    public String getName() {
+        return realm.getName();
+    }
+
+    public String getDisplayName() {
+        String displayName = realm.getDisplayName();
+        if (displayName != null && displayName.length() > 0) {
+            return displayName;
+        } else {
+            return getName();
+        }
+    }
+
+    public String getDisplayNameHtml() {
+        String displayNameHtml = realm.getDisplayNameHtml();
+        if (displayNameHtml != null && displayNameHtml.length() > 0) {
+            return displayNameHtml;
+        } else {
+            return getDisplayName();
+        }
+    }
+
     public boolean isInternationalizationEnabled() {
         return realm.isInternationalizationEnabled();
     }
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js
index a3c99e8..548c6e1 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js
@@ -343,8 +343,8 @@ module.controller('RealmThemeCtrl', function($scope, Current, Realm, realm, serv
     };
 
     $scope.$watch('realm.supportedLocales', function(oldVal, newVal) {
-        if(angular.isUndefined(newVal) || (angular.isArray(newVal) && newVal.length == 0)){
-            $scope.realm.defaultLocale = undefined;
+        if ($scope.realm.defaultLocale && newVal && newVal.indexOf($scope.realm.defaultLocale) == -1) {
+            $scope.realm.defaultLocale = null;
         }
     }, true);
 });
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-theme-settings.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-theme-settings.html
index 4d77b89..0c36f93 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-theme-settings.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-theme-settings.html
@@ -65,7 +65,9 @@
                 <label class="col-md-2 control-label" for="supportedLocales" class="control-label two-lines">{{:: 'supported-locales' | translate}}</label>
 
                 <div class="col-md-6">
-                    <input id="supportedLocales" type="text" ui-select2="supportedLocalesOptions" ng-model="realm.supportedLocales" placeholder="{{:: 'supported-locales.placeholder' | translate}}" ng-required="realm.internationalizationEnabled" ng-disabled="!realm.internationalizationEnabled">
+                    <select ui-select2 id="supportedLocales" ng-model="realm.supportedLocales" data-placeholder="{{:: 'supported-locales.placeholder' | translate}}" ng-required="realm.internationalizationEnabled" multiple>
+                        <option ng-repeat="option in supportedLocalesOptions.tags" value="{{option}}">{{option}}</option>
+                    </select>
                 </div>
             </div>
             <div class="form-group" data-ng-show="realm.internationalizationEnabled">
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-list.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-list.html
index cf34778..fcf6b86 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-list.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-list.html
@@ -5,7 +5,7 @@
         <caption data-ng-show="users" class="hidden">Table of realm users</caption>
         <thead>
         <tr>
-            <th colspan="{{access.impersonation == true ? '7' : '6'}}">
+            <th colspan="{{access.impersonation == true ? '8' : '7'}}">
                 <div class="form-inline">
                     <div class="form-group">
                         <div class="input-group">
@@ -26,10 +26,11 @@
         </tr>
         <tr>
         <tr data-ng-show="searchLoaded && users.length > 0">
-            <th>Username</th>
-            <th>Last Name</th>
-            <th>First Name</th>
-            <th>Email</th>
+            <th class="w-15">ID</th>
+            <th class="w-15">Username</th>
+            <th class="w-15">Email</th>
+            <th class="w-15">Last Name</th>
+            <th class="w-15">First Name</th>
             <th colspan="{{access.impersonation == true ? '3' : '2'}}">Actions</th>
         </tr>
         </tr>
@@ -47,10 +48,11 @@
         </tfoot>
         <tbody>
         <tr ng-repeat="user in users">
-            <td><a href="#/realms/{{realm.realm}}/users/{{user.id}}">{{user.username}}</a></td>
-            <td>{{user.lastName}}</td>
-            <td>{{user.firstName}}</td>
-            <td>{{user.email}}</td>
+            <td class="clip"><a href="#/realms/{{realm.realm}}/users/{{user.id}}">{{user.id}}</a></td>
+            <td class="clip">{{user.username}}</td>
+            <td class="clip">{{user.email}}</td>
+            <td class="clip">{{user.lastName}}</td>
+            <td class="clip">{{user.firstName}}</td>
             <td class="kc-action-cell">
                 <button class="btn btn-default btn-block btn-sm" kc-open="/realms/{{realm.realm}}/users/{{user.id}}">Edit</button>
             </td>
diff --git a/forms/common-themes/src/main/resources/theme/base/login/template.ftl b/forms/common-themes/src/main/resources/theme/base/login/template.ftl
index a637969..57aab78 100755
--- a/forms/common-themes/src/main/resources/theme/base/login/template.ftl
+++ b/forms/common-themes/src/main/resources/theme/base/login/template.ftl
@@ -38,18 +38,6 @@
                 <div id="kc-header-wrapper" class="${properties.kcHeaderWrapperClass!}"><#nested "header"></div>
             </div>
 
-            <#if displayMessage && message?has_content>
-                <div id="kc-feedback" class="feedback-${message.type} ${properties.kcFeedBackClass!}">
-                    <div id="kc-feedback-wrapper">
-                        <span class="kc-feedback-text">${message.summary}</span>
-                    </div>
-                </div>
-            <#else>
-                <div id="kc-feedback-placeholder" class="${properties.kcFeedBackPlaceholderClass!}">
-                    <div id="kc-feedback-placeholder-wrapper"></div>
-                </div>
-            </#if>
-
             <#if realm.internationalizationEnabled>
                 <div id="kc-locale" class="${properties.kcLocaleClass!}">
                     <div id="kc-locale-wrapper" class="${properties.kcLocaleWrapperClass!}">
@@ -67,6 +55,18 @@
 
             <div id="kc-content" class="${properties.kcContentClass!}">
                 <div id="kc-content-wrapper" class="${properties.kcContentWrapperClass!}">
+
+                    <#if displayMessage && message?has_content>
+                        <div class="${properties.kcFeedbackAreaClass!}">
+                            <div class="alert alert-${message.type}">
+                                <#if message.type = 'success'><span class="${properties.kcFeedbackSuccessIcon}"></span></#if>
+                                <#if message.type = 'warning'><span class="${properties.kcFeedbackWarningIcon}"></span></#if>
+                                <#if message.type = 'error'><span class="${properties.kcFeedbackErrorIcon}"></span></#if>
+                                <span class="kc-feedback-text">${message.summary}</span>
+                            </div>
+                        </div>
+                    </#if>
+
                     <div id="kc-form" class="${properties.kcFormAreaClass!}">
                         <div id="kc-form-wrapper" class="${properties.kcFormAreaWrapperClass!}">
                             <#nested "form">
diff --git a/forms/common-themes/src/main/resources/theme/keycloak/admin/resources/css/styles.css b/forms/common-themes/src/main/resources/theme/keycloak/admin/resources/css/styles.css
index 500ed89..a6d4021 100644
--- a/forms/common-themes/src/main/resources/theme/keycloak/admin/resources/css/styles.css
+++ b/forms/common-themes/src/main/resources/theme/keycloak/admin/resources/css/styles.css
@@ -26,8 +26,47 @@ table {
     margin-top: 0px !important;
 }
 
+table {
+    max-width: 100%;
+}
+
+td.clip {
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    max-width: 0;
+}
+
+th.w-10 {
+    width: 10%;
+}
+
+th.w-15 {
+    width: 15%;
+}
+
+th.w-20 {
+    width: 20%;
+}
 
 
+th.w-25 {
+    width: 25%;
+}
+
+th.w-30 {
+    width: 30%;
+}
+
+
+th.w-35 {
+    width: 35%;
+}
+
+th.w-40 {
+    width: 40%;
+}
+
 /*********** Loading ***********/
 
 .loading {
@@ -299,6 +338,9 @@ h1 i {
 .kc-action-cell {
     position: relative;
     width: 100px;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
 }
 
 .kc-action-cell .btn {
@@ -308,6 +350,9 @@ h1 i {
     left: 0;
     right: 0;
     bottom: 0;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
 }
 
 .kc-sorter span {
diff --git a/forms/common-themes/src/main/resources/theme/keycloak/login/resources/css/login.css b/forms/common-themes/src/main/resources/theme/keycloak/login/resources/css/login.css
index 0c05a4b..b45f9b9 100644
--- a/forms/common-themes/src/main/resources/theme/keycloak/login/resources/css/login.css
+++ b/forms/common-themes/src/main/resources/theme/keycloak/login/resources/css/login.css
@@ -3,60 +3,64 @@
     background-size: 100% auto;
 }
 
-.kc-dropdown{
-    position: relative;
-    z-index: 9999;
+.alert-error {
+    background-color: #ffffff;
+    border-color: #cc0000;
+    color: #333333;
 }
-.kc-dropdown > a{
+
+#kc-locale ul {
+    display: none;
     position: absolute;
-    right: 0px;
-    display:block;
-    padding: 11px 10px 12px;
-    line-height: 12px;
-    font-size: 12px;
-    color: #fff !important;
-    text-decoration: none;
-}
-.kc-dropdown > a::after{
-    content: "\2c5";
-    margin-left: 4px;
+    background-color: #fff;
+    list-style: none;
+    right: 20px;
+    top: 30px;
+    width: 200px;
+    padding: 2px;
 }
-.kc-dropdown:hover > a{
-    background-color: rgba(0,0,0,0.2);
+
+#kc-locale:hover ul {
+    display: block;
+    margin: 0;
 }
-.kc-dropdown ul li a{
+
+#kc-locale ul li a {
+    display: block;
     padding: 1px 11px;
-    font-size: 12px;
     color: #000 !important;
     border: 1px solid #fff;
     text-decoration: none;
     display:block;
     line-height: 20px;
 }
-.kc-dropdown ul li a:hover{
+
+#kc-locale ul li a:hover {
     color: #4d5258;
     background-color: #d4edfa;
     border-color: #b3d3e7;
 }
-.kc-dropdown ul{
-    position: absolute;
-    right: 0px;
-    top: 35px;
-    z-index: 2000;
-    list-style:none;
-    display:none;
-    padding: 5px 0px;
-    margin: 0px;
-    background-color: #fff !important;
-    border: 1px solid #b6b6b6;
-    border-radius: 1px;
-    -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
-    box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
-    background-clip: padding-box;
-    min-width: 100px;
-}
-.kc-dropdown:hover ul{
-    display:block;
+
+#kc-locale-dropdown a {
+    color: #fff;
+}
+
+#kc-locale-dropdown a:hover {
+    text-decoration: none;
+}
+
+a#kc-current-locale-link {
+    display: block;
+    padding: 5px;
+}
+
+a#kc-current-locale-link:hover {
+    background-color: rgba(0,0,0,0.2);
+}
+
+a#kc-current-locale-link::after {
+    content: "\2c5";
+    margin-left: 4px;
 }
 
 .login-pf .container {
@@ -114,59 +118,10 @@
     display: block;
 }
 
-#kc-feedback-wrapper {
-    display: inline-block;
-    width: auto;
-    background-position: left bottom;
-    background-repeat: no-repeat;
-    padding-bottom: 10px;
-}
-
-#kc-feedback span {
-    display: block;
-    padding: 0.90909090909091em 3.63636363636364em;
-    border-style: solid;
-    border-width: 1px 1px 0px 1px;
-    background-repeat: no-repeat;
-    background-position: 1.27272727272727em center;
-    font-weight: normal;
-    line-height: 1.4em;
-    border-radius: 2px;
-    color: #4d5258;
-    margin-bottom: 0;
-}
-
 #kc-terms-text {
     margin-bottom: 20px;
 }
 
-.feedback-error #kc-feedback-wrapper {
-    background-image: url(../img/feedback-error-arrow-down.png);
-}
-.feedback-error span {
-    border-color: #b91415;
-    background-image: url(../img/feedback-error-sign.png);
-    background-color: #f8e7e7;
-}
-
-.feedback-success #kc-feedback-wrapper {
-    background-image: url(../img/feedback-success-arrow-down.png);
-}
-.feedback-success span {
-    border-color: #4b9e39;
-    background-image: url(../img/feedback-success-sign.png);
-    background-color: #e4f1e1;
-}
-
-.feedback-warning #kc-feedback-wrapper {
-    background-image: url(../img/feedback-warning-arrow-down.png);
-}
-.feedback-warning span {
-    border-color: #f17528;
-    background-image: url(../img/feedback-warning-sign.png);
-    background-color: #fef1e9;
-}
-
 #kc-registration {
     margin-bottom: 15px;
 }
@@ -283,6 +238,18 @@ ol#kc-totp-settings li:first-of-type {
         top: 50px;
         right: 50px;
     }
+
+    .login-pf .container {
+        padding-right: 80px;
+    }
+
+    #kc-locale {
+        position: relative;
+        width: 200px;
+        left: -230px;
+        text-align: right;
+        z-index: 9999;
+    }
 }
 
 @media (max-width: 767px) {
@@ -300,12 +267,6 @@ ol#kc-totp-settings li:first-of-type {
         text-align: center;
     }
 
-    #kc-feedback {
-        padding-left: 15px;
-        padding-right: 15px;
-        float: none;
-    }
-
     #kc-form {
         float: none;
     }
@@ -327,6 +288,15 @@ ol#kc-totp-settings li:first-of-type {
         padding-top: 15px;
         padding-bottom: 15px;
     }
+
+    #kc-locale {
+        position: absolute;
+        width: 200px;
+        top: 10px;
+        right: 0px;
+        text-align: right;
+        z-index: 9999;
+    }
 }
 
 @media (max-height: 500px) {
diff --git a/forms/common-themes/src/main/resources/theme/keycloak/login/theme.properties b/forms/common-themes/src/main/resources/theme/keycloak/login/theme.properties
index b2364e1..8891151 100644
--- a/forms/common-themes/src/main/resources/theme/keycloak/login/theme.properties
+++ b/forms/common-themes/src/main/resources/theme/keycloak/login/theme.properties
@@ -11,13 +11,18 @@ kcLogoLink=http://www.keycloak.org
 kcContentClass=col-sm-12 col-md-12 col-lg-12 container
 kcContentWrapperClass=row
 
-kcHeaderClass=col-xs-12 col-sm-7 col-md-6 col-lg-5
-kcFeedBackClass=col-xs-12 col-sm-4 col-md-5 col-lg-6
-kcFeedBackPlaceholderClass=col-xs-12 col-sm-4 col-md-5 col-lg-6
+kcHeaderClass=col-xs-12 col-sm-8 col-md-8 col-lg-7
+kcFeedbackAreaClass=col-md-12
 kcLocaleClass=col-xs-12 col-sm-1
+kcAlertIconClasserror=pficon pficon-error-circle-o
 
 kcFormAreaClass=col-xs-12 col-sm-8 col-md-8 col-lg-7 login
 
+kcFeedbackErrorIcon=pficon pficon-error-circle-o
+kcFeedbackWarningIcon=pficon pficon-warning-triangle-o
+kcFeedbackSuccessIcon=alert alert-success
+
+
 kcFormClass=form-horizontal
 kcFormGroupClass=form-group
 kcFormGroupErrorClass=has-error
diff --git a/forms/email-freemarker/src/main/java/org/keycloak/email/freemarker/FreeMarkerEmailTemplateProvider.java b/forms/email-freemarker/src/main/java/org/keycloak/email/freemarker/FreeMarkerEmailTemplateProvider.java
index 4ce8170..0a47851 100755
--- a/forms/email-freemarker/src/main/java/org/keycloak/email/freemarker/FreeMarkerEmailTemplateProvider.java
+++ b/forms/email-freemarker/src/main/java/org/keycloak/email/freemarker/FreeMarkerEmailTemplateProvider.java
@@ -55,6 +55,14 @@ public class FreeMarkerEmailTemplateProvider implements EmailTemplateProvider {
         return this;
     }
 
+    private String getRealmName() {
+        if (realm.getDisplayName() != null) {
+            return realm.getDisplayName();
+        } else {
+            return ObjectUtil.capitalize(realm.getName());
+        }
+    }
+
     @Override
     public void sendEvent(Event event) throws EmailException {
         Map<String, Object> attributes = new HashMap<String, Object>();
@@ -71,8 +79,7 @@ public class FreeMarkerEmailTemplateProvider implements EmailTemplateProvider {
         attributes.put("link", link);
         attributes.put("linkExpiration", expirationInMinutes);
 
-        String realmName = ObjectUtil.capitalize(realm.getName());
-        attributes.put("realmName", realmName);
+        attributes.put("realmName", getRealmName());
 
         send("passwordResetSubject", "password-reset.ftl", attributes);
     }
@@ -84,8 +91,7 @@ public class FreeMarkerEmailTemplateProvider implements EmailTemplateProvider {
         attributes.put("link", link);
         attributes.put("linkExpiration", expirationInMinutes);
 
-        String realmName = ObjectUtil.capitalize(realm.getName());
-        attributes.put("realmName", realmName);
+        attributes.put("realmName", getRealmName());
 
         BrokeredIdentityContext brokerContext = (BrokeredIdentityContext) this.attributes.get(IDENTITY_PROVIDER_BROKER_CONTEXT);
         String idpAlias = brokerContext.getIdpConfig().getAlias();
@@ -105,8 +111,7 @@ public class FreeMarkerEmailTemplateProvider implements EmailTemplateProvider {
         attributes.put("link", link);
         attributes.put("linkExpiration", expirationInMinutes);
 
-        String realmName = ObjectUtil.capitalize(realm.getName());
-        attributes.put("realmName", realmName);
+        attributes.put("realmName", getRealmName());
 
         send("executeActionsSubject", "executeActions.ftl", attributes);
 
@@ -119,8 +124,7 @@ public class FreeMarkerEmailTemplateProvider implements EmailTemplateProvider {
         attributes.put("link", link);
         attributes.put("linkExpiration", expirationInMinutes);
 
-        String realmName = ObjectUtil.capitalize(realm.getName());
-        attributes.put("realmName", realmName);
+        attributes.put("realmName", getRealmName());
 
         send("emailVerificationSubject", "email-verification.ftl", attributes);
     }
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java
index 6f0fdae..27070ad 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java
@@ -60,8 +60,6 @@ public class AuthorizationEndpoint extends AuthorizationEndpointBase {
     private String nonce;
     private String idpHint;
 
-    private String legacyResponseType;
-
     public AuthorizationEndpoint(RealmModel realm, EventBuilder event) {
         super(realm, event);
         event.event(EventType.LOGIN);
@@ -102,15 +100,6 @@ public class AuthorizationEndpoint extends AuthorizationEndpointBase {
         throw new RuntimeException("Unknown action " + action);
     }
 
-    /**
-     * @deprecated
-     */
-    public AuthorizationEndpoint legacy(String legacyResponseType) {
-        logger.warnv("Invoking deprecated endpoint {0}", uriInfo.getRequestUri());
-        this.legacyResponseType = legacyResponseType;
-        return this;
-    }
-
     public AuthorizationEndpoint register() {
         event.event(EventType.REGISTER);
         action = Action.REGISTER;
@@ -181,12 +170,8 @@ public class AuthorizationEndpoint extends AuthorizationEndpointBase {
 
     private void checkResponseType() {
         if (responseType == null) {
-            if (legacyResponseType != null) {
-                responseType = legacyResponseType;
-            } else {
-                event.error(Errors.INVALID_REQUEST);
-                throw new ErrorPageException(session, Messages.MISSING_PARAMETER, OIDCLoginProtocol.RESPONSE_TYPE_PARAM);
-            }
+            event.error(Errors.INVALID_REQUEST);
+            throw new ErrorPageException(session, Messages.MISSING_PARAMETER, OIDCLoginProtocol.RESPONSE_TYPE_PARAM);
         }
 
         event.detail(Details.RESPONSE_TYPE, responseType);
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenEndpoint.java
index 8f875e1..382d2e2 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenEndpoint.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenEndpoint.java
@@ -83,8 +83,6 @@ public class TokenEndpoint {
 
     private String grantType;
 
-    private String legacyGrantType;
-
     public TokenEndpoint(TokenManager tokenManager, RealmModel realm, EventBuilder event) {
         this.tokenManager = tokenManager;
         this.realm = realm;
@@ -132,15 +130,6 @@ public class TokenEndpoint {
         return Cors.add(request, Response.ok()).auth().preflight().build();
     }
 
-    /**
-     * @deprecated
-     */
-    public TokenEndpoint legacy(String legacyGrantType) {
-        logger.warnv("Invoking deprecated endpoint {0}", uriInfo.getRequestUri());
-        this.legacyGrantType = legacyGrantType;
-        return this;
-    }
-
     private void checkSsl() {
         if (!uriInfo.getBaseUri().getScheme().equals("https") && realm.getSslRequired().isRequired(clientConnection)) {
             throw new ErrorResponseException("invalid_request", "HTTPS required", Response.Status.FORBIDDEN);
@@ -165,11 +154,7 @@ public class TokenEndpoint {
 
     private void checkGrantType() {
         if (grantType == null) {
-            if (legacyGrantType != null) {
-                grantType = legacyGrantType;
-            } else {
-                throw new ErrorResponseException("invalid_request", "Missing form parameter: " + OIDCLoginProtocol.GRANT_TYPE_PARAM, Response.Status.BAD_REQUEST);
-            }
+            throw new ErrorResponseException("invalid_request", "Missing form parameter: " + OIDCLoginProtocol.GRANT_TYPE_PARAM, Response.Status.BAD_REQUEST);
         }
 
         if (grantType.equals(OAuth2Constants.AUTHORIZATION_CODE)) {
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolService.java b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolService.java
index 382e85c..6f6be0c 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolService.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolService.java
@@ -14,9 +14,7 @@ import org.keycloak.protocol.oidc.endpoints.AuthorizationEndpoint;
 import org.keycloak.protocol.oidc.endpoints.LoginStatusIframeEndpoint;
 import org.keycloak.protocol.oidc.endpoints.LogoutEndpoint;
 import org.keycloak.protocol.oidc.endpoints.TokenEndpoint;
-import org.keycloak.protocol.oidc.endpoints.TokenIntrospectionEndpoint;
 import org.keycloak.protocol.oidc.endpoints.UserInfoEndpoint;
-import org.keycloak.protocol.oidc.endpoints.ValidateTokenEndpoint;
 import org.keycloak.protocol.oidc.representations.JSONWebKeySet;
 import org.keycloak.services.resources.RealmsResource;
 
@@ -88,17 +86,6 @@ public class OIDCLoginProtocolService {
         return tokenUrl(baseUriBuilder).path(TokenEndpoint.class, "introspect");
     }
 
-    /**
-     * @deprecated use {@link OIDCLoginProtocolService#tokenIntrospectionUrl(UriBuilder)} instead
-     * @param baseUriBuilder
-     * @return
-     */
-    @Deprecated
-    public static UriBuilder validateAccessTokenUrl(UriBuilder baseUriBuilder) {
-        UriBuilder uriBuilder = tokenServiceBaseUrl(baseUriBuilder);
-        return uriBuilder.path(OIDCLoginProtocolService.class, "validateAccessToken");
-    }
-
     public static UriBuilder logoutUrl(UriInfo uriInfo) {
         UriBuilder baseUriBuilder = uriInfo.getBaseUriBuilder();
         return logoutUrl(baseUriBuilder);
@@ -149,14 +136,6 @@ public class OIDCLoginProtocolService {
         return endpoint;
     }
 
-    @Path("login")
-    @Deprecated
-    public Object loginPage() {
-        AuthorizationEndpoint endpoint = new AuthorizationEndpoint(realm, event);
-        ResteasyProviderFactory.getInstance().injectProperties(endpoint);
-        return endpoint.legacy(OIDCLoginProtocol.CODE_PARAM);
-    }
-
     @Path("login-status-iframe.html")
     public Object getLoginStatusIframe() {
         LoginStatusIframeEndpoint endpoint = new LoginStatusIframeEndpoint(realm);
@@ -164,45 +143,6 @@ public class OIDCLoginProtocolService {
         return endpoint;
     }
 
-    @Path("grants/access")
-    @Deprecated
-    public Object grantAccessToken() {
-        TokenEndpoint endpoint = new TokenEndpoint(tokenManager, realm, event);
-        ResteasyProviderFactory.getInstance().injectProperties(endpoint);
-        return endpoint.legacy(OAuth2Constants.PASSWORD);
-    }
-
-    @Path("refresh")
-    @Deprecated
-    public Object refreshAccessToken() {
-        TokenEndpoint endpoint = new TokenEndpoint(tokenManager, realm, event);
-        ResteasyProviderFactory.getInstance().injectProperties(endpoint);
-        return endpoint.legacy(OAuth2Constants.REFRESH_TOKEN);
-    }
-
-    @Path("access/codes")
-    @Deprecated
-    public Object accessCodeToToken() {
-        TokenEndpoint endpoint = new TokenEndpoint(tokenManager, realm, event);
-        ResteasyProviderFactory.getInstance().injectProperties(endpoint);
-        return endpoint.legacy(OAuth2Constants.AUTHORIZATION_CODE);
-    }
-
-    /**
-     * @deprecated use {@link TokenIntrospectionEndpoint#introspect()} instead
-     * @param tokenString
-     * @return
-     */
-    @Path("validate")
-    @Deprecated
-    public Object validateAccessToken(@QueryParam("access_token") String tokenString) {
-        logger.warnv("Invoking deprecated endpoint {0}", uriInfo.getRequestUri());
-        ValidateTokenEndpoint endpoint = new ValidateTokenEndpoint(tokenManager, realm, event);
-        ResteasyProviderFactory.getInstance().injectProperties(endpoint);
-        return endpoint;
-
-    }
-
     @GET
     @Path("certs")
     @Produces(MediaType.APPLICATION_JSON)
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java
index 4e2f1f3..2b4ec04 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java
@@ -401,65 +401,6 @@ public class AccessTokenTest {
     }
 
     @Test
-    public void testValidateAccessToken() throws Exception {
-        Client client = ClientBuilder.newClient();
-        UriBuilder builder = UriBuilder.fromUri(org.keycloak.testsuite.Constants.AUTH_SERVER_ROOT);
-        URI grantUri = OIDCLoginProtocolService.tokenUrl(builder).build("test");
-        WebTarget grantTarget = client.target(grantUri);
-        builder = UriBuilder.fromUri(org.keycloak.testsuite.Constants.AUTH_SERVER_ROOT);
-        URI validateUri = OIDCLoginProtocolService.validateAccessTokenUrl(builder).build("test");
-        WebTarget validateTarget = client.target(validateUri);
-
-        {
-            Response response = validateTarget.queryParam("access_token", "bad token").request().get();
-            Assert.assertEquals(400, response.getStatus());
-            HashMap<String, String> error = response.readEntity(new GenericType<HashMap<String, String>>() {
-            });
-            Assert.assertNotNull(error.get("error"));
-        }
-
-
-        org.keycloak.representations.AccessTokenResponse tokenResponse = null;
-        {
-            Response response = executeGrantAccessTokenRequest(grantTarget);
-            Assert.assertEquals(200, response.getStatus());
-            tokenResponse = response.readEntity(org.keycloak.representations.AccessTokenResponse.class);
-            response.close();
-        }
-
-        {
-            Response response = validateTarget.queryParam("access_token", tokenResponse.getToken()).request().get();
-            Assert.assertEquals(200, response.getStatus());
-            AccessToken token = response.readEntity(AccessToken.class);
-            Assert.assertNotNull(token);
-            response.close();
-        }
-        {
-            builder = UriBuilder.fromUri(org.keycloak.testsuite.Constants.AUTH_SERVER_ROOT);
-            URI logoutUri = OIDCLoginProtocolService.logoutUrl(builder).build("test");
-            String header = BasicAuthHelper.createHeader("test-app", "password");
-            Form form = new Form();
-            form.param("refresh_token", tokenResponse.getRefreshToken());
-            Response response = client.target(logoutUri).request()
-                    .header(HttpHeaders.AUTHORIZATION, header)
-                    .post(Entity.form(form));
-            Assert.assertEquals(204, response.getStatus());
-            response.close();
-        }
-        {
-            Response response = validateTarget.queryParam("access_token", tokenResponse.getToken()).request().get();
-            Assert.assertEquals(400, response.getStatus());
-            HashMap<String, String> error = response.readEntity(new GenericType<HashMap<String, String>>() {
-            });
-            Assert.assertNotNull(error.get("error"));
-        }
-
-        client.close();
-        events.clear();
-
-    }
-
-    @Test
     public void testGrantAccessToken() throws Exception {
         Client client = ClientBuilder.newClient();
         UriBuilder builder = UriBuilder.fromUri(org.keycloak.testsuite.Constants.AUTH_SERVER_ROOT);
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginPage.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginPage.java
index 04e5ddd..4fdb888 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginPage.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginPage.java
@@ -62,13 +62,13 @@ public class LoginPage extends AbstractPage {
     @FindBy(linkText = "Username")
     private WebElement recoverUsernameLink;
 
-    @FindBy(className = "feedback-error")
+    @FindBy(className = "alert-error")
     private WebElement loginErrorMessage;
 
-    @FindBy(className = "feedback-warning")
+    @FindBy(className = "alert-warning")
     private WebElement loginWarningMessage;
 
-    @FindBy(className = "feedback-success")
+    @FindBy(className = "alert-success")
     private WebElement emailSuccessMessage;
 
 
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginPasswordResetPage.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginPasswordResetPage.java
index a244c32..e60aeb5 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginPasswordResetPage.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginPasswordResetPage.java
@@ -35,10 +35,10 @@ public class LoginPasswordResetPage extends AbstractPage {
     @FindBy(css = "input[type=\"submit\"]")
     private WebElement submitButton;
 
-    @FindBy(className = "feedback-success")
+    @FindBy(className = "alert-success")
     private WebElement emailSuccessMessage;
 
-    @FindBy(className = "feedback-error")
+    @FindBy(className = "alert-error")
     private WebElement emailErrorMessage;
 
     @FindBy(partialLinkText = "Back to Login")
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginPasswordUpdatePage.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginPasswordUpdatePage.java
index d8adea4..dafb726 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginPasswordUpdatePage.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginPasswordUpdatePage.java
@@ -38,7 +38,7 @@ public class LoginPasswordUpdatePage extends AbstractPage {
     @FindBy(css = "input[type=\"submit\"]")
     private WebElement submitButton;
 
-    @FindBy(className = "feedback-error")
+    @FindBy(className = "alert-error")
     private WebElement loginErrorMessage;
 
     public void changePassword(String newPassword, String passwordConfirm) {
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginRecoverUsernamePage.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginRecoverUsernamePage.java
index 6759070..e8e8014 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginRecoverUsernamePage.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginRecoverUsernamePage.java
@@ -35,7 +35,7 @@ public class LoginRecoverUsernamePage extends AbstractPage {
     @FindBy(css = "input[type=\"submit\"]")
     private WebElement submitButton;
 
-    @FindBy(className = "feedback-error")
+    @FindBy(className = "alert-error")
     private WebElement emailErrorMessage;
 
     public void recoverUsername(String email) {
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginTotpPage.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginTotpPage.java
index 09782c9..bc203bc 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginTotpPage.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginTotpPage.java
@@ -42,7 +42,7 @@ public class LoginTotpPage extends AbstractPage {
     @FindBy(id = "kc-cancel")
     private WebElement cancelButton;
 
-    @FindBy(className = "feedback-error")
+    @FindBy(className = "alert-error")
     private WebElement loginErrorMessage;
 
     public void login(String totp) {
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginUpdateProfilePage.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginUpdateProfilePage.java
index c9038a4..2f7e9bf 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginUpdateProfilePage.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginUpdateProfilePage.java
@@ -43,7 +43,7 @@ public class LoginUpdateProfilePage extends AbstractPage {
     @FindBy(css = "input[type=\"submit\"]")
     private WebElement submitButton;
 
-    @FindBy(className = "feedback-error")
+    @FindBy(className = "alert-error")
     private WebElement loginErrorMessage;
 
     public void update(String firstName, String lastName, String email) {
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/RegisterPage.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/RegisterPage.java
index 456d0a8..29b5f9f 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/RegisterPage.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/RegisterPage.java
@@ -54,7 +54,7 @@ public class RegisterPage extends AbstractPage {
     @FindBy(css = "input[type=\"submit\"]")
     private WebElement submitButton;
 
-    @FindBy(className = "feedback-error")
+    @FindBy(className = "alert-error")
     private WebElement loginErrorMessage;
 
     public void register(String firstName, String lastName, String email, String username, String password, String passwordConfirm) {
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/ValidatePassworrdEmailResetPage.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/ValidatePassworrdEmailResetPage.java
index 780b704..84c2d4c 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/ValidatePassworrdEmailResetPage.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/ValidatePassworrdEmailResetPage.java
@@ -38,10 +38,10 @@ public class ValidatePassworrdEmailResetPage extends AbstractPage {
     @FindBy(id="kc-cancel")
     private WebElement cancelButton;
 
-    @FindBy(className = "feedback-success")
+    @FindBy(className = "alert-success")
     private WebElement emailSuccessMessage;
 
-    @FindBy(className = "feedback-error")
+    @FindBy(className = "alert-error")
     private WebElement emailErrorMessage;
 
     public void submitCode(String code) {
diff --git a/testsuite/integration-arquillian/tests/pom.xml b/testsuite/integration-arquillian/tests/pom.xml
index 4f03fab..d520de6 100644
--- a/testsuite/integration-arquillian/tests/pom.xml
+++ b/testsuite/integration-arquillian/tests/pom.xml
@@ -43,6 +43,8 @@
         <skip.unpack.server>true</skip.unpack.server>
         <skip.unpack.previous>true</skip.unpack.previous>
         <skip.install.adapters>true</skip.install.adapters>
+        
+        <jboss.server.config.dir>${project.build.directory}/undertow-configuration</jboss.server.config.dir>
     </properties>
 
     <dependencyManagement>
@@ -96,7 +98,7 @@
                             <auth.server.management.port.jmx>${auth.server.management.port.jmx}</auth.server.management.port.jmx>
                             <auth.server.ssl.required>${auth.server.ssl.required}</auth.server.ssl.required>
                             <startup.timeout.sec>${startup.timeout.sec}</startup.timeout.sec>
-                            <jboss.server.config.dir>${project.build.directory}/undertow-configuration</jboss.server.config.dir>
+                            <jboss.server.config.dir>${jboss.server.config.dir}</jboss.server.config.dir>
                             <skip.install.adapters>${skip.install.adapters}</skip.install.adapters>
                         </systemPropertyVariables>
                         <properties>