From 9ab4a6e303c0e8a4997252b4c6a8b2dd601d73af Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 5 Apr 2023 17:40:11 +0100 Subject: Implement OpenID auto discovery --- src/main/java/org/traccar/config/Keys.java | 15 ++++++-- .../java/org/traccar/database/OpenIdProvider.java | 44 ++++++++++++++++++++-- 2 files changed, 53 insertions(+), 6 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 3ff423ad1..3ed6c6026 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -636,11 +636,20 @@ public final class Keys { "openid.clientSecret", List.of(KeyType.CONFIG)); + /** + * OpenID Connect Issuer (Base) URL. + * This is used to automatically configure the authorization, token and user info URLs if + * they are not provided. + */ + public static final ConfigKey OPENID_ISSUERURL = new StringConfigKey( + "openid.issuerUrl", + List.of(KeyType.CONFIG)); + /** * OpenID Connect Authorization URL. * This can usually be found in the documentation of your identity provider or by using the well-known * configuration endpoint, eg. https://auth.example.com//.well-known/openid-configuration - * Required to enable SSO. + * Required to enable SSO if openid.issuerUrl is not set. */ public static final ConfigKey OPENID_AUTHURL = new StringConfigKey( "openid.authUrl", @@ -648,7 +657,7 @@ public final class Keys { /** * OpenID Connect Token URL. * This can be found in the same ways at openid.authUrl. - * Required to enable SSO. + * Required to enable SSO if openid.issuerUrl is not set. */ public static final ConfigKey OPENID_TOKENURL = new StringConfigKey( "openid.tokenUrl", @@ -657,7 +666,7 @@ public final class Keys { /** * OpenID Connect User Info URL. * This can be found in the same ways at openid.authUrl. - * Required to enable SSO. + * Required to enable SSO if openid.issuerUrl is not set. */ public static final ConfigKey OPENID_USERINFOURL = new StringConfigKey( "openid.userInfoUrl", diff --git a/src/main/java/org/traccar/database/OpenIdProvider.java b/src/main/java/org/traccar/database/OpenIdProvider.java index 537319b31..2b0f9d290 100644 --- a/src/main/java/org/traccar/database/OpenIdProvider.java +++ b/src/main/java/org/traccar/database/OpenIdProvider.java @@ -26,9 +26,16 @@ import org.traccar.helper.ServletHelper; import java.net.URI; import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse.BodyHandlers; import java.security.GeneralSecurityException; +import java.util.Map; import java.io.IOException; import javax.servlet.http.HttpServletRequest; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import com.google.inject.Inject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -82,12 +89,43 @@ public class OpenIdProvider { try { callbackUrl = new URI(config.getString(Keys.WEB_URL, "") + "/api/session/openid/callback"); - authUrl = new URI(config.getString(Keys.OPENID_AUTHURL, "")); - tokenUrl = new URI(config.getString(Keys.OPENID_TOKENURL, "")); - userInfoUrl = new URI(config.getString(Keys.OPENID_USERINFOURL, "")); baseUrl = new URI(config.getString(Keys.WEB_URL, "")); + + if ( + config.hasKey(Keys.OPENID_ISSUERURL) + && ( + !config.hasKey(Keys.OPENID_AUTHURL) + || !config.hasKey(Keys.OPENID_TOKENURL) + || !config.hasKey(Keys.OPENID_USERINFOURL)) + ) { + HttpClient httpClient = HttpClient.newHttpClient(); + + HttpRequest httpRequest = HttpRequest.newBuilder( + URI.create( + config.getString(Keys.OPENID_ISSUERURL) + "/.well-known/openid-configuration") + ) + .header("accept", "application/json") + .build(); + + String httpResponse = httpClient.send(httpRequest, BodyHandlers.ofString()).body(); + + Map discoveryMap = new ObjectMapper().readValue( + httpResponse, new TypeReference>() { }); + + authUrl = new URI(discoveryMap.get("authorization_endpoint").toString()); + tokenUrl = new URI(discoveryMap.get("token_endpoint").toString()); + userInfoUrl = new URI(discoveryMap.get("userinfo_endpoint").toString()); + + LOGGER.info("OpenID Connect auto discovery successful"); + } else { + authUrl = new URI(config.getString(Keys.OPENID_AUTHURL)); + tokenUrl = new URI(config.getString(Keys.OPENID_TOKENURL)); + userInfoUrl = new URI(config.getString(Keys.OPENID_USERINFOURL)); + } } catch (URISyntaxException error) { LOGGER.error("Invalid URIs provided in OpenID configuration"); + } catch (InterruptedException | IOException error) { + LOGGER.error("OpenID Connect auto discovery failed"); } adminGroup = config.getString(Keys.OPENID_ADMINGROUP); -- cgit v1.2.3 From c56b136a328bc1781ccc74aa27fdecf4a17b9595 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 5 Apr 2023 17:59:04 +0100 Subject: Added openid.allowGroup --- src/main/java/org/traccar/config/Keys.java | 9 +++++++++ src/main/java/org/traccar/database/OpenIdProvider.java | 10 +++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 3ed6c6026..363d4a472 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -672,6 +672,15 @@ public final class Keys { "openid.userInfoUrl", List.of(KeyType.CONFIG)); + /** + * OpenID Connect group to restrict access to. + * If this is not provided, all OpenID users will have access to Traccar. + * This option will only work if your OpenID provider supports the groups scope. + */ + public static final ConfigKey OPENID_ALLOWGROUP = new StringConfigKey( + "openid.allowGroup", + List.of(KeyType.CONFIG)); + /** * OpenID Connect group to grant admin access. * If this is not provided, no groups will be granted admin access. diff --git a/src/main/java/org/traccar/database/OpenIdProvider.java b/src/main/java/org/traccar/database/OpenIdProvider.java index 2b0f9d290..370876ed9 100644 --- a/src/main/java/org/traccar/database/OpenIdProvider.java +++ b/src/main/java/org/traccar/database/OpenIdProvider.java @@ -30,6 +30,7 @@ import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse.BodyHandlers; import java.security.GeneralSecurityException; +import java.util.List; import java.util.Map; import java.io.IOException; import javax.servlet.http.HttpServletRequest; @@ -76,6 +77,7 @@ public class OpenIdProvider { private URI userInfoUrl; private URI baseUrl; private final String adminGroup; + private final String allowGroup; private LoginService loginService; @@ -129,6 +131,7 @@ public class OpenIdProvider { } adminGroup = config.getString(Keys.OPENID_ADMINGROUP); + allowGroup = config.getString(Keys.OPENID_ALLOWGROUP); } public URI createAuthUri() { @@ -200,7 +203,12 @@ public class OpenIdProvider { UserInfo userInfo = getUserInfo(bearerToken); - Boolean administrator = adminGroup != null && userInfo.getStringListClaim("groups").contains(adminGroup); + List userGroups = userInfo.getStringListClaim("groups"); + Boolean administrator = adminGroup != null && userGroups.contains(adminGroup); + + if (!(administrator || allowGroup == null || userGroups.contains(allowGroup))) { + throw new GeneralSecurityException("Your OpenID Groups do not permit access to Traccar."); + } User user = loginService.login(userInfo.getEmailAddress(), userInfo.getName(), administrator); -- cgit v1.2.3 From 5ba5cc8291d0bd5d497563ddebf08dfc6d239ee9 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 5 Apr 2023 20:40:09 +0100 Subject: Review changes --- src/main/java/org/traccar/MainModule.java | 12 +++-- src/main/java/org/traccar/config/Keys.java | 16 +++--- .../java/org/traccar/database/OpenIdProvider.java | 62 +++++++++------------- 3 files changed, 41 insertions(+), 49 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 51097511a..220798767 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -97,6 +97,7 @@ import javax.ws.rs.client.ClientBuilder; import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; +import java.net.http.HttpClient; import java.util.Properties; public class MainModule extends AbstractModule { @@ -174,11 +175,12 @@ public class MainModule extends AbstractModule { @Singleton @Provides - public static OpenIdProvider provideOpenIDProvider(Config config, LoginService loginService) { - if (config.hasKey(Keys.OPENID_CLIENTID)) { - return new OpenIdProvider(config, loginService); - } - return null; + public static OpenIdProvider provideOpenIDProvider( + Config config, LoginService loginService, ObjectMapper objectMapper) throws InterruptedException, IOException { + if (config.hasKey(Keys.OPENID_CLIENT_ID)) { + return new OpenIdProvider(config, loginService, HttpClient.newHttpClient(), objectMapper); + } + return null; } @Provides diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 363d4a472..6c46ef390 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -623,7 +623,7 @@ public final class Keys { * This is a unique ID assigned to each application you register with your identity provider. * Required to enable SSO. */ - public static final ConfigKey OPENID_CLIENTID = new StringConfigKey( + public static final ConfigKey OPENID_CLIENT_ID = new StringConfigKey( "openid.clientId", List.of(KeyType.CONFIG)); @@ -632,7 +632,7 @@ public final class Keys { * This is a secret assigned to each application you register with your identity provider. * Required to enable SSO. */ - public static final ConfigKey OPENID_CLIENTSECRET = new StringConfigKey( + public static final ConfigKey OPENID_CLIENT_SECRET = new StringConfigKey( "openid.clientSecret", List.of(KeyType.CONFIG)); @@ -641,7 +641,7 @@ public final class Keys { * This is used to automatically configure the authorization, token and user info URLs if * they are not provided. */ - public static final ConfigKey OPENID_ISSUERURL = new StringConfigKey( + public static final ConfigKey OPENID_ISSUER_URL = new StringConfigKey( "openid.issuerUrl", List.of(KeyType.CONFIG)); @@ -651,7 +651,7 @@ public final class Keys { * configuration endpoint, eg. https://auth.example.com//.well-known/openid-configuration * Required to enable SSO if openid.issuerUrl is not set. */ - public static final ConfigKey OPENID_AUTHURL = new StringConfigKey( + public static final ConfigKey OPENID_AUTH_URL = new StringConfigKey( "openid.authUrl", List.of(KeyType.CONFIG)); /** @@ -659,7 +659,7 @@ public final class Keys { * This can be found in the same ways at openid.authUrl. * Required to enable SSO if openid.issuerUrl is not set. */ - public static final ConfigKey OPENID_TOKENURL = new StringConfigKey( + public static final ConfigKey OPENID_TOKEN_URL = new StringConfigKey( "openid.tokenUrl", List.of(KeyType.CONFIG)); @@ -668,7 +668,7 @@ public final class Keys { * This can be found in the same ways at openid.authUrl. * Required to enable SSO if openid.issuerUrl is not set. */ - public static final ConfigKey OPENID_USERINFOURL = new StringConfigKey( + public static final ConfigKey OPENID_USERINFO_URL = new StringConfigKey( "openid.userInfoUrl", List.of(KeyType.CONFIG)); @@ -677,7 +677,7 @@ public final class Keys { * If this is not provided, all OpenID users will have access to Traccar. * This option will only work if your OpenID provider supports the groups scope. */ - public static final ConfigKey OPENID_ALLOWGROUP = new StringConfigKey( + public static final ConfigKey OPENID_ALLOW_GROUP = new StringConfigKey( "openid.allowGroup", List.of(KeyType.CONFIG)); @@ -686,7 +686,7 @@ public final class Keys { * If this is not provided, no groups will be granted admin access. * This option will only work if your OpenID provider supports the groups scope. */ - public static final ConfigKey OPENID_ADMINGROUP = new StringConfigKey( + public static final ConfigKey OPENID_ADMIN_GROUP = new StringConfigKey( "openid.adminGroup", List.of(KeyType.CONFIG)); diff --git a/src/main/java/org/traccar/database/OpenIdProvider.java b/src/main/java/org/traccar/database/OpenIdProvider.java index 370876ed9..8b93feea7 100644 --- a/src/main/java/org/traccar/database/OpenIdProvider.java +++ b/src/main/java/org/traccar/database/OpenIdProvider.java @@ -82,56 +82,46 @@ public class OpenIdProvider { private LoginService loginService; @Inject - public OpenIdProvider(Config config, LoginService loginService) { - this.loginService = loginService; - - force = config.getBoolean(Keys.OPENID_FORCE); - clientId = new ClientID(config.getString(Keys.OPENID_CLIENTID)); - clientAuth = new ClientSecretBasic(clientId, new Secret(config.getString(Keys.OPENID_CLIENTSECRET))); - - try { - callbackUrl = new URI(config.getString(Keys.WEB_URL, "") + "/api/session/openid/callback"); - baseUrl = new URI(config.getString(Keys.WEB_URL, "")); - - if ( - config.hasKey(Keys.OPENID_ISSUERURL) - && ( - !config.hasKey(Keys.OPENID_AUTHURL) - || !config.hasKey(Keys.OPENID_TOKENURL) - || !config.hasKey(Keys.OPENID_USERINFOURL)) - ) { - HttpClient httpClient = HttpClient.newHttpClient(); + public OpenIdProvider( + Config config, LoginService loginService, HttpClient httpClient, ObjectMapper objectMapper + ) throws InterruptedException, IOException { + this.loginService = loginService; + force = config.getBoolean(Keys.OPENID_FORCE); + clientId = new ClientID(config.getString(Keys.OPENID_CLIENT_ID)); + clientAuth = new ClientSecretBasic(clientId, new Secret(config.getString(Keys.OPENID_CLIENT_SECRET))); + + try { + callbackUrl = new URI(config.getString(Keys.WEB_URL, "") + "/api/session/openid/callback"); + baseUrl = new URI(config.getString(Keys.WEB_URL, "")); + + if (config.hasKey(Keys.OPENID_ISSUER_URL)) { HttpRequest httpRequest = HttpRequest.newBuilder( - URI.create( - config.getString(Keys.OPENID_ISSUERURL) + "/.well-known/openid-configuration") - ) - .header("accept", "application/json") + URI.create(config.getString(Keys.OPENID_ISSUER_URL) + "/.well-known/openid-configuration")) + .header("Accept", "application/json") .build(); String httpResponse = httpClient.send(httpRequest, BodyHandlers.ofString()).body(); - Map discoveryMap = new ObjectMapper().readValue( + Map discoveryMap = objectMapper.readValue( httpResponse, new TypeReference>() { }); - authUrl = new URI(discoveryMap.get("authorization_endpoint").toString()); - tokenUrl = new URI(discoveryMap.get("token_endpoint").toString()); - userInfoUrl = new URI(discoveryMap.get("userinfo_endpoint").toString()); + authUrl = new URI((String) discoveryMap.get("authorization_endpoint")); + tokenUrl = new URI((String) discoveryMap.get("token_endpoint")); + userInfoUrl = new URI((String) discoveryMap.get("userinfo_endpoint")); LOGGER.info("OpenID Connect auto discovery successful"); - } else { - authUrl = new URI(config.getString(Keys.OPENID_AUTHURL)); - tokenUrl = new URI(config.getString(Keys.OPENID_TOKENURL)); - userInfoUrl = new URI(config.getString(Keys.OPENID_USERINFOURL)); - } + } else { + authUrl = new URI(config.getString(Keys.OPENID_AUTH_URL)); + tokenUrl = new URI(config.getString(Keys.OPENID_TOKEN_URL)); + userInfoUrl = new URI(config.getString(Keys.OPENID_USERINFO_URL)); + } } catch (URISyntaxException error) { LOGGER.error("Invalid URIs provided in OpenID configuration"); - } catch (InterruptedException | IOException error) { - LOGGER.error("OpenID Connect auto discovery failed"); } - adminGroup = config.getString(Keys.OPENID_ADMINGROUP); - allowGroup = config.getString(Keys.OPENID_ALLOWGROUP); + adminGroup = config.getString(Keys.OPENID_ADMIN_GROUP); + allowGroup = config.getString(Keys.OPENID_ALLOW_GROUP); } public URI createAuthUri() { -- cgit v1.2.3 From 1ecd7efca41344f29f8caa42fc6caaed8c7294a1 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 5 Apr 2023 20:49:10 +0100 Subject: Config doc change --- src/main/java/org/traccar/config/Keys.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 6c46ef390..b97acfd66 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -638,8 +638,7 @@ public final class Keys { /** * OpenID Connect Issuer (Base) URL. - * This is used to automatically configure the authorization, token and user info URLs if - * they are not provided. + * This is used to automatically configure the authorization, token and user info URLs if provided. */ public static final ConfigKey OPENID_ISSUER_URL = new StringConfigKey( "openid.issuerUrl", -- cgit v1.2.3 From a710ddd5ad336cd45d3a0e69f13985db840763dc Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 5 Apr 2023 21:45:37 +0100 Subject: Review changes 2 --- src/main/java/org/traccar/MainModule.java | 12 ++-- .../java/org/traccar/database/OpenIdProvider.java | 67 +++++++++------------- 2 files changed, 35 insertions(+), 44 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 220798767..4db6e0e32 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -96,6 +96,7 @@ import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import java.io.IOException; import java.net.InetAddress; +import java.net.URISyntaxException; import java.net.UnknownHostException; import java.net.http.HttpClient; import java.util.Properties; @@ -176,11 +177,12 @@ public class MainModule extends AbstractModule { @Singleton @Provides public static OpenIdProvider provideOpenIDProvider( - Config config, LoginService loginService, ObjectMapper objectMapper) throws InterruptedException, IOException { - if (config.hasKey(Keys.OPENID_CLIENT_ID)) { - return new OpenIdProvider(config, loginService, HttpClient.newHttpClient(), objectMapper); - } - return null; + Config config, LoginService loginService, ObjectMapper objectMapper + ) throws InterruptedException, IOException, URISyntaxException { + if (config.hasKey(Keys.OPENID_CLIENT_ID)) { + return new OpenIdProvider(config, loginService, HttpClient.newHttpClient(), objectMapper); + } + return null; } @Provides diff --git a/src/main/java/org/traccar/database/OpenIdProvider.java b/src/main/java/org/traccar/database/OpenIdProvider.java index 8b93feea7..941d0e587 100644 --- a/src/main/java/org/traccar/database/OpenIdProvider.java +++ b/src/main/java/org/traccar/database/OpenIdProvider.java @@ -38,8 +38,6 @@ import javax.servlet.http.HttpServletRequest; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.inject.Inject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import com.nimbusds.oauth2.sdk.http.HTTPResponse; import com.nimbusds.oauth2.sdk.AuthorizationCode; @@ -62,12 +60,9 @@ import com.nimbusds.openid.connect.sdk.OIDCTokenResponseParser; import com.nimbusds.openid.connect.sdk.UserInfoResponse; import com.nimbusds.openid.connect.sdk.UserInfoRequest; import com.nimbusds.openid.connect.sdk.AuthenticationRequest; - import com.nimbusds.openid.connect.sdk.claims.UserInfo; public class OpenIdProvider { - private static final Logger LOGGER = LoggerFactory.getLogger(OpenIdProvider.class); - private final Boolean force; private final ClientID clientId; private final ClientAuthentication clientAuth; @@ -84,40 +79,34 @@ public class OpenIdProvider { @Inject public OpenIdProvider( Config config, LoginService loginService, HttpClient httpClient, ObjectMapper objectMapper - ) throws InterruptedException, IOException { - this.loginService = loginService; - - force = config.getBoolean(Keys.OPENID_FORCE); - clientId = new ClientID(config.getString(Keys.OPENID_CLIENT_ID)); - clientAuth = new ClientSecretBasic(clientId, new Secret(config.getString(Keys.OPENID_CLIENT_SECRET))); - - try { - callbackUrl = new URI(config.getString(Keys.WEB_URL, "") + "/api/session/openid/callback"); - baseUrl = new URI(config.getString(Keys.WEB_URL, "")); - - if (config.hasKey(Keys.OPENID_ISSUER_URL)) { - HttpRequest httpRequest = HttpRequest.newBuilder( - URI.create(config.getString(Keys.OPENID_ISSUER_URL) + "/.well-known/openid-configuration")) - .header("Accept", "application/json") - .build(); - - String httpResponse = httpClient.send(httpRequest, BodyHandlers.ofString()).body(); - - Map discoveryMap = objectMapper.readValue( - httpResponse, new TypeReference>() { }); - - authUrl = new URI((String) discoveryMap.get("authorization_endpoint")); - tokenUrl = new URI((String) discoveryMap.get("token_endpoint")); - userInfoUrl = new URI((String) discoveryMap.get("userinfo_endpoint")); - - LOGGER.info("OpenID Connect auto discovery successful"); - } else { - authUrl = new URI(config.getString(Keys.OPENID_AUTH_URL)); - tokenUrl = new URI(config.getString(Keys.OPENID_TOKEN_URL)); - userInfoUrl = new URI(config.getString(Keys.OPENID_USERINFO_URL)); - } - } catch (URISyntaxException error) { - LOGGER.error("Invalid URIs provided in OpenID configuration"); + ) throws InterruptedException, IOException, URISyntaxException { + this.loginService = loginService; + + force = config.getBoolean(Keys.OPENID_FORCE); + clientId = new ClientID(config.getString(Keys.OPENID_CLIENT_ID)); + clientAuth = new ClientSecretBasic(clientId, new Secret(config.getString(Keys.OPENID_CLIENT_SECRET))); + + callbackUrl = new URI(config.getString(Keys.WEB_URL, "") + "/api/session/openid/callback"); + baseUrl = new URI(config.getString(Keys.WEB_URL, "")); + + if (config.hasKey(Keys.OPENID_ISSUER_URL)) { + HttpRequest httpRequest = HttpRequest.newBuilder( + URI.create(config.getString(Keys.OPENID_ISSUER_URL) + "/.well-known/openid-configuration")) + .header("Accept", "application/json") + .build(); + + String httpResponse = httpClient.send(httpRequest, BodyHandlers.ofString()).body(); + + Map discoveryMap = objectMapper.readValue( + httpResponse, new TypeReference>() { }); + + authUrl = new URI((String) discoveryMap.get("authorization_endpoint")); + tokenUrl = new URI((String) discoveryMap.get("token_endpoint")); + userInfoUrl = new URI((String) discoveryMap.get("userinfo_endpoint")); + } else { + authUrl = new URI(config.getString(Keys.OPENID_AUTH_URL)); + tokenUrl = new URI(config.getString(Keys.OPENID_TOKEN_URL)); + userInfoUrl = new URI(config.getString(Keys.OPENID_USERINFO_URL)); } adminGroup = config.getString(Keys.OPENID_ADMIN_GROUP); -- cgit v1.2.3 From c0dd2a6187de517af33aa92e0524414e65d973b4 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 5 Apr 2023 22:27:02 +0100 Subject: Rename ServletHelper to WebHelper --- src/main/java/org/traccar/MainModule.java | 15 +------ .../org/traccar/api/resource/SessionResource.java | 14 +++--- .../java/org/traccar/database/OpenIdProvider.java | 6 +-- .../java/org/traccar/helper/ServletHelper.java | 45 ------------------- src/main/java/org/traccar/helper/WebHelper.java | 51 ++++++++++++++++++++++ .../java/org/traccar/helper/ServletHelperTest.java | 39 ----------------- .../java/org/traccar/helper/WebHelperTest.java | 39 +++++++++++++++++ 7 files changed, 102 insertions(+), 107 deletions(-) delete mode 100644 src/main/java/org/traccar/helper/ServletHelper.java create mode 100644 src/main/java/org/traccar/helper/WebHelper.java delete mode 100644 src/test/java/org/traccar/helper/ServletHelperTest.java create mode 100644 src/test/java/org/traccar/helper/WebHelperTest.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 4db6e0e32..41124bd03 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -75,6 +75,7 @@ import org.traccar.handler.GeolocationHandler; import org.traccar.handler.SpeedLimitHandler; import org.traccar.helper.ObjectMapperContextResolver; import org.traccar.helper.SanitizerModule; +import org.traccar.helper.WebHelper; import org.traccar.mail.LogMailManager; import org.traccar.mail.MailManager; import org.traccar.mail.SmtpMailManager; @@ -390,19 +391,7 @@ public class MainModule extends AbstractModule { public static VelocityEngine provideVelocityEngine(Config config) { Properties properties = new Properties(); properties.setProperty("resource.loader.file.path", config.getString(Keys.TEMPLATES_ROOT) + "/"); - - if (config.hasKey(Keys.WEB_URL)) { - properties.setProperty("web.url", config.getString(Keys.WEB_URL).replaceAll("/$", "")); - } else { - String address; - try { - address = config.getString(Keys.WEB_ADDRESS, InetAddress.getLocalHost().getHostAddress()); - } catch (UnknownHostException e) { - address = "localhost"; - } - String url = URIUtil.newURI("http", address, config.getInteger(Keys.WEB_PORT), "", ""); - properties.setProperty("web.url", url); - } + properties.setProperty("web.url", WebHelper.retrieveWebUrl(config)); VelocityEngine velocityEngine = new VelocityEngine(); velocityEngine.init(properties); diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index ac39fa449..9b6a74ddb 100644 --- a/src/main/java/org/traccar/api/resource/SessionResource.java +++ b/src/main/java/org/traccar/api/resource/SessionResource.java @@ -21,7 +21,7 @@ import org.traccar.api.signature.TokenManager; import org.traccar.database.OpenIdProvider; import org.traccar.helper.DataConverter; import org.traccar.helper.LogAction; -import org.traccar.helper.ServletHelper; +import org.traccar.helper.WebHelper; import org.traccar.model.User; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; @@ -84,7 +84,7 @@ public class SessionResource extends BaseResource { User user = loginService.login(token); if (user != null) { request.getSession().setAttribute(USER_ID_KEY, user.getId()); - LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); + LogAction.login(user.getId(), WebHelper.retrieveRemoteAddress(request)); return user; } } @@ -111,7 +111,7 @@ public class SessionResource extends BaseResource { User user = loginService.login(email, password); if (user != null) { request.getSession().setAttribute(USER_ID_KEY, user.getId()); - LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); + LogAction.login(user.getId(), WebHelper.retrieveRemoteAddress(request)); return user; } } @@ -135,7 +135,7 @@ public class SessionResource extends BaseResource { User user = storage.getObject(User.class, new Request( new Columns.All(), new Condition.Equals("id", userId))); request.getSession().setAttribute(USER_ID_KEY, user.getId()); - LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); + LogAction.login(user.getId(), WebHelper.retrieveRemoteAddress(request)); return user; } @@ -146,17 +146,17 @@ public class SessionResource extends BaseResource { User user = loginService.login(email, password); if (user != null) { request.getSession().setAttribute(USER_ID_KEY, user.getId()); - LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); + LogAction.login(user.getId(), WebHelper.retrieveRemoteAddress(request)); return user; } else { - LogAction.failedLogin(ServletHelper.retrieveRemoteAddress(request)); + LogAction.failedLogin(WebHelper.retrieveRemoteAddress(request)); throw new WebApplicationException(Response.status(Response.Status.UNAUTHORIZED).build()); } } @DELETE public Response remove() { - LogAction.logout(getUserId(), ServletHelper.retrieveRemoteAddress(request)); + LogAction.logout(getUserId(), WebHelper.retrieveRemoteAddress(request)); request.getSession().removeAttribute(USER_ID_KEY); return Response.noContent().build(); } diff --git a/src/main/java/org/traccar/database/OpenIdProvider.java b/src/main/java/org/traccar/database/OpenIdProvider.java index 941d0e587..6550a1278 100644 --- a/src/main/java/org/traccar/database/OpenIdProvider.java +++ b/src/main/java/org/traccar/database/OpenIdProvider.java @@ -22,7 +22,7 @@ import org.traccar.api.security.LoginService; import org.traccar.model.User; import org.traccar.storage.StorageException; import org.traccar.helper.LogAction; -import org.traccar.helper.ServletHelper; +import org.traccar.helper.WebHelper; import java.net.URI; import java.net.URISyntaxException; @@ -88,7 +88,7 @@ public class OpenIdProvider { callbackUrl = new URI(config.getString(Keys.WEB_URL, "") + "/api/session/openid/callback"); baseUrl = new URI(config.getString(Keys.WEB_URL, "")); - + if (config.hasKey(Keys.OPENID_ISSUER_URL)) { HttpRequest httpRequest = HttpRequest.newBuilder( URI.create(config.getString(Keys.OPENID_ISSUER_URL) + "/.well-known/openid-configuration")) @@ -192,7 +192,7 @@ public class OpenIdProvider { User user = loginService.login(userInfo.getEmailAddress(), userInfo.getName(), administrator); request.getSession().setAttribute(SessionResource.USER_ID_KEY, user.getId()); - LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); + LogAction.login(user.getId(), WebHelper.retrieveRemoteAddress(request)); return baseUrl; } diff --git a/src/main/java/org/traccar/helper/ServletHelper.java b/src/main/java/org/traccar/helper/ServletHelper.java deleted file mode 100644 index b6c587ec3..000000000 --- a/src/main/java/org/traccar/helper/ServletHelper.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2020 Anton Tananaev (anton@traccar.org) - * - * 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.traccar.helper; - -import javax.servlet.http.HttpServletRequest; - -public final class ServletHelper { - - private ServletHelper() { - } - - public static String retrieveRemoteAddress(HttpServletRequest request) { - - if (request != null) { - String remoteAddress = request.getHeader("X-FORWARDED-FOR"); - - if (remoteAddress != null && !remoteAddress.isEmpty()) { - int separatorIndex = remoteAddress.indexOf(","); - if (separatorIndex > 0) { - return remoteAddress.substring(0, separatorIndex); // remove the additional data - } else { - return remoteAddress; - } - } else { - return request.getRemoteAddr(); - } - } else { - return null; - } - } - -} diff --git a/src/main/java/org/traccar/helper/WebHelper.java b/src/main/java/org/traccar/helper/WebHelper.java new file mode 100644 index 000000000..9c6547d8d --- /dev/null +++ b/src/main/java/org/traccar/helper/WebHelper.java @@ -0,0 +1,51 @@ +/* + * Copyright 2020 Anton Tananaev (anton@traccar.org) + * + * 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.traccar.helper; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +import javax.servlet.http.HttpServletRequest; + +import org.eclipse.jetty.util.URIUtil; +import org.traccar.config.Config; +import org.traccar.config.Keys; + +public final class WebHelper { + + private WebHelper() { + } + + public static String retrieveRemoteAddress(HttpServletRequest request) { + + if (request != null) { + String remoteAddress = request.getHeader("X-FORWARDED-FOR"); + + if (remoteAddress != null && !remoteAddress.isEmpty()) { + int separatorIndex = remoteAddress.indexOf(","); + if (separatorIndex > 0) { + return remoteAddress.substring(0, separatorIndex); // remove the additional data + } else { + return remoteAddress; + } + } else { + return request.getRemoteAddr(); + } + } else { + return null; + } + } +} diff --git a/src/test/java/org/traccar/helper/ServletHelperTest.java b/src/test/java/org/traccar/helper/ServletHelperTest.java deleted file mode 100644 index 3a645bc36..000000000 --- a/src/test/java/org/traccar/helper/ServletHelperTest.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.traccar.helper; - -import org.junit.jupiter.api.Test; - -import javax.servlet.http.HttpServletRequest; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class ServletHelperTest { - - @Test - public void testRetrieveRemoteAddressProxyMultiple() { - HttpServletRequest request = mock(HttpServletRequest.class); - when(request.getRemoteAddr()).thenReturn("147.120.1.5"); - when(request.getHeader("X-FORWARDED-FOR")).thenReturn("231.23.45.65, 10.20.10.33, 10.20.20.34"); - - assertEquals("231.23.45.65", ServletHelper.retrieveRemoteAddress(request)); - } - - @Test - public void testRetrieveRemoteAddressProxySingle() { - HttpServletRequest request = mock(HttpServletRequest.class); - when(request.getRemoteAddr()).thenReturn("147.120.1.5"); - when(request.getHeader("X-FORWARDED-FOR")).thenReturn("231.23.45.65"); - - assertEquals("231.23.45.65", ServletHelper.retrieveRemoteAddress(request)); - } - - @Test - public void testRetrieveRemoteAddressNoProxy() { - HttpServletRequest request = mock(HttpServletRequest.class); - when(request.getRemoteAddr()).thenReturn("231.23.45.65"); - - assertEquals("231.23.45.65", ServletHelper.retrieveRemoteAddress(request)); - } - -} diff --git a/src/test/java/org/traccar/helper/WebHelperTest.java b/src/test/java/org/traccar/helper/WebHelperTest.java new file mode 100644 index 000000000..3a7329cb8 --- /dev/null +++ b/src/test/java/org/traccar/helper/WebHelperTest.java @@ -0,0 +1,39 @@ +package org.traccar.helper; + +import org.junit.jupiter.api.Test; + +import javax.servlet.http.HttpServletRequest; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class WebHelperTest { + + @Test + public void testRetrieveRemoteAddressProxyMultiple() { + HttpServletRequest request = mock(HttpServletRequest.class); + when(request.getRemoteAddr()).thenReturn("147.120.1.5"); + when(request.getHeader("X-FORWARDED-FOR")).thenReturn("231.23.45.65, 10.20.10.33, 10.20.20.34"); + + assertEquals("231.23.45.65", WebHelper.retrieveRemoteAddress(request)); + } + + @Test + public void testRetrieveRemoteAddressProxySingle() { + HttpServletRequest request = mock(HttpServletRequest.class); + when(request.getRemoteAddr()).thenReturn("147.120.1.5"); + when(request.getHeader("X-FORWARDED-FOR")).thenReturn("231.23.45.65"); + + assertEquals("231.23.45.65", WebHelper.retrieveRemoteAddress(request)); + } + + @Test + public void testRetrieveRemoteAddressNoProxy() { + HttpServletRequest request = mock(HttpServletRequest.class); + when(request.getRemoteAddr()).thenReturn("231.23.45.65"); + + assertEquals("231.23.45.65", WebHelper.retrieveRemoteAddress(request)); + } + +} -- cgit v1.2.3 From 88a56f29fff1ab252a2c415f0d44a22192dd6b66 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 5 Apr 2023 22:29:32 +0100 Subject: Implement retrieveWebUrl --- src/main/java/org/traccar/MainModule.java | 3 --- src/main/java/org/traccar/database/OpenIdProvider.java | 6 +++--- src/main/java/org/traccar/helper/WebHelper.java | 14 ++++++++++++++ 3 files changed, 17 insertions(+), 6 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 41124bd03..6a2fe21c3 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -26,7 +26,6 @@ import com.google.inject.name.Names; import io.netty.util.HashedWheelTimer; import io.netty.util.Timer; import org.apache.velocity.app.VelocityEngine; -import org.eclipse.jetty.util.URIUtil; import org.traccar.broadcast.BroadcastService; import org.traccar.broadcast.MulticastBroadcastService; import org.traccar.broadcast.NullBroadcastService; @@ -96,9 +95,7 @@ import javax.inject.Singleton; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import java.io.IOException; -import java.net.InetAddress; import java.net.URISyntaxException; -import java.net.UnknownHostException; import java.net.http.HttpClient; import java.util.Properties; diff --git a/src/main/java/org/traccar/database/OpenIdProvider.java b/src/main/java/org/traccar/database/OpenIdProvider.java index 6550a1278..d0ec4e98d 100644 --- a/src/main/java/org/traccar/database/OpenIdProvider.java +++ b/src/main/java/org/traccar/database/OpenIdProvider.java @@ -86,9 +86,9 @@ public class OpenIdProvider { clientId = new ClientID(config.getString(Keys.OPENID_CLIENT_ID)); clientAuth = new ClientSecretBasic(clientId, new Secret(config.getString(Keys.OPENID_CLIENT_SECRET))); - callbackUrl = new URI(config.getString(Keys.WEB_URL, "") + "/api/session/openid/callback"); - baseUrl = new URI(config.getString(Keys.WEB_URL, "")); - + baseUrl = new URI(WebHelper.retrieveWebUrl(config)); + callbackUrl = new URI(WebHelper.retrieveWebUrl(config) + "/api/session/openid/callback"); + if (config.hasKey(Keys.OPENID_ISSUER_URL)) { HttpRequest httpRequest = HttpRequest.newBuilder( URI.create(config.getString(Keys.OPENID_ISSUER_URL) + "/.well-known/openid-configuration")) diff --git a/src/main/java/org/traccar/helper/WebHelper.java b/src/main/java/org/traccar/helper/WebHelper.java index 9c6547d8d..e2844bc4d 100644 --- a/src/main/java/org/traccar/helper/WebHelper.java +++ b/src/main/java/org/traccar/helper/WebHelper.java @@ -48,4 +48,18 @@ public final class WebHelper { return null; } } + + public static String retrieveWebUrl(Config config) { + if (config.hasKey(Keys.WEB_URL)) { + return config.getString(Keys.WEB_URL).replaceAll("/$", ""); + } else { + String address; + try { + address = config.getString(Keys.WEB_ADDRESS, InetAddress.getLocalHost().getHostAddress()); + } catch (UnknownHostException e) { + address = "localhost"; + } + return URIUtil.newURI("http", address, config.getInteger(Keys.WEB_PORT), "", ""); + } + } } -- cgit v1.2.3