Compare commits

...

2 Commits

Author SHA1 Message Date
10537ea96b forgot a sh*tload of configuration
All checks were successful
continuous-integration/drone/push Build is passing
2024-12-23 14:41:21 +01:00
b9251e3ab4 unused code
something went wrong during reorga of project structure
2024-12-23 14:40:56 +01:00
13 changed files with 158 additions and 284 deletions

View File

@ -1,26 +0,0 @@
package de.devloop.mavor;
import java.io.IOException;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
public class AuthenticatedServlet extends HttpServlet {
protected Session session;
@Override
protected final void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
session = new Session(req.getSession(true));
if (!session.isAuthenticated()) {
resp.sendRedirect("/mavor/authenticate");
} else {
doAuthenticatedGet(req, resp);
}
}
protected void doAuthenticatedGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// nooooothing
}
}

View File

@ -1,57 +0,0 @@
package de.devloop.mavor;
import jakarta.servlet.http.HttpSession;
public class Session {
private HttpSession session;
private static final String ATTRIBUTE_USERNAME = "username";
private static final String ATTRIBUTE_OAUTH_STATE = "oauth.state";
private static final String ATTRIBUTE_OAUTH_TOKEN = "oauth.token";
public Session(HttpSession session) {
this.session = session;
}
private String getSafeString(String parameter) {
Object value = session.getAttribute(parameter);
if (value != null) {
return value.toString();
} else {
return null;
}
}
public Boolean isAuthenticated() {
return getUsername() != null;
}
public String getUsername() {
return getSafeString(ATTRIBUTE_USERNAME);
}
public void setUsername(String username) {
session.setAttribute(ATTRIBUTE_USERNAME, username);
}
public void setOAuthState(String state) {
session.setAttribute(ATTRIBUTE_OAUTH_STATE, state);
}
public String getOAuthState() {
return getSafeString(ATTRIBUTE_OAUTH_STATE);
}
public void clearOAuthState() {
session.removeAttribute(ATTRIBUTE_OAUTH_STATE);
}
public void setOAuthToken(String token) {
session.setAttribute(ATTRIBUTE_OAUTH_TOKEN, token);
}
public String getOAuthToken() {
return getSafeString(ATTRIBUTE_OAUTH_TOKEN);
}
}

View File

@ -1,22 +0,0 @@
package de.devloop.mavor.servlet;
import java.io.IOException;
import de.devloop.mavor.AuthenticatedServlet;
import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@WebServlet("")
public class Main extends AuthenticatedServlet {
@Override
protected void doAuthenticatedGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setAttribute("username", session.getUsername());
RequestDispatcher view = req.getRequestDispatcher("/main.jsp");
view.forward(req, resp);
}
}

View File

@ -1,19 +0,0 @@
package de.devloop.openid;
public class AuthenticationUrl {
private String url;
private String state;
public AuthenticationUrl(String url, String state) {
this.url = url;
this.state = state;
}
public String getUrl() {
return url;
}
public String getState() {
return state;
}
}

View File

