aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/traccar/api
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/traccar/api')
-rw-r--r--src/main/java/org/traccar/api/AsyncSocket.java40
-rw-r--r--src/main/java/org/traccar/api/BaseObjectResource.java10
-rw-r--r--src/main/java/org/traccar/api/resource/AttributeResource.java6
-rw-r--r--src/main/java/org/traccar/api/resource/DeviceResource.java9
-rw-r--r--src/main/java/org/traccar/api/resource/PermissionsResource.java8
-rw-r--r--src/main/java/org/traccar/api/resource/ServerResource.java28
-rw-r--r--src/main/java/org/traccar/api/resource/UserResource.java2
7 files changed, 69 insertions, 34 deletions
diff --git a/src/main/java/org/traccar/api/AsyncSocket.java b/src/main/java/org/traccar/api/AsyncSocket.java
index 5fc4b4412..f5fbcbf62 100644
--- a/src/main/java/org/traccar/api/AsyncSocket.java
+++ b/src/main/java/org/traccar/api/AsyncSocket.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2023 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.
@@ -22,16 +22,17 @@ import org.eclipse.jetty.websocket.api.WebSocketAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.traccar.helper.model.PositionUtil;
-import org.traccar.session.ConnectionManager;
import org.traccar.model.Device;
import org.traccar.model.Event;
+import org.traccar.model.LogRecord;
import org.traccar.model.Position;
+import org.traccar.session.ConnectionManager;
import org.traccar.storage.Storage;
import org.traccar.storage.StorageException;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
public class AsyncSocket extends WebSocketAdapter implements ConnectionManager.UpdateListener {
@@ -41,12 +42,15 @@ public class AsyncSocket extends WebSocketAdapter implements ConnectionManager.U
private static final String KEY_DEVICES = "devices";
private static final String KEY_POSITIONS = "positions";
private static final String KEY_EVENTS = "events";
+ private static final String KEY_LOGS = "logs";
private final ObjectMapper objectMapper;
private final ConnectionManager connectionManager;
private final Storage storage;
private final long userId;
+ private boolean includeLogs;
+
public AsyncSocket(ObjectMapper objectMapper, ConnectionManager connectionManager, Storage storage, long userId) {
this.objectMapper = objectMapper;
this.connectionManager = connectionManager;
@@ -76,29 +80,41 @@ public class AsyncSocket extends WebSocketAdapter implements ConnectionManager.U
}
@Override
+ public void onWebSocketText(String message) {
+ super.onWebSocketText(message);
+
+ try {
+ includeLogs = objectMapper.readTree(message).get("logs").asBoolean();
+ } catch (JsonProcessingException e) {
+ LOGGER.warn("Socket JSON parsing error", e);
+ }
+ }
+
+ @Override
public void onKeepalive() {
sendData(new HashMap<>());
}
@Override
public void onUpdateDevice(Device device) {
- Map<String, Collection<?>> data = new HashMap<>();
- data.put(KEY_DEVICES, Collections.singletonList(device));
- sendData(data);
+ sendData(Map.of(KEY_DEVICES, List.of(device)));
}
@Override
public void onUpdatePosition(Position position) {
- Map<String, Collection<?>> data = new HashMap<>();
- data.put(KEY_POSITIONS, Collections.singletonList(position));
- sendData(data);
+ sendData(Map.of(KEY_POSITIONS, List.of(position)));
}
@Override
public void onUpdateEvent(Event event) {
- Map<String, Collection<?>> data = new HashMap<>();
- data.put(KEY_EVENTS, Collections.singletonList(event));
- sendData(data);
+ sendData(Map.of(KEY_EVENTS, List.of(event)));
+ }
+
+ @Override
+ public void onUpdateLog(LogRecord record) {
+ if (includeLogs) {
+ sendData(Map.of(KEY_LOGS, List.of(record)));
+ }
}
private void sendData(Map<String, Collection<?>> data) {
diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java
index ebfa93ff0..2a801221b 100644
--- a/src/main/java/org/traccar/api/BaseObjectResource.java
+++ b/src/main/java/org/traccar/api/BaseObjectResource.java
@@ -67,7 +67,7 @@ public abstract class BaseObjectResource<T extends BaseModel> extends BaseResour
}
@POST
- public Response add(T entity) throws StorageException {
+ public Response add(T entity) throws Exception {
permissionsService.checkEdit(getUserId(), entity, true);
entity.setId(storage.addObject(entity, new Request(new Columns.Exclude("id"))));
@@ -85,7 +85,7 @@ public abstract class BaseObjectResource<T extends BaseModel> extends BaseResour
@Path("{id}")
@PUT
- public Response update(T entity) throws StorageException {
+ public Response update(T entity) throws Exception {
permissionsService.checkEdit(getUserId(), entity, false);
permissionsService.checkPermission(baseClass, getUserId(), entity.getId());
@@ -111,7 +111,7 @@ public abstract class BaseObjectResource<T extends BaseModel> extends BaseResour
new Condition.Equals("id", entity.getId())));
}
}
- cacheManager.updateOrInvalidate(true, entity, ObjectOperation.UPDATE);
+ cacheManager.invalidateObject(true, entity.getClass(), entity.getId(), ObjectOperation.UPDATE);
LogAction.edit(getUserId(), entity);
return Response.ok(entity).build();
@@ -119,12 +119,12 @@ public abstract class BaseObjectResource<T extends BaseModel> extends BaseResour
@Path("{id}")
@DELETE
- public Response remove(@PathParam("id") long id) throws StorageException {
+ public Response remove(@PathParam("id") long id) throws Exception {
permissionsService.checkEdit(getUserId(), baseClass, false);
permissionsService.checkPermission(baseClass, getUserId(), id);
storage.removeObject(baseClass, new Request(new Condition.Equals("id", id)));
- cacheManager.invalidate(baseClass, id);
+ cacheManager.invalidateObject(true, baseClass, id, ObjectOperation.DELETE);
LogAction.remove(getUserId(), baseClass, id);
diff --git a/src/main/java/org/traccar/api/resource/AttributeResource.java b/src/main/java/org/traccar/api/resource/AttributeResource.java
index 44f0ef452..52c4d6324 100644
--- a/src/main/java/org/traccar/api/resource/AttributeResource.java
+++ b/src/main/java/org/traccar/api/resource/AttributeResource.java
@@ -78,21 +78,21 @@ public class AttributeResource extends ExtendedObjectResource<Attribute> {
}
@POST
- public Response add(Attribute entity) throws StorageException {
+ public Response add(Attribute entity) throws Exception {
permissionsService.checkAdmin(getUserId());
return super.add(entity);
}
@Path("{id}")
@PUT
- public Response update(Attribute entity) throws StorageException {
+ public Response update(Attribute entity) throws Exception {
permissionsService.checkAdmin(getUserId());
return super.update(entity);
}
@Path("{id}")
@DELETE
- public Response remove(@PathParam("id") long id) throws StorageException {
+ public Response remove(@PathParam("id") long id) throws Exception {
permissionsService.checkAdmin(getUserId());
return super.remove(id);
}
diff --git a/src/main/java/org/traccar/api/resource/DeviceResource.java b/src/main/java/org/traccar/api/resource/DeviceResource.java
index ebc40a9b1..540450cbb 100644
--- a/src/main/java/org/traccar/api/resource/DeviceResource.java
+++ b/src/main/java/org/traccar/api/resource/DeviceResource.java
@@ -19,6 +19,8 @@ import jakarta.ws.rs.FormParam;
import org.traccar.api.BaseObjectResource;
import org.traccar.api.signature.TokenManager;
import org.traccar.broadcast.BroadcastService;
+import org.traccar.config.Config;
+import org.traccar.config.Keys;
import org.traccar.database.MediaManager;
import org.traccar.helper.LogAction;
import org.traccar.model.Device;
@@ -61,6 +63,9 @@ import java.util.List;
public class DeviceResource extends BaseObjectResource<Device> {
@Inject
+ private Config config;
+
+ @Inject
private CacheManager cacheManager;
@Inject
@@ -128,7 +133,7 @@ public class DeviceResource extends BaseObjectResource<Device> {
@Path("{id}/accumulators")
@PUT
- public Response updateAccumulators(DeviceAccumulators entity) throws StorageException {
+ public Response updateAccumulators(DeviceAccumulators entity) throws Exception {
if (permissionsService.notAdmin(getUserId())) {
permissionsService.checkManager(getUserId());
permissionsService.checkPermission(Device.class, getUserId(), entity.getDeviceId());
@@ -212,6 +217,8 @@ public class DeviceResource extends BaseObjectResource<Device> {
share.setExpirationTime(expiration);
share.setTemporary(true);
share.setReadonly(true);
+ share.setLimitCommands(!config.getBoolean(Keys.WEB_SHARE_DEVICE_COMMANDS));
+ share.setDisableReports(!config.getBoolean(Keys.WEB_SHARE_DEVICE_REPORTS));
share.setId(storage.addObject(share, new Request(new Columns.Exclude("id"))));
diff --git a/src/main/java/org/traccar/api/resource/PermissionsResource.java b/src/main/java/org/traccar/api/resource/PermissionsResource.java
index 2a8ac62f7..9e2d21f2c 100644
--- a/src/main/java/org/traccar/api/resource/PermissionsResource.java
+++ b/src/main/java/org/traccar/api/resource/PermissionsResource.java
@@ -64,7 +64,7 @@ public class PermissionsResource extends BaseResource {
@Path("bulk")
@POST
- public Response add(List<LinkedHashMap<String, Long>> entities) throws StorageException, ClassNotFoundException {
+ public Response add(List<LinkedHashMap<String, Long>> entities) throws Exception {
permissionsService.checkRestriction(getUserId(), UserRestrictions::getReadonly);
checkPermissionTypes(entities);
for (LinkedHashMap<String, Long> entity: entities) {
@@ -84,13 +84,13 @@ public class PermissionsResource extends BaseResource {
}
@POST
- public Response add(LinkedHashMap<String, Long> entity) throws StorageException, ClassNotFoundException {
+ public Response add(LinkedHashMap<String, Long> entity) throws Exception {
return add(Collections.singletonList(entity));
}
@DELETE
@Path("bulk")
- public Response remove(List<LinkedHashMap<String, Long>> entities) throws StorageException, ClassNotFoundException {
+ public Response remove(List<LinkedHashMap<String, Long>> entities) throws Exception {
permissionsService.checkRestriction(getUserId(), UserRestrictions::getReadonly);
checkPermissionTypes(entities);
for (LinkedHashMap<String, Long> entity: entities) {
@@ -110,7 +110,7 @@ public class PermissionsResource extends BaseResource {
}
@DELETE
- public Response remove(LinkedHashMap<String, Long> entity) throws StorageException, ClassNotFoundException {
+ public Response remove(LinkedHashMap<String, Long> entity) throws Exception {
return remove(Collections.singletonList(entity));
}
diff --git a/src/main/java/org/traccar/api/resource/ServerResource.java b/src/main/java/org/traccar/api/resource/ServerResource.java
index 59ef642c8..66ecc74e1 100644
--- a/src/main/java/org/traccar/api/resource/ServerResource.java
+++ b/src/main/java/org/traccar/api/resource/ServerResource.java
@@ -107,14 +107,14 @@ public class ServerResource extends BaseResource {
}
@PUT
- public Response update(Server entity) throws StorageException {
+ public Response update(Server server) throws Exception {
permissionsService.checkAdmin(getUserId());
- storage.updateObject(entity, new Request(
+ storage.updateObject(server, new Request(
new Columns.Exclude("id"),
- new Condition.Equals("id", entity.getId())));
- cacheManager.updateOrInvalidate(true, entity, ObjectOperation.UPDATE);
- LogAction.edit(getUserId(), entity);
- return Response.ok(entity).build();
+ new Condition.Equals("id", server.getId())));
+ cacheManager.invalidateObject(true, Server.class, server.getId(), ObjectOperation.UPDATE);
+ LogAction.edit(getUserId(), server);
+ return Response.ok(server).build();
}
@Path("geocode")
@@ -136,11 +136,16 @@ public class ServerResource extends BaseResource {
@Path("file/{path}")
@POST
@Consumes("*/*")
- public Response uploadImage(@PathParam("path") String path, File inputFile) throws IOException, StorageException {
+ public Response uploadFile(@PathParam("path") String path, File inputFile) throws IOException, StorageException {
permissionsService.checkAdmin(getUserId());
String root = config.getString(Keys.WEB_OVERRIDE, config.getString(Keys.WEB_PATH));
- var outputPath = Paths.get(root, path);
+ var rootPath = Paths.get(root).normalize();
+ var outputPath = rootPath.resolve(path).normalize();
+ if (!outputPath.startsWith(rootPath)) {
+ return Response.status(Response.Status.BAD_REQUEST).build();
+ }
+
var directoryPath = outputPath.getParent();
if (directoryPath != null) {
Files.createDirectories(directoryPath);
@@ -152,4 +157,11 @@ public class ServerResource extends BaseResource {
return Response.ok().build();
}
+ @Path("cache")
+ @GET
+ public String cache() throws StorageException {
+ permissionsService.checkAdmin(getUserId());
+ return cacheManager.toString();
+ }
+
}
diff --git a/src/main/java/org/traccar/api/resource/UserResource.java b/src/main/java/org/traccar/api/resource/UserResource.java
index 99537f912..47ea9b07c 100644
--- a/src/main/java/org/traccar/api/resource/UserResource.java
+++ b/src/main/java/org/traccar/api/resource/UserResource.java
@@ -126,7 +126,7 @@ public class UserResource extends BaseObjectResource<User> {
@Path("{id}")
@DELETE
- public Response remove(@PathParam("id") long id) throws StorageException {
+ public Response remove(@PathParam("id") long id) throws Exception {
Response response = super.remove(id);
if (getUserId() == id) {
request.getSession().removeAttribute(SessionResource.USER_ID_KEY);