keycloak-uncached

Merge pull request #1348 from mposolda/master KEYCLOAK-1088

6/9/2015 3:55:26 PM

Details

diff --git a/events/api/src/main/java/org/keycloak/events/Details.java b/events/api/src/main/java/org/keycloak/events/Details.java
index 1a9c479..4a0a1ad 100755
--- a/events/api/src/main/java/org/keycloak/events/Details.java
+++ b/events/api/src/main/java/org/keycloak/events/Details.java
@@ -27,4 +27,9 @@ public interface Details {
     String CLIENT_SESSION_STATE = "client_session_state";
     String CLIENT_SESSION_HOST = "client_session_host";
 
+    String CONSENT = "consent";
+    String CONSENT_VALUE_NO_CONSENT_REQUIRED = "no_consent_required"; // No consent is required by client
+    String CONSENT_VALUE_CONSENT_GRANTED = "consent_granted";         // Consent granted by user
+    String CONSENT_VALUE_PERSISTED_CONSENT = "persistent_consent";    // Persistent consent used (was already granted by user before)
+
 }
diff --git a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
index e76ab3a..f200130 100755
--- a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
@@ -465,7 +465,6 @@ public class AuthenticationManager {
         }
 
         if (client.isConsentRequired()) {
-            accessCode.setAction(ClientSessionModel.Action.OAUTH_GRANT);
 
             UserConsentModel grantedConsent = user.getConsentByClient(client.getId());
 
@@ -496,11 +495,18 @@ public class AuthenticationManager {
 
             // Skip grant screen if everything was already approved by this user
             if (realmRoles.size() > 0 || resourceRoles.size() > 0 || protocolMappers.size() > 0) {
+                accessCode.setAction(ClientSessionModel.Action.OAUTH_GRANT);
+
                 return session.getProvider(LoginFormsProvider.class)
                         .setClientSessionCode(accessCode.getCode())
                         .setAccessRequest(realmRoles, resourceRoles, protocolMappers)
                         .createOAuthGrant(clientSession);
+            } else {
+                String consentDetail = (grantedConsent != null) ? Details.CONSENT_VALUE_PERSISTED_CONSENT : Details.CONSENT_VALUE_NO_CONSENT_REQUIRED;
+                event.detail(Details.CONSENT, consentDetail);
             }
+        } else {
+            event.detail(Details.CONSENT, Details.CONSENT_VALUE_NO_CONSENT_REQUIRED);
         }
 
         event.success();
diff --git a/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java b/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
index c2571d9..08a05c9 100755
--- a/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
+++ b/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
@@ -316,7 +316,7 @@ public class LoginActionsService {
             return ErrorPage.error(session, Messages.UNKNOWN_LOGIN_REQUESTER);
         }
         if (!client.isEnabled()) {
-            event.error(Errors.CLIENT_NOT_FOUND);
+            event.error(Errors.CLIENT_DISABLED);
             return ErrorPage.error(session, Messages.LOGIN_REQUESTER_NOT_ENABLED);
         }
 
@@ -443,7 +443,7 @@ public class LoginActionsService {
             return ErrorPage.error(session, Messages.UNKNOWN_LOGIN_REQUESTER);
         }
         if (!client.isEnabled()) {
-            event.error(Errors.CLIENT_NOT_FOUND);
+            event.error(Errors.CLIENT_DISABLED);
             return ErrorPage.error(session, Messages.LOGIN_REQUESTER_NOT_ENABLED);
         }
 
@@ -741,6 +741,7 @@ public class LoginActionsService {
         }
         user.updateConsent(grantedConsent);
 
+        event.detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED);
         event.success();
 
         return authManager.redirectAfterSuccessfulFlow(session, realm, userSession, clientSession, request, uriInfo, clientConnection);
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java
index 0f1eba1..4fafbb3 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java
@@ -242,7 +242,9 @@ public class AccountTest {
 
         Assert.assertEquals("Invalid username or password.", loginPage.getError());
 
-        events.expectLogin().session((String) null).error("invalid_user_credentials").assertEvent();
+        events.expectLogin().session((String) null).error("invalid_user_credentials")
+                .removeDetail(Details.CONSENT)
+                .assertEvent();
 
         loginPage.open();
         loginPage.login("test-user@localhost", "new-password");
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/AssertEvents.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/AssertEvents.java
index ce80527..21e5190 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/AssertEvents.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/AssertEvents.java
@@ -113,7 +113,7 @@ public class AssertEvents implements TestRule, EventListenerProviderFactory {
     }
 
     public ExpectedEvent expectRequiredAction(EventType event) {
-        return expectLogin().event(event).session(isUUID());
+        return expectLogin().event(event).removeDetail(Details.CONSENT).session(isUUID());
     }
 
     public ExpectedEvent expectLogin() {
@@ -123,6 +123,7 @@ public class AssertEvents implements TestRule, EventListenerProviderFactory {
                 .detail(Details.RESPONSE_TYPE, "code")
                 .detail(Details.AUTH_METHOD, "form")
                 .detail(Details.REDIRECT_URI, DEFAULT_REDIRECT_URI)
+                .detail(Details.CONSENT, Details.CONSENT_VALUE_NO_CONSENT_REQUIRED)
                 .session(isUUID());
     }
 
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 644fff3..03da92f 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTest.java
@@ -127,7 +127,10 @@ public class LoginTest {
 
         Assert.assertEquals("Invalid username or password.", loginPage.getError());
 
-        events.expectLogin().user(userId).session((String) null).error("invalid_user_credentials").detail(Details.USERNAME, "login-test").assertEvent();
+        events.expectLogin().user(userId).session((String) null).error("invalid_user_credentials")
+                .detail(Details.USERNAME, "login-test")
+                .removeDetail(Details.CONSENT)
+                .assertEvent();
     }
 
     @Test
@@ -147,7 +150,10 @@ public class LoginTest {
 
             Assert.assertEquals("Invalid username or password.", loginPage.getError());
 
-            events.expectLogin().user(userId).session((String) null).error("invalid_user_credentials").detail(Details.USERNAME, "login-test").assertEvent();
+            events.expectLogin().user(userId).session((String) null).error("invalid_user_credentials")
+                    .detail(Details.USERNAME, "login-test")
+                    .removeDetail(Details.CONSENT)
+                    .assertEvent();
         } finally {
             keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
                 @Override
@@ -175,7 +181,10 @@ public class LoginTest {
 
             Assert.assertEquals("Account is disabled, contact admin.", loginPage.getError());
 
-            events.expectLogin().user(userId).session((String) null).error("user_disabled").detail(Details.USERNAME, "login-test").assertEvent();
+            events.expectLogin().user(userId).session((String) null).error("user_disabled")
+                    .detail(Details.USERNAME, "login-test")
+                    .removeDetail(Details.CONSENT)
+                    .assertEvent();
         } finally {
             keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
                 @Override
@@ -195,7 +204,10 @@ public class LoginTest {
 
         Assert.assertEquals("Invalid username or password.", loginPage.getError());
 
-        events.expectLogin().user((String) null).session((String) null).error("user_not_found").detail(Details.USERNAME, "invalid").assertEvent();
+        events.expectLogin().user((String) null).session((String) null).error("user_not_found")
+                .detail(Details.USERNAME, "invalid")
+                .removeDetail(Details.CONSENT)
+                .assertEvent();
     }
 
     @Test
@@ -413,7 +425,10 @@ public class LoginTest {
         Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
         Assert.assertEquals("access_denied", oauth.getCurrentQuery().get(OAuth2Constants.ERROR));
 
-        events.expectLogin().error("rejected_by_user").user((String) null).session((String) null).removeDetail(Details.USERNAME).assertEvent();
+        events.expectLogin().error("rejected_by_user").user((String) null).session((String) null)
+                .removeDetail(Details.USERNAME)
+                .removeDetail(Details.CONSENT)
+                .assertEvent();
     }
 
     // KEYCLOAK-1037
@@ -427,7 +442,10 @@ public class LoginTest {
             loginPage.assertCurrent();
             Assert.assertEquals("Login timeout. Please login again.", loginPage.getError());
 
-            events.expectLogin().user((String) null).session((String) null).error("expired_code").clearDetails().detail(Details.CODE_ID, AssertEvents.isCodeId()).assertEvent();
+            events.expectLogin().user((String) null).session((String) null).error("expired_code").clearDetails()
+                    .detail(Details.CODE_ID, AssertEvents.isCodeId())
+                    .removeDetail(Details.CONSENT)
+                    .assertEvent();
 
         } finally {
             Time.setOffset(0);
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java
index 45795da..8eea530 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java
@@ -114,7 +114,9 @@ public class LoginTotpTest {
         loginPage.assertCurrent();
         Assert.assertEquals("Invalid username or password.", loginPage.getError());
 
-        events.expectLogin().error("invalid_user_credentials").session((String) null).assertEvent();
+        events.expectLogin().error("invalid_user_credentials").session((String) null)
+                .removeDetail(Details.CONSENT)
+                .assertEvent();
     }
 
     @Test
@@ -140,7 +142,9 @@ public class LoginTotpTest {
 
         Assert.assertEquals("Invalid username or password.", loginPage.getError());
 
-        events.expectLogin().error("invalid_user_credentials").session((String) null).assertEvent();
+        events.expectLogin().error("invalid_user_credentials").session((String) null)
+                .removeDetail(Details.CONSENT)
+                .assertEvent();
     }
 
     @Test
@@ -159,7 +163,8 @@ public class LoginTotpTest {
             Assert.assertEquals("Invalid username or password.", loginPage.getError());
 
             AssertEvents.ExpectedEvent expectedEvent = events.expectLogin().error("invalid_user_credentials")
-                    .session((String) null);
+                    .session((String) null)
+                    .removeDetail(Details.CONSENT);
             expectedEvent.assertEvent();
         } finally {
             Time.setOffset(0);
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java
index 0a70da0..784318f 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java
@@ -141,6 +141,7 @@ public class AuthorizationCodeTest {
 
         events.expectLogin().error("rejected_by_user").user((String) null).session((String) null)
                 .removeDetail(Details.USERNAME)
+                .removeDetail(Details.CONSENT)
                 .detail(Details.REDIRECT_URI, "http://localhost:8081/auth/realms/test/protocol/openid-connect/oauth/oob")
                 .assertEvent().getDetails().get(Details.CODE_ID);
 
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 939231f..bfff4bd 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
@@ -36,7 +36,6 @@ import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.protocol.oidc.OIDCLoginProtocol;
-import org.keycloak.protocol.oidc.OIDCLoginProtocolFactory;
 import org.keycloak.protocol.oidc.mappers.UserSessionNoteMapper;
 import org.keycloak.representations.AccessToken;
 import org.keycloak.services.managers.RealmManager;
@@ -51,7 +50,6 @@ import org.keycloak.testsuite.rule.WebResource;
 import org.keycloak.testsuite.rule.WebRule;
 import org.openqa.selenium.WebDriver;
 
-import java.io.IOException;
 import java.util.Map;
 
 import static org.junit.Assert.assertEquals;
@@ -104,7 +102,10 @@ public class OAuthGrantTest {
 
         Assert.assertTrue(oauth.getCurrentQuery().containsKey(OAuth2Constants.CODE));
 
-        Event loginEvent = events.expectLogin().client("third-party").assertEvent();
+        Event loginEvent = events.expectLogin()
+                .client("third-party")
+                .detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED)
+                .assertEvent();
         String codeId = loginEvent.getDetails().get(Details.CODE_ID);
         String sessionId = loginEvent.getSessionId();
 
@@ -147,7 +148,11 @@ public class OAuthGrantTest {
         Assert.assertTrue(oauth.getCurrentQuery().containsKey(OAuth2Constants.ERROR));
         assertEquals("access_denied", oauth.getCurrentQuery().get(OAuth2Constants.ERROR));
 
-        events.expectLogin().client("third-party").error("rejected_by_user").assertEvent();
+        events.expectLogin()
+                .client("third-party")
+                .error("rejected_by_user")
+                .removeDetail(Details.CONSENT)
+                .assertEvent();
     }
 
     @Test
@@ -159,7 +164,10 @@ public class OAuthGrantTest {
         grantPage.assertCurrent();
         grantPage.accept();
 
-        events.expectLogin().client("third-party").assertEvent();
+        events.expectLogin()
+                .client("third-party")
+                .detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED)
+                .assertEvent();
 
         // Assert permissions granted on Account mgmt. applications page
         accountAppsPage.open();
@@ -172,7 +180,11 @@ public class OAuthGrantTest {
         // Open login form and assert grantPage not shown
         oauth.openLoginForm();
         appPage.assertCurrent();
-        events.expectLogin().detail(Details.AUTH_METHOD, "sso").removeDetail(Details.USERNAME).client("third-party").assertEvent();
+        events.expectLogin()
+                .detail(Details.AUTH_METHOD, "sso")
+                .detail(Details.CONSENT, Details.CONSENT_VALUE_PERSISTED_CONSENT)
+                .removeDetail(Details.USERNAME)
+                .client("third-party").assertEvent();
 
         // Revoke grant in account mgmt.
         accountAppsPage.open();
@@ -219,7 +231,10 @@ public class OAuthGrantTest {
         // Confirm grant page
         grantPage.assertCurrent();
         grantPage.accept();
-        events.expectLogin().client("third-party").assertEvent();
+        events.expectLogin()
+                .client("third-party")
+                .detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED)
+                .assertEvent();
 
         // Assert new role and protocol mapper not in account mgmt.
         accountAppsPage.open();
@@ -235,7 +250,10 @@ public class OAuthGrantTest {
         Assert.assertTrue(driver.getPageSource().contains("new-role"));
         Assert.assertTrue(driver.getPageSource().contains(KerberosConstants.GSS_DELEGATION_CREDENTIAL_DISPLAY_NAME));
         grantPage.accept();
-        events.expectLogin().client("third-party").assertEvent();
+        events.expectLogin()
+                .client("third-party")
+                .detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED)
+                .assertEvent();
 
         // Go to account mgmt. Everything is granted now
         accountAppsPage.open();
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/ResourceOwnerPasswordCredentialsGrantTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/ResourceOwnerPasswordCredentialsGrantTest.java
index 59ba8aa..23d2e5e 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/ResourceOwnerPasswordCredentialsGrantTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/ResourceOwnerPasswordCredentialsGrantTest.java
@@ -93,6 +93,7 @@ public class ResourceOwnerPasswordCredentialsGrantTest {
                 .detail(Details.USERNAME, login)
                 .removeDetail(Details.CODE_ID)
                 .removeDetail(Details.REDIRECT_URI)
+                .removeDetail(Details.CONSENT)
                 .assertEvent();
 
         assertEquals(accessToken.getSessionState(), refreshToken.getSessionState());
@@ -128,6 +129,7 @@ public class ResourceOwnerPasswordCredentialsGrantTest {
                 .detail(Details.REFRESH_TOKEN_ID, refreshToken.getId())
                 .removeDetail(Details.CODE_ID)
                 .removeDetail(Details.REDIRECT_URI)
+                .removeDetail(Details.CONSENT)
                 .assertEvent();
 
         HttpResponse logoutResponse = oauth.doLogout(response.getRefreshToken(), "secret");
@@ -180,6 +182,7 @@ public class ResourceOwnerPasswordCredentialsGrantTest {
                 .detail(Details.RESPONSE_TYPE, "token")
                 .removeDetail(Details.CODE_ID)
                 .removeDetail(Details.REDIRECT_URI)
+                .removeDetail(Details.CONSENT)
                 .error(Errors.INVALID_USER_CREDENTIALS)
                 .assertEvent();
     }
@@ -203,6 +206,7 @@ public class ResourceOwnerPasswordCredentialsGrantTest {
                 .detail(Details.USERNAME, "invalid")
                 .removeDetail(Details.CODE_ID)
                 .removeDetail(Details.REDIRECT_URI)
+                .removeDetail(Details.CONSENT)
                 .error(Errors.INVALID_USER_CREDENTIALS)
                 .assertEvent();
     }