@ -1,102 +0,0 @@
package de.devloop.openid;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpRequest.BodyPublishers;
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandlers;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import com.google.gson.Gson;
public class OpenID {
private static final String CLIENT_ID = "vP9xF2s1yy2n6sR05jV6dguyMeOvIxCg1GarV71O";
private static final String CLIENT_SECRET = "PrwGSMcucxYPkOdrb23jddWqyn31vphrxCUu9MGdLTCUnbk0OJI5oWCvO0khVhcnJNDbJaKWxNMxaC4bJ92jy8bDjtG6oaWG37qhuLRPMh5DKluZxsCMmCvQ8f9ZQckZ";
private static final String REDIRECT_URL = "http://localhost:8080/mavor/authenticate";
private static final String OAUTH_AUTH_URL = "https://auth.devloop.de/application/o/authorize/";
private static final String OAUTH_TOKEN_URL = "https://auth.devloop.de/application/o/token/";
private static final String OAUTH_USERINFO_URL = "https://auth.devloop.de/application/o/userinfo/";
public AuthenticationUrl getAuthenticationUrl() {
String state = UUID.randomUUID().toString();
String url = String.format("%s?response_type=code&client_id=%s&redirect_uri=%s&state=%s&scope=openid email", OAUTH_AUTH_URL, CLIENT_ID, REDIRECT_URL, state);
return new AuthenticationUrl(url, state);
}
private URI getUriObject(String url) throws OpenIdRequestException {
try {
return new URI(url);
} catch (URISyntaxException e) {
throw new OpenIdRequestException(String.format("Invalid URL: '%s'", url), e);
}
}
public Token requestToken(String code) throws OpenIdRequestException {
URI tokenUrl = getUriObject(OAUTH_TOKEN_URL);
HashMap<String, String> tokenParameter = new HashMap<>();
tokenParameter.put("grant_type", "authorization_code");
tokenParameter.put("client_id", CLIENT_ID);
tokenParameter.put("client_secret", CLIENT_SECRET);
tokenParameter.put("code", code);
tokenParameter.put("redirect_uri", REDIRECT_URL);
HttpRequest tokenRequest = HttpRequest.newBuilder()
.uri(tokenUrl)
.header("Content-Type", "application/x-www-form-urlencoded")
.header("Accept", "application/json")
.POST(BodyPublishers.ofString(getFormDataAsString(tokenParameter)))
.build();
HttpClient tokenClient = HttpClient.newHttpClient();
HttpResponse<String> tokenResponse;
try {
tokenResponse = tokenClient.send(tokenRequest, BodyHandlers.ofString());
} catch (IOException | InterruptedException e) {
throw new OpenIdRequestException("Requesting access token failed", e);
}
Gson gson = new Gson();
return gson.fromJson(tokenResponse.body(), Token.class);
}
public UserInfo requestUserInfo(Token token) throws OpenIdRequestException {
URI userInfoUrl = getUriObject(OAUTH_USERINFO_URL);
HttpRequest userInfoRequest = HttpRequest.newBuilder()
.uri(userInfoUrl)
.header("Accept", "application/json")
.header("Authorization", "Bearer " + token.getAccessToken())
.GET()
.build();
HttpClient userInfoClient = HttpClient.newHttpClient();
HttpResponse<String> userInfoResponse;
try {
userInfoResponse = userInfoClient.send(userInfoRequest, BodyHandlers.ofString());
} catch (IOException | InterruptedException e) {
throw new OpenIdRequestException("Requesting user info failed", e);
}
Gson gson = new Gson();
return gson.fromJson(userInfoResponse.body(), UserInfo.class);
}
private String getFormDataAsString(Map<String, String> formData) {
StringBuilder formBodyBuilder = new StringBuilder();
for (Map.Entry<String, String> singleEntry : formData.entrySet()) {
if (formBodyBuilder.length() > 0) {
formBodyBuilder.append("&");
}
formBodyBuilder.append(URLEncoder.encode(singleEntry.getKey(), StandardCharsets.UTF_8));
formBodyBuilder.append("=");
formBodyBuilder.append(URLEncoder.encode(singleEntry.getValue(), StandardCharsets.UTF_8));
}
return formBodyBuilder.toString();
}
}

View File

