keycloak-aplcache

Details

diff --git a/services/src/main/java/org/keycloak/services/resources/AbstractSecuredLocalService.java b/services/src/main/java/org/keycloak/services/resources/AbstractSecuredLocalService.java
index 5d2eab5..0f3a80b 100755
--- a/services/src/main/java/org/keycloak/services/resources/AbstractSecuredLocalService.java
+++ b/services/src/main/java/org/keycloak/services/resources/AbstractSecuredLocalService.java
@@ -21,9 +21,11 @@ import org.jboss.resteasy.spi.BadRequestException;
 import org.jboss.resteasy.spi.HttpRequest;
 import org.keycloak.AbstractOAuthClient;
 import org.keycloak.OAuth2Constants;
+import org.keycloak.OAuthErrorException;
 import org.keycloak.common.ClientConnection;
 import org.keycloak.common.util.Base64Url;
 import org.keycloak.common.util.KeycloakUriBuilder;
+import org.keycloak.forms.login.LoginFormsProvider;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
@@ -32,6 +34,7 @@ import org.keycloak.protocol.oidc.OIDCLoginProtocolService;
 import org.keycloak.services.ForbiddenException;
 import org.keycloak.services.managers.Auth;
 import org.keycloak.services.managers.AuthenticationManager;
+import org.keycloak.services.messages.Messages;
 import org.keycloak.services.util.CookieHelper;
 import org.keycloak.util.TokenUtil;
 
