diff options
Diffstat (limited to 'src')
15 files changed, 161 insertions, 62 deletions
diff --git a/src/main/java/org/traccar/Main.java b/src/main/java/org/traccar/Main.java index db9892bb9..b14f22a00 100644 --- a/src/main/java/org/traccar/Main.java +++ b/src/main/java/org/traccar/Main.java @@ -17,6 +17,7 @@ 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.schedule.ScheduleManager; @@ -111,7 +112,7 @@ public final class Main { public static void run(String configFile) { try { - injector = Guice.createInjector(new MainModule()); + injector = Guice.createInjector(new MainModule(), new ServletModule()); Context.init(configFile); logSystemInfo(); LOGGER.info("Version: " + Main.class.getPackage().getImplementationVersion()); diff --git a/src/main/java/org/traccar/api/resource/PasswordResource.java b/src/main/java/org/traccar/api/resource/PasswordResource.java index ed7131718..91d994153 100644 --- a/src/main/java/org/traccar/api/resource/PasswordResource.java +++ b/src/main/java/org/traccar/api/resource/PasswordResource.java @@ -51,7 +51,8 @@ public class PasswordResource extends BaseResource { String token = UUID.randomUUID().toString().replaceAll("-", ""); user.set(PASSWORD_RESET_TOKEN, token); Context.getUsersManager().updateItem(user); - VelocityContext velocityContext = TextTemplateFormatter.prepareContext(null); + VelocityContext velocityContext = TextTemplateFormatter.prepareContext( + permissionsService.getServer(), user); velocityContext.put("token", token); NotificationMessage fullMessage = TextTemplateFormatter.formatMessage(velocityContext, "passwordReset", "full"); diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index 9ec3b43c1..c70414b2a 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -15,6 +15,7 @@ */ package org.traccar.api.security; +import com.google.inject.servlet.RequestScoped; import org.traccar.model.BaseModel; import org.traccar.model.Calendar; import org.traccar.model.Command; @@ -34,6 +35,7 @@ import org.traccar.storage.query.Request; import javax.inject.Inject; +@RequestScoped public class PermissionsService { private final Storage storage; diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index 47941d681..e8f2380a2 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -412,16 +412,4 @@ public class PermissionsManager { return null; } - public Object lookupAttribute(long userId, String key, Object defaultValue) { - Object preference; - Object serverPreference = server.getAttributes().get(key); - Object userPreference = getUser(userId).getAttributes().get(key); - if (server.getForceSettings()) { - preference = serverPreference != null ? serverPreference : userPreference; - } else { - preference = userPreference != null ? userPreference : serverPreference; - } - return preference != null ? preference : defaultValue; - } - } diff --git a/src/main/java/org/traccar/helper/UserUtil.java b/src/main/java/org/traccar/helper/UserUtil.java new file mode 100644 index 000000000..6050ad349 --- /dev/null +++ b/src/main/java/org/traccar/helper/UserUtil.java @@ -0,0 +1,57 @@ +/* + * 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.helper; + +import org.traccar.model.Server; +import org.traccar.model.User; + +import java.util.TimeZone; + +public final class UserUtil { + + private UserUtil() { + } + + public static String getDistanceUnit(Server server, User user) { + return lookupStringAttribute(server, user, "distanceUnit", "km"); + } + + public static String getSpeedUnit(Server server, User user) { + return lookupStringAttribute(server, user, "speedUnit", "kn"); + } + + public static String getVolumeUnit(Server server, User user) { + return lookupStringAttribute(server, user, "volumeUnit", "ltr"); + } + + public static TimeZone getTimezone(Server server, User user) { + String timezone = lookupStringAttribute(server, user, "timezone", null); + return timezone != null ? TimeZone.getTimeZone(timezone) : TimeZone.getDefault(); + } + + private static String lookupStringAttribute(Server server, User user, String key, String defaultValue) { + String preference; + String serverPreference = server.getString(key); + String userPreference = user.getString(key); + if (server.getForceSettings()) { + preference = serverPreference != null ? serverPreference : userPreference; + } else { + preference = userPreference != null ? userPreference : serverPreference; + } + return preference != null ? preference : defaultValue; + } + +} diff --git a/src/main/java/org/traccar/notification/NotificationFormatter.java b/src/main/java/org/traccar/notification/NotificationFormatter.java index be90761b1..13f42a8b2 100644 --- a/src/main/java/org/traccar/notification/NotificationFormatter.java +++ b/src/main/java/org/traccar/notification/NotificationFormatter.java @@ -17,13 +17,14 @@ package org.traccar.notification; import org.apache.velocity.VelocityContext; +import org.traccar.helper.UserUtil; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Geofence; import org.traccar.model.Maintenance; import org.traccar.model.Position; +import org.traccar.model.Server; import org.traccar.model.User; -import org.traccar.reports.common.ReportUtils; import org.traccar.session.cache.CacheManager; public final class NotificationFormatter { @@ -34,17 +35,18 @@ public final class NotificationFormatter { public static NotificationMessage formatMessage( CacheManager cacheManager, User user, Event event, Position position, String templatePath) { + Server server = cacheManager.getServer(); Device device = cacheManager.getObject(Device.class, event.getDeviceId()); - VelocityContext velocityContext = TextTemplateFormatter.prepareContext(user); + VelocityContext velocityContext = TextTemplateFormatter.prepareContext(server, user); velocityContext.put("device", device); velocityContext.put("event", event); if (position != null) { velocityContext.put("position", position); - velocityContext.put("speedUnit", ReportUtils.getSpeedUnit(user.getId())); - velocityContext.put("distanceUnit", ReportUtils.getDistanceUnit(user.getId())); - velocityContext.put("volumeUnit", ReportUtils.getVolumeUnit(user.getId())); + velocityContext.put("speedUnit", UserUtil.getSpeedUnit(server, user)); + velocityContext.put("distanceUnit", UserUtil.getDistanceUnit(server, user)); + velocityContext.put("volumeUnit", UserUtil.getVolumeUnit(server, user)); } if (event.getGeofenceId() != 0) { velocityContext.put("geofence", cacheManager.getObject(Geofence.class, event.getGeofenceId())); diff --git a/src/main/java/org/traccar/notification/TextTemplateFormatter.java b/src/main/java/org/traccar/notification/TextTemplateFormatter.java index 469de2d4a..06375afac 100644 --- a/src/main/java/org/traccar/notification/TextTemplateFormatter.java +++ b/src/main/java/org/traccar/notification/TextTemplateFormatter.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2021 - 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. @@ -23,8 +23,9 @@ import org.apache.velocity.tools.generic.NumberTool; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; +import org.traccar.helper.UserUtil; +import org.traccar.model.Server; import org.traccar.model.User; -import org.traccar.reports.common.ReportUtils; import java.io.StringWriter; import java.nio.charset.StandardCharsets; @@ -38,13 +39,13 @@ public final class TextTemplateFormatter { private TextTemplateFormatter() { } - public static VelocityContext prepareContext(User user) { + public static VelocityContext prepareContext(Server server, User user) { VelocityContext velocityContext = new VelocityContext(); if (user != null) { velocityContext.put("user", user); - velocityContext.put("timezone", ReportUtils.getTimezone(user.getId())); + velocityContext.put("timezone", UserUtil.getTimezone(server, user)); } velocityContext.put("webUrl", Context.getVelocityEngine().getProperty("web.url")); diff --git a/src/main/java/org/traccar/reports/EventsReportProvider.java b/src/main/java/org/traccar/reports/EventsReportProvider.java index 9b4a7df2b..f0c8c31b6 100644 --- a/src/main/java/org/traccar/reports/EventsReportProvider.java +++ b/src/main/java/org/traccar/reports/EventsReportProvider.java @@ -28,6 +28,7 @@ import java.util.Iterator; import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; +import org.traccar.api.security.PermissionsService; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Geofence; @@ -42,10 +43,12 @@ import javax.inject.Inject; public class EventsReportProvider { + private final PermissionsService permissionsService; private final Storage storage; @Inject - public EventsReportProvider(Storage storage) { + public EventsReportProvider(PermissionsService permissionsService, Storage storage) { + this.permissionsService = permissionsService; this.storage = storage; } @@ -127,7 +130,8 @@ public class EventsReportProvider { String templatePath = Context.getConfig().getString("report.templatesPath", "templates/export/"); try (InputStream inputStream = new FileInputStream(templatePath + "/events.xlsx")) { - org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); + var jxlsContext = ReportUtils.initializeContext( + permissionsService.getServer(), permissionsService.getUser(userId)); jxlsContext.putVar("devices", devicesEvents); jxlsContext.putVar("sheetNames", sheetNames); jxlsContext.putVar("geofenceNames", geofenceNames); diff --git a/src/main/java/org/traccar/reports/RouteReportProvider.java b/src/main/java/org/traccar/reports/RouteReportProvider.java index 4c4a41405..e20ba6885 100644 --- a/src/main/java/org/traccar/reports/RouteReportProvider.java +++ b/src/main/java/org/traccar/reports/RouteReportProvider.java @@ -26,6 +26,7 @@ import java.util.Date; import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; +import org.traccar.api.security.PermissionsService; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.model.Position; @@ -33,8 +34,17 @@ import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.DeviceReportSection; import org.traccar.storage.StorageException; +import javax.inject.Inject; + public class RouteReportProvider { + private final PermissionsService permissionsService; + + @Inject + public RouteReportProvider(PermissionsService permissionsService) { + this.permissionsService = permissionsService; + } + public Collection<Position> getObjects(long userId, Collection<Long> deviceIds, Collection<Long> groupIds, Date from, Date to) throws StorageException { ReportUtils.checkPeriodLimit(from, to); @@ -72,7 +82,8 @@ public class RouteReportProvider { String templatePath = Context.getConfig().getString("report.templatesPath", "templates/export/"); try (InputStream inputStream = new FileInputStream(templatePath + "/route.xlsx")) { - org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); + var jxlsContext = ReportUtils.initializeContext( + permissionsService.getServer(), permissionsService.getUser(userId)); jxlsContext.putVar("devices", devicesRoutes); jxlsContext.putVar("sheetNames", sheetNames); jxlsContext.putVar("from", from); diff --git a/src/main/java/org/traccar/reports/StopsReportProvider.java b/src/main/java/org/traccar/reports/StopsReportProvider.java index 58dc71d2d..8899dc42f 100644 --- a/src/main/java/org/traccar/reports/StopsReportProvider.java +++ b/src/main/java/org/traccar/reports/StopsReportProvider.java @@ -28,6 +28,7 @@ import java.util.Date; import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; import org.traccar.Main; +import org.traccar.api.security.PermissionsService; import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; import org.traccar.model.Device; @@ -42,10 +43,12 @@ import javax.inject.Inject; public class StopsReportProvider { + private final PermissionsService permissionsService; private final Storage storage; @Inject - public StopsReportProvider(Storage storage) { + public StopsReportProvider(PermissionsService permissionsService, Storage storage) { + this.permissionsService = permissionsService; this.storage = storage; } @@ -98,7 +101,8 @@ public class StopsReportProvider { String templatePath = Context.getConfig().getString("report.templatesPath", "templates/export/"); try (InputStream inputStream = new FileInputStream(templatePath + "/stops.xlsx")) { - org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); + var jxlsContext = ReportUtils.initializeContext( + permissionsService.getServer(), permissionsService.getUser(userId)); jxlsContext.putVar("devices", devicesStops); jxlsContext.putVar("sheetNames", sheetNames); jxlsContext.putVar("from", from); diff --git a/src/main/java/org/traccar/reports/SummaryReportProvider.java b/src/main/java/org/traccar/reports/SummaryReportProvider.java index a2306f3d1..c9fac4309 100644 --- a/src/main/java/org/traccar/reports/SummaryReportProvider.java +++ b/src/main/java/org/traccar/reports/SummaryReportProvider.java @@ -27,14 +27,25 @@ import java.util.Date; import org.jxls.util.JxlsHelper; import org.traccar.Context; +import org.traccar.api.security.PermissionsService; import org.traccar.helper.UnitsConverter; +import org.traccar.helper.UserUtil; import org.traccar.model.Position; import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.SummaryReportItem; import org.traccar.storage.StorageException; +import javax.inject.Inject; + public class SummaryReportProvider { + private final PermissionsService permissionsService; + + @Inject + public SummaryReportProvider(PermissionsService permissionsService) { + this.permissionsService = permissionsService; + } + private SummaryReportItem calculateSummaryResult(long deviceId, Collection<Position> positions) { SummaryReportItem result = new SummaryReportItem(); result.setDeviceId(deviceId); @@ -88,8 +99,9 @@ public class SummaryReportProvider { return result; } - private int getDay(long userId, Date date) { - Calendar calendar = Calendar.getInstance(ReportUtils.getTimezone(userId)); + private int getDay(long userId, Date date) throws StorageException { + Calendar calendar = Calendar.getInstance(UserUtil.getTimezone( + permissionsService.getServer(), permissionsService.getUser(userId))); calendar.setTime(date); return calendar.get(Calendar.DAY_OF_MONTH); } @@ -144,7 +156,8 @@ public class SummaryReportProvider { String templatePath = Context.getConfig().getString("report.templatesPath", "templates/export/"); try (InputStream inputStream = new FileInputStream(templatePath + "/summary.xlsx")) { - org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); + var jxlsContext = ReportUtils.initializeContext( + permissionsService.getServer(), permissionsService.getUser(userId)); jxlsContext.putVar("summaries", summaries); jxlsContext.putVar("from", from); jxlsContext.putVar("to", to); diff --git a/src/main/java/org/traccar/reports/TripsReportProvider.java b/src/main/java/org/traccar/reports/TripsReportProvider.java index 5ff31dbe2..bcd79ab25 100644 --- a/src/main/java/org/traccar/reports/TripsReportProvider.java +++ b/src/main/java/org/traccar/reports/TripsReportProvider.java @@ -27,6 +27,7 @@ import java.util.Date; import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; import org.traccar.Main; +import org.traccar.api.security.PermissionsService; import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; import org.traccar.model.Device; @@ -41,10 +42,12 @@ import javax.inject.Inject; public class TripsReportProvider { + private final PermissionsService permissionsService; private final Storage storage; @Inject - public TripsReportProvider(Storage storage) { + public TripsReportProvider(PermissionsService permissionsService, Storage storage) { + this.permissionsService = permissionsService; this.storage = storage; } @@ -96,7 +99,8 @@ public class TripsReportProvider { String templatePath = Context.getConfig().getString("report.templatesPath", "templates/export/"); try (InputStream inputStream = new FileInputStream(templatePath + "/trips.xlsx")) { - org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); + var jxlsContext = ReportUtils.initializeContext( + permissionsService.getServer(), permissionsService.getUser(userId)); jxlsContext.putVar("devices", devicesTrips); jxlsContext.putVar("sheetNames", sheetNames); jxlsContext.putVar("from", from); diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index 4bcb54899..71c49f65b 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -31,7 +31,9 @@ import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; import org.traccar.handler.events.MotionEventHandler; import org.traccar.helper.UnitsConverter; +import org.traccar.helper.UserUtil; import org.traccar.model.BaseModel; +import org.traccar.model.Server; import org.traccar.model.User; import org.traccar.session.DeviceState; import org.traccar.model.Driver; @@ -58,7 +60,6 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.TimeZone; public final class ReportUtils { @@ -81,23 +82,6 @@ public final class ReportUtils { } } - public static String getDistanceUnit(long userId) { - return (String) Context.getPermissionsManager().lookupAttribute(userId, "distanceUnit", "km"); - } - - public static String getSpeedUnit(long userId) { - return (String) Context.getPermissionsManager().lookupAttribute(userId, "speedUnit", "kn"); - } - - public static String getVolumeUnit(long userId) { - return (String) Context.getPermissionsManager().lookupAttribute(userId, "volumeUnit", "ltr"); - } - - public static TimeZone getTimezone(long userId) { - String timezone = (String) Context.getPermissionsManager().lookupAttribute(userId, "timezone", null); - return timezone != null ? TimeZone.getTimeZone(timezone) : TimeZone.getDefault(); - } - public static Collection<Long> getDeviceList(Collection<Long> deviceIds, Collection<Long> groupIds) { Collection<Long> result = new LinkedHashSet<>(deviceIds); for (long groupId : groupIds) { @@ -158,15 +142,15 @@ public final class ReportUtils { return null; } - public static org.jxls.common.Context initializeContext(long userId) { + public static org.jxls.common.Context initializeContext(Server server, User user) { org.jxls.common.Context jxlsContext = PoiTransformer.createInitialContext(); - jxlsContext.putVar("distanceUnit", getDistanceUnit(userId)); - jxlsContext.putVar("speedUnit", getSpeedUnit(userId)); - jxlsContext.putVar("volumeUnit", getVolumeUnit(userId)); + jxlsContext.putVar("distanceUnit", UserUtil.getDistanceUnit(server, user)); + jxlsContext.putVar("speedUnit", UserUtil.getSpeedUnit(server, user)); + jxlsContext.putVar("volumeUnit", UserUtil.getVolumeUnit(server, user)); jxlsContext.putVar("webUrl", Context.getVelocityEngine().getProperty("web.url")); jxlsContext.putVar("dateTool", new DateTool()); jxlsContext.putVar("numberTool", new NumberTool()); - jxlsContext.putVar("timezone", getTimezone(userId)); + jxlsContext.putVar("timezone", UserUtil.getTimezone(server, user)); jxlsContext.putVar("locale", Locale.getDefault()); jxlsContext.putVar("bracketsRegex", "[\\{\\}\"]"); return jxlsContext; diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 6ea0f252d..586237655 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -23,6 +23,7 @@ import org.traccar.model.Geofence; import org.traccar.model.Maintenance; import org.traccar.model.Notification; import org.traccar.model.Position; +import org.traccar.model.Server; import org.traccar.model.User; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; @@ -57,12 +58,14 @@ public class CacheManager { private final Map<CacheKey, CacheValue> deviceCache = new HashMap<>(); private final Map<Long, Map<Class<? extends BaseModel>, List<Long>>> deviceLinks = new HashMap<>(); + private Server server; private final Map<Long, Position> devicePositions = new HashMap<>(); private final Map<Long, List<User>> notificationUsers = new HashMap<>(); @Inject public CacheManager(Storage storage) throws StorageException { this.storage = storage; + invalidateServer(); invalidateUsers(); } @@ -96,6 +99,15 @@ public class CacheManager { } } + public Server getServer() { + try { + lock.readLock().lock(); + return server; + } finally { + lock.readLock().unlock(); + } + } + public List<User> getNotificationUsers(long notificationId) { try { lock.readLock().lock(); @@ -154,6 +166,10 @@ public class CacheManager { invalidate(new CacheKey(clazz1, id1), new CacheKey(clazz2, id2)); } + private void invalidateServer() throws StorageException { + server = storage.getObject(Server.class, new Request(new Columns.All())); + } + private void invalidateUsers() throws StorageException { Map<Long, User> users = new HashMap<>(); storage.getObjects(User.class, new Request(new Columns.All())) @@ -220,21 +236,29 @@ public class CacheManager { } private void unsafeInvalidate(CacheKey[] keys) throws StorageException { + boolean invalidateServer = false; boolean invalidateUsers = false; Set<Long> linkedDevices = new HashSet<>(); for (var key : keys) { - if (key.classIs(User.class) || key.classIs(Notification.class)) { - invalidateUsers = true; + if (key.classIs(Server.class)) { + invalidateServer = true; + } else { + if (key.classIs(User.class) || key.classIs(Notification.class)) { + invalidateUsers = true; + } + deviceCache.computeIfPresent(key, (k, value) -> { + linkedDevices.addAll(value.getReferences()); + return value; + }); } - deviceCache.computeIfPresent(key, (k, value) -> { - linkedDevices.addAll(value.getReferences()); - return value; - }); } for (long deviceId : linkedDevices) { unsafeRemoveDevice(deviceId); unsafeAddDevice(deviceId); } + if (invalidateServer) { + invalidateServer(); + } if (invalidateUsers) { invalidateUsers(); } diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index 06676fb41..f1ee8fcb2 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.google.inject.servlet.GuiceFilter; import org.eclipse.jetty.http.HttpCookie; import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpStatus; @@ -164,6 +165,8 @@ public class WebServer implements LifecycleObject { } private void initApi(Config config, ServletContextHandler servletHandler) { + servletHandler.addFilter(GuiceFilter.class, "/api/*", EnumSet.allOf(DispatcherType.class)); + servletHandler.addServlet(new ServletHolder(new AsyncSocketServlet()), "/api/socket"); JettyWebSocketServletContainerInitializer.configure(servletHandler, null); |