diff options
Diffstat (limited to 'src/main/java/org/traccar/api')
7 files changed, 45 insertions, 48 deletions
diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index 2a801221b..e35850e1f 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -68,7 +68,7 @@ public abstract class BaseObjectResource<T extends BaseModel> extends BaseResour @POST public Response add(T entity) throws Exception { - permissionsService.checkEdit(getUserId(), entity, true); + permissionsService.checkEdit(getUserId(), entity, true, false); entity.setId(storage.addObject(entity, new Request(new Columns.Exclude("id")))); LogAction.create(getUserId(), entity); @@ -86,25 +86,27 @@ public abstract class BaseObjectResource<T extends BaseModel> extends BaseResour @Path("{id}") @PUT public Response update(T entity) throws Exception { - permissionsService.checkEdit(getUserId(), entity, false); permissionsService.checkPermission(baseClass, getUserId(), entity.getId()); - if (entity instanceof User) { + boolean skipReadonly = false; + if (entity instanceof User after) { User before = storage.getObject(User.class, new Request( new Columns.All(), new Condition.Equals("id", entity.getId()))); permissionsService.checkUserUpdate(getUserId(), before, (User) entity); - } else if (entity instanceof Group) { - Group group = (Group) entity; + skipReadonly = permissionsService.getUser(getUserId()) + .compare(after, "notificationTokens", "termsAccepted"); + } else if (entity instanceof Group group) { if (group.getId() == group.getGroupId()) { throw new IllegalArgumentException("Cycle in group hierarchy"); } } + permissionsService.checkEdit(getUserId(), entity, false, skipReadonly); + storage.updateObject(entity, new Request( new Columns.Exclude("id"), new Condition.Equals("id", entity.getId()))); - if (entity instanceof User) { - User user = (User) entity; + if (entity instanceof User user) { if (user.getHashedPassword() != null) { storage.updateObject(entity, new Request( new Columns.Include("hashedPassword", "salt"), @@ -120,8 +122,8 @@ public abstract class BaseObjectResource<T extends BaseModel> extends BaseResour @Path("{id}") @DELETE public Response remove(@PathParam("id") long id) throws Exception { - permissionsService.checkEdit(getUserId(), baseClass, false); permissionsService.checkPermission(baseClass, getUserId(), id); + permissionsService.checkEdit(getUserId(), baseClass, false, false); storage.removeObject(baseClass, new Request(new Condition.Equals("id", id))); cacheManager.invalidateObject(true, baseClass, id, ObjectOperation.DELETE); diff --git a/src/main/java/org/traccar/api/ResourceErrorHandler.java b/src/main/java/org/traccar/api/ResourceErrorHandler.java index 387f3db6a..5f5e70632 100644 --- a/src/main/java/org/traccar/api/ResourceErrorHandler.java +++ b/src/main/java/org/traccar/api/ResourceErrorHandler.java @@ -25,8 +25,7 @@ public class ResourceErrorHandler implements ExceptionMapper<Exception> { @Override public Response toResponse(Exception e) { - if (e instanceof WebApplicationException) { - WebApplicationException webException = (WebApplicationException) e; + if (e instanceof WebApplicationException webException) { return Response.fromResponse(webException.getResponse()).entity(Log.exceptionStack(webException)).build(); } else { return Response.status(Response.Status.BAD_REQUEST).entity(Log.exceptionStack(e)).build(); diff --git a/src/main/java/org/traccar/api/resource/AttributeResource.java b/src/main/java/org/traccar/api/resource/AttributeResource.java index 52c4d6324..8debb2e50 100644 --- a/src/main/java/org/traccar/api/resource/AttributeResource.java +++ b/src/main/java/org/traccar/api/resource/AttributeResource.java @@ -62,16 +62,10 @@ public class AttributeResource extends ExtendedObjectResource<Attribute> { Object result = computedAttributesHandler.computeAttribute(entity, position); if (result != null) { - switch (entity.getType()) { - case "number": - Number numberValue = (Number) result; - return Response.ok(numberValue).build(); - case "boolean": - Boolean booleanValue = (Boolean) result; - return Response.ok(booleanValue).build(); - default: - return Response.ok(result.toString()).build(); - } + return switch (entity.getType()) { + case "number", "boolean" -> Response.ok(result).build(); + default -> Response.ok(result.toString()).build(); + }; } else { return Response.noContent().build(); } diff --git a/src/main/java/org/traccar/api/resource/DeviceResource.java b/src/main/java/org/traccar/api/resource/DeviceResource.java index 971c29c60..4be8dbb12 100644 --- a/src/main/java/org/traccar/api/resource/DeviceResource.java +++ b/src/main/java/org/traccar/api/resource/DeviceResource.java @@ -137,8 +137,8 @@ public class DeviceResource extends BaseObjectResource<Device> { @Path("{id}/accumulators") @PUT public Response updateAccumulators(DeviceAccumulators entity) throws Exception { - permissionsService.checkEdit(getUserId(), Device.class, false); permissionsService.checkPermission(Device.class, getUserId(), entity.getDeviceId()); + permissionsService.checkEdit(getUserId(), Device.class, false, false); Position position = storage.getObject(Position.class, new Request( new Columns.All(), new Condition.LatestPositions(entity.getDeviceId()))); @@ -174,20 +174,14 @@ public class DeviceResource extends BaseObjectResource<Device> { } private String imageExtension(String type) { - switch (type) { - case "image/jpeg": - return "jpg"; - case "image/png": - return "png"; - case "image/gif": - return "gif"; - case "image/webp": - return "webp"; - case "image/svg+xml": - return "svg"; - default: - throw new IllegalArgumentException("Unsupported image type"); - } + return switch (type) { + case "image/jpeg" -> "jpg"; + case "image/png" -> "png"; + case "image/gif" -> "gif"; + case "image/webp" -> "webp"; + case "image/svg+xml" -> "svg"; + default -> throw new IllegalArgumentException("Unsupported image type"); + }; } @Path("{id}/image") diff --git a/src/main/java/org/traccar/api/resource/NotificationResource.java b/src/main/java/org/traccar/api/resource/NotificationResource.java index a41d00cf3..8bc81a3a4 100644 --- a/src/main/java/org/traccar/api/resource/NotificationResource.java +++ b/src/main/java/org/traccar/api/resource/NotificationResource.java @@ -85,7 +85,7 @@ public class NotificationResource extends ExtendedObjectResource<Notification> { public Collection<Typed> getNotificators(@QueryParam("announcement") boolean announcement) { Set<String> announcementsUnsupported = Set.of("command", "web"); return notificatorManager.getAllNotificatorTypes().stream() - .filter(typed -> !announcement || !announcementsUnsupported.contains(typed.getType())) + .filter(typed -> !announcement || !announcementsUnsupported.contains(typed.type())) .collect(Collectors.toUnmodifiableSet()); } @@ -94,7 +94,7 @@ public class NotificationResource extends ExtendedObjectResource<Notification> { public Response testMessage() throws MessageException, StorageException { User user = permissionsService.getUser(getUserId()); for (Typed method : notificatorManager.getAllNotificatorTypes()) { - notificatorManager.getNotificator(method.getType()).send(null, user, new Event("test", 0), null); + notificatorManager.getNotificator(method.type()).send(null, user, new Event("test", 0), null); } return Response.noContent().build(); } diff --git a/src/main/java/org/traccar/api/resource/UserResource.java b/src/main/java/org/traccar/api/resource/UserResource.java index fbc31e46a..65ca2c883 100644 --- a/src/main/java/org/traccar/api/resource/UserResource.java +++ b/src/main/java/org/traccar/api/resource/UserResource.java @@ -25,6 +25,7 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.helper.LogAction; import org.traccar.helper.model.UserUtil; +import org.traccar.model.Device; import org.traccar.model.ManagedUser; import org.traccar.model.Permission; import org.traccar.model.User; @@ -61,12 +62,18 @@ public class UserResource extends BaseObjectResource<User> { } @GET - public Collection<User> get(@QueryParam("userId") long userId) throws StorageException { + public Collection<User> get( + @QueryParam("userId") long userId, @QueryParam("deviceId") long deviceId) throws StorageException { if (userId > 0) { permissionsService.checkUser(getUserId(), userId); return storage.getObjects(baseClass, new Request( new Columns.All(), new Condition.Permission(User.class, userId, ManagedUser.class).excludeGroups())); + } else if (deviceId > 0) { + permissionsService.checkAdmin(getUserId()); + return storage.getObjects(baseClass, new Request( + new Columns.All(), + new Condition.Permission(User.class, Device.class, deviceId).excludeGroups())); } else if (permissionsService.notAdmin(getUserId())) { return storage.getObjects(baseClass, new Request( new Columns.All(), diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index d60bbafb8..721793c2f 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -98,10 +98,12 @@ public class PermissionsService { } } - public void checkEdit(long userId, Class<?> clazz, boolean addition) throws StorageException, SecurityException { + public void checkEdit( + long userId, Class<?> clazz, boolean addition, boolean skipReadonly) + throws StorageException, SecurityException { if (!getUser(userId).getAdministrator()) { boolean denied = false; - if (getServer().getReadonly() || getUser(userId).getReadonly()) { + if (!skipReadonly && (getServer().getReadonly() || getUser(userId).getReadonly())) { denied = true; } else if (clazz.equals(Device.class)) { denied = getServer().getDeviceReadonly() || getUser(userId).getDeviceReadonly() @@ -121,11 +123,12 @@ public class PermissionsService { } } - public void checkEdit(long userId, BaseModel object, boolean addition) throws StorageException, SecurityException { + public void checkEdit( + long userId, BaseModel object, boolean addition, boolean skipReadonly) + throws StorageException, SecurityException { if (!getUser(userId).getAdministrator()) { - checkEdit(userId, object.getClass(), addition); - if (object instanceof GroupedModel) { - GroupedModel after = ((GroupedModel) object); + checkEdit(userId, object.getClass(), addition, skipReadonly); + if (object instanceof GroupedModel after) { if (after.getGroupId() > 0) { GroupedModel before = null; if (!addition) { @@ -137,8 +140,7 @@ public class PermissionsService { } } } - if (object instanceof Schedulable) { - Schedulable after = ((Schedulable) object); + if (object instanceof Schedulable after) { if (after.getCalendarId() > 0) { Schedulable before = null; if (!addition) { @@ -150,8 +152,7 @@ public class PermissionsService { } } } - if (object instanceof Notification) { - Notification after = ((Notification) object); + if (object instanceof Notification after) { if (after.getCommandId() > 0) { Notification before = null; if (!addition) { |