KEYCLOAK-2590 Add custom rest endpoint to set time offset

This commit is contained in:
Stian Thorgersen 2016-04-06 11:14:37 +02:00
parent 4db73942e6
commit 0fc4ca0d12
6 changed files with 232 additions and 0 deletions

View file

@ -42,6 +42,10 @@ public class Time {
return ((long) time) * 1000;
}
public static int getOffset() {
return offset;
}
public static void setOffset(int offset) {
Time.offset = offset;
}

View file

@ -0,0 +1,63 @@
/*
* 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.
*/
package org.keycloak.testsuite.rest;
import org.keycloak.common.util.Time;
import org.keycloak.services.resource.RealmResourceProvider;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.HashMap;
import java.util.Map;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class TimeOffsetResourceProvider implements RealmResourceProvider {
@Override
public Object getResource() {
return this;
}
@GET
@Produces(MediaType.APPLICATION_JSON)
public Map<String, String> get() {
Map<String, String> response = new HashMap<>();
response.put("currentTime", String.valueOf(Time.currentTime()));
response.put("offset", String.valueOf(Time.getOffset()));
return response;
}
@PUT
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Map<String, String> put(Map<String, String> time) {
int offset = Integer.parseInt(time.get("offset"));
Time.setOffset(offset);
return get();
}
@Override
public void close() {
}
}

View file

@ -0,0 +1,53 @@
/*
* 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.
*/
package org.keycloak.testsuite.rest;
import org.keycloak.Config.Scope;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.services.resource.RealmResourceProvider;
import org.keycloak.services.resource.RealmResourceProviderFactory;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class TimeOffsetResourceProviderFactory implements RealmResourceProviderFactory {
@Override
public RealmResourceProvider create(KeycloakSession session) {
return new TimeOffsetResourceProvider();
}
@Override
public void init(Scope config) {
}
@Override
public void postInit(KeycloakSessionFactory factory) {
}
@Override
public void close() {
}
@Override
public String getId() {
return "time-offset";
}
}

View file

@ -0,0 +1,18 @@
#
# 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.
#
org.keycloak.testsuite.rest.TimeOffsetResourceProviderFactory

View file

@ -18,10 +18,23 @@ package org.keycloak.testsuite;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.io.IOUtils;
import org.keycloak.broker.provider.util.SimpleHttp;
import org.keycloak.common.util.KeycloakUriBuilder;
import org.keycloak.testsuite.arquillian.TestContext;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.ws.rs.NotFoundException;
import org.jboss.arquillian.container.test.api.RunAsClient;
@ -48,6 +61,7 @@ import org.keycloak.testsuite.arquillian.AuthServerTestEnricher;
import org.keycloak.testsuite.arquillian.SuiteContext;
import org.keycloak.testsuite.auth.page.WelcomePage;
import org.keycloak.testsuite.util.OAuthClient;
import org.keycloak.util.JsonSerialization;
import org.openqa.selenium.WebDriver;
import org.keycloak.testsuite.auth.page.AuthServer;
import org.keycloak.testsuite.auth.page.AuthServerContextRoot;
@ -108,6 +122,8 @@ public abstract class AbstractKeycloakTest {
private PropertiesConfiguration constantsProperties;
private boolean resetTimeOffset;
@Before
public void beforeAbstractKeycloakTest() {
adminClient = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth",
@ -134,6 +150,10 @@ public abstract class AbstractKeycloakTest {
@After
public void afterAbstractKeycloakTest() {
if (resetTimeOffset) {
resetTimeOffset();
}
// removeTestRealms(); // keeping test realms after test to be able to inspect failures, instead deleting existing realms before import
// keycloak.close(); // keeping admin connection open
}
@ -275,6 +295,41 @@ public abstract class AbstractKeycloakTest {
userResource.update(userRepresentation);
}
public void setTimeOffset(int offset) {invokeTimeOffset(offset);
String response = invokeTimeOffset(offset);
resetTimeOffset = offset != 0;
log.debugv("Set time offset, response {0}", response);
}
public void resetTimeOffset() {
String response = invokeTimeOffset(0);
resetTimeOffset = false;
log.debugv("Reset time offset, response {0}", response);
}
private String invokeTimeOffset(int offset) {
try {
String data = JsonSerialization.writeValueAsString(Collections.singletonMap("offset", String.valueOf(offset)));
URI uri = KeycloakUriBuilder.fromUri(suiteContext.getAuthServerInfo().getContextRoot().toURI()).path("/auth/realms/master/time-offset").build();
HttpURLConnection connection = (HttpURLConnection) uri.toURL().openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("PUT");
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Content-Length", String.valueOf(data.length()));
OutputStream os = connection.getOutputStream();
os.write(data.getBytes());
os.close();
InputStream is = connection.getInputStream();
String response = IOUtils.toString(is);
is.close();
return response;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private void loadConstantsProperties() throws ConfigurationException {
constantsProperties = new PropertiesConfiguration(System.getProperty("testsuite.constants"));
constantsProperties.setThrowExceptionOnMissing(true);

View file

@ -0,0 +1,39 @@
/*
* 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.
*/
package org.keycloak.testsuite;
import org.junit.Test;
import org.keycloak.representations.idm.RealmRepresentation;
import java.util.List;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class TempSetTimeOffsetTest extends AbstractKeycloakTest {
@Override
public void addTestRealms(List<RealmRepresentation> testRealms) {
}
@Test
public void test() {
setTimeOffset(60);
}
}