keycloak-uncached

Details

diff --git a/forms/src/main/resources/META-INF/resources/forms/theme/default/css/login-register.css b/forms/src/main/resources/META-INF/resources/forms/theme/default/css/login-register.css
index e26aa9d..cf293d4 100644
--- a/forms/src/main/resources/META-INF/resources/forms/theme/default/css/login-register.css
+++ b/forms/src/main/resources/META-INF/resources/forms/theme/default/css/login-register.css
@@ -129,10 +129,10 @@ body {
   margin-bottom: 0.54545454545455em;
   /* 6px */
 }
-.rcue-login-register form > input[type="button"],
-.rcue-login-register form > input[type="submit"]{
-  float: right;
-  margin-top: 0.76923076923077em;
+.rcue-login-register div.form-buttons {
+    display: inline;
+    float: right;
+    margin-top: 0.76923076923077em;
   /* 10px */
 
 }
diff --git a/forms/src/main/resources/META-INF/resources/forms/theme/default/login.ftl b/forms/src/main/resources/META-INF/resources/forms/theme/default/login.ftl
index 2e90a5d..07bcf43 100755
--- a/forms/src/main/resources/META-INF/resources/forms/theme/default/login.ftl
+++ b/forms/src/main/resources/META-INF/resources/forms/theme/default/login.ftl
@@ -22,7 +22,10 @@
                 </div>
             </#list>
 
-            <input class="btn-primary" type="submit" value="Log In"/>
+            <div class="form-buttons">
+                <input class="btn-primary" name="login" type="submit" value="Log In"/>
+                <input class="btn-secondary" name="cancel" type="submit" value="Cancel"/>
+            </div>
 
             <div class="aside-btn">
                 <p>Forgot <a href="${url.loginPasswordResetUrl}">Password</a>?</p>
diff --git a/services/src/main/java/org/keycloak/services/resources/TokenService.java b/services/src/main/java/org/keycloak/services/resources/TokenService.java
index 5d8380d..2bc755e 100755
--- a/services/src/main/java/org/keycloak/services/resources/TokenService.java
+++ b/services/src/main/java/org/keycloak/services/resources/TokenService.java
@@ -199,6 +199,10 @@ public class TokenService {
             return oauth.forwardToSecurityFailure("Login requester not enabled.");
         }
 
+        if (formData.containsKey("cancel")) {
+            return oauth.redirectError(client, "access_denied", state, redirect);
+        }
+
         String username = formData.getFirst("username");
         UserModel user = realm.getUser(username);
 
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTest.java
index fab49b2..23750c1 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTest.java
@@ -25,6 +25,7 @@ import org.junit.Assert;
 import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
+import org.keycloak.testsuite.OAuthClient;
 import org.keycloak.testsuite.pages.AppPage;
 import org.keycloak.testsuite.pages.AppPage.RequestType;
 import org.keycloak.testsuite.pages.LoginPage;
@@ -45,6 +46,10 @@ public class LoginTest {
     public WebRule webRule = new WebRule(this);
 
     @WebResource
+    protected OAuthClient oauth;
+
+
+    @WebResource
     protected WebDriver driver;
 
     @WebResource
@@ -79,6 +84,17 @@ public class LoginTest {
         loginPage.login("test-user@localhost", "password");
         
         Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
+        Assert.assertNotNull(oauth.getCurrentQuery().get("code"));
+    }
+
+    @Test
+    public void loginCancel() {
+        loginPage.open();
+        loginPage.cancel();
+
+        Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
+
+        Assert.assertEquals("access_denied", oauth.getCurrentQuery().get("error"));
     }
 
 }
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java
index 5b1118f..eab1260 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java
@@ -93,7 +93,7 @@ public class OAuthClient {
 
         driver.findElement(By.id("username")).sendKeys(username);
         driver.findElement(By.id("password")).sendKeys(password);
-        driver.findElement(By.cssSelector("input[type=\"submit\"]")).click();
+        driver.findElement(By.name("login")).click();
 
         return new AuthorizationCodeResponse(this);
     }
@@ -103,7 +103,7 @@ public class OAuthClient {
 
         driver.findElement(By.id("username")).sendKeys(username);
         driver.findElement(By.id("password")).sendKeys(password);
-        driver.findElement(By.cssSelector("input[type=\"submit\"]")).click();
+        driver.findElement(By.name("login")).click();
     }
 
     public AccessTokenResponse doAccessTokenRequest(String code, String password) {
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 28e87cf..dfbaf46 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginPage.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginPage.java
@@ -44,9 +44,12 @@ public class LoginPage extends AbstractPage {
     @FindBy(id = "totp")
     private WebElement totp;
 
-    @FindBy(css = "input[type=\"submit\"]")
+    @FindBy(name = "login")
     private WebElement submitButton;
 
+    @FindBy(name = "cancel")
+    private WebElement cancelButton;
+
     @FindBy(linkText = "Register")
     private WebElement registerLink;
 
@@ -66,6 +69,10 @@ public class LoginPage extends AbstractPage {
         submitButton.click();
     }
 
+    public void cancel() {
+        cancelButton.click();
+    }
+
     public void loginTotp(String username, String password, String code) {
         usernameInput.clear();
         usernameInput.sendKeys(username);