aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/traccar
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/traccar')
-rw-r--r--src/main/java/org/traccar/api/BaseObjectResource.java11
-rw-r--r--src/main/java/org/traccar/api/resource/DeviceResource.java2
-rw-r--r--src/main/java/org/traccar/api/security/PermissionsService.java12
-rw-r--r--src/main/java/org/traccar/model/User.java15
4 files changed, 32 insertions, 8 deletions
diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java
index 2a801221b..3c97dd1f8 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,13 +86,16 @@ 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());
+ boolean skipReadonly = false;
if (entity instanceof User) {
+ User after = (User) entity;
User before = storage.getObject(User.class, new Request(
new Columns.All(), new Condition.Equals("id", entity.getId())));
permissionsService.checkUserUpdate(getUserId(), before, (User) entity);
+ skipReadonly = permissionsService.getUser(getUserId())
+ .compare(after, "notificationTokens", "termsAccepted");
} else if (entity instanceof Group) {
Group group = (Group) entity;
if (group.getId() == group.getGroupId()) {
@@ -100,6 +103,8 @@ public abstract class BaseObjectResource<T extends BaseModel> extends BaseResour
}
}
+ permissionsService.checkEdit(getUserId(), entity, false, skipReadonly);
+
storage.updateObject(entity, new Request(
new Columns.Exclude("id"),
new Condition.Equals("id", entity.getId())));
@@ -120,8 +125,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/resource/DeviceResource.java b/src/main/java/org/traccar/api/resource/DeviceResource.java
index 971c29c60..61d96669e 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())));
diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java
index d60bbafb8..d4a6fba1a 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,9 +123,11 @@ 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);
+ checkEdit(userId, object.getClass(), addition, skipReadonly);
if (object instanceof GroupedModel) {
GroupedModel after = ((GroupedModel) object);
if (after.getGroupId() > 0) {
diff --git a/src/main/java/org/traccar/model/User.java b/src/main/java/org/traccar/model/User.java
index 9b8ee3e53..7cf8c25a6 100644
--- a/src/main/java/org/traccar/model/User.java
+++ b/src/main/java/org/traccar/model/User.java
@@ -17,11 +17,13 @@ package org.traccar.model;
import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.apache.commons.lang3.builder.EqualsBuilder;
import org.traccar.storage.QueryIgnore;
import org.traccar.helper.Hashing;
import org.traccar.storage.StorageName;
import java.util.Date;
+import java.util.HashMap;
@StorageName("tc_users")
public class User extends ExtendedModel implements UserRestrictions, Disableable {
@@ -305,4 +307,17 @@ public class User extends ExtendedModel implements UserRestrictions, Disableable
return Hashing.validatePassword(password, hashedPassword, salt);
}
+ public boolean compare(User other, String... exclusions) {
+ if (!EqualsBuilder.reflectionEquals(this, other, "attributes", "hashedPassword", "salt")) {
+ return false;
+ }
+ var thisAttributes = new HashMap<>(getAttributes());
+ var otherAttributes = new HashMap<>(other.getAttributes());
+ for (String exclusion : exclusions) {
+ thisAttributes.remove(exclusion);
+ otherAttributes.remove(exclusion);
+ }
+ return thisAttributes.equals(otherAttributes);
+ }
+
}