From b100cb211161d1014dfaa1ab532f1670c699e80d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 16 Jun 2022 16:20:13 -0700 Subject: Improve web injection --- src/main/java/org/traccar/Main.java | 4 +- .../java/org/traccar/api/AsyncSocketServlet.java | 2 + src/main/java/org/traccar/api/MediaFilter.java | 47 +++++++++++++--------- .../java/org/traccar/api/ObjectMapperProvider.java | 13 +++--- src/main/java/org/traccar/web/WebModule.java | 29 +++++++++++++ src/main/java/org/traccar/web/WebServer.java | 25 +++++------- 6 files changed, 81 insertions(+), 39 deletions(-) create mode 100644 src/main/java/org/traccar/web/WebModule.java (limited to 'src/main/java/org/traccar') diff --git a/src/main/java/org/traccar/Main.java b/src/main/java/org/traccar/Main.java index e3286fd5e..bf69b565d 100644 --- a/src/main/java/org/traccar/Main.java +++ b/src/main/java/org/traccar/Main.java @@ -17,12 +17,12 @@ package org.traccar; import com.google.inject.Guice; import com.google.inject.Injector; -import com.google.inject.servlet.ServletModule; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.broadcast.BroadcastService; import org.traccar.schedule.ScheduleManager; import org.traccar.storage.DatabaseModule; +import org.traccar.web.WebModule; import org.traccar.web.WebServer; import java.io.File; @@ -115,7 +115,7 @@ public final class Main { public static void run(String configFile) { try { - injector = Guice.createInjector(new MainModule(), new DatabaseModule(), new ServletModule()); + injector = Guice.createInjector(new MainModule(), new DatabaseModule(), new WebModule()); Context.init(configFile); logSystemInfo(); LOGGER.info("Version: " + Main.class.getPackage().getImplementationVersion()); diff --git a/src/main/java/org/traccar/api/AsyncSocketServlet.java b/src/main/java/org/traccar/api/AsyncSocketServlet.java index 317ec469e..7c532179b 100644 --- a/src/main/java/org/traccar/api/AsyncSocketServlet.java +++ b/src/main/java/org/traccar/api/AsyncSocketServlet.java @@ -24,9 +24,11 @@ import org.traccar.config.Keys; import org.traccar.session.ConnectionManager; import javax.inject.Inject; +import javax.inject.Singleton; import javax.servlet.http.HttpSession; import java.time.Duration; +@Singleton public class AsyncSocketServlet extends JettyWebSocketServlet { private final ObjectMapper objectMapper; diff --git a/src/main/java/org/traccar/api/MediaFilter.java b/src/main/java/org/traccar/api/MediaFilter.java index e0609871a..6d95c66a8 100644 --- a/src/main/java/org/traccar/api/MediaFilter.java +++ b/src/main/java/org/traccar/api/MediaFilter.java @@ -16,19 +16,7 @@ */ package org.traccar.api; -import java.io.IOException; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import org.traccar.Main; +import com.google.inject.Provider; import org.traccar.api.resource.SessionResource; import org.traccar.api.security.PermissionsService; import org.traccar.database.StatisticsManager; @@ -40,8 +28,35 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; +import javax.inject.Inject; +import javax.inject.Singleton; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.io.IOException; + +@Singleton public class MediaFilter implements Filter { + private final Storage storage; + private final StatisticsManager statisticsManager; + private final Provider permissionsServiceProvider; + + @Inject + public MediaFilter( + Storage storage, StatisticsManager statisticsManager, + Provider permissionsServiceProvider) { + this.storage = storage; + this.statisticsManager = statisticsManager; + this.permissionsServiceProvider = permissionsServiceProvider; + } + @Override public void init(FilterConfig filterConfig) throws ServletException { } @@ -50,10 +65,6 @@ public class MediaFilter implements Filter { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { - PermissionsService permissionsService = Main.getInjector().getInstance(PermissionsService.class); - Storage storage = Main.getInjector().getInstance(Storage.class); - StatisticsManager statisticsManager = Main.getInjector().getInstance(StatisticsManager.class); - HttpServletResponse httpResponse = (HttpServletResponse) response; try { HttpSession session = ((HttpServletRequest) request).getSession(false); @@ -75,7 +86,7 @@ public class MediaFilter implements Filter { Device device = storage.getObject(Device.class, new Request( new Columns.All(), new Condition.Equals("uniqueId", "uniqueId", parts[1]))); if (device != null) { - permissionsService.checkPermission(Device.class, userId, device.getId()); + permissionsServiceProvider.get().checkPermission(Device.class, userId, device.getId()); chain.doFilter(request, response); return; } diff --git a/src/main/java/org/traccar/api/ObjectMapperProvider.java b/src/main/java/org/traccar/api/ObjectMapperProvider.java index cb7adab6c..4d8b266fa 100644 --- a/src/main/java/org/traccar/api/ObjectMapperProvider.java +++ b/src/main/java/org/traccar/api/ObjectMapperProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 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. @@ -16,17 +16,20 @@ package org.traccar.api; import com.fasterxml.jackson.databind.ObjectMapper; -import org.traccar.Main; import javax.ws.rs.ext.ContextResolver; -import javax.ws.rs.ext.Provider; -@Provider public class ObjectMapperProvider implements ContextResolver { + private final ObjectMapper objectMapper; + + public ObjectMapperProvider(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + @Override public ObjectMapper getContext(Class type) { - return Main.getInjector().getInstance(ObjectMapper.class); + return objectMapper; } } diff --git a/src/main/java/org/traccar/web/WebModule.java b/src/main/java/org/traccar/web/WebModule.java new file mode 100644 index 000000000..6c133ff74 --- /dev/null +++ b/src/main/java/org/traccar/web/WebModule.java @@ -0,0 +1,29 @@ +/* + * Copyright 2022 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.web; + +import com.google.inject.servlet.ServletModule; +import org.traccar.api.AsyncSocketServlet; +import org.traccar.api.MediaFilter; + +public class WebModule extends ServletModule { + + @Override + protected void configureServlets() { + filter("/api/media/*").through(MediaFilter.class); + serve("/api/socket").with(AsyncSocketServlet.class); + } +} diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index 36f3d7682..46e401779 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -15,6 +15,7 @@ */ package org.traccar.web; +import com.fasterxml.jackson.databind.ObjectMapper; import com.google.inject.Injector; import com.google.inject.servlet.GuiceFilter; import org.eclipse.jetty.http.HttpCookie; @@ -40,13 +41,9 @@ import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerI import org.glassfish.jersey.jackson.JacksonFeature; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.servlet.ServletContainer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.traccar.LifecycleObject; -import org.traccar.api.AsyncSocketServlet; import org.traccar.api.CorsResponseFilter; import org.traccar.api.DateParameterConverterProvider; -import org.traccar.api.MediaFilter; import org.traccar.api.ObjectMapperProvider; import org.traccar.api.ResourceErrorHandler; import org.traccar.api.resource.ServerResource; @@ -88,6 +85,8 @@ public class WebServer implements LifecycleObject { } ServletContextHandler servletHandler = new ServletContextHandler(ServletContextHandler.SESSIONS); + JettyWebSocketServletContainerInitializer.configure(servletHandler, null); + servletHandler.addFilter(GuiceFilter.class, "/*", EnumSet.allOf(DispatcherType.class)); initApi(servletHandler); initSessionConfig(servletHandler); @@ -140,7 +139,7 @@ public class WebServer implements LifecycleObject { } } }; - ServletHolder servletHolder = new ServletHolder(new AsyncProxyServlet.Transparent()); + ServletHolder servletHolder = new ServletHolder(AsyncProxyServlet.Transparent.class); servletHolder.setInitParameter("proxyTo", "http://localhost:" + port); servletHandler.addServlet(servletHolder, "/"); handlers.addHandler(servletHandler); @@ -164,11 +163,6 @@ public class WebServer implements LifecycleObject { } private void initApi(ServletContextHandler servletHandler) { - servletHandler.addFilter(GuiceFilter.class, "/api/*", EnumSet.allOf(DispatcherType.class)); - - servletHandler.addServlet(new ServletHolder(injector.getInstance(AsyncSocketServlet.class)), "/api/socket"); - JettyWebSocketServletContainerInitializer.configure(servletHandler, null); - String mediaPath = config.getString(Keys.MEDIA_PATH); if (mediaPath != null) { ServletHolder servletHolder = new ServletHolder(DefaultServlet.class); @@ -176,15 +170,18 @@ public class WebServer implements LifecycleObject { servletHolder.setInitParameter("dirAllowed", "false"); servletHolder.setInitParameter("pathInfoOnly", "true"); servletHandler.addServlet(servletHolder, "/api/media/*"); - servletHandler.addFilter(MediaFilter.class, "/api/media/*", EnumSet.allOf(DispatcherType.class)); } ResourceConfig resourceConfig = new ResourceConfig(); + resourceConfig.register(new GuiceBridgeInitializer(injector)); + resourceConfig.register(new ObjectMapperProvider(injector.getInstance(ObjectMapper.class))); resourceConfig.registerClasses( - JacksonFeature.class, ObjectMapperProvider.class, ResourceErrorHandler.class, - SecurityRequestFilter.class, CorsResponseFilter.class, DateParameterConverterProvider.class); + JacksonFeature.class, + DateParameterConverterProvider.class, + SecurityRequestFilter.class, + CorsResponseFilter.class, + ResourceErrorHandler.class); resourceConfig.packages(ServerResource.class.getPackage().getName()); - resourceConfig.register(new GuiceBridgeInitializer(injector)); servletHandler.addServlet(new ServletHolder(new ServletContainer(resourceConfig)), "/api/*"); } -- cgit v1.2.3