@@ -89,8 +92,14 @@ public abstract class AbstractSecuredLocalService {
                                   @Context HttpHeaders headers) {
         try {
             if (error != null) {
-                logger.debug("error from oauth");
-                throw new ForbiddenException("error");
+                if (OAuthErrorException.ACCESS_DENIED.equals(error)) {
+                    // cased by CANCELLED_BY_USER or CONSENT_DENIED
+                    session.getContext().setClient(client);
+                    return session.getProvider(LoginFormsProvider.class).setError(Messages.NO_ACCESS).createErrorPage(Response.Status.FORBIDDEN);
+                } else {
+                    logger.debug("error from oauth");
+                    throw new ForbiddenException("error");
+                }
             }
             if (path != null && !getValidPaths().contains(path)) {
                 throw new BadRequestException("Invalid path");
@@ -111,7 +120,6 @@ public abstract class AbstractSecuredLocalService {
                 logger.debug("state not specified");
                 throw new BadRequestException("state not specified");
             }
-
             KeycloakUriBuilder redirect = KeycloakUriBuilder.fromUri(getBaseRedirectUri());
             if (path != null) {
                 redirect.path(path);
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ConsentsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ConsentsTest.java
index 8407610..1cb3ce6 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ConsentsTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ConsentsTest.java
@@ -18,8 +18,10 @@
 package org.keycloak.testsuite.admin;
 
 import org.jboss.arquillian.graphene.page.Page;
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.keycloak.admin.client.resource.ClientResource;
 import org.keycloak.admin.client.resource.RealmResource;
 import org.keycloak.admin.client.resource.UserResource;
 import org.keycloak.admin.client.resource.UsersResource;
@@ -31,13 +33,16 @@ import org.keycloak.representations.idm.UserSessionRepresentation;
 import org.keycloak.testsuite.AbstractKeycloakTest;
 import org.keycloak.testsuite.Assert;
 import org.keycloak.testsuite.pages.ConsentPage;
+import org.keycloak.testsuite.pages.ErrorPage;
 import org.keycloak.testsuite.pages.LoginPage;
 
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
+import static org.junit.Assert.assertEquals;
 import static org.keycloak.testsuite.admin.ApiUtil.createUserWithAdminClient;
+import static org.keycloak.testsuite.admin.ApiUtil.findClientByClientId;
 import static org.keycloak.testsuite.admin.ApiUtil.resetUserPassword;
 
 /**
@@ -149,6 +154,9 @@ public class ConsentsTest extends AbstractKeycloakTest {
     @Page
     protected ConsentPage consentPage;
 
+    @Page
+    protected ErrorPage errorPage;
+
     @Override
     public void addTestRealms(List<RealmRepresentation> testRealms) {
         RealmRepresentation providerRealm = createProviderRealm();
@@ -223,6 +231,12 @@ public class ConsentsTest extends AbstractKeycloakTest {
         }
     }
 
+    @After
+    public void cleanUser() {
+        String userId = adminClient.realm(providerRealmName()).users().search(getUserLogin()).get(0).getId();
+        adminClient.realm(providerRealmName()).users().delete(userId);
+    }
+
     @Test
     public void testConsents() {
         driver.navigate().to(getAccountUrl(consumerRealmName()));
@@ -295,6 +309,41 @@ public class ConsentsTest extends AbstractKeycloakTest {
         Assert.assertEquals("There should be no active session", 0, sessions.size());
     }
 
+    @Test
+    public void testConsentCancel() {
+        // setup account client to require consent
+        RealmResource providerRealm = adminClient.realm(providerRealmName());
+        ClientResource accountClient = findClientByClientId(providerRealm, "account");
+
+        ClientRepresentation clientRepresentation = accountClient.toRepresentation();
+        clientRepresentation.setConsentRequired(true);
+        accountClient.update(clientRepresentation);
+
+        // setup correct realm
+        accountPage.setAuthRealm(providerRealmName());
+
+        // navigate to account console and login
+        accountPage.navigateTo();
+        loginPage.form().login(getUserLogin(), getUserPassword());
+
+        consentPage.assertCurrent();
+
+        consentPage.cancel();
+
+        // check an error page after cancelling the consent
+        errorPage.assertCurrent();
+        assertEquals("No access", errorPage.getError());
+
+        // follow the link "back to application"
+        errorPage.clickBackToApplication();
+
+        loginPage.form().login(getUserLogin(), getUserPassword());
+        consentPage.confirm();
+
+        // successful login
+        accountPage.assertCurrent();
+    }
+
     private String getAccountUrl(String realmName) {
         return getAuthRoot() + "/auth/realms/" + realmName + "/account";
     }
diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authentication/actions/TermsAndConditionsTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authentication/actions/TermsAndConditionsTest.java
index f9ee517..0795e6f 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authentication/actions/TermsAndConditionsTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authentication/actions/TermsAndConditionsTest.java
@@ -28,10 +28,13 @@ import org.keycloak.testsuite.auth.page.login.Registration;
 import org.keycloak.testsuite.auth.page.login.TermsAndConditions;
 import org.keycloak.testsuite.console.AbstractConsoleTest;
 import org.keycloak.testsuite.console.page.authentication.RequiredActions;
+import org.keycloak.testsuite.pages.ErrorPage;
 
 import java.util.ArrayList;
 import java.util.List;
 
+import static org.junit.Assert.assertEquals;
+
 /**
  * 
  */
@@ -48,12 +51,19 @@ public class TermsAndConditionsTest extends AbstractConsoleTest {
     private static final String HOMER = "Homer";
     
     private static final String HOMER_PASS = "Mmm donuts.";
+
+    private static final String FLANDERS = "Flanders";
+
+    private static final String FLANDERS_PASS = "Okily Dokily";
             
     @Page
     private TermsAndConditions termsAndConditionsPage;
     
     @Page
     private Registration registrationPage;
+
+    @Page
+    protected ErrorPage errorPage;
     
     @Override
     public void beforeConsoleTest() {
@@ -75,7 +85,7 @@ public class TermsAndConditionsTest extends AbstractConsoleTest {
         testRealms.add(testRealmRep);
     }
     
-    @Test 
+    @Test
     public void testExistingUser() {
         // create user
         String userId = createUser(REALM, HOMER, HOMER_PASS);
@@ -107,7 +117,7 @@ public class TermsAndConditionsTest extends AbstractConsoleTest {
         setRequiredActionEnabled(REALM, RequiredActions.TERMS_AND_CONDITIONS, false, false);
     }
     
-    @Test 
+    @Test
     public void testAdminCreatedUser() {
         // enable terms
         setRequiredActionEnabled(REALM, RequiredActions.TERMS_AND_CONDITIONS, true, false);
@@ -125,7 +135,7 @@ public class TermsAndConditionsTest extends AbstractConsoleTest {
         setRequiredActionEnabled(REALM, RequiredActions.TERMS_AND_CONDITIONS, false, false);
     }
     
-    @Test 
+    @Test
     public void testSelfRegisteredUser() {
         // enable self-registration
         RealmResource realmResource = adminClient.realm(REALM);
@@ -162,5 +172,35 @@ public class TermsAndConditionsTest extends AbstractConsoleTest {
         // disable terms
         setRequiredActionEnabled(REALM, RequiredActions.TERMS_AND_CONDITIONS, false, false);
     }
-    
+
+    @Test
+    public void testTermsAndConditionsOnAccountPage() {
+        String userId = createUser(REALM, FLANDERS, FLANDERS_PASS);
+
+        setRequiredActionEnabled(REALM, RequiredActions.TERMS_AND_CONDITIONS, true, false);
+        setRequiredActionEnabled(REALM, userId, RequiredActions.TERMS_AND_CONDITIONS, true);
+
+        // login and decline the terms -- an error page should be shown
+        testRealmAccountPage.navigateTo();
+        loginPage.form().login(FLANDERS, FLANDERS_PASS);
+        termsAndConditionsPage.assertCurrent();
+        termsAndConditionsPage.declineTerms();
+
+        // check an error page after declining the terms
+        errorPage.assertCurrent();
+        assertEquals("No access", errorPage.getError());
+
+        // follow the link "back to application"
+        errorPage.clickBackToApplication();
+
+        // login again and accept the terms for now
+        loginPage.form().login(FLANDERS, FLANDERS_PASS);
+        termsAndConditionsPage.assertCurrent();
+        termsAndConditionsPage.acceptTerms();
+        testRealmAccountPage.assertCurrent();
+        testRealmAccountPage.logOut();
+
+        // disable terms
+        setRequiredActionEnabled(REALM, RequiredActions.TERMS_AND_CONDITIONS, false, false);
+    }
 }
\ No newline at end of file