Skip to content

Commit

Permalink
KEYCLOAK-2881 Admin events testing
Browse files Browse the repository at this point in the history
  • Loading branch information
mposolda committed May 13, 2016
1 parent 7193b54 commit fc9dbcf
Show file tree
Hide file tree
Showing 35 changed files with 1,649 additions and 316 deletions.
Expand Up @@ -30,6 +30,7 @@
public class EventsListenerProvider implements EventListenerProvider {

private static final BlockingQueue<Event> events = new LinkedBlockingQueue<Event>();
private static final BlockingQueue<AdminEvent> adminEvents = new LinkedBlockingQueue<>();

@Override
public void onEvent(Event event) {
Expand All @@ -38,15 +39,40 @@ public void onEvent(Event event) {

@Override
public void onEvent(AdminEvent event, boolean includeRepresentation) {
// TODO: implement if needed
// Save the copy for case when same AdminEventBuilder is used more times during same transaction to avoid overwriting previously referenced event
adminEvents.add(copy(event));
}

@Override
public void close() {

}

public static BlockingQueue<Event> getInstance() {
return events;
public static Event poll() {
return events.poll();
}

public static AdminEvent pollAdminEvent() {
return adminEvents.poll();
}

public static void clear() {
events.clear();
}

public static void clearAdminEvents() {
adminEvents.clear();
}

private AdminEvent copy(AdminEvent adminEvent) {
AdminEvent newEvent = new AdminEvent();
newEvent.setAuthDetails(adminEvent.getAuthDetails());
newEvent.setError(adminEvent.getError());
newEvent.setOperationType(adminEvent.getOperationType());
newEvent.setRealmId(adminEvent.getRealmId());
newEvent.setRepresentation(adminEvent.getRepresentation());
newEvent.setResourcePath(adminEvent.getResourcePath());
newEvent.setTime(adminEvent.getTime());
return newEvent;
}
}
Expand Up @@ -28,6 +28,8 @@
*/
public class EventsListenerProviderFactory implements EventListenerProviderFactory {

public static final String PROVIDER_ID = "event-queue";

private static final EventsListenerProvider INSTANCE = new EventsListenerProvider();

@Override
Expand All @@ -49,6 +51,6 @@ public void close() {

@Override
public String getId() {
return "event-queue";
return PROVIDER_ID;
}
}
Expand Up @@ -21,10 +21,12 @@
import org.keycloak.common.util.Time;
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
import org.keycloak.events.Event;
import org.keycloak.events.admin.AdminEvent;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserSessionModel;
import org.keycloak.models.utils.ModelToRepresentation;
import org.keycloak.representations.idm.AdminEventRepresentation;
import org.keycloak.representations.idm.EventRepresentation;
import org.keycloak.services.managers.ClientSessionCode;
import org.keycloak.services.managers.RealmManager;
Expand Down Expand Up @@ -139,19 +141,39 @@ public Map<String, String> setTimeOffset(Map<String, String> time) {
@Path("/poll-event-queue")
@Produces(MediaType.APPLICATION_JSON)
public EventRepresentation getEvent() {
Event event = EventsListenerProvider.getInstance().poll();
Event event = EventsListenerProvider.poll();
if (event != null) {
return ModelToRepresentation.toRepresentation(event);
} else {
return null;
}
}

@POST
@Path("/poll-admin-event-queue")
@Produces(MediaType.APPLICATION_JSON)
public AdminEventRepresentation getAdminEvent() {
AdminEvent adminEvent = EventsListenerProvider.pollAdminEvent();
if (adminEvent != null) {
return ModelToRepresentation.toRepresentation(adminEvent);
} else {
return null;
}
}

@POST
@Path("/clear-event-queue")
@Produces(MediaType.APPLICATION_JSON)
public Response clearQueue() {
EventsListenerProvider.getInstance().clear();
public Response clearEventQueue() {
EventsListenerProvider.clear();
return Response.ok().build();
}

@POST
@Path("/clear-admin-event-queue")
@Produces(MediaType.APPLICATION_JSON)
public Response clearAdminEventQueue() {
EventsListenerProvider.clearAdminEvents();
return Response.ok().build();
}

Expand Down
Expand Up @@ -17,6 +17,7 @@

package org.keycloak.testsuite.client.resources;

import org.keycloak.representations.idm.AdminEventRepresentation;
import org.keycloak.representations.idm.EventRepresentation;
import org.keycloak.testsuite.rest.representation.AuthenticatorState;

Expand Down Expand Up @@ -56,10 +57,20 @@ public interface TestingResource {
@Produces(MediaType.APPLICATION_JSON)
EventRepresentation pollEvent();

@POST
@Path("/poll-admin-event-queue")
@Produces(MediaType.APPLICATION_JSON)
AdminEventRepresentation pollAdminEvent();

@POST
@Path("/clear-event-queue")
@Produces(MediaType.APPLICATION_JSON)
Response clearQueue();
Response clearEventQueue();

@POST
@Path("/clear-admin-event-queue")
@Produces(MediaType.APPLICATION_JSON)
Response clearAdminEventQueue();

@POST
@Path("/remove-user-session")
Expand Down
Expand Up @@ -184,13 +184,17 @@ public void setDefaultPageUriParameters() {
loginPage.setAuthRealm(MASTER);
}

protected KeycloakTestingClient getTestingClient() {
public KeycloakTestingClient getTestingClient() {
if (testingClient == null) {
testingClient = KeycloakTestingClient.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth");
}
return testingClient;
}

public Keycloak getAdminClient() {
return adminClient;
}

public abstract void addTestRealms(List<RealmRepresentation> testRealms);

private void addTestRealms() {
Expand Down
Expand Up @@ -63,7 +63,8 @@ public Statement apply(final Statement base, org.junit.runner.Description descri
return new Statement() {
@Override
public void evaluate() throws Throwable {
context.getTestingClient().testing().clearQueue();
// TODO: Ideally clear the queue just before testClass rather then before each method
context.getTestingClient().testing().clearEventQueue();
base.evaluate();
// TODO Test should fail if there are leftover events
}
Expand All @@ -83,7 +84,7 @@ public void assertEmpty() {
}

public void clear() {
Response res = context.testingClient.testing().clearQueue();
Response res = context.testingClient.testing().clearEventQueue();
try {
Assert.assertEquals("clear-event-queue success", res.getStatus(), 200);
} finally {
Expand Down
Expand Up @@ -19,6 +19,7 @@

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
Expand All @@ -27,11 +28,15 @@
import java.util.Map;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.events.log.JBossLoggingEventListenerProviderFactory;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.IdentityProviderRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.testsuite.TestRealmKeycloakTest;
import org.keycloak.testsuite.events.EventsListenerProviderFactory;
import org.keycloak.testsuite.util.AssertAdminEvents;
import org.keycloak.util.JsonSerialization;

import static org.junit.Assert.assertArrayEquals;
Expand All @@ -46,6 +51,10 @@ public abstract class AbstractAdminTest extends TestRealmKeycloakTest {
protected static final String REALM_NAME = "admin-client-test";

protected RealmResource realm;
protected String realmId;

@Rule
public AssertAdminEvents assertAdminEvents = new AssertAdminEvents(this);

@Override
public void configureTestRealm(RealmRepresentation testRealm) {
Expand All @@ -64,12 +73,19 @@ public void addTestRealms(List<RealmRepresentation> testRealms) {
config.put("host", "localhost");
config.put("port", "3025");
adminRealmRep.setSmtpServer(config);

List<String> eventListeners = new ArrayList<>();
eventListeners.add(JBossLoggingEventListenerProviderFactory.ID);
eventListeners.add(EventsListenerProviderFactory.PROVIDER_ID);
adminRealmRep.setEventsListeners(eventListeners);

testRealms.add(adminRealmRep);
}

@Before
public void setRealm() {
realm = adminClient.realm(REALM_NAME);
realmId = realm.toRepresentation().getId();
}

// old testsuite expects this realm to be removed at the end of the test
Expand Down
Expand Up @@ -162,7 +162,7 @@ public static void assignClientRoles(RealmResource realm, String userId, String
+ clientName + "\" in realm: \"" + realmName + "\"");
userResource.roles().clientLevel(clientId).add(roleRepresentations);
} else {
log.warn("client with name " + clientName + "doesn't exist in realm " + realmName);
log.warn("client with name " + clientName + " doesn't exist in realm " + realmName);
}
}

Expand Down
Expand Up @@ -33,6 +33,8 @@
import static org.junit.Assert.assertTrue;

/**
* TODO adminEvents: Add adminEvents once resourcePath is added in AttackDetectionResource (server-side) events
*
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class AttackDetectionResourceTest extends AbstractAdminTest {
Expand Down

0 comments on commit fc9dbcf

Please sign in to comment.