diff --git a/admin-ui-styles/src/main/resources/META-INF/resources/admin-ui/css/tables.css b/admin-ui-styles/src/main/resources/META-INF/resources/admin-ui/css/tables.css
index 0e60a40d04..4ae1b27869 100644
--- a/admin-ui-styles/src/main/resources/META-INF/resources/admin-ui/css/tables.css
+++ b/admin-ui-styles/src/main/resources/META-INF/resources/admin-ui/css/tables.css
@@ -11,6 +11,9 @@ table caption {
table tbody tr:nth-child(even) {
background-color: #f6f6f6;
}
+table tbody tr:nth-child(odd) {
+ background-color: #fff;
+}
table tbody tr td,
table thead tr th {
font-weight: normal;
@@ -138,10 +141,14 @@ table tfoot tr {
table tfoot tr .table-nav {
float: right;
}
-table tfoot tr .table-nav a {
+table tfoot tr .table-nav a,
+table tfoot tr .table-nav button {
display: inline-block;
- line-height: 2.4em;
+ line-height: 22px;
border-left: 1px solid #d9d9d9;
+ border-right: none;
+ border-top: none;
+ border-bottom: none;
width: 3.5em;
background-color: #f3f3f3;
background-image: linear-gradient(top, #fafafa 0%, #ededed 100%);
@@ -156,28 +163,35 @@ table tfoot tr .table-nav a {
background-position: left top;
vertical-align: top;
}
-table tfoot tr .table-nav a.last {
+table tfoot tr .table-nav a.last,
+table tfoot tr .table-nav button.last {
background-position: top right;
}
-table tfoot tr .table-nav a.prev {
+table tfoot tr .table-nav a.prev,
+table tfoot tr .table-nav button.prev {
background-position: bottom left;
}
-table tfoot tr .table-nav a.next {
+table tfoot tr .table-nav a.next,
+table tfoot tr .table-nav button.next {
background-position: bottom right;
}
-table tfoot tr .table-nav a:hover {
+table tfoot tr .table-nav a:hover,
+table tfoot tr .table-nav button:hover {
background-image: url(img/sprite-table-nav.png);
background-color: #eeeeee;
}
-table tfoot tr .table-nav a:active {
+table tfoot tr .table-nav a:active,
+table tfoot tr .table-nav button:active {
box-shadow: 0 0 5px 2px rgba(0, 0, 0, 0.25) inset;
}
-table tfoot tr .table-nav a.disabled {
+table tfoot tr .table-nav a.disabled,
+table tfoot tr .table-nav button:disabled {
opacity: 0.5;
filter: alpha(opacity=50);
cursor: default;
}
-table tfoot tr .table-nav a.disabled:active {
+table tfoot tr .table-nav a.disabled:active,
+table tfoot tr .table-nav button:disabled:active {
box-shadow: none;
}
table tfoot tr .table-nav span {
@@ -195,3 +209,20 @@ table tfoot tr .table-nav span {
td .form-group {
margin-bottom: 0;
}
+
+td.audit-success {
+ background-color: #E4F1E1;
+}
+
+td.audit-error {
+ background-color: #F8E7E7;
+}
+
+.kc-table-actions .form-group {
+ margin-top: 5px;
+ margin-bottom: 5px;
+}
+
+.kc-table-actions select {
+ height: 26px;
+}
\ No newline at end of file
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/js/app.js b/admin-ui/src/main/resources/META-INF/resources/admin/js/app.js
index d780e60f15..6fa9473bee 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/js/app.js
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/js/app.js
@@ -131,6 +131,15 @@ module.config([ '$routeProvider', function($routeProvider) {
},
controller : 'RealmLdapSettingsCtrl'
})
+ .when('/realms/:realm/audit', {
+ templateUrl : 'partials/realm-audit.html',
+ resolve : {
+ realm : function(RealmLoader) {
+ return RealmLoader();
+ }
+ },
+ controller : 'RealmAuditCtrl'
+ })
.when('/create/user/:realm', {
templateUrl : 'partials/user-detail.html',
resolve : {
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/realm.js b/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/realm.js
index b441e318a7..c2e78cd48a 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/realm.js
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/realm.js
@@ -42,6 +42,10 @@ module.controller('GlobalCtrl', function($scope, $http, Auth, Current, $location
return getAccess('view-users') || this.manageClients;
},
+ get viewAudit() {
+ return getAccess('view-audit') || this.manageClients;
+ },
+
get manageRealm() {
return getAccess('manage-realm');
},
@@ -56,6 +60,10 @@ module.controller('GlobalCtrl', function($scope, $http, Auth, Current, $location
get manageUsers() {
return getAccess('manage-users');
+ },
+
+ get manageAudit() {
+ return getAccess('manage-audit');
}
}
})
@@ -914,4 +922,49 @@ module.controller('RealmLdapSettingsCtrl', function($scope, Realm, realm, $locat
$scope.realm = angular.copy(oldCopy);
$scope.changed = false;
};
+});
+
+
+module.controller('RealmAuditCtrl', function($scope, RealmAudit, realm) {
+ $scope.realm = realm;
+ $scope.page = 0;
+
+ $scope.query = {
+ id : realm.realm,
+ max : 5,
+ first : 0
+ }
+
+ $scope.update = function() {
+ for (var i in $scope.query) {
+ if ($scope.query[i] === '') {
+ delete $scope.query[i];
+ }
+ }
+ console.debug($scope.query.first);
+ $scope.events = RealmAudit.query($scope.query);
+ }
+
+ $scope.firstPage = function() {
+ $scope.query.first = 0;
+ if ($scope.query.first < 0) {
+ $scope.query.first = 0;
+ }
+ $scope.update();
+ }
+
+ $scope.previousPage = function() {
+ $scope.query.first -= parseInt($scope.query.max);
+ if ($scope.query.first < 0) {
+ $scope.query.first = 0;
+ }
+ $scope.update();
+ }
+
+ $scope.nextPage = function() {
+ $scope.query.first += parseInt($scope.query.max);
+ $scope.update();
+ }
+
+ $scope.update();
});
\ No newline at end of file
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/js/services.js b/admin-ui/src/main/resources/META-INF/resources/admin/js/services.js
index cb31b5e842..4d904d638f 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/js/services.js
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/js/services.js
@@ -142,6 +142,12 @@ module.factory('Realm', function($resource) {
});
});
+module.factory('RealmAudit', function($resource) {
+ return $resource('/auth/rest/admin/realms/:id/audit', {
+ id : '@realm'
+ });
+});
+
module.factory('ServerInfo', function($resource) {
return $resource('/auth/rest/admin/serverinfo');
});
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-audit.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-audit.html
new file mode 100755
index 0000000000..f31ab363ae
--- /dev/null
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-audit.html
@@ -0,0 +1,100 @@
+
+
+
+
+
+ - {{realm.realm}}
+ - Audit
+ - Social
+
+
{{realm.realm}} Audit Log
+
+
+
+
+
+
+
+
+
+
+
+ |
+
+
+ Time |
+ Event |
+ Details |
+
+
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+ {{event.time|date:'shortDate'}} {{event.time|date:'mediumTime'}} |
+ {{event.event}} {{event.error}} |
+
+
+ Client | {{event.clientId}} |
+ User | {{event.userId}} |
+ IP Address | {{event.ipAddress}} |
+
+ Details |
+
+
+
+
+ {{key}} |
+ {{value}} |
+
+
+ |
+
+
+ |
+
+
+
+
+
+
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-menu.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-menu.html
index b0ae3869d3..e2d0a2bf43 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-menu.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-menu.html
@@ -7,4 +7,5 @@
Applications
OAuth Clients
Sessions
+ Audit
\ No newline at end of file
diff --git a/audit/api/src/main/java/org/keycloak/audit/Event.java b/audit/api/src/main/java/org/keycloak/audit/Event.java
index 85b968a8c3..6ab7400623 100644
--- a/audit/api/src/main/java/org/keycloak/audit/Event.java
+++ b/audit/api/src/main/java/org/keycloak/audit/Event.java
@@ -72,10 +72,6 @@ public class Event {
this.ipAddress = ipAddress;
}
- public boolean isError() {
- return error != null;
- }
-
public String getError() {
return error;
}
diff --git a/audit/api/src/main/java/org/keycloak/audit/EventQuery.java b/audit/api/src/main/java/org/keycloak/audit/EventQuery.java
index 339bc64b4a..3e5cf60642 100644
--- a/audit/api/src/main/java/org/keycloak/audit/EventQuery.java
+++ b/audit/api/src/main/java/org/keycloak/audit/EventQuery.java
@@ -15,6 +15,8 @@ public interface EventQuery {
public EventQuery user(String userId);
+ public EventQuery ipAddress(String ipAddress);
+
public EventQuery firstResult(int result);
public EventQuery maxResults(int results);
diff --git a/audit/jboss-logging/src/main/java/org/keycloak/audit/log/JBossLoggingAuditListener.java b/audit/jboss-logging/src/main/java/org/keycloak/audit/log/JBossLoggingAuditListener.java
index d5381e24ce..691a3221fe 100644
--- a/audit/jboss-logging/src/main/java/org/keycloak/audit/log/JBossLoggingAuditListener.java
+++ b/audit/jboss-logging/src/main/java/org/keycloak/audit/log/JBossLoggingAuditListener.java
@@ -19,7 +19,7 @@ public class JBossLoggingAuditListener implements AuditListener {
@Override
public void onEvent(Event event) {
- Logger.Level level = event.isError() ? Logger.Level.WARN : Logger.Level.INFO;
+ Logger.Level level = event.getError() != null ? Logger.Level.WARN : Logger.Level.INFO;
if (logger.isEnabled(level)) {
StringBuilder sb = new StringBuilder();
@@ -35,7 +35,7 @@ public class JBossLoggingAuditListener implements AuditListener {
sb.append(", ipAddress=");
sb.append(event.getIpAddress());
- if (event.isError()) {
+ if (event.getError() != null) {
sb.append(", error=");
sb.append(event.getError());
}
diff --git a/audit/jpa/src/main/java/org/keycloak/audit/jpa/JpaEventQuery.java b/audit/jpa/src/main/java/org/keycloak/audit/jpa/JpaEventQuery.java
index c0dd127a4f..f69fe4b622 100644
--- a/audit/jpa/src/main/java/org/keycloak/audit/jpa/JpaEventQuery.java
+++ b/audit/jpa/src/main/java/org/keycloak/audit/jpa/JpaEventQuery.java
@@ -59,6 +59,12 @@ public class JpaEventQuery implements EventQuery {
return this;
}
+ @Override
+ public EventQuery ipAddress(String ipAddress) {
+ predicates.add(cb.equal(root.get("ipAddress"), ipAddress));
+ return this;
+ }
+
@Override
public EventQuery firstResult(int firstResult) {
this.firstResult = firstResult;
diff --git a/audit/mongo/src/main/java/org/keycloak/audit/mongo/MongoEventQuery.java b/audit/mongo/src/main/java/org/keycloak/audit/mongo/MongoEventQuery.java
index 5c75e63dca..d220f0e183 100644
--- a/audit/mongo/src/main/java/org/keycloak/audit/mongo/MongoEventQuery.java
+++ b/audit/mongo/src/main/java/org/keycloak/audit/mongo/MongoEventQuery.java
@@ -48,6 +48,12 @@ public class MongoEventQuery implements EventQuery {
return this;
}
+ @Override
+ public EventQuery ipAddress(String ipAddress) {
+ query.put("ipAddress", ipAddress);
+ return this;
+ }
+
@Override
public EventQuery firstResult(int firstResult) {
this.firstResult = firstResult;
diff --git a/model/api/src/main/java/org/keycloak/models/AdminRoles.java b/model/api/src/main/java/org/keycloak/models/AdminRoles.java
index e1216cfef7..e21a57a318 100644
--- a/model/api/src/main/java/org/keycloak/models/AdminRoles.java
+++ b/model/api/src/main/java/org/keycloak/models/AdminRoles.java
@@ -15,13 +15,15 @@ public class AdminRoles {
public static String VIEW_USERS = "view-users";
public static String VIEW_APPLICATIONS = "view-applications";
public static String VIEW_CLIENTS = "view-clients";
+ public static String VIEW_AUDIT = "view-audit";
public static String MANAGE_REALM = "manage-realm";
public static String MANAGE_USERS = "manage-users";
public static String MANAGE_APPLICATIONS = "manage-applications";
public static String MANAGE_CLIENTS = "manage-clients";
+ public static String MANAGE_AUDIT = "manage-audit";
- public static String[] ALL_REALM_ROLES = {VIEW_REALM, VIEW_USERS, VIEW_APPLICATIONS, VIEW_CLIENTS, MANAGE_REALM, MANAGE_USERS, MANAGE_APPLICATIONS, MANAGE_CLIENTS};
+ public static String[] ALL_REALM_ROLES = {VIEW_REALM, VIEW_USERS, VIEW_APPLICATIONS, VIEW_CLIENTS, VIEW_AUDIT, MANAGE_REALM, MANAGE_USERS, MANAGE_APPLICATIONS, MANAGE_CLIENTS, MANAGE_AUDIT};
public static String getAdminApp(RealmModel realm) {
return realm.getName() + APP_SUFFIX;
diff --git a/services/src/main/java/org/keycloak/services/resources/AccountService.java b/services/src/main/java/org/keycloak/services/resources/AccountService.java
index febd31c021..a7896600a3 100755
--- a/services/src/main/java/org/keycloak/services/resources/AccountService.java
+++ b/services/src/main/java/org/keycloak/services/resources/AccountService.java
@@ -95,7 +95,7 @@ public class AccountService {
private static final Logger logger = Logger.getLogger(AccountService.class);
private static final String[] AUDIT_EVENTS = {Events.LOGIN, Events.LOGOUT, Events.REGISTER, Events.REMOVE_SOCIAL_LINK, Events.REMOVE_TOTP, Events.SEND_RESET_PASSWORD,
- Events.SEND_VERIFY_EMAIL, Events.SOCIAL_LINK, Events.UPDATE_EMAIL, Events.UPDATE_PASSWORD, Events.UPDATE_PASSWORD, Events.UPDATE_TOTP, Events.VERIFY_EMAIL};
+ Events.SEND_VERIFY_EMAIL, Events.SOCIAL_LINK, Events.UPDATE_EMAIL, Events.UPDATE_PASSWORD, Events.UPDATE_PROFILE, Events.UPDATE_TOTP, Events.VERIFY_EMAIL};
private static final Set AUDIT_DETAILS = new HashSet();
static {
diff --git a/services/src/main/java/org/keycloak/services/resources/SocialResource.java b/services/src/main/java/org/keycloak/services/resources/SocialResource.java
index 815418a156..4204ff975c 100755
--- a/services/src/main/java/org/keycloak/services/resources/SocialResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/SocialResource.java
@@ -243,7 +243,7 @@ public class SocialResource {
realm.addSocialLink(user, socialLink);
audit.clone().user(user).event(Events.REGISTER)
- .detail(Details.REGISTER_METHOD, "social")
+ .detail(Details.REGISTER_METHOD, "social@" + provider.getId())
.detail(Details.EMAIL, socialUser.getEmail())
.removeDetail("auth_method")
.success();
@@ -256,7 +256,7 @@ public class SocialResource {
return oauth.forwardToSecurityFailure("Your account is not enabled.");
}
- return oauth.processAccessCode(scope, state, redirectUri, client, user, socialLink.getSocialUserId() + "@" + socialLink.getSocialProvider(), false, "social", audit);
+ return oauth.processAccessCode(scope, state, redirectUri, client, user, socialLink.getSocialUserId() + "@" + socialLink.getSocialProvider(), false, "social@" + provider.getId(), audit);
}
@GET
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java
index c9bf4f4d20..4194e612d8 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java
@@ -2,11 +2,15 @@ package org.keycloak.services.resources.admin;
import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.logging.Logger;
+import org.keycloak.audit.AuditProvider;
+import org.keycloak.audit.Event;
+import org.keycloak.audit.EventQuery;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.representations.adapters.action.SessionStats;
import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.services.ProviderSession;
import org.keycloak.services.managers.ModelToRepresentation;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.services.managers.ResourceAdminManager;
@@ -36,6 +40,9 @@ public class RealmAdminResource {
@Context
protected KeycloakSession session;
+ @Context
+ protected ProviderSession providers;
+
public RealmAdminResource(RealmAuth auth, RealmModel realm, TokenManager tokenManager) {
this.auth = auth;
this.realm = realm;
@@ -129,7 +136,7 @@ public class RealmAdminResource {
@GET
@NoCache
@Produces(MediaType.APPLICATION_JSON)
- public Map getSessionStats() {
+ public Map getSessionStats() {
logger.info("session-stats");
auth.requireView();
Map stats = new HashMap();
@@ -141,4 +148,37 @@ public class RealmAdminResource {
return stats;
}
+ @Path("audit")
+ @GET
+ @NoCache
+ @Produces(MediaType.APPLICATION_JSON)
+ public List getAudit(@QueryParam("client") String client, @QueryParam("event") String event, @QueryParam("user") String user,
+ @QueryParam("ipAddress") String ipAddress, @QueryParam("first") Integer firstResult, @QueryParam("max") Integer maxResults) {
+ auth.init(RealmAuth.Resource.AUDIT).requireView();
+
+ AuditProvider audit = providers.getProvider(AuditProvider.class);
+
+ EventQuery query = audit.createQuery().realm(realm.getId());
+ if (client != null) {
+ query.client(client);
+ }
+ if (event != null) {
+ query.event(event);
+ }
+ if (user != null) {
+ query.user(user);
+ }
+ if (ipAddress != null) {
+ query.ipAddress(ipAddress);
+ }
+ if (firstResult != null) {
+ query.firstResult(firstResult);
+ }
+ if (maxResults != null) {
+ query.maxResults(maxResults);
+ }
+
+ return query.getResultList();
+ }
+
}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmAuth.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmAuth.java
index d059c4c68c..e8b8e64a04 100644
--- a/services/src/main/java/org/keycloak/services/resources/admin/RealmAuth.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmAuth.java
@@ -13,7 +13,7 @@ public class RealmAuth {
private Resource resource;
public enum Resource {
- APPLICATION, CLIENT, USER, REALM
+ APPLICATION, CLIENT, USER, REALM, AUDIT
}
private Auth auth;
@@ -65,6 +65,8 @@ public class RealmAuth {
return AdminRoles.VIEW_USERS;
case REALM:
return AdminRoles.VIEW_REALM;
+ case AUDIT:
+ return AdminRoles.VIEW_AUDIT;
default:
throw new IllegalStateException();
}
@@ -80,6 +82,8 @@ public class RealmAuth {
return AdminRoles.MANAGE_USERS;
case REALM:
return AdminRoles.MANAGE_REALM;
+ case AUDIT:
+ return AdminRoles.MANAGE_AUDIT;
default:
throw new IllegalStateException();
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/social/SocialLoginTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/social/SocialLoginTest.java
index 8424550997..6ed3294d45 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/social/SocialLoginTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/social/SocialLoginTest.java
@@ -113,12 +113,12 @@ public class SocialLoginTest {
.user(AssertEvents.isUUID())
.detail(Details.EMAIL, "bob@builder.com")
.detail(Details.RESPONSE_TYPE, "code")
- .detail(Details.REGISTER_METHOD, "social")
+ .detail(Details.REGISTER_METHOD, "social@dummy")
.detail(Details.REDIRECT_URI, AssertEvents.DEFAULT_REDIRECT_URI)
.detail(Details.USERNAME, "1@dummy")
.assertEvent().getUserId();
- String codeId = events.expectLogin().user(userId).detail(Details.USERNAME, "1@dummy").detail(Details.AUTH_METHOD, "social").assertEvent().getDetails().get(Details.CODE_ID);
+ String codeId = events.expectLogin().user(userId).detail(Details.USERNAME, "1@dummy").detail(Details.AUTH_METHOD, "social@dummy").assertEvent().getDetails().get(Details.CODE_ID);
AccessTokenResponse response = oauth.doAccessTokenRequest(oauth.getCurrentQuery().get(OAuth2Constants.CODE), "password");
@@ -146,7 +146,7 @@ public class SocialLoginTest {
driver.findElement(By.id("username")).sendKeys("dummy-user1");
driver.findElement(By.id("login")).click();
- events.expectLogin().user(userId).detail(Details.USERNAME, "1@dummy").detail(Details.AUTH_METHOD, "social").assertEvent();
+ events.expectLogin().user(userId).detail(Details.USERNAME, "1@dummy").detail(Details.AUTH_METHOD, "social@dummy").assertEvent();
}
@Test
@@ -160,7 +160,7 @@ public class SocialLoginTest {
Assert.assertTrue(loginPage.isCurrent());
Assert.assertEquals("Access denied", loginPage.getWarning());
- events.expectLogin().error("rejected_by_user").user((String) null).detail(Details.AUTH_METHOD, "social").removeDetail(Details.USERNAME).removeDetail(Details.CODE_ID).assertEvent();
+ events.expectLogin().error("rejected_by_user").user((String) null).detail(Details.AUTH_METHOD, "social@dummy").removeDetail(Details.USERNAME).removeDetail(Details.CODE_ID).assertEvent();
loginPage.login("test-user@localhost", "password");
@@ -200,19 +200,19 @@ public class SocialLoginTest {
.user(AssertEvents.isUUID())
.detail(Details.EMAIL, "bob@builder.com")
.detail(Details.RESPONSE_TYPE, "code")
- .detail(Details.REGISTER_METHOD, "social")
+ .detail(Details.REGISTER_METHOD, "social@dummy")
.detail(Details.REDIRECT_URI, AssertEvents.DEFAULT_REDIRECT_URI)
.detail(Details.USERNAME, "2@dummy")
.assertEvent().getUserId();
profilePage.update("Dummy", "User", "dummy-user-reg@dummy-social");
- events.expectRequiredAction("update_profile").user(userId).detail(Details.AUTH_METHOD, "social").detail(Details.USERNAME, "2@dummy").assertEvent();
- events.expectRequiredAction("update_email").user(userId).detail(Details.AUTH_METHOD, "social").detail(Details.USERNAME, "2@dummy").detail(Details.PREVIOUS_EMAIL, "bob@builder.com").detail(Details.UPDATED_EMAIL, "dummy-user-reg@dummy-social").assertEvent();
+ events.expectRequiredAction("update_profile").user(userId).detail(Details.AUTH_METHOD, "social@dummy").detail(Details.USERNAME, "2@dummy").assertEvent();
+ events.expectRequiredAction("update_email").user(userId).detail(Details.AUTH_METHOD, "social@dummy").detail(Details.USERNAME, "2@dummy").detail(Details.PREVIOUS_EMAIL, "bob@builder.com").detail(Details.UPDATED_EMAIL, "dummy-user-reg@dummy-social").assertEvent();
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
- String codeId = events.expectLogin().user(userId).removeDetail(Details.USERNAME).detail(Details.AUTH_METHOD, "social").detail(Details.USERNAME, "2@dummy").assertEvent().getDetails().get(Details.CODE_ID);
+ String codeId = events.expectLogin().user(userId).removeDetail(Details.USERNAME).detail(Details.AUTH_METHOD, "social@dummy").detail(Details.USERNAME, "2@dummy").assertEvent().getDetails().get(Details.CODE_ID);
AccessTokenResponse response = oauth.doAccessTokenRequest(oauth.getCurrentQuery().get(OAuth2Constants.CODE), "password");
AccessToken token = oauth.verifyToken(response.getAccessToken());