Merge upstream-master into cluster-testing

This commit is contained in:
Tomas Kyjovsky committed 2016-02-08 23:53:30 +01:00
commit 28fa2b92d9
13 files changed
+977 -14

No files matched your search

@@ -17,6 +17,7 @@
package org.keycloak.testsuite.adapter.example;
import org.apache.commons.io.FileUtils;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.graphene.page.Page;
import org.jboss.shrinkwrap.api.spec.WebArchive;
@@ -26,6 +27,7 @@ import org.junit.Test;
import org.keycloak.admin.client.resource.ClientResource;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.testsuite.adapter.AbstractExampleAdapterTest;
import org.keycloak.testsuite.adapter.page.CustomerPortalExample;
import org.keycloak.testsuite.adapter.page.DatabaseServiceExample;
@@ -43,6 +45,8 @@ import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -269,4 +273,103 @@ public abstract class AbstractDemoExampleAdapterTest extends AbstractExampleAdap
resultList.get(0).findElement(By.xpath(".//td[text()='username']/../td[text()='bburke@redhat.com']"));
resultList.get(0).findElement(By.xpath(".//td[text()='consent']/../td[text()='consent_granted']"));
}
@Test
public void historyOfAccessResourceTest() throws IOException {
RealmRepresentation realm = testRealmResource().toRepresentation();
realm.setEventsEnabled(true);
realm.setEnabledEventTypes(Arrays.asList("LOGIN", "LOGIN_ERROR", "LOGOUT", "CODE_TO_TOKEN"));
testRealmResource().update(realm);
customerPortalExamplePage.navigateTo();
customerPortalExamplePage.customerListing();
testRealmLoginPage.form().login("bburke@redhat.com", "password");
Assert.assertTrue(driver.getPageSource().contains("Username: bburke@redhat.com")
&& driver.getPageSource().contains("Bill Burke")
&& driver.getPageSource().contains("Stian Thorgersen")
);
if (isRelative()) { //KEYCLOAK-1546
productPortalExamplePage.logOut();
} else {
driver.navigate().to(testRealmPage.getOIDCLogoutUrl() + "?redirect_uri=" + productPortalExamplePage);
}
loginEventsPage.navigateTo();
if (!testContext.isAdminLoggedIn()) {
loginPage.form().login(adminUser);
testContext.setAdminLoggedIn(true);
}
loginEventsPage.table().filter();
loginEventsPage.table().filterForm().addEventType("LOGOUT");
loginEventsPage.table().update();
List<WebElement> resultList = loginEventsPage.table().rows();
assertEquals(1, resultList.size());
resultList.get(0).findElement(By.xpath(".//td[text()='LOGOUT']"));
resultList.get(0).findElement(By.xpath(".//td[text()='Client']/../td[text()='']"));
resultList.get(0).findElement(By.xpath(".//td[text()='IP Address']/../td[text()='127.0.0.1']"));
loginEventsPage.table().reset();
loginEventsPage.table().filterForm().addEventType("LOGIN");
loginEventsPage.table().update();
resultList = loginEventsPage.table().rows();
assertEquals(1, resultList.size());
resultList.get(0).findElement(By.xpath(".//td[text()='LOGIN']"));
resultList.get(0).findElement(By.xpath(".//td[text()='Client']/../td[text()='customer-portal']"));
resultList.get(0).findElement(By.xpath(".//td[text()='IP Address']/../td[text()='127.0.0.1']"));
resultList.get(0).findElement(By.xpath(".//td[text()='username']/../td[text()='bburke@redhat.com']"));
loginEventsPage.table().reset();
loginEventsPage.table().filterForm().addEventType("CODE_TO_TOKEN");
loginEventsPage.table().update();
resultList = loginEventsPage.table().rows();
assertEquals(1, resultList.size());
resultList.get(0).findElement(By.xpath(".//td[text()='CODE_TO_TOKEN']"));
resultList.get(0).findElement(By.xpath(".//td[text()='Client']/../td[text()='customer-portal']"));
resultList.get(0).findElement(By.xpath(".//td[text()='IP Address']/../td[text()='127.0.0.1']"));
resultList.get(0).findElement(By.xpath(".//td[text()='refresh_token_type']/../td[text()='Refresh']"));
String serverLogPath = null;
if (System.getProperty("app.server.wildfly", "false").equals("true")) {
serverLogPath = System.getProperty("app.server.wildfly.home") + "/standalone/log/server.log";
}
if (System.getProperty("app.server.eap6", "false").equals("true")) {
serverLogPath = System.getProperty("app.server.eap6.home") + "/standalone/log/server.log";
}
if (System.getProperty("app.server.eap7", "false").equals("true")) {
serverLogPath = System.getProperty("app.server.eap7.home") + "/standalone/log/server.log";
}
String appServerUrl;
if (Boolean.parseBoolean(System.getProperty("app.server.ssl.required"))) {
appServerUrl = "https://localhost:" + System.getProperty("app.server.https.port", "8543") + "/";
} else {
appServerUrl = "http://localhost:" + System.getProperty("app.server.http.port", "8280") + "/";
}
if (serverLogPath != null) {
File serverLog = new File(serverLogPath);
String serverLogContent = FileUtils.readFileToString(serverLog);
UserRepresentation bburke = ApiUtil.findUserByUsername(testRealmResource(), "bburke@redhat.com");
Pattern pattern = Pattern.compile("User '" + bburke.getId() + "' invoking '" + appServerUrl + "customer-portal\\/customers\\/view\\.jsp[^\\s]+' on client 'customer-portal'");
Matcher matcher = pattern.matcher(serverLogContent);
assertTrue(matcher.find());
assertTrue(serverLogContent.contains("User '" + bburke.getId() + "' invoking '" + appServerUrl + "database/customers' on client 'database-service'"));
}
}
}
@@ -0,0 +1,57 @@
/*
* Copyright 2016 Red Hat Inc. and/or its affiliates and other contributors
* as indicated by the @author tags. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.keycloak.testsuite.event;
import java.util.Collections;
import org.junit.Before;
import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.representations.idm.RealmEventsConfigRepresentation;
import org.keycloak.testsuite.AbstractAuthTest;
/**
*
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
*/
public abstract class AbstractEventTest extends AbstractAuthTest {
protected RealmEventsConfigRepresentation configRep;
@Before
public void setConfigRep() {
RealmResource testRsc = testRealmResource();
configRep = testRsc.getRealmEventsConfig();
configRep.setAdminEventsDetailsEnabled(false);
configRep.setAdminEventsEnabled(false);
configRep.setEventsEnabled(false);
configRep.setEnabledEventTypes(Collections.EMPTY_LIST); // resets to all types
saveConfig();
}
protected void saveConfig() {
RealmResource testRsc = testRealmResource();
testRsc.updateRealmEventsConfig(configRep);
configRep = testRsc.getRealmEventsConfig();
}
protected void enableEvents() {
configRep.setEventsEnabled(true);
configRep.setAdminEventsEnabled(Boolean.TRUE);
saveConfig();
}
}
@@ -0,0 +1,111 @@
/*
* Copyright 2016 Red Hat Inc. and/or its affiliates and other contributors
* as indicated by the @author tags. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.keycloak.testsuite.event;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.keycloak.representations.idm.AdminEventRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.testsuite.admin.ApiUtil;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
/**
* Test getting and filtering admin events.
*
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
*/
public class AdminEventTest extends AbstractEventTest {
@Before
public void initConfig() {
enableEvents();
testRealmResource().clearAdminEvents();
}
private List<AdminEventRepresentation> events() {
return testRealmResource().getAdminEvents();
}
private void createUser(String username) {
UserRepresentation user = createUserRepresentation(username, username + "@foo.com", "foo", "bar", true);
ApiUtil.createUserWithAdminClient(testRealmResource(), user);
}
private void updateRealm() {
RealmRepresentation realm = testRealmResource().toRepresentation();
realm.setDisplayName("Fury Road");
testRealmResource().update(realm);
}
private String realmName() {
return testRealmResource().toRepresentation().getId();
}
@Test
public void clearAdminEventsTest() {
createUser("user0");
assertEquals(1, events().size());
testRealmResource().clearAdminEvents();
assertEquals(Collections.EMPTY_LIST, events());
}
@Test
public void retrieveAdminEventTest() {
createUser("user1");
List<AdminEventRepresentation> events = events();
assertEquals(1, events.size());
AdminEventRepresentation event = events().get(0);
assertEquals("CREATE", event.getOperationType());
assertEquals(realmName(), event.getRealmId());
assertEquals(realmName(), event.getAuthDetails().getRealmId());
assertNull(event.getRepresentation());
}
@Test
public void testGetRepresentation() {
configRep.setAdminEventsDetailsEnabled(Boolean.TRUE);
saveConfig();
createUser("user2");
AdminEventRepresentation event = events().get(0);
assertNotNull(event.getRepresentation());
assertTrue(event.getRepresentation().contains("foo"));
}
@Test
public void testFilterAdminEvents() {
// two CREATE and one UPDATE
createUser("user3");
createUser("user4");
updateRealm();
assertEquals(3, events().size());
List<AdminEventRepresentation> events = testRealmResource().getAdminEvents(Arrays.asList("CREATE"), realmName(), null, null, null, null, null, null, null, null);
assertEquals(2, events.size());
}
}
@@ -0,0 +1,126 @@
/*
* Copyright 2016 Red Hat Inc. and/or its affiliates and other contributors
* as indicated by the @author tags. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.keycloak.testsuite.event;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
/**
* Test updates to the events configuration.
*
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
*/
public class EventConfigTest extends AbstractEventTest {
@Test
public void defaultEventConfigTest() {
assertFalse(configRep.isAdminEventsDetailsEnabled());
assertFalse(configRep.isAdminEventsEnabled());
assertFalse(configRep.isEventsEnabled());
List<String> eventListeners = configRep.getEventsListeners();
assertEquals(1, eventListeners.size());
assertEquals("jboss-logging", eventListeners.get(0));
}
@Test
public void enableEventsTest() {
enableEvents();
assertTrue(configRep.isEventsEnabled());
assertTrue(configRep.isAdminEventsEnabled());
}
@Test
public void addRemoveListenerTest() {
configRep.setEventsListeners(Collections.EMPTY_LIST);
saveConfig();
assertEquals(0, configRep.getEventsListeners().size());
configRep.setEventsListeners(Arrays.asList("email"));
saveConfig();
List<String> eventListeners = configRep.getEventsListeners();
assertEquals(1, eventListeners.size());
assertEquals("email", eventListeners.get(0));
}
@Test
public void loginEventSettingsTest() {
enableEvents();
assertTrue(hasEventType("LOGIN"));
assertTrue(hasEventType("LOGOUT"));
assertTrue(hasEventType("CLIENT_DELETE_ERROR"));
int defaultEventCount = configRep.getEnabledEventTypes().size();
configRep.setEnabledEventTypes(Arrays.asList("CLIENT_DELETE", "CLEINT_DELETE_ERROR"));
saveConfig();
List<String> enabledEventTypes = configRep.getEnabledEventTypes();
assertEquals(2, enabledEventTypes.size());
// remove all event types
configRep.setEnabledEventTypes(Collections.EMPTY_LIST);
saveConfig();
// removing all event types restores default events
assertEquals(defaultEventCount, configRep.getEnabledEventTypes().size());
}
private boolean hasEventType(String eventType) {
for (String event : configRep.getEnabledEventTypes()) {
if (eventType.equals(event)) return true;
}
return false;
}
@Test
public void includeRepresentationTest() {
enableEvents();
assertTrue(configRep.isAdminEventsEnabled());
assertFalse(configRep.isAdminEventsDetailsEnabled());
configRep.setAdminEventsDetailsEnabled(Boolean.TRUE);
saveConfig();
assertTrue(configRep.isAdminEventsDetailsEnabled());
}
@Test
public void setLoginEventExpirationTest() {
enableEvents();
assertNull(configRep.getEventsExpiration());
Long oneHour = 3600L;
configRep.setEventsExpiration(oneHour);
saveConfig();
assertEquals(oneHour, configRep.getEventsExpiration());
}
}
@@ -0,0 +1,118 @@
/*
* Copyright 2016 Red Hat Inc. and/or its affiliates and other contributors
* as indicated by the @author tags. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.keycloak.testsuite.event;
import java.util.Arrays;
import java.util.List;
import org.jboss.arquillian.graphene.page.Page;
import org.junit.Before;
import org.junit.Test;
import org.keycloak.representations.idm.EventRepresentation;
import org.keycloak.testsuite.console.page.events.LoginEvents;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
/**
* Test getting and filtering login-related events.
*
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
*/
public class LoginEventsTest extends AbstractEventTest {
@Page
private LoginEvents loginEventsPage;
@Before
public void init() {
configRep.setEventsEnabled(true);
saveConfig();
testRealmResource().clearEvents();
}
private List<EventRepresentation> events() {
return testRealmResource().getEvents();
}
private void badLogin() {
loginEventsPage.navigateTo();
loginPage.form().login("bad", "user");
}
private void pause(int seconds) {
try {
Thread.sleep(seconds * 1000L);
} catch (InterruptedException e) {
fail(e.getMessage());
}
}
@Test
public void clearEventsTest() {
assertEquals(0, events().size());
badLogin();
badLogin();
assertEquals(2, events().size());
testRealmResource().clearEvents();
assertEquals(0, events().size());
}
@Test
public void loggingOfCertainTypeTest() {
assertEquals(0, events().size());
configRep.setEnabledEventTypes(Arrays.asList("REVOKE_GRANT"));
saveConfig();
badLogin();
assertEquals(0, events().size());
configRep.setEnabledEventTypes(Arrays.asList("LOGIN_ERROR"));
saveConfig();
badLogin();
assertEquals(1, events().size());
}
@Test
public void filterTest() {
badLogin();
badLogin();
assertEquals(2, events().size());
List<EventRepresentation> filteredEvents = testRealmResource().getEvents(Arrays.asList("REVOKE_GRANT"), null, null, null, null, null, null, null);
assertEquals(0, filteredEvents.size());
filteredEvents = testRealmResource().getEvents(Arrays.asList("LOGIN_ERROR"), null, null, null, null, null, null, null);
assertEquals(2, filteredEvents.size());
}
/*
Removed this test because it takes too long. The default interval for
event cleanup is 15 minutes (900 seconds). I don't have time to figure out
a way to set the cleanup thread to a lower interval for testing.
@Test
public void eventExpirationTest() {
configRep.setEventsExpiration(1L); // second
saveConfig();
badLogin();
assertEquals(1, events().size());
pause(900); // pause 900 seconds
assertEquals(0, events().size());
}**/
}
@@ -117,6 +117,32 @@
</systemPropertyVariables>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>xml-maven-plugin</artifactId>
<executions>
<execution>
<id>configure-adapter-debug-log</id>
<phase>process-resources</phase>
<goals>
<goal>transform</goal>
</goals>
<configuration>
<transformationSets>
<transformationSet>
<dir>${app.server.wildfly.home}/standalone/configuration</dir>
<includes>
<include>standalone.xml</include>
</includes>
<stylesheet>src/main/xslt/add-adapter-log-level.xsl</stylesheet>
<outputDir>${app.server.wildfly.home}/standalone/configuration</outputDir>
</transformationSet>
</transformationSets>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
@@ -0,0 +1,50 @@
<!--
~ Copyright 2016 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xalan="http://xml.apache.org/xalan"
xmlns:j="urn:jboss:domain:4.0"
xmlns:ds="urn:jboss:domain:datasources:4.0"
xmlns:k="urn:jboss:domain:keycloak:1.1"
xmlns:sec="urn:jboss:domain:security:1.2"
version="2.0"
exclude-result-prefixes="xalan j ds k sec">
<xsl:param name="config"/>
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" xalan:indent-amount="4" standalone="no"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="nsDS" select="'urn:jboss:domain:logging:'"/>
<xsl:template match="//*[local-name()='subsystem' and starts-with(namespace-uri(), $nsDS)]
/*[local-name()='root-logger' and starts-with(namespace-uri(), $nsDS)]">
<logger category="org.keycloak.adapters">
<level name="DEBUG"/>
</logger>
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>