@ -1,7 +0,0 @@
package de.devloop.openid;
public class OpenIdRequestException extends Exception {
public OpenIdRequestException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@ -1,18 +0,0 @@
package de.devloop.openid;
import com.google.gson.annotations.SerializedName;
public class Token {
@SerializedName("access_token")
private String accessToken;
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
}

View File

@ -1,15 +0,0 @@
package de.devloop.openid;
public class UserInfo {
private String email;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}

View File

@ -12,8 +12,21 @@ public class Configuration {
private static final String ENV_MAVEN_EXECUTABLE = "MAVOR_MAVEN_EXECUTABLE";
private static final String ENV_TEMP_DIR = "MAVOR_TEMP_DIR";
private static final String ENV_OPENID_CLIENT_ID = "MAVOR_OPENID_CLIENT_ID";
private static final String ENV_OPENID_CLIENT_SECRET = "MAVOR_OPENID_CLIENT_SECRET";
private static final String ENV_OPENID_REDIRECT_URL = "MAVOR_OPENID_REDIRECT_URL";
private static final String ENV_OPENID_AUTH_URL = "MAVOR_OPENID_AUTH_URL";
private static final String ENV_OPENID_TOKEN_URL = "MAVOR_OPENID_TOKEN_URL";
private static final String ENV_OPENID_USERINFO_URL = "MAVOR_OPENID_USERINFO_URL";
private String mavenExecutable;
private String tempDir;
private String openIdClientId;
private String openIdClientSecret;
private String openIdRedirectUrl;
private String openIdAuthUrl;
private String openIdTokenUrl;
private String openIdUserInfoUrl;
public Configuration() throws IOException {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
@ -28,8 +41,18 @@ public class Configuration {
}
private void initByProperties(Properties properties) {
mavenExecutable = properties.getProperty(ENV_MAVEN_EXECUTABLE);
tempDir = properties.getProperty(ENV_TEMP_DIR);
mavenExecutable = getNullSafeProperty(properties, ENV_MAVEN_EXECUTABLE);
tempDir = getNullSafeProperty(properties, ENV_TEMP_DIR);
openIdClientId = getNullSafeProperty(properties, ENV_OPENID_CLIENT_ID);
openIdClientSecret = getNullSafeProperty(properties, ENV_OPENID_CLIENT_SECRET);
openIdRedirectUrl = getNullSafeProperty((properties), ENV_OPENID_REDIRECT_URL);
openIdAuthUrl = getNullSafeProperty(properties, ENV_OPENID_AUTH_URL);
openIdTokenUrl = getNullSafeProperty(properties, ENV_OPENID_TOKEN_URL);
openIdUserInfoUrl = getNullSafeProperty(properties, ENV_OPENID_USERINFO_URL);
}
private String getNullSafeProperty(Properties properties, String key) {
return Objects.requireNonNull(properties.getProperty(key));
}
public String getMavenExecutable() {
@ -39,4 +62,28 @@ public class Configuration {
public String getTempDir() {
return tempDir;
}
public String getOpenIdClientId() {
return openIdClientId;
}
public String getOpenIdClientSecret() {
return openIdClientSecret;
}
public String getOpenIdRedirectUrl() {
return openIdRedirectUrl;
}
public String getOpenIdAuthUrl() {
return openIdAuthUrl;
}
public String getOpenIdTokenUrl() {
return openIdTokenUrl;
}
public String getOpenIdUserInfoUrl() {
return openIdUserInfoUrl;
}
}

View File

@ -2,9 +2,11 @@ package de.devloop.mavor.servlet;
import java.io.IOException;
import de.devloop.mavor.Configuration;
import de.devloop.mavor.Session;
import de.devloop.openid.AuthenticationUrl;
import de.devloop.openid.OpenID;
import de.devloop.openid.OpenIdConfiguration;
import de.devloop.openid.OpenIdRequestException;
import de.devloop.openid.Token;
import de.devloop.openid.UserInfo;
@ -20,12 +22,32 @@ public class Authentication extends HttpServlet {
private static final String PARAMETER_STATE = "state";
private static final String PARAMETER_CODE = "code";
private OpenIdConfiguration openIdConfiguration;
private OpenID openID;
@Override
public void init() throws ServletException {
Configuration configuration;
try {
configuration = new Configuration();
} catch (IOException e) {
throw new ServletException("Configuration Error", e);
}
openIdConfiguration = new OpenIdConfiguration();
openIdConfiguration.setAuthUrl(configuration.getOpenIdAuthUrl());
openIdConfiguration.setClientId(configuration.getOpenIdClientId());
openIdConfiguration.setClientSecret(configuration.getOpenIdClientSecret());
openIdConfiguration.setRedirectUrl(configuration.getOpenIdRedirectUrl());
openIdConfiguration.setTokenUrl(configuration.getOpenIdTokenUrl());
openIdConfiguration.setUserInfoUrl(configuration.getOpenIdUserInfoUrl());
openID = new OpenID(openIdConfiguration);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Session session = new Session(req.getSession(true));
OpenID openID = new OpenID();
if (req.getParameter(PARAMETER_STATE) != null && req.getParameter(PARAMETER_CODE) != null) {
if (req.getParameter(PARAMETER_STATE).equals(session.getOAuthState())) {
session.clearOAuthState();

View File

@ -1,6 +1,7 @@
package de.devloop.openid;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
@ -17,19 +18,23 @@ import java.util.UUID;
import com.google.gson.Gson;
public class OpenID {
private static final String CLIENT_ID = "vP9xF2s1yy2n6sR05jV6dguyMeOvIxCg1GarV71O";
private static final String CLIENT_SECRET = "PrwGSMcucxYPkOdrb23jddWqyn31vphrxCUu9MGdLTCUnbk0OJI5oWCvO0khVhcnJNDbJaKWxNMxaC4bJ92jy8bDjtG6oaWG37qhuLRPMh5DKluZxsCMmCvQ8f9ZQckZ";
private static final String REDIRECT_URL = "http://localhost:8080/mavor/authenticate";
private final OpenIdConfiguration configuration;
private static final String OAUTH_AUTH_URL = "https://auth.devloop.de/application/o/authorize/";
private static final String OAUTH_TOKEN_URL = "https://auth.devloop.de/application/o/token/";
private static final String OAUTH_USERINFO_URL = "https://auth.devloop.de/application/o/userinfo/";
public OpenID(OpenIdConfiguration configuration) {
this.configuration = configuration;
}
public AuthenticationUrl getAuthenticationUrl() {
String state = UUID.randomUUID().toString();
String url = String.format("%s?response_type=code&client_id=%s&redirect_uri=%s&state=%s&scope=openid email", OAUTH_AUTH_URL, CLIENT_ID, REDIRECT_URL, state);
return new AuthenticationUrl(url, state);
StringBuilder url = new StringBuilder();
url.append(configuration.getAuthUrl());
url.append("?response_type=code");
url.append("&client_id=" + configuration.getClientId());
url.append("&redirect_uri=" + configuration.getRedirectUrl());
url.append("&state=" + state);
return new AuthenticationUrl(url.toString(), state);
}
private URI getUriObject(String url) throws OpenIdRequestException {
@ -41,13 +46,13 @@ public class OpenID {
}
public Token requestToken(String code) throws OpenIdRequestException {
URI tokenUrl = getUriObject(OAUTH_TOKEN_URL);
URI tokenUrl = getUriObject(configuration.getTokenUrl());
HashMap<String, String> tokenParameter = new HashMap<>();
tokenParameter.put("grant_type", "authorization_code");
tokenParameter.put("client_id", CLIENT_ID);
tokenParameter.put("client_secret", CLIENT_SECRET);
tokenParameter.put("client_id", configuration.getClientId());
tokenParameter.put("client_secret", configuration.getClientSecret());
tokenParameter.put("code", code);
tokenParameter.put("redirect_uri", REDIRECT_URL);
tokenParameter.put("redirect_uri", configuration.getRedirectUrl());
HttpRequest tokenRequest = HttpRequest.newBuilder()
.uri(tokenUrl)
@ -68,7 +73,7 @@ public class OpenID {
}
public UserInfo requestUserInfo(Token token) throws OpenIdRequestException {
URI userInfoUrl = getUriObject(OAUTH_USERINFO_URL);
URI userInfoUrl = getUriObject(configuration.getUserInfoUrl());
HttpRequest userInfoRequest = HttpRequest.newBuilder()
.uri(userInfoUrl)
.header("Accept", "application/json")
@ -83,6 +88,10 @@ public class OpenID {
throw new OpenIdRequestException("Requesting user info failed", e);
}
if (userInfoResponse.statusCode() != HttpURLConnection.HTTP_OK) {
throw new OpenIdRequestException(String.format("Requesting user info failed with HTTP code '%d'", userInfoResponse.statusCode()));
}
Gson gson = new Gson();
return gson.fromJson(userInfoResponse.body(), UserInfo.class);
}

View File

@ -0,0 +1,58 @@
package de.devloop.openid;
public class OpenIdConfiguration {
private String clientId;
private String clientSecret;
private String redirectUrl;
private String authUrl;
private String tokenUrl;
private String userInfoUrl;
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getClientSecret() {
return clientSecret;
}
public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
}
public String getRedirectUrl() {
return redirectUrl;
}
public void setRedirectUrl(String redirectUrl) {
this.redirectUrl = redirectUrl;
}
public String getAuthUrl() {
return authUrl;
}
public void setAuthUrl(String authUrl) {
this.authUrl = authUrl;
}
public String getTokenUrl() {
return tokenUrl;
}
public void setTokenUrl(String tokenUrl) {
this.tokenUrl = tokenUrl;
}
public String getUserInfoUrl() {
return userInfoUrl;
}
public void setUserInfoUrl(String userInfoUrl) {
this.userInfoUrl = userInfoUrl;
}
}

View File

@ -1,6 +1,10 @@
package de.devloop.openid;
public class OpenIdRequestException extends Exception {
public OpenIdRequestException(String message) {
super(message);
}
public OpenIdRequestException(String message, Throwable cause) {
super(message, cause);
}