Merge branch 'jetty-12.0.x' into jetty-12.1.x
This commit is contained in:
commit
dd172f58db
|
@ -1,29 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<parent>
|
|
||||||
<groupId>org.eclipse.jetty.tests</groupId>
|
|
||||||
<artifactId>tests</artifactId>
|
|
||||||
<version>12.1.0-SNAPSHOT</version>
|
|
||||||
</parent>
|
|
||||||
<artifactId>jetty-test-common</artifactId>
|
|
||||||
<packaging>jar</packaging>
|
|
||||||
<name>Tests :: Test Utilities</name>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<bundle-symbolic-name>${project.groupId}.testers</bundle-symbolic-name>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
|
||||||
<artifactId>jetty-server</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
|
||||||
<artifactId>jetty-util</artifactId>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
</project>
|
|
|
@ -1,53 +0,0 @@
|
||||||
//
|
|
||||||
// ========================================================================
|
|
||||||
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
|
|
||||||
//
|
|
||||||
// This program and the accompanying materials are made available under the
|
|
||||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
||||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
|
||||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
|
||||||
// ========================================================================
|
|
||||||
//
|
|
||||||
|
|
||||||
package org.eclipse.jetty.tests;
|
|
||||||
|
|
||||||
import java.util.Base64;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A basic JWT encoder for testing purposes.
|
|
||||||
*/
|
|
||||||
public class JwtEncoder
|
|
||||||
{
|
|
||||||
private static final Base64.Encoder ENCODER = Base64.getUrlEncoder();
|
|
||||||
private static final String DEFAULT_HEADER = "{\"INFO\": \"this is not used or checked in our implementation\"}";
|
|
||||||
private static final String DEFAULT_SIGNATURE = "we do not validate signature as we use the authorization code flow";
|
|
||||||
|
|
||||||
public static String encode(String idToken)
|
|
||||||
{
|
|
||||||
return stripPadding(ENCODER.encodeToString(DEFAULT_HEADER.getBytes())) + "." +
|
|
||||||
stripPadding(ENCODER.encodeToString(idToken.getBytes())) + "." +
|
|
||||||
stripPadding(ENCODER.encodeToString(DEFAULT_SIGNATURE.getBytes()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String stripPadding(String paddedBase64)
|
|
||||||
{
|
|
||||||
return paddedBase64.split("=")[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a basic JWT for testing using argument supplied attributes.
|
|
||||||
*/
|
|
||||||
public static String createIdToken(String provider, String clientId, String subject, String name, long expiry)
|
|
||||||
{
|
|
||||||
return "{" +
|
|
||||||
"\"iss\": \"" + provider + "\"," +
|
|
||||||
"\"sub\": \"" + subject + "\"," +
|
|
||||||
"\"aud\": \"" + clientId + "\"," +
|
|
||||||
"\"exp\": " + expiry + "," +
|
|
||||||
"\"name\": \"" + name + "\"," +
|
|
||||||
"\"email\": \"" + name + "@example.com" + "\"" +
|
|
||||||
"}";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,421 +0,0 @@
|
||||||
//
|
|
||||||
// ========================================================================
|
|
||||||
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
|
|
||||||
//
|
|
||||||
// This program and the accompanying materials are made available under the
|
|
||||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
||||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
|
||||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
|
||||||
// ========================================================================
|
|
||||||
//
|
|
||||||
|
|
||||||
package org.eclipse.jetty.tests;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.time.Duration;
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.http.BadMessageException;
|
|
||||||
import org.eclipse.jetty.http.HttpHeader;
|
|
||||||
import org.eclipse.jetty.http.HttpMethod;
|
|
||||||
import org.eclipse.jetty.http.HttpStatus;
|
|
||||||
import org.eclipse.jetty.server.Handler;
|
|
||||||
import org.eclipse.jetty.server.Request;
|
|
||||||
import org.eclipse.jetty.server.Response;
|
|
||||||
import org.eclipse.jetty.server.Server;
|
|
||||||
import org.eclipse.jetty.server.ServerConnector;
|
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
|
||||||
import org.eclipse.jetty.util.Callback;
|
|
||||||
import org.eclipse.jetty.util.Fields;
|
|
||||||
import org.eclipse.jetty.util.StringUtil;
|
|
||||||
import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
|
||||||
import org.eclipse.jetty.util.statistic.CounterStatistic;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
public class OpenIdProvider extends ContainerLifeCycle
|
|
||||||
{
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(OpenIdProvider.class);
|
|
||||||
|
|
||||||
private static final String CONFIG_PATH = "/.well-known/openid-configuration";
|
|
||||||
private static final String AUTH_PATH = "/auth";
|
|
||||||
private static final String TOKEN_PATH = "/token";
|
|
||||||
private static final String END_SESSION_PATH = "/end_session";
|
|
||||||
private final Map<String, User> issuedAuthCodes = new HashMap<>();
|
|
||||||
|
|
||||||
protected final String clientId;
|
|
||||||
protected final String clientSecret;
|
|
||||||
protected final List<String> redirectUris = new ArrayList<>();
|
|
||||||
private final ServerConnector connector;
|
|
||||||
private final Server server;
|
|
||||||
private int port = 0;
|
|
||||||
private String provider;
|
|
||||||
private User preAuthedUser;
|
|
||||||
private final CounterStatistic loggedInUsers = new CounterStatistic();
|
|
||||||
private long _idTokenDuration = Duration.ofSeconds(10).toMillis();
|
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception
|
|
||||||
{
|
|
||||||
String clientId = "CLIENT_ID123";
|
|
||||||
String clientSecret = "PASSWORD123";
|
|
||||||
int port = 5771;
|
|
||||||
String redirectUri = "http://localhost:8080/j_security_check";
|
|
||||||
|
|
||||||
OpenIdProvider openIdProvider = new OpenIdProvider(clientId, clientSecret);
|
|
||||||
openIdProvider.addRedirectUri(redirectUri);
|
|
||||||
openIdProvider.setPort(port);
|
|
||||||
openIdProvider.start();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
openIdProvider.join();
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
openIdProvider.stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public OpenIdProvider()
|
|
||||||
{
|
|
||||||
this("clientId" + StringUtil.randomAlphaNumeric(4), StringUtil.randomAlphaNumeric(10));
|
|
||||||
}
|
|
||||||
|
|
||||||
public OpenIdProvider(String clientId, String clientSecret)
|
|
||||||
{
|
|
||||||
this.clientId = clientId;
|
|
||||||
this.clientSecret = clientSecret;
|
|
||||||
|
|
||||||
server = new Server();
|
|
||||||
connector = new ServerConnector(server);
|
|
||||||
server.addConnector(connector);
|
|
||||||
|
|
||||||
server.setHandler(new OpenIdProviderHandler());
|
|
||||||
addBean(server);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getClientId()
|
|
||||||
{
|
|
||||||
return clientId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getClientSecret()
|
|
||||||
{
|
|
||||||
return clientSecret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIdTokenDuration(long duration)
|
|
||||||
{
|
|
||||||
_idTokenDuration = duration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getIdTokenDuration()
|
|
||||||
{
|
|
||||||
return _idTokenDuration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void join() throws InterruptedException
|
|
||||||
{
|
|
||||||
server.join();
|
|
||||||
}
|
|
||||||
|
|
||||||
public CounterStatistic getLoggedInUsers()
|
|
||||||
{
|
|
||||||
return loggedInUsers;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doStart() throws Exception
|
|
||||||
{
|
|
||||||
connector.setPort(port);
|
|
||||||
super.doStart();
|
|
||||||
provider = "http://localhost:" + connector.getLocalPort();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPort(int port)
|
|
||||||
{
|
|
||||||
if (isStarted())
|
|
||||||
throw new IllegalStateException();
|
|
||||||
this.port = port;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUser(User user)
|
|
||||||
{
|
|
||||||
this.preAuthedUser = user;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getProvider()
|
|
||||||
{
|
|
||||||
if (!isStarted() && port == 0)
|
|
||||||
throw new IllegalStateException("Port of OpenIdProvider not configured");
|
|
||||||
return provider;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addRedirectUri(String uri)
|
|
||||||
{
|
|
||||||
redirectUris.add(uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class OpenIdProviderHandler extends Handler.Abstract
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public boolean handle(Request request, Response response, Callback callback) throws Exception
|
|
||||||
{
|
|
||||||
String pathInContext = Request.getPathInContext(request);
|
|
||||||
switch (pathInContext)
|
|
||||||
{
|
|
||||||
case CONFIG_PATH -> doGetConfigServlet(request, response, callback);
|
|
||||||
case AUTH_PATH -> doAuthEndpoint(request, response, callback);
|
|
||||||
case TOKEN_PATH -> doTokenEndpoint(request, response, callback);
|
|
||||||
case END_SESSION_PATH -> doEndSessionEndpoint(request, response, callback);
|
|
||||||
default -> Response.writeError(request, response, callback, HttpStatus.NOT_FOUND_404);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void doAuthEndpoint(Request request, Response response, Callback callback) throws Exception
|
|
||||||
{
|
|
||||||
String method = request.getMethod();
|
|
||||||
switch (method)
|
|
||||||
{
|
|
||||||
case "GET" -> doGetAuthEndpoint(request, response, callback);
|
|
||||||
case "POST" -> doPostAuthEndpoint(request, response, callback);
|
|
||||||
default -> throw new BadMessageException("Unsupported HTTP method: " + method);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void doGetAuthEndpoint(Request request, Response response, Callback callback) throws Exception
|
|
||||||
{
|
|
||||||
Fields parameters = Request.getParameters(request);
|
|
||||||
|
|
||||||
if (!clientId.equals(parameters.getValue("client_id")))
|
|
||||||
{
|
|
||||||
Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403, "invalid client_id");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String redirectUri = parameters.getValue("redirect_uri");
|
|
||||||
if (!redirectUris.contains(redirectUri))
|
|
||||||
{
|
|
||||||
LOG.warn("invalid redirectUri {}", redirectUri);
|
|
||||||
Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403, "invalid redirect_uri");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String scopeString = parameters.getValue("scope");
|
|
||||||
List<String> scopes = (scopeString == null) ? Collections.emptyList() : Arrays.asList(scopeString.split(" "));
|
|
||||||
if (!scopes.contains("openid"))
|
|
||||||
{
|
|
||||||
Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403, "no openid scope");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!"code".equals(parameters.getValue("response_type")))
|
|
||||||
{
|
|
||||||
Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403, "response_type must be code");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String state = parameters.getValue("state");
|
|
||||||
if (state == null)
|
|
||||||
{
|
|
||||||
Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403, "no state param");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (preAuthedUser == null)
|
|
||||||
{
|
|
||||||
String responseContent = String.format("""
|
|
||||||
<h2>Login to OpenID Connect Provider</h2>
|
|
||||||
<form action="%s" method="post">
|
|
||||||
<input type="text" autocomplete="off" placeholder="Username" name="username" required>
|
|
||||||
<input type="hidden" name="redirectUri" value="%s">
|
|
||||||
<input type="hidden" name="state" value="%s">
|
|
||||||
<input type="submit">
|
|
||||||
</form>
|
|
||||||
""", AUTH_PATH, redirectUri, state);
|
|
||||||
response.getHeaders().put(HttpHeader.CONTENT_TYPE, "text/html");
|
|
||||||
response.write(true, BufferUtil.toBuffer(responseContent), callback);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
redirectUser(request, response, callback, preAuthedUser, redirectUri, state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void doPostAuthEndpoint(Request request, Response response, Callback callback) throws Exception
|
|
||||||
{
|
|
||||||
Fields parameters = Request.getParameters(request);
|
|
||||||
String redirectUri = parameters.getValue("redirectUri");
|
|
||||||
if (!redirectUris.contains(redirectUri))
|
|
||||||
{
|
|
||||||
Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403, "invalid redirect_uri");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String state = parameters.getValue("state");
|
|
||||||
if (state == null)
|
|
||||||
{
|
|
||||||
Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403, "no state param");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String username = parameters.getValue("username");
|
|
||||||
if (username == null)
|
|
||||||
{
|
|
||||||
Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403, "no username");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
User user = new User(username);
|
|
||||||
redirectUser(request, response, callback, user, redirectUri, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void redirectUser(Request request, Response response, Callback callback, User user, String redirectUri, String state) throws IOException
|
|
||||||
{
|
|
||||||
String authCode = UUID.randomUUID().toString().replace("-", "");
|
|
||||||
issuedAuthCodes.put(authCode, user);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
redirectUri += "?code=" + authCode + "&state=" + state;
|
|
||||||
Response.sendRedirect(request, response, callback, redirectUri);
|
|
||||||
}
|
|
||||||
catch (Throwable t)
|
|
||||||
{
|
|
||||||
issuedAuthCodes.remove(authCode);
|
|
||||||
throw t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void doTokenEndpoint(Request request, Response response, Callback callback) throws Exception
|
|
||||||
{
|
|
||||||
if (!HttpMethod.POST.is(request.getMethod()))
|
|
||||||
throw new BadMessageException("Unsupported HTTP method for token Endpoint: " + request.getMethod());
|
|
||||||
|
|
||||||
Fields parameters = Request.getParameters(request);
|
|
||||||
String code = parameters.getValue("code");
|
|
||||||
|
|
||||||
if (!clientId.equals(parameters.getValue("client_id")) ||
|
|
||||||
!clientSecret.equals(parameters.getValue("client_secret")) ||
|
|
||||||
!redirectUris.contains(parameters.getValue("redirect_uri")) ||
|
|
||||||
!"authorization_code".equals(parameters.getValue("grant_type")) ||
|
|
||||||
code == null)
|
|
||||||
{
|
|
||||||
Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403, "bad auth request");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
User user = issuedAuthCodes.remove(code);
|
|
||||||
if (user == null)
|
|
||||||
{
|
|
||||||
Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403, "invalid auth code");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String accessToken = "ABCDEFG";
|
|
||||||
long accessTokenDuration = Duration.ofMinutes(10).toSeconds();
|
|
||||||
String responseContent = "{" +
|
|
||||||
"\"access_token\": \"" + accessToken + "\"," +
|
|
||||||
"\"id_token\": \"" + JwtEncoder.encode(user.getIdToken(provider, clientId, _idTokenDuration)) + "\"," +
|
|
||||||
"\"expires_in\": " + accessTokenDuration + "," +
|
|
||||||
"\"token_type\": \"Bearer\"" +
|
|
||||||
"}";
|
|
||||||
|
|
||||||
loggedInUsers.increment();
|
|
||||||
response.getHeaders().put(HttpHeader.CONTENT_TYPE, "text/plain");
|
|
||||||
response.write(true, BufferUtil.toBuffer(responseContent), callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void doEndSessionEndpoint(Request request, Response response, Callback callback) throws Exception
|
|
||||||
{
|
|
||||||
Fields parameters = Request.getParameters(request);
|
|
||||||
String idToken = parameters.getValue("id_token_hint");
|
|
||||||
if (idToken == null)
|
|
||||||
{
|
|
||||||
Response.writeError(request, response, callback, HttpStatus.BAD_REQUEST_400, "no id_token_hint");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String logoutRedirect = parameters.getValue("post_logout_redirect_uri");
|
|
||||||
if (logoutRedirect == null)
|
|
||||||
{
|
|
||||||
response.setStatus(HttpStatus.OK_200);
|
|
||||||
response.write(true, BufferUtil.toBuffer("logout success on end_session_endpoint"), callback);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
loggedInUsers.decrement();
|
|
||||||
Response.sendRedirect(request, response, callback, logoutRedirect);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void doGetConfigServlet(Request request, Response response, Callback callback) throws IOException
|
|
||||||
{
|
|
||||||
String discoveryDocument = "{" +
|
|
||||||
"\"issuer\": \"" + provider + "\"," +
|
|
||||||
"\"authorization_endpoint\": \"" + provider + AUTH_PATH + "\"," +
|
|
||||||
"\"token_endpoint\": \"" + provider + TOKEN_PATH + "\"," +
|
|
||||||
"\"end_session_endpoint\": \"" + provider + END_SESSION_PATH + "\"," +
|
|
||||||
"}";
|
|
||||||
|
|
||||||
response.write(true, BufferUtil.toBuffer(discoveryDocument), callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class User
|
|
||||||
{
|
|
||||||
private final String subject;
|
|
||||||
private final String name;
|
|
||||||
|
|
||||||
public User(String name)
|
|
||||||
{
|
|
||||||
this(UUID.nameUUIDFromBytes(name.getBytes()).toString(), name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public User(String subject, String name)
|
|
||||||
{
|
|
||||||
this.subject = subject;
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName()
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSubject()
|
|
||||||
{
|
|
||||||
return subject;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getIdToken(String provider, String clientId, long duration)
|
|
||||||
{
|
|
||||||
long expiryTime = Instant.now().plusMillis(duration).getEpochSecond();
|
|
||||||
return JwtEncoder.createIdToken(provider, clientId, subject, name, expiryTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj)
|
|
||||||
{
|
|
||||||
if (!(obj instanceof User))
|
|
||||||
return false;
|
|
||||||
return Objects.equals(subject, ((User)obj).subject) && Objects.equals(name, ((User)obj).name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode()
|
|
||||||
{
|
|
||||||
return Objects.hash(subject, name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -15,7 +15,6 @@
|
||||||
<module>jetty-jmh</module>
|
<module>jetty-jmh</module>
|
||||||
<module>jetty-test-multipart</module>
|
<module>jetty-test-multipart</module>
|
||||||
<module>jetty-test-session-common</module>
|
<module>jetty-test-session-common</module>
|
||||||
<module>jetty-test-common</module>
|
|
||||||
<module>test-cross-context-dispatch</module>
|
<module>test-cross-context-dispatch</module>
|
||||||
<module>test-distribution</module>
|
<module>test-distribution</module>
|
||||||
<module>test-integration</module>
|
<module>test-integration</module>
|
||||||
|
|
|
@ -13,9 +13,6 @@
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
<module>test-distribution-common</module>
|
<module>test-distribution-common</module>
|
||||||
<module>test-ee11-distribution</module>
|
|
||||||
<module>test-ee10-distribution</module>
|
|
||||||
<module>test-ee9-distribution</module>
|
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
|
|
@ -15,9 +15,21 @@
|
||||||
<bundle-symbolic-name>${project.groupId}.tests.distribution.common</bundle-symbolic-name>
|
<bundle-symbolic-name>${project.groupId}.tests.distribution.common</bundle-symbolic-name>
|
||||||
<!-- <junit.jupiter.execution.parallel.enabled>false</junit.jupiter.execution.parallel.enabled>-->
|
<!-- <junit.jupiter.execution.parallel.enabled>false</junit.jupiter.execution.parallel.enabled>-->
|
||||||
<junit.jupiter.execution.parallel.config.fixed.parallelism>2</junit.jupiter.execution.parallel.config.fixed.parallelism>
|
<junit.jupiter.execution.parallel.config.fixed.parallelism>2</junit.jupiter.execution.parallel.config.fixed.parallelism>
|
||||||
|
<testcontainers-keycloak.version>3.4.0</testcontainers-keycloak.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.dasniko</groupId>
|
||||||
|
<artifactId>testcontainers-keycloak</artifactId>
|
||||||
|
<version>${testcontainers-keycloak.version}</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>io.quarkus</groupId>
|
||||||
|
<artifactId>quarkus-junit4-mock</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.maven</groupId>
|
<groupId>org.apache.maven</groupId>
|
||||||
<artifactId>maven-artifact</artifactId>
|
<artifactId>maven-artifact</artifactId>
|
||||||
|
@ -138,6 +150,12 @@
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
<artifactId>jetty-infinispan-common</artifactId>
|
<artifactId>jetty-infinispan-common</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>io.smallrye</groupId>
|
||||||
|
<artifactId>jandex</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
@ -155,6 +173,20 @@
|
||||||
<artifactId>jetty-util-ajax</artifactId>
|
<artifactId>jetty-util-ajax</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty.ee10</groupId>
|
||||||
|
<artifactId>jetty-ee10-test-log4j2-webapp</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<type>war</type>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty.ee9</groupId>
|
||||||
|
<artifactId>jetty-ee9-test-openid-webapp</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<type>war</type>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.jetty.http2</groupId>
|
<groupId>org.eclipse.jetty.http2</groupId>
|
||||||
<artifactId>jetty-http2-client</artifactId>
|
<artifactId>jetty-http2-client</artifactId>
|
||||||
|
@ -246,6 +278,7 @@
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<<<<<<< HEAD
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
|
@ -257,6 +290,8 @@
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
=======
|
||||||
|
>>>>>>> jetty-12.0.x
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<configuration>
|
<configuration>
|
||||||
<systemPropertyVariables combine.children="append">
|
<systemPropertyVariables combine.children="append">
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
//
|
//
|
||||||
|
|
||||||
package org.eclipse.jetty.ee10.tests.distribution;
|
package org.eclipse.jetty.tests.distribution;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
@ -23,7 +23,6 @@ import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.eclipse.jetty.client.ContentResponse;
|
import org.eclipse.jetty.client.ContentResponse;
|
||||||
import org.eclipse.jetty.http.HttpStatus;
|
import org.eclipse.jetty.http.HttpStatus;
|
||||||
import org.eclipse.jetty.tests.distribution.AbstractJettyHomeTest;
|
|
||||||
import org.eclipse.jetty.tests.testers.JettyHomeTester;
|
import org.eclipse.jetty.tests.testers.JettyHomeTester;
|
||||||
import org.eclipse.jetty.tests.testers.Tester;
|
import org.eclipse.jetty.tests.testers.Tester;
|
||||||
import org.eclipse.jetty.toolchain.test.FS;
|
import org.eclipse.jetty.toolchain.test.FS;
|
|
@ -0,0 +1,203 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under the
|
||||||
|
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||||
|
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
package org.eclipse.jetty.tests.distribution;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import dasniko.testcontainers.keycloak.KeycloakContainer;
|
||||||
|
import org.eclipse.jetty.client.ContentResponse;
|
||||||
|
import org.eclipse.jetty.http.HttpStatus;
|
||||||
|
import org.eclipse.jetty.tests.testers.JettyHomeTester;
|
||||||
|
import org.eclipse.jetty.tests.testers.Tester;
|
||||||
|
import org.eclipse.jetty.util.Fields;
|
||||||
|
import org.junit.jupiter.api.AfterAll;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
import org.keycloak.admin.client.CreatedResponseUtil;
|
||||||
|
import org.keycloak.admin.client.Keycloak;
|
||||||
|
import org.keycloak.representations.idm.ClientRepresentation;
|
||||||
|
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||||
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
|
import org.keycloak.representations.idm.UserRepresentation;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.containsString;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
public class OpenIdTests extends AbstractJettyHomeTest
|
||||||
|
{
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(OpenIdTests.class);
|
||||||
|
|
||||||
|
private static final KeycloakContainer KEYCLOAK_CONTAINER = new KeycloakContainer();
|
||||||
|
|
||||||
|
private static final String clientId = "jetty-api";
|
||||||
|
private static final String clientSecret = "JettyRocks!";
|
||||||
|
|
||||||
|
private static final String userName = "jetty";
|
||||||
|
private static final String password = "JettyRocks!Really";
|
||||||
|
|
||||||
|
private static final String firstName = "John";
|
||||||
|
private static final String lastName = "Doe";
|
||||||
|
private static final String email = "jetty@jetty.org";
|
||||||
|
|
||||||
|
private static String userId;
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
public static void startKeycloak()
|
||||||
|
{
|
||||||
|
KEYCLOAK_CONTAINER.start();
|
||||||
|
// init keycloak
|
||||||
|
try (Keycloak keycloak = KEYCLOAK_CONTAINER.getKeycloakAdminClient())
|
||||||
|
{
|
||||||
|
RealmRepresentation jettyRealm = new RealmRepresentation();
|
||||||
|
jettyRealm.setId("jetty");
|
||||||
|
jettyRealm.setRealm("jetty");
|
||||||
|
jettyRealm.setEnabled(true);
|
||||||
|
keycloak.realms().create(jettyRealm);
|
||||||
|
|
||||||
|
ClientRepresentation clientRepresentation = new ClientRepresentation();
|
||||||
|
clientRepresentation.setClientId(clientId);
|
||||||
|
clientRepresentation.setSecret(clientSecret);
|
||||||
|
clientRepresentation.setRedirectUris(List.of("http://localhost:*"));
|
||||||
|
clientRepresentation.setEnabled(true);
|
||||||
|
clientRepresentation.setPublicClient(Boolean.TRUE);
|
||||||
|
keycloak.realm("jetty").clients().create(clientRepresentation);
|
||||||
|
|
||||||
|
UserRepresentation user = new UserRepresentation();
|
||||||
|
user.setEnabled(true);
|
||||||
|
user.setFirstName(firstName);
|
||||||
|
user.setLastName(lastName);
|
||||||
|
user.setUsername(userName);
|
||||||
|
user.setEmail(email);
|
||||||
|
|
||||||
|
userId = CreatedResponseUtil.getCreatedId(keycloak.realm("jetty").users().create(user));
|
||||||
|
|
||||||
|
CredentialRepresentation passwordCred = new CredentialRepresentation();
|
||||||
|
passwordCred.setTemporary(false);
|
||||||
|
passwordCred.setType(CredentialRepresentation.PASSWORD);
|
||||||
|
passwordCred.setValue(password);
|
||||||
|
|
||||||
|
// Set password credential
|
||||||
|
keycloak.realm("jetty").users().get(userId).resetPassword(passwordCred);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterAll
|
||||||
|
public static void stopKeycloak()
|
||||||
|
{
|
||||||
|
if (KEYCLOAK_CONTAINER.isRunning())
|
||||||
|
{
|
||||||
|
KEYCLOAK_CONTAINER.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Stream<Arguments> tests()
|
||||||
|
{
|
||||||
|
return Stream.of(
|
||||||
|
Arguments.of("ee9", "ee9-openid"),
|
||||||
|
Arguments.of("ee10", "openid")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("tests")
|
||||||
|
public void testOpenID(String env, String openIdModule) throws Exception
|
||||||
|
{
|
||||||
|
Path jettyBase = newTestJettyBaseDirectory();
|
||||||
|
String jettyVersion = System.getProperty("jettyVersion");
|
||||||
|
JettyHomeTester distribution = JettyHomeTester.Builder.newInstance()
|
||||||
|
.jettyVersion(jettyVersion)
|
||||||
|
.jettyBase(jettyBase)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
String[] args1 = {
|
||||||
|
"--create-startd",
|
||||||
|
"--approve-all-licenses",
|
||||||
|
"--add-to-start=http," + toEnvironment("webapp", env) + "," + toEnvironment("deploy", env) + "," + openIdModule
|
||||||
|
};
|
||||||
|
|
||||||
|
try (JettyHomeTester.Run run1 = distribution.start(args1))
|
||||||
|
{
|
||||||
|
assertTrue(run1.awaitFor(START_TIMEOUT, TimeUnit.SECONDS));
|
||||||
|
assertEquals(0, run1.getExitValue());
|
||||||
|
|
||||||
|
Path webApp = distribution.resolveArtifact("org.eclipse.jetty." + env + ":jetty-" + env + "-test-openid-webapp:war:" + jettyVersion);
|
||||||
|
distribution.installWar(webApp, "test");
|
||||||
|
String openIdProvider = KEYCLOAK_CONTAINER.getAuthServerUrl() + "/realms/jetty";
|
||||||
|
LOGGER.info("openIdProvider: {}", openIdProvider);
|
||||||
|
|
||||||
|
int port = Tester.freePort();
|
||||||
|
String[] args2 = {
|
||||||
|
"jetty.http.port=" + port,
|
||||||
|
"jetty.ssl.port=" + port,
|
||||||
|
"jetty.openid.provider=" + openIdProvider,
|
||||||
|
"jetty.openid.clientId=" + clientId,
|
||||||
|
"jetty.openid.clientSecret=" + clientSecret,
|
||||||
|
//"jetty.server.dumpAfterStart=true",
|
||||||
|
};
|
||||||
|
|
||||||
|
try (JettyHomeTester.Run run2 = distribution.start(args2))
|
||||||
|
{
|
||||||
|
assertTrue(run2.awaitConsoleLogsFor("Started oejs.Server@", START_TIMEOUT, TimeUnit.SECONDS));
|
||||||
|
String uri = "http://localhost:" + port + "/test";
|
||||||
|
// Initially not authenticated
|
||||||
|
startHttpClient();
|
||||||
|
ContentResponse contentResponse = client.GET(uri + "/");
|
||||||
|
assertThat(contentResponse.getStatus(), is(HttpStatus.OK_200));
|
||||||
|
assertThat(contentResponse.getContentAsString(), containsString("not authenticated"));
|
||||||
|
|
||||||
|
// Request to login is success
|
||||||
|
contentResponse = client.GET(uri + "/login");
|
||||||
|
assertThat(contentResponse.getStatus(), is(HttpStatus.OK_200));
|
||||||
|
// need to extract form
|
||||||
|
String html = contentResponse.getContentAsString();
|
||||||
|
// need this attribute <form ***** action="***"
|
||||||
|
String postUrl = html.substring(html.indexOf("action=\"")).substring(0, html.substring(html.indexOf("action=\"")).indexOf("\"", 9)).substring(8);
|
||||||
|
Fields fields = new Fields();
|
||||||
|
fields.put("username", userName);
|
||||||
|
fields.add("password", password);
|
||||||
|
contentResponse = client.FORM(postUrl, fields);
|
||||||
|
assertThat(contentResponse.getStatus(), is(HttpStatus.OK_200));
|
||||||
|
assertThat(contentResponse.getContentAsString(), containsString("success"));
|
||||||
|
|
||||||
|
// Now authenticated we can get info
|
||||||
|
String content = client.GET(uri + "/").getContentAsString();
|
||||||
|
assertThat(content, containsString("userId: " + userId));
|
||||||
|
assertThat(content, containsString("name: " + firstName + " " + lastName));
|
||||||
|
assertThat(content, containsString("email: " + email));
|
||||||
|
|
||||||
|
// Request to admin page gives 403 as we do not have admin role
|
||||||
|
contentResponse = client.GET(uri + "/admin");
|
||||||
|
assertThat(contentResponse.getStatus(), is(HttpStatus.FORBIDDEN_403));
|
||||||
|
|
||||||
|
// We are no longer authenticated after logging out
|
||||||
|
contentResponse = client.GET(uri + "/logout");
|
||||||
|
assertThat(contentResponse.getStatus(), is(HttpStatus.OK_200));
|
||||||
|
content = contentResponse.getContentAsString();
|
||||||
|
assertThat(content, containsString("not authenticated"));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,3 +6,6 @@ org.testcontainers.LEVEL=INFO
|
||||||
#org.testcontainers.LEVEL=DEBUG
|
#org.testcontainers.LEVEL=DEBUG
|
||||||
#org.eclipse.jetty.LEVEL=DEBUG
|
#org.eclipse.jetty.LEVEL=DEBUG
|
||||||
#org.eclipse.jetty.tests.distribution.LEVEL=DEBUG
|
#org.eclipse.jetty.tests.distribution.LEVEL=DEBUG
|
||||||
|
# uncomment to get output of forked jetty process in the logs
|
||||||
|
#org.eclipse.jetty.tests.testers.ProcessWrapper.LEVEL=DEBUG
|
||||||
|
com.gargoylesoftware.htmlunit.LEVEL=ERROR
|
|
@ -1,81 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<parent>
|
|
||||||
<groupId>org.eclipse.jetty.tests</groupId>
|
|
||||||
<artifactId>test-distribution</artifactId>
|
|
||||||
<version>12.1.0-SNAPSHOT</version>
|
|
||||||
</parent>
|
|
||||||
<artifactId>test-ee10-distribution</artifactId>
|
|
||||||
<packaging>jar</packaging>
|
|
||||||
<name>Tests :: Distribution :: EE10</name>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<bundle-symbolic-name>${project.groupId}.ee10.distribution</bundle-symbolic-name>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
|
||||||
<artifactId>jetty-home</artifactId>
|
|
||||||
<type>zip</type>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>*</groupId>
|
|
||||||
<artifactId>*</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
|
||||||
<artifactId>jetty-client</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
|
||||||
<artifactId>jetty-ethereum</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
|
||||||
<artifactId>jetty-openid</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
|
||||||
<artifactId>jetty-slf4j-impl</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty.ee10</groupId>
|
|
||||||
<artifactId>jetty-ee10-servlet</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty.ee10</groupId>
|
|
||||||
<artifactId>jetty-ee10-test-openid-webapp</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
<type>war</type>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty.tests</groupId>
|
|
||||||
<artifactId>jetty-test-common</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty.tests</groupId>
|
|
||||||
<artifactId>jetty-testers</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty.tests</groupId>
|
|
||||||
<artifactId>test-distribution-common</artifactId>
|
|
||||||
<type>test-jar</type>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
</project>
|
|
|
@ -1,119 +0,0 @@
|
||||||
//
|
|
||||||
// ========================================================================
|
|
||||||
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
|
|
||||||
//
|
|
||||||
// This program and the accompanying materials are made available under the
|
|
||||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
||||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
|
||||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
|
||||||
// ========================================================================
|
|
||||||
//
|
|
||||||
|
|
||||||
package org.eclipse.jetty.ee10.tests.distribution;
|
|
||||||
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.client.ContentResponse;
|
|
||||||
import org.eclipse.jetty.http.HttpStatus;
|
|
||||||
import org.eclipse.jetty.tests.OpenIdProvider;
|
|
||||||
import org.eclipse.jetty.tests.distribution.AbstractJettyHomeTest;
|
|
||||||
import org.eclipse.jetty.tests.testers.JettyHomeTester;
|
|
||||||
import org.eclipse.jetty.tests.testers.Tester;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.junit.jupiter.api.parallel.Isolated;
|
|
||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
|
||||||
import static org.hamcrest.Matchers.containsString;
|
|
||||||
import static org.hamcrest.Matchers.is;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
|
|
||||||
@Isolated
|
|
||||||
public class OpenIdTests extends AbstractJettyHomeTest
|
|
||||||
{
|
|
||||||
@Test
|
|
||||||
public void testOpenID() throws Exception
|
|
||||||
{
|
|
||||||
Path jettyBase = newTestJettyBaseDirectory();
|
|
||||||
String jettyVersion = System.getProperty("jettyVersion");
|
|
||||||
JettyHomeTester distribution = JettyHomeTester.Builder.newInstance()
|
|
||||||
.jettyVersion(jettyVersion)
|
|
||||||
.jettyBase(jettyBase)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
String[] args1 = {
|
|
||||||
"--create-startd",
|
|
||||||
"--approve-all-licenses",
|
|
||||||
"--add-to-start=http,ee10-webapp,ee10-deploy,openid"
|
|
||||||
};
|
|
||||||
|
|
||||||
String clientId = "clientId123";
|
|
||||||
String clientSecret = "clientSecret456";
|
|
||||||
OpenIdProvider openIdProvider = new OpenIdProvider(clientId, clientSecret);
|
|
||||||
try (JettyHomeTester.Run run1 = distribution.start(args1))
|
|
||||||
{
|
|
||||||
assertTrue(run1.awaitFor(START_TIMEOUT, TimeUnit.SECONDS));
|
|
||||||
assertEquals(0, run1.getExitValue());
|
|
||||||
|
|
||||||
Path webApp = distribution.resolveArtifact("org.eclipse.jetty.ee10:jetty-ee10-test-openid-webapp:war:" + jettyVersion);
|
|
||||||
distribution.installWar(webApp, "test");
|
|
||||||
|
|
||||||
int port = Tester.freePort();
|
|
||||||
openIdProvider.addRedirectUri("http://localhost:" + port + "/test/j_security_check");
|
|
||||||
openIdProvider.start();
|
|
||||||
String[] args2 = {
|
|
||||||
"jetty.http.port=" + port,
|
|
||||||
"jetty.ssl.port=" + port,
|
|
||||||
"jetty.openid.provider=" + openIdProvider.getProvider(),
|
|
||||||
"jetty.openid.clientId=" + clientId,
|
|
||||||
"jetty.openid.clientSecret=" + clientSecret,
|
|
||||||
//"jetty.server.dumpAfterStart=true",
|
|
||||||
};
|
|
||||||
|
|
||||||
try (JettyHomeTester.Run run2 = distribution.start(args2))
|
|
||||||
{
|
|
||||||
assertTrue(run2.awaitConsoleLogsFor("Started oejs.Server@", START_TIMEOUT, TimeUnit.SECONDS));
|
|
||||||
startHttpClient(false);
|
|
||||||
String uri = "http://localhost:" + port + "/test";
|
|
||||||
openIdProvider.setUser(new OpenIdProvider.User("123456789", "Alice"));
|
|
||||||
|
|
||||||
// Initially not authenticated
|
|
||||||
ContentResponse response = client.GET(uri + "/");
|
|
||||||
assertThat(response.getStatus(), is(HttpStatus.OK_200));
|
|
||||||
String content = response.getContentAsString();
|
|
||||||
assertThat(content, containsString("not authenticated"));
|
|
||||||
|
|
||||||
// Request to login is success
|
|
||||||
response = client.GET(uri + "/login");
|
|
||||||
assertThat(response.getStatus(), is(HttpStatus.OK_200));
|
|
||||||
content = response.getContentAsString();
|
|
||||||
assertThat(content, containsString("success"));
|
|
||||||
|
|
||||||
// Now authenticated we can get info
|
|
||||||
response = client.GET(uri + "/");
|
|
||||||
assertThat(response.getStatus(), is(HttpStatus.OK_200));
|
|
||||||
content = response.getContentAsString();
|
|
||||||
assertThat(content, containsString("userId: 123456789"));
|
|
||||||
assertThat(content, containsString("name: Alice"));
|
|
||||||
assertThat(content, containsString("email: Alice@example.com"));
|
|
||||||
|
|
||||||
// Request to admin page gives 403 as we do not have admin role
|
|
||||||
response = client.GET(uri + "/admin");
|
|
||||||
assertThat(response.getStatus(), is(HttpStatus.FORBIDDEN_403));
|
|
||||||
|
|
||||||
// We are no longer authenticated after logging out
|
|
||||||
response = client.GET(uri + "/logout");
|
|
||||||
assertThat(response.getStatus(), is(HttpStatus.OK_200));
|
|
||||||
content = response.getContentAsString();
|
|
||||||
assertThat(content, containsString("not authenticated"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
openIdProvider.stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,81 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<parent>
|
|
||||||
<groupId>org.eclipse.jetty.tests</groupId>
|
|
||||||
<artifactId>test-distribution</artifactId>
|
|
||||||
<version>12.1.0-SNAPSHOT</version>
|
|
||||||
</parent>
|
|
||||||
<artifactId>test-ee11-distribution</artifactId>
|
|
||||||
<packaging>jar</packaging>
|
|
||||||
<name>Tests :: Distribution :: EE11</name>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<bundle-symbolic-name>${project.groupId}.ee11.distribution</bundle-symbolic-name>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
|
||||||
<artifactId>jetty-home</artifactId>
|
|
||||||
<type>zip</type>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>*</groupId>
|
|
||||||
<artifactId>*</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
|
||||||
<artifactId>jetty-client</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
|
||||||
<artifactId>jetty-openid</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
|
||||||
<artifactId>jetty-slf4j-impl</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty.ee11</groupId>
|
|
||||||
<artifactId>jetty-ee11-servlet</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty.ee11</groupId>
|
|
||||||
<artifactId>jetty-ee11-test-openid-webapp</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
<type>war</type>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty.tests</groupId>
|
|
||||||
<artifactId>jetty-test-common</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty.tests</groupId>
|
|
||||||
<artifactId>jetty-testers</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty.tests</groupId>
|
|
||||||
<artifactId>test-distribution-common</artifactId>
|
|
||||||
<type>test-jar</type>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty.tests</groupId>
|
|
||||||
<artifactId>test-distribution-common</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
</project>
|
|
|
@ -1,143 +0,0 @@
|
||||||
//
|
|
||||||
// ========================================================================
|
|
||||||
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
|
|
||||||
//
|
|
||||||
// This program and the accompanying materials are made available under the
|
|
||||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
||||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
|
||||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
|
||||||
// ========================================================================
|
|
||||||
//
|
|
||||||
|
|
||||||
package org.eclipse.jetty.ee11.tests.distribution;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.attribute.FileTime;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.client.ContentResponse;
|
|
||||||
import org.eclipse.jetty.http.HttpStatus;
|
|
||||||
import org.eclipse.jetty.tests.distribution.AbstractJettyHomeTest;
|
|
||||||
import org.eclipse.jetty.tests.testers.JettyHomeTester;
|
|
||||||
import org.eclipse.jetty.tests.testers.Tester;
|
|
||||||
import org.eclipse.jetty.toolchain.test.FS;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.junit.jupiter.api.parallel.Isolated;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
|
||||||
import static org.hamcrest.Matchers.containsString;
|
|
||||||
import static org.hamcrest.Matchers.is;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
|
|
||||||
@Isolated
|
|
||||||
public class DisableUrlCacheTest extends AbstractJettyHomeTest
|
|
||||||
{
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(DisableUrlCacheTest.class);
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testReloadWebAppWithLog4j2() throws Exception
|
|
||||||
{
|
|
||||||
Path jettyBase = newTestJettyBaseDirectory();
|
|
||||||
String jettyVersion = System.getProperty("jettyVersion");
|
|
||||||
JettyHomeTester distribution = JettyHomeTester.Builder.newInstance()
|
|
||||||
.jettyVersion(jettyVersion)
|
|
||||||
.jettyBase(jettyBase)
|
|
||||||
.jvmArgs(List.of("-Dorg.eclipse.jetty.deploy.LEVEL=DEBUG"))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
String[] setupArgs = {
|
|
||||||
"--add-modules=http,ee11-webapp,ee11-deploy,disable-urlcache"
|
|
||||||
};
|
|
||||||
|
|
||||||
try (JettyHomeTester.Run setupRun = distribution.start(setupArgs))
|
|
||||||
{
|
|
||||||
assertTrue(setupRun.awaitFor(START_TIMEOUT, TimeUnit.SECONDS));
|
|
||||||
assertEquals(0, setupRun.getExitValue());
|
|
||||||
|
|
||||||
Path webApp = distribution.resolveArtifact("org.eclipse.jetty.ee11:jetty-ee11-test-log4j2-webapp:war:" + jettyVersion);
|
|
||||||
Path testWebApp = distribution.getJettyBase().resolve("webapps/test.war");
|
|
||||||
|
|
||||||
Files.copy(webApp, testWebApp);
|
|
||||||
|
|
||||||
Path tempDir = distribution.getJettyBase().resolve("work");
|
|
||||||
FS.ensureEmpty(tempDir);
|
|
||||||
|
|
||||||
Path resourcesDir = distribution.getJettyBase().resolve("resources");
|
|
||||||
FS.ensureEmpty(resourcesDir);
|
|
||||||
|
|
||||||
Path webappsDir = distribution.getJettyBase().resolve("webapps");
|
|
||||||
String warXml = """
|
|
||||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
|
||||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
|
|
||||||
<Configure class="org.eclipse.jetty.ee11.webapp.WebAppContext">
|
|
||||||
<Set name="contextPath">/test</Set>
|
|
||||||
<Set name="war"><Property name="jetty.webapps"/>/test.war</Set>
|
|
||||||
<Set name="tempDirectory"><Property name="jetty.base"/>/work/test</Set>
|
|
||||||
<Set name="tempDirectoryPersistent">false</Set>
|
|
||||||
</Configure>
|
|
||||||
""";
|
|
||||||
Path warXmlPath = webappsDir.resolve("test.xml");
|
|
||||||
Files.writeString(warXmlPath, warXml, StandardCharsets.UTF_8);
|
|
||||||
|
|
||||||
Path loggingFile = resourcesDir.resolve("jetty-logging.properties");
|
|
||||||
String loggingConfig = """
|
|
||||||
org.eclipse.jetty.LEVEL=INFO
|
|
||||||
org.eclipse.jetty.deploy.LEVEL=DEBUG
|
|
||||||
org.eclipse.jetty.ee11.webapp.LEVEL=DEBUG
|
|
||||||
org.eclipse.jetty.ee11.webapp.WebAppClassLoader.LEVEL=INFO
|
|
||||||
org.eclipse.jetty.ee11.servlet.LEVEL=DEBUG
|
|
||||||
""";
|
|
||||||
Files.writeString(loggingFile, loggingConfig, StandardCharsets.UTF_8);
|
|
||||||
|
|
||||||
|
|
||||||
int port = Tester.freePort();
|
|
||||||
String[] runArgs = {
|
|
||||||
"jetty.http.port=" + port,
|
|
||||||
"jetty.deploy.scanInterval=1"
|
|
||||||
//"jetty.server.dumpAfterStart=true",
|
|
||||||
};
|
|
||||||
try (JettyHomeTester.Run run2 = distribution.start(runArgs))
|
|
||||||
{
|
|
||||||
assertTrue(run2.awaitConsoleLogsFor("Started oejs.Server@", START_TIMEOUT, TimeUnit.SECONDS));
|
|
||||||
startHttpClient(false);
|
|
||||||
|
|
||||||
// Test webapp is there
|
|
||||||
ContentResponse response = client.GET("http://localhost:" + port + "/test/log/");
|
|
||||||
assertThat(response.getStatus(), is(HttpStatus.OK_200));
|
|
||||||
String content = response.getContentAsString();
|
|
||||||
assertThat(content, containsString("GET at LogServlet"));
|
|
||||||
|
|
||||||
// Trigger a hot-reload
|
|
||||||
run2.getLogs().clear();
|
|
||||||
touch(warXmlPath);
|
|
||||||
|
|
||||||
// Wait for reload to start context
|
|
||||||
assertTrue(run2.awaitConsoleLogsFor("Started oeje11w.WebAppContext@", START_TIMEOUT, TimeUnit.SECONDS));
|
|
||||||
// wait for deployer node to complete so context is Started not Starting
|
|
||||||
assertTrue(run2.awaitConsoleLogsFor("Executing Node Node[started]", START_TIMEOUT, TimeUnit.SECONDS));
|
|
||||||
|
|
||||||
// Is webapp still there?
|
|
||||||
response = client.GET("http://localhost:" + port + "/test/log/");
|
|
||||||
content = response.getContentAsString();
|
|
||||||
assertThat(content, response.getStatus(), is(HttpStatus.OK_200));
|
|
||||||
assertThat(content, containsString("GET at LogServlet"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void touch(Path path) throws IOException
|
|
||||||
{
|
|
||||||
LOG.info("Touch: {}", path);
|
|
||||||
FileTime now = FileTime.fromMillis(System.currentTimeMillis() + 2000);
|
|
||||||
Files.setLastModifiedTime(path, now);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,119 +0,0 @@
|
||||||
//
|
|
||||||
// ========================================================================
|
|
||||||
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
|
|
||||||
//
|
|
||||||
// This program and the accompanying materials are made available under the
|
|
||||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
||||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
|
||||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
|
||||||
// ========================================================================
|
|
||||||
//
|
|
||||||
|
|
||||||
package org.eclipse.jetty.ee11.tests.distribution;
|
|
||||||
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.client.ContentResponse;
|
|
||||||
import org.eclipse.jetty.http.HttpStatus;
|
|
||||||
import org.eclipse.jetty.tests.OpenIdProvider;
|
|
||||||
import org.eclipse.jetty.tests.distribution.AbstractJettyHomeTest;
|
|
||||||
import org.eclipse.jetty.tests.testers.JettyHomeTester;
|
|
||||||
import org.eclipse.jetty.tests.testers.Tester;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.junit.jupiter.api.parallel.Isolated;
|
|
||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
|
||||||
import static org.hamcrest.Matchers.containsString;
|
|
||||||
import static org.hamcrest.Matchers.is;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
|
|
||||||
@Isolated
|
|
||||||
public class OpenIdTests extends AbstractJettyHomeTest
|
|
||||||
{
|
|
||||||
@Test
|
|
||||||
public void testOpenID() throws Exception
|
|
||||||
{
|
|
||||||
Path jettyBase = newTestJettyBaseDirectory();
|
|
||||||
String jettyVersion = System.getProperty("jettyVersion");
|
|
||||||
JettyHomeTester distribution = JettyHomeTester.Builder.newInstance()
|
|
||||||
.jettyVersion(jettyVersion)
|
|
||||||
.jettyBase(jettyBase)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
String[] args1 = {
|
|
||||||
"--create-startd",
|
|
||||||
"--approve-all-licenses",
|
|
||||||
"--add-to-start=http,ee11-webapp,ee11-deploy,openid"
|
|
||||||
};
|
|
||||||
|
|
||||||
String clientId = "clientId123";
|
|
||||||
String clientSecret = "clientSecret456";
|
|
||||||
OpenIdProvider openIdProvider = new OpenIdProvider(clientId, clientSecret);
|
|
||||||
try (JettyHomeTester.Run run1 = distribution.start(args1))
|
|
||||||
{
|
|
||||||
assertTrue(run1.awaitFor(START_TIMEOUT, TimeUnit.SECONDS));
|
|
||||||
assertEquals(0, run1.getExitValue());
|
|
||||||
|
|
||||||
Path webApp = distribution.resolveArtifact("org.eclipse.jetty.ee11:jetty-ee11-test-openid-webapp:war:" + jettyVersion);
|
|
||||||
distribution.installWar(webApp, "test");
|
|
||||||
|
|
||||||
int port = Tester.freePort();
|
|
||||||
openIdProvider.addRedirectUri("http://localhost:" + port + "/test/j_security_check");
|
|
||||||
openIdProvider.start();
|
|
||||||
String[] args2 = {
|
|
||||||
"jetty.http.port=" + port,
|
|
||||||
"jetty.ssl.port=" + port,
|
|
||||||
"jetty.openid.provider=" + openIdProvider.getProvider(),
|
|
||||||
"jetty.openid.clientId=" + clientId,
|
|
||||||
"jetty.openid.clientSecret=" + clientSecret,
|
|
||||||
//"jetty.server.dumpAfterStart=true",
|
|
||||||
};
|
|
||||||
|
|
||||||
try (JettyHomeTester.Run run2 = distribution.start(args2))
|
|
||||||
{
|
|
||||||
assertTrue(run2.awaitConsoleLogsFor("Started oejs.Server@", START_TIMEOUT, TimeUnit.SECONDS));
|
|
||||||
startHttpClient(false);
|
|
||||||
String uri = "http://localhost:" + port + "/test";
|
|
||||||
openIdProvider.setUser(new OpenIdProvider.User("123456789", "Alice"));
|
|
||||||
|
|
||||||
// Initially not authenticated
|
|
||||||
ContentResponse response = client.GET(uri + "/");
|
|
||||||
assertThat(response.getStatus(), is(HttpStatus.OK_200));
|
|
||||||
String content = response.getContentAsString();
|
|
||||||
assertThat(content, containsString("not authenticated"));
|
|
||||||
|
|
||||||
// Request to login is success
|
|
||||||
response = client.GET(uri + "/login");
|
|
||||||
assertThat(response.getStatus(), is(HttpStatus.OK_200));
|
|
||||||
content = response.getContentAsString();
|
|
||||||
assertThat(content, containsString("success"));
|
|
||||||
|
|
||||||
// Now authenticated we can get info
|
|
||||||
response = client.GET(uri + "/");
|
|
||||||
assertThat(response.getStatus(), is(HttpStatus.OK_200));
|
|
||||||
content = response.getContentAsString();
|
|
||||||
assertThat(content, containsString("userId: 123456789"));
|
|
||||||
assertThat(content, containsString("name: Alice"));
|
|
||||||
assertThat(content, containsString("email: Alice@example.com"));
|
|
||||||
|
|
||||||
// Request to admin page gives 403 as we do not have admin role
|
|
||||||
response = client.GET(uri + "/admin");
|
|
||||||
assertThat(response.getStatus(), is(HttpStatus.FORBIDDEN_403));
|
|
||||||
|
|
||||||
// We are no longer authenticated after logging out
|
|
||||||
response = client.GET(uri + "/logout");
|
|
||||||
assertThat(response.getStatus(), is(HttpStatus.OK_200));
|
|
||||||
content = response.getContentAsString();
|
|
||||||
assertThat(content, containsString("not authenticated"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
openIdProvider.stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,77 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<parent>
|
|
||||||
<groupId>org.eclipse.jetty.tests</groupId>
|
|
||||||
<artifactId>test-distribution</artifactId>
|
|
||||||
<version>12.1.0-SNAPSHOT</version>
|
|
||||||
</parent>
|
|
||||||
<artifactId>test-ee9-distribution</artifactId>
|
|
||||||
<packaging>jar</packaging>
|
|
||||||
<name>Tests :: Distribution :: EE9</name>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<bundle-symbolic-name>${project.groupId}.ee9.distribution</bundle-symbolic-name>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
|
||||||
<artifactId>jetty-home</artifactId>
|
|
||||||
<type>zip</type>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>*</groupId>
|
|
||||||
<artifactId>*</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
|
||||||
<artifactId>jetty-client</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
|
||||||
<artifactId>jetty-slf4j-impl</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty.ee9</groupId>
|
|
||||||
<artifactId>jetty-ee9-openid</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty.ee9</groupId>
|
|
||||||
<artifactId>jetty-ee9-servlet</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty.ee9</groupId>
|
|
||||||
<artifactId>jetty-ee9-test-openid-webapp</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
<type>war</type>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty.tests</groupId>
|
|
||||||
<artifactId>jetty-test-common</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty.tests</groupId>
|
|
||||||
<artifactId>jetty-testers</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty.tests</groupId>
|
|
||||||
<artifactId>test-distribution-common</artifactId>
|
|
||||||
<type>test-jar</type>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
</project>
|
|
|
@ -1,120 +0,0 @@
|
||||||
//
|
|
||||||
// ========================================================================
|
|
||||||
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
|
|
||||||
//
|
|
||||||
// This program and the accompanying materials are made available under the
|
|
||||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
||||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
|
||||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
|
||||||
// ========================================================================
|
|
||||||
//
|
|
||||||
|
|
||||||
package org.eclipse.jetty.ee9.tests.distribution;
|
|
||||||
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.client.ContentResponse;
|
|
||||||
import org.eclipse.jetty.http.HttpStatus;
|
|
||||||
import org.eclipse.jetty.tests.OpenIdProvider;
|
|
||||||
import org.eclipse.jetty.tests.distribution.AbstractJettyHomeTest;
|
|
||||||
import org.eclipse.jetty.tests.testers.JettyHomeTester;
|
|
||||||
import org.eclipse.jetty.tests.testers.Tester;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.junit.jupiter.api.parallel.Isolated;
|
|
||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
|
||||||
import static org.hamcrest.Matchers.containsString;
|
|
||||||
import static org.hamcrest.Matchers.is;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
|
|
||||||
@Isolated
|
|
||||||
public class OpenIdTests extends AbstractJettyHomeTest
|
|
||||||
{
|
|
||||||
@Test
|
|
||||||
public void testOpenID() throws Exception
|
|
||||||
{
|
|
||||||
Path jettyBase = newTestJettyBaseDirectory();
|
|
||||||
String jettyVersion = System.getProperty("jettyVersion");
|
|
||||||
JettyHomeTester distribution = JettyHomeTester.Builder.newInstance()
|
|
||||||
.jettyVersion(jettyVersion)
|
|
||||||
.jettyBase(jettyBase)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
String[] args1 = {
|
|
||||||
"--create-startd",
|
|
||||||
"--approve-all-licenses",
|
|
||||||
"--add-to-start=http,ee9-webapp,ee9-deploy,ee9-openid"
|
|
||||||
};
|
|
||||||
|
|
||||||
String clientId = "clientId123";
|
|
||||||
String clientSecret = "clientSecret456";
|
|
||||||
OpenIdProvider openIdProvider = new OpenIdProvider(clientId, clientSecret);
|
|
||||||
try (JettyHomeTester.Run run1 = distribution.start(args1))
|
|
||||||
{
|
|
||||||
assertTrue(run1.awaitFor(START_TIMEOUT, TimeUnit.SECONDS));
|
|
||||||
assertEquals(0, run1.getExitValue());
|
|
||||||
|
|
||||||
Path webApp = distribution.resolveArtifact("org.eclipse.jetty.ee9:jetty-ee9-test-openid-webapp:war:" + jettyVersion);
|
|
||||||
distribution.installWar(webApp, "test");
|
|
||||||
|
|
||||||
int port = Tester.freePort();
|
|
||||||
openIdProvider.addRedirectUri("http://localhost:" + port + "/test/j_security_check");
|
|
||||||
openIdProvider.start();
|
|
||||||
String[] args2 = {
|
|
||||||
"jetty.http.port=" + port,
|
|
||||||
"jetty.ssl.port=" + port,
|
|
||||||
"jetty.openid.provider=" + openIdProvider.getProvider(),
|
|
||||||
"jetty.openid.clientId=" + clientId,
|
|
||||||
"jetty.openid.clientSecret=" + clientSecret,
|
|
||||||
//"jetty.server.dumpAfterStart=true",
|
|
||||||
};
|
|
||||||
|
|
||||||
try (JettyHomeTester.Run run2 = distribution.start(args2))
|
|
||||||
{
|
|
||||||
assertTrue(run2.awaitConsoleLogsFor("Started oejs.Server@", START_TIMEOUT, TimeUnit.SECONDS));
|
|
||||||
startHttpClient(false);
|
|
||||||
String uri = "http://localhost:" + port + "/test";
|
|
||||||
openIdProvider.setUser(new OpenIdProvider.User("123456789", "Alice"));
|
|
||||||
|
|
||||||
// Initially not authenticated
|
|
||||||
ContentResponse response = client.GET(uri + "/");
|
|
||||||
assertThat(response.getStatus(), is(HttpStatus.OK_200));
|
|
||||||
String content = response.getContentAsString();
|
|
||||||
assertThat(content, containsString("not authenticated"));
|
|
||||||
|
|
||||||
// Request to login is success
|
|
||||||
response = client.GET(uri + "/login");
|
|
||||||
assertThat(response.getStatus(), is(HttpStatus.OK_200));
|
|
||||||
content = response.getContentAsString();
|
|
||||||
assertThat(content, containsString("success"));
|
|
||||||
|
|
||||||
// Now authenticated we can get info
|
|
||||||
response = client.GET(uri + "/");
|
|
||||||
assertThat(response.getStatus(), is(HttpStatus.OK_200));
|
|
||||||
content = response.getContentAsString();
|
|
||||||
assertThat(content, containsString("userId: 123456789"));
|
|
||||||
assertThat(content, containsString("name: Alice"));
|
|
||||||
assertThat(content, containsString("email: Alice@example.com"));
|
|
||||||
|
|
||||||
// Request to admin page gives 403 as we do not have admin role
|
|
||||||
response = client.GET(uri + "/admin");
|
|
||||||
assertThat(response.getStatus(), is(HttpStatus.FORBIDDEN_403));
|
|
||||||
|
|
||||||
// We are no longer authenticated after logging out
|
|
||||||
response = client.GET(uri + "/logout");
|
|
||||||
assertThat(response.getStatus(), is(HttpStatus.OK_200));
|
|
||||||
content = response.getContentAsString();
|
|
||||||
assertThat(content, containsString("not authenticated"));
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
openIdProvider.stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue