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/Context.java13
-rw-r--r--src/main/java/org/traccar/MainModule.java9
-rw-r--r--src/main/java/org/traccar/api/BaseObjectResource.java17
-rw-r--r--src/main/java/org/traccar/api/resource/DeviceResource.java16
-rw-r--r--src/main/java/org/traccar/api/resource/PasswordResource.java43
-rw-r--r--src/main/java/org/traccar/api/resource/SessionResource.java6
-rw-r--r--src/main/java/org/traccar/api/resource/UserResource.java77
-rw-r--r--src/main/java/org/traccar/api/security/PermissionsService.java33
-rw-r--r--src/main/java/org/traccar/database/DataManager.java3
-rw-r--r--src/main/java/org/traccar/database/DeviceManager.java16
-rw-r--r--src/main/java/org/traccar/database/PermissionsManager.java98
-rw-r--r--src/main/java/org/traccar/database/SimpleObjectManager.java70
-rw-r--r--src/main/java/org/traccar/database/UsersManager.java99
13 files changed, 141 insertions, 359 deletions
diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java
index 51c420390..5eaa1e15c 100644
--- a/src/main/java/org/traccar/Context.java
+++ b/src/main/java/org/traccar/Context.java
@@ -23,12 +23,10 @@ import org.traccar.database.DeviceManager;
import org.traccar.database.GroupsManager;
import org.traccar.database.IdentityManager;
import org.traccar.database.PermissionsManager;
-import org.traccar.database.UsersManager;
import org.traccar.helper.Log;
import org.traccar.model.BaseModel;
import org.traccar.model.Device;
import org.traccar.model.Group;
-import org.traccar.model.User;
import org.traccar.session.ConnectionManager;
public final class Context {
@@ -54,12 +52,6 @@ public final class Context {
return dataManager;
}
- private static UsersManager usersManager;
-
- public static UsersManager getUsersManager() {
- return usersManager;
- }
-
private static GroupsManager groupsManager;
public static GroupsManager getGroupsManager() {
@@ -94,7 +86,6 @@ public final class Context {
}
if (dataManager != null) {
- usersManager = new UsersManager(dataManager);
groupsManager = new GroupsManager(dataManager);
deviceManager = new DeviceManager(
config, dataManager, Main.getInjector().getInstance(ConnectionManager.class));
@@ -102,7 +93,7 @@ public final class Context {
identityManager = deviceManager;
- permissionsManager = new PermissionsManager(dataManager, usersManager);
+ permissionsManager = new PermissionsManager(dataManager, dataManager.getStorage());
}
@@ -111,8 +102,6 @@ public final class Context {
return (BaseObjectManager<T>) deviceManager;
} else if (clazz.equals(Group.class)) {
return (BaseObjectManager<T>) groupsManager;
- } else if (clazz.equals(User.class)) {
- return (BaseObjectManager<T>) usersManager;
}
return null;
}
diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java
index dd496e5a4..dd7e375d3 100644
--- a/src/main/java/org/traccar/MainModule.java
+++ b/src/main/java/org/traccar/MainModule.java
@@ -31,7 +31,6 @@ import org.traccar.broadcast.BroadcastService;
import org.traccar.config.Config;
import org.traccar.config.Keys;
import org.traccar.database.LdapProvider;
-import org.traccar.database.UsersManager;
import org.traccar.helper.SanitizerModule;
import org.traccar.notification.EventForwarder;
import org.traccar.database.DataManager;
@@ -119,11 +118,6 @@ public class MainModule extends AbstractModule {
}
@Provides
- public static UsersManager provideUsersManager() {
- return Context.getUsersManager();
- }
-
- @Provides
public static IdentityManager provideIdentityManager() {
return Context.getIdentityManager();
}
@@ -292,8 +286,7 @@ public class MainModule extends AbstractModule {
}
@Provides
- public static EventForwarder provideEventForwarder(
- Config config, Client client, CacheManager cacheManager, UsersManager usersManager) {
+ public static EventForwarder provideEventForwarder(Config config, Client client, CacheManager cacheManager) {
if (config.hasKey(Keys.EVENT_FORWARD_URL)) {
return new EventForwarder(config, client, cacheManager);
}
diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java
index aa777f3f6..f8545a5d7 100644
--- a/src/main/java/org/traccar/api/BaseObjectResource.java
+++ b/src/main/java/org/traccar/api/BaseObjectResource.java
@@ -19,7 +19,6 @@ package org.traccar.api;
import org.traccar.Context;
import org.traccar.database.BaseObjectManager;
import org.traccar.database.ExtendedObjectManager;
-import org.traccar.database.SimpleObjectManager;
import org.traccar.helper.LogAction;
import org.traccar.model.BaseModel;
import org.traccar.model.Device;
@@ -82,9 +81,7 @@ public abstract class BaseObjectResource<T extends BaseModel> extends BaseResour
cacheManager.invalidate(User.class, getUserId(), baseClass, entity.getId());
LogAction.link(getUserId(), User.class, getUserId(), baseClass, entity.getId());
- if (manager instanceof SimpleObjectManager) {
- ((SimpleObjectManager<T>) manager).refreshUserItems();
- } else if (baseClass.equals(Group.class) || baseClass.equals(Device.class)) {
+ if (baseClass.equals(Group.class) || baseClass.equals(Device.class)) {
Context.getPermissionsManager().refreshDeviceAndGroupPermissions();
}
return Response.ok(entity).build();
@@ -95,6 +92,11 @@ public abstract class BaseObjectResource<T extends BaseModel> extends BaseResour
public Response update(T entity) throws StorageException {
permissionsService.checkEdit(getUserId(), entity, false);
permissionsService.checkPermission(baseClass, getUserId(), entity.getId());
+ if (entity instanceof User) {
+ User before = storage.getObject(User.class, new Request(
+ new Columns.All(), new Condition.Equals("id", "id", entity.getId())));
+ permissionsService.checkUserUpdate(getUserId(), before, (User) entity);
+ }
BaseObjectManager<T> manager = Context.getManager(baseClass);
if (manager != null) {
@@ -123,11 +125,8 @@ public abstract class BaseObjectResource<T extends BaseModel> extends BaseResour
BaseObjectManager<T> manager = Context.getManager(baseClass);
if (manager != null) {
manager.removeItem(id);
- if (manager instanceof SimpleObjectManager) {
- ((SimpleObjectManager<T>) manager).refreshUserItems();
- if (manager instanceof ExtendedObjectManager) {
- ((ExtendedObjectManager<T>) manager).refreshExtendedPermissions();
- }
+ if (manager instanceof ExtendedObjectManager) {
+ ((ExtendedObjectManager<T>) manager).refreshExtendedPermissions();
}
} else {
storage.removeObject(baseClass, new Request(new Condition.Equals("id", "id", id)));
diff --git a/src/main/java/org/traccar/api/resource/DeviceResource.java b/src/main/java/org/traccar/api/resource/DeviceResource.java
index 309308e75..cd5ebf0c5 100644
--- a/src/main/java/org/traccar/api/resource/DeviceResource.java
+++ b/src/main/java/org/traccar/api/resource/DeviceResource.java
@@ -49,7 +49,7 @@ public class DeviceResource extends BaseObjectResource<Device> {
public Collection<Device> get(
@QueryParam("all") boolean all, @QueryParam("userId") long userId,
@QueryParam("uniqueId") List<String> uniqueIds,
- @QueryParam("id") List<Long> deviceIds) {
+ @QueryParam("id") List<Long> deviceIds) throws StorageException {
DeviceManager deviceManager = Context.getDeviceManager();
Set<Long> result;
if (all) {
@@ -57,13 +57,13 @@ public class DeviceResource extends BaseObjectResource<Device> {
result = deviceManager.getAllItems();
} else {
Context.getPermissionsManager().checkManager(getUserId());
- result = deviceManager.getManagedItems(getUserId());
+ result = deviceManager.getUserItems(getUserId());
}
} else if (uniqueIds.isEmpty() && deviceIds.isEmpty()) {
if (userId == 0) {
userId = getUserId();
}
- Context.getPermissionsManager().checkUser(getUserId(), userId);
+ permissionsService.checkUser(getUserId(), userId);
if (Context.getPermissionsManager().getUserAdmin(getUserId())) {
result = deviceManager.getAllUserItems(userId);
} else {
@@ -73,11 +73,11 @@ public class DeviceResource extends BaseObjectResource<Device> {
result = new HashSet<>();
for (String uniqueId : uniqueIds) {
Device device = deviceManager.getByUniqueId(uniqueId);
- Context.getPermissionsManager().checkDevice(getUserId(), device.getId());
+ permissionsService.checkPermission(Device.class, getUserId(), device.getId());
result.add(device.getId());
}
for (Long deviceId : deviceIds) {
- Context.getPermissionsManager().checkDevice(getUserId(), deviceId);
+ permissionsService.checkPermission(Device.class, getUserId(), deviceId);
result.add(deviceId);
}
}
@@ -87,9 +87,9 @@ public class DeviceResource extends BaseObjectResource<Device> {
@Path("{id}/accumulators")
@PUT
public Response updateAccumulators(DeviceAccumulators entity) throws StorageException {
- if (!Context.getPermissionsManager().getUserAdmin(getUserId())) {
- Context.getPermissionsManager().checkManager(getUserId());
- Context.getPermissionsManager().checkPermission(Device.class, getUserId(), entity.getDeviceId());
+ if (permissionsService.notAdmin(getUserId())) {
+ permissionsService.checkManager(getUserId());
+ permissionsService.checkPermission(Device.class, getUserId(), entity.getDeviceId());
}
Context.getDeviceManager().resetDeviceAccumulators(entity);
LogAction.resetDeviceAccumulators(getUserId(), entity.getDeviceId());
diff --git a/src/main/java/org/traccar/api/resource/PasswordResource.java b/src/main/java/org/traccar/api/resource/PasswordResource.java
index c7244f41c..643471797 100644
--- a/src/main/java/org/traccar/api/resource/PasswordResource.java
+++ b/src/main/java/org/traccar/api/resource/PasswordResource.java
@@ -15,12 +15,14 @@
*/
package org.traccar.api.resource;
-import org.traccar.Context;
import org.traccar.api.BaseResource;
import org.traccar.database.MailManager;
import org.traccar.model.User;
import org.traccar.notification.TextTemplateFormatter;
import org.traccar.storage.StorageException;
+import org.traccar.storage.query.Columns;
+import org.traccar.storage.query.Condition;
+import org.traccar.storage.query.Request;
import javax.annotation.security.PermitAll;
import javax.inject.Inject;
@@ -51,18 +53,17 @@ public class PasswordResource extends BaseResource {
@PermitAll
@POST
public Response reset(@FormParam("email") String email) throws StorageException, MessagingException {
- for (long userId : Context.getUsersManager().getAllItems()) {
- User user = Context.getUsersManager().getById(userId);
- if (email.equals(user.getEmail())) {
- String token = UUID.randomUUID().toString().replaceAll("-", "");
- user.set(PASSWORD_RESET_TOKEN, token);
- Context.getUsersManager().updateItem(user);
- var velocityContext = textTemplateFormatter.prepareContext(permissionsService.getServer(), user);
- velocityContext.put("token", token);
- var fullMessage = textTemplateFormatter.formatMessage(velocityContext, "passwordReset", "full");
- mailManager.sendMessage(user, fullMessage.getSubject(), fullMessage.getBody());
- break;
- }
+ User user = storage.getObject(User.class, new Request(
+ new Columns.All(), new Condition.Equals("email", "email", email)));
+ if (user != null) {
+ String token = UUID.randomUUID().toString().replaceAll("-", "");
+ user.set(PASSWORD_RESET_TOKEN, token);
+ storage.updateObject(user, new Request(new Columns.Exclude("id"), new Condition.Equals("id", "id")));
+
+ var velocityContext = textTemplateFormatter.prepareContext(permissionsService.getServer(), user);
+ velocityContext.put("token", token);
+ var fullMessage = textTemplateFormatter.formatMessage(velocityContext, "passwordReset", "full");
+ mailManager.sendMessage(user, fullMessage.getSubject(), fullMessage.getBody());
}
return Response.ok().build();
}
@@ -72,14 +73,14 @@ public class PasswordResource extends BaseResource {
@POST
public Response update(
@FormParam("token") String token, @FormParam("password") String password) throws StorageException {
- for (long userId : Context.getUsersManager().getAllItems()) {
- User user = Context.getUsersManager().getById(userId);
- if (token.equals(user.getString(PASSWORD_RESET_TOKEN))) {
- user.getAttributes().remove(PASSWORD_RESET_TOKEN);
- user.setPassword(password);
- Context.getUsersManager().updateItem(user);
- return Response.ok().build();
- }
+ User user = storage.getObjects(User.class, new Request(new Columns.All())).stream()
+ .filter(it -> token.equals(it.getString(PASSWORD_RESET_TOKEN)))
+ .findFirst().orElse(null);
+ if (user != null) {
+ user.getAttributes().remove(PASSWORD_RESET_TOKEN);
+ user.setPassword(password);
+ storage.updateObject(user, new Request(new Columns.Exclude("id"), new Condition.Equals("id", "id")));
+ return Response.ok().build();
}
return Response.status(Response.Status.NOT_FOUND).build();
}
diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java
index 1ccba1270..a0bf0cba5 100644
--- a/src/main/java/org/traccar/api/resource/SessionResource.java
+++ b/src/main/java/org/traccar/api/resource/SessionResource.java
@@ -22,6 +22,9 @@ import org.traccar.helper.ServletHelper;
import org.traccar.helper.LogAction;
import org.traccar.model.User;
import org.traccar.storage.StorageException;
+import org.traccar.storage.query.Columns;
+import org.traccar.storage.query.Condition;
+import org.traccar.storage.query.Request;
import javax.annotation.security.PermitAll;
import javax.servlet.http.Cookie;
@@ -59,7 +62,8 @@ public class SessionResource extends BaseResource {
public User get(@QueryParam("token") String token) throws StorageException, UnsupportedEncodingException {
if (token != null) {
- User user = Context.getUsersManager().getUserByToken(token);
+ User user = storage.getObject(User.class, new Request(
+ new Columns.All(), new Condition.Equals("token", "token", token)));
if (user != null) {
Context.getPermissionsManager().checkUserEnabled(user.getId());
request.getSession().setAttribute(USER_ID_KEY, user.getId());
diff --git a/src/main/java/org/traccar/api/resource/UserResource.java b/src/main/java/org/traccar/api/resource/UserResource.java
index 84f41ca1a..20fce9e32 100644
--- a/src/main/java/org/traccar/api/resource/UserResource.java
+++ b/src/main/java/org/traccar/api/resource/UserResource.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2017 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.
@@ -15,17 +15,20 @@
*/
package org.traccar.api.resource;
-import org.traccar.Context;
import org.traccar.api.BaseObjectResource;
+import org.traccar.config.Config;
import org.traccar.config.Keys;
-import org.traccar.database.UsersManager;
import org.traccar.helper.LogAction;
import org.traccar.model.ManagedUser;
import org.traccar.model.Permission;
import org.traccar.model.User;
import org.traccar.storage.StorageException;
+import org.traccar.storage.query.Columns;
+import org.traccar.storage.query.Condition;
+import org.traccar.storage.query.Request;
import javax.annotation.security.PermitAll;
+import javax.inject.Inject;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
@@ -34,63 +37,77 @@ import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
-import java.sql.SQLException;
import java.util.Collection;
import java.util.Date;
-import java.util.Set;
@Path("users")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class UserResource extends BaseObjectResource<User> {
+ @Inject
+ private Config config;
+
public UserResource() {
super(User.class);
}
@GET
- public Collection<User> get(@QueryParam("userId") long userId) throws SQLException {
- UsersManager usersManager = Context.getUsersManager();
- Set<Long> result;
- if (Context.getPermissionsManager().getUserAdmin(getUserId())) {
- if (userId != 0) {
- result = usersManager.getUserItems(userId);
- } else {
- result = usersManager.getAllItems();
- }
- } else if (Context.getPermissionsManager().getUserManager(getUserId())) {
- result = usersManager.getManagedItems(getUserId());
+ public Collection<User> get(@QueryParam("userId") long userId) throws StorageException {
+ permissionsService.checkUser(getUserId(), userId);
+ if (userId > 0) {
+ return storage.getObjects(baseClass, new Request(
+ new Columns.All(),
+ new Condition.Permission(User.class, userId, ManagedUser.class).excludeGroups()));
+ } else if (permissionsService.notAdmin(getUserId())) {
+ return storage.getObjects(baseClass, new Request(
+ new Columns.All(),
+ new Condition.Permission(User.class, getUserId(), ManagedUser.class).excludeGroups()));
} else {
- throw new SecurityException("Admin or manager access required");
+ return storage.getObjects(baseClass, new Request(new Columns.All()));
}
- return usersManager.getItems(result);
}
@Override
@PermitAll
@POST
public Response add(User entity) throws StorageException {
- if (!Context.getPermissionsManager().getUserAdmin(getUserId())) {
- Context.getPermissionsManager().checkUserUpdate(getUserId(), new User(), entity);
- if (Context.getPermissionsManager().getUserManager(getUserId())) {
- Context.getPermissionsManager().checkUserLimit(getUserId());
+ User currentUser = permissionsService.getUser(getUserId());
+ if (permissionsService.notAdmin(getUserId())) {
+ permissionsService.checkUserUpdate(getUserId(), new User(), entity);
+ if (currentUser != null && currentUser.getUserLimit() != 0) {
+ int userLimit = currentUser.getUserLimit();
+ if (userLimit > 0) {
+ int userCount = storage.getObjects(baseClass, new Request(
+ new Columns.All(),
+ new Condition.Permission(User.class, getUserId(), ManagedUser.class).excludeGroups()))
+ .size();
+ if (userCount >= userLimit) {
+ throw new SecurityException("Manager user limit reached");
+ }
+ }
} else {
- Context.getPermissionsManager().checkRegistration(getUserId());
- entity.setDeviceLimit(Context.getConfig().getInteger(Keys.USERS_DEFAULT_DEVICE_LIMIT));
- int expirationDays = Context.getConfig().getInteger(Keys.USERS_DEFAULT_EXPIRATION_DAYS);
+ if (!permissionsService.getServer().getRegistration()) {
+ throw new SecurityException("Registration disabled");
+ }
+ entity.setDeviceLimit(config.getInteger(Keys.USERS_DEFAULT_DEVICE_LIMIT));
+ int expirationDays = config.getInteger(Keys.USERS_DEFAULT_EXPIRATION_DAYS);
if (expirationDays > 0) {
- entity.setExpirationTime(
- new Date(System.currentTimeMillis() + (long) expirationDays * 24 * 3600 * 1000));
+ entity.setExpirationTime(new Date(System.currentTimeMillis() + expirationDays * 86400000L));
}
}
}
- Context.getUsersManager().addItem(entity);
+
+ entity.setId(storage.addObject(entity, new Request(new Columns.Exclude("id"))));
+ storage.updateObject(entity, new Request(
+ new Columns.Include("hashedPassword", "salt"), new Condition.Equals("id", "id")));
+
LogAction.create(getUserId(), entity);
- if (Context.getPermissionsManager().getUserManager(getUserId())) {
+
+ if (currentUser != null && currentUser.getUserLimit() != 0) {
storage.addPermission(new Permission(User.class, getUserId(), ManagedUser.class, entity.getId()));
LogAction.link(getUserId(), User.class, getUserId(), ManagedUser.class, entity.getId());
}
- Context.getUsersManager().refreshUserItems();
return Response.ok(entity).build();
}
diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java
index c70414b2a..f39ded2b7 100644
--- a/src/main/java/org/traccar/api/security/PermissionsService.java
+++ b/src/main/java/org/traccar/api/security/PermissionsService.java
@@ -57,7 +57,7 @@ public class PermissionsService {
}
public User getUser(long userId) throws StorageException {
- if (user == null) {
+ if (user == null && userId > 0) {
user = storage.getObject(
User.class, new Request(new Columns.All(), new Condition.Equals("id", "id", userId)));
}
@@ -74,6 +74,12 @@ public class PermissionsService {
}
}
+ public void checkManager(long userId) throws StorageException, SecurityException {
+ if (!getUser(userId).getAdministrator() && getUser(userId).getUserLimit() == 0) {
+ throw new SecurityException("Manager access required");
+ }
+ }
+
public interface CheckRestrictionCallback {
boolean denied(UserRestrictions userRestrictions);
}
@@ -137,6 +143,31 @@ public class PermissionsService {
}
}
+ public void checkUserUpdate(long userId, User before, User after) throws StorageException, SecurityException {
+ if (before.getAdministrator() != after.getAdministrator()
+ || before.getDeviceLimit() != after.getDeviceLimit()
+ || before.getUserLimit() != after.getUserLimit()) {
+ checkAdmin(userId);
+ }
+ User user = getUser(userId);
+ if (user != null && user.getExpirationTime() != null
+ && (after.getExpirationTime() == null
+ || user.getExpirationTime().compareTo(after.getExpirationTime()) < 0)) {
+ checkAdmin(userId);
+ }
+ if (before.getReadonly() != after.getReadonly()
+ || before.getDeviceReadonly() != after.getDeviceReadonly()
+ || before.getDisabled() != after.getDisabled()
+ || before.getLimitCommands() != after.getLimitCommands()
+ || before.getDisableReports() != after.getDisableReports()) {
+ if (userId == after.getId()) {
+ checkAdmin(userId);
+ } else {
+ checkUser(userId, after.getId());
+ }
+ }
+ }
+
public <T extends BaseModel> void checkPermission(
Class<T> clazz, long userId, long objectId) throws StorageException, SecurityException {
if (!getUser(userId).getAdministrator() && !(clazz.equals(User.class) && userId == objectId)) {
diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java
index fd45a0321..6921634dd 100644
--- a/src/main/java/org/traccar/database/DataManager.java
+++ b/src/main/java/org/traccar/database/DataManager.java
@@ -25,7 +25,6 @@ import liquibase.database.DatabaseFactory;
import liquibase.exception.LiquibaseException;
import liquibase.resource.FileSystemResourceAccessor;
import liquibase.resource.ResourceAccessor;
-import org.traccar.Context;
import org.traccar.Main;
import org.traccar.config.Config;
import org.traccar.config.Keys;
@@ -155,7 +154,7 @@ public class DataManager {
} else {
if (ldapProvider != null && ldapProvider.login(email, password)) {
user = ldapProvider.getUser(email);
- Context.getUsersManager().addItem(user);
+ user.setId(storage.addObject(user, new Request(new Columns.Exclude("id"))));
return user;
}
}
diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java
index e1d6ad1dd..9ba486988 100644
--- a/src/main/java/org/traccar/database/DeviceManager.java
+++ b/src/main/java/org/traccar/database/DeviceManager.java
@@ -177,22 +177,6 @@ public class DeviceManager extends BaseObjectManager<Device> implements Identity
}
}
- public Set<Long> getAllManagedItems(long userId) {
- Set<Long> result = new HashSet<>(getAllUserItems(userId));
- for (long managedUserId : Context.getUsersManager().getUserItems(userId)) {
- result.addAll(getAllUserItems(managedUserId));
- }
- return result;
- }
-
- public Set<Long> getManagedItems(long userId) {
- Set<Long> result = new HashSet<>(getUserItems(userId));
- for (long managedUserId : Context.getUsersManager().getUserItems(userId)) {
- result.addAll(getUserItems(managedUserId));
- }
- return result;
- }
-
private void addByUniqueId(Device device) {
try {
writeLock();
diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java
index f34810439..833480eea 100644
--- a/src/main/java/org/traccar/database/PermissionsManager.java
+++ b/src/main/java/org/traccar/database/PermissionsManager.java
@@ -18,14 +18,17 @@ package org.traccar.database;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.traccar.Context;
-import org.traccar.model.BaseModel;
+import org.traccar.api.security.PermissionsService;
import org.traccar.model.Device;
import org.traccar.model.Group;
-import org.traccar.model.ManagedUser;
import org.traccar.model.Permission;
import org.traccar.model.Server;
import org.traccar.model.User;
+import org.traccar.storage.Storage;
import org.traccar.storage.StorageException;
+import org.traccar.storage.query.Columns;
+import org.traccar.storage.query.Condition;
+import org.traccar.storage.query.Request;
import java.util.HashMap;
import java.util.HashSet;
@@ -39,7 +42,7 @@ public class PermissionsManager {
private static final Logger LOGGER = LoggerFactory.getLogger(PermissionsManager.class);
private final DataManager dataManager;
- private final UsersManager usersManager;
+ private final Storage storage;
private volatile Server server;
@@ -50,9 +53,9 @@ public class PermissionsManager {
private final Map<Long, Set<Long>> deviceUsers = new HashMap<>();
private final Map<Long, Set<Long>> groupDevices = new HashMap<>();
- public PermissionsManager(DataManager dataManager, UsersManager usersManager) {
+ public PermissionsManager(DataManager dataManager, Storage storage) {
this.dataManager = dataManager;
- this.usersManager = usersManager;
+ this.storage = storage;
refreshServer();
refreshDeviceAndGroupPermissions();
}
@@ -74,11 +77,11 @@ public class PermissionsManager {
}
public User getUser(long userId) {
- readLock();
try {
- return usersManager.getById(userId);
- } finally {
- readUnlock();
+ return storage.getObject(User.class, new Request(
+ new Columns.All(), new Condition.Equals("id", "id", userId)));
+ } catch (StorageException e) {
+ throw new RuntimeException(e);
}
}
@@ -222,20 +225,6 @@ public class PermissionsManager {
}
}
- public void checkManager(long userId, long managedUserId) throws SecurityException {
- checkManager(userId);
- if (!usersManager.getUserItems(userId).contains(managedUserId)) {
- throw new SecurityException("User access denied");
- }
- }
-
- public void checkUserLimit(long userId) throws SecurityException {
- int userLimit = getUser(userId).getUserLimit();
- if (userLimit != -1 && usersManager.getUserItems(userId).size() >= userLimit) {
- throw new SecurityException("Manager user limit reached");
- }
- }
-
public boolean getUserReadonly(long userId) {
User user = getUser(userId);
return user != null && user.getReadonly();
@@ -260,64 +249,11 @@ public class PermissionsManager {
}
}
- public void checkUserUpdate(long userId, User before, User after) throws SecurityException {
- if (before.getAdministrator() != after.getAdministrator()
- || before.getDeviceLimit() != after.getDeviceLimit()
- || before.getUserLimit() != after.getUserLimit()) {
- checkAdmin(userId);
- }
- User user = getUser(userId);
- if (user != null && user.getExpirationTime() != null
- && (after.getExpirationTime() == null
- || user.getExpirationTime().compareTo(after.getExpirationTime()) < 0)) {
- checkAdmin(userId);
- }
- if (before.getReadonly() != after.getReadonly()
- || before.getDeviceReadonly() != after.getDeviceReadonly()
- || before.getDisabled() != after.getDisabled()
- || before.getLimitCommands() != after.getLimitCommands()
- || before.getDisableReports() != after.getDisableReports()) {
- if (userId == after.getId()) {
- checkAdmin(userId);
- }
- if (!getUserAdmin(userId)) {
- checkManager(userId);
- }
- }
- }
-
- public void checkUser(long userId, long managedUserId) throws SecurityException {
- if (userId != managedUserId && !getUserAdmin(userId)) {
- checkManager(userId, managedUserId);
- }
- }
-
public void checkDevice(long userId, long deviceId) throws SecurityException {
- if (!Context.getDeviceManager().getUserItems(userId).contains(deviceId) && !getUserAdmin(userId)) {
- checkManager(userId);
- for (long managedUserId : usersManager.getUserItems(userId)) {
- if (Context.getDeviceManager().getUserItems(managedUserId).contains(deviceId)) {
- return;
- }
- }
- throw new SecurityException("Device access denied");
- }
- }
-
- public void checkRegistration(long userId) {
- if (!server.getRegistration() && !getUserAdmin(userId)) {
- throw new SecurityException("Registration disabled");
- }
- }
-
- public void checkPermission(Class<?> object, long userId, long objectId)
- throws SecurityException {
- SimpleObjectManager<? extends BaseModel> manager = null;
-
- if (object.equals(Device.class)) {
- checkDevice(userId, objectId);
- } else {
- throw new IllegalArgumentException("Unknown object type");
+ try {
+ new PermissionsService(storage).checkPermission(Device.class, userId, deviceId);
+ } catch (StorageException e) {
+ throw new RuntimeException(e);
}
}
@@ -326,8 +262,6 @@ public class PermissionsManager {
if (permission.getPropertyClass().equals(Device.class)
|| permission.getPropertyClass().equals(Group.class)) {
refreshDeviceAndGroupPermissions();
- } else if (permission.getPropertyClass().equals(ManagedUser.class)) {
- usersManager.refreshUserItems();
}
}
}
diff --git a/src/main/java/org/traccar/database/SimpleObjectManager.java b/src/main/java/org/traccar/database/SimpleObjectManager.java
index 74bbc054f..8bb22b8a8 100644
--- a/src/main/java/org/traccar/database/SimpleObjectManager.java
+++ b/src/main/java/org/traccar/database/SimpleObjectManager.java
@@ -16,82 +16,12 @@
*/
package org.traccar.database;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.traccar.Context;
import org.traccar.model.BaseModel;
-import org.traccar.model.Permission;
-import org.traccar.model.User;
-import org.traccar.storage.StorageException;
public abstract class SimpleObjectManager<T extends BaseModel> extends BaseObjectManager<T> {
- private static final Logger LOGGER = LoggerFactory.getLogger(SimpleObjectManager.class);
-
- private Map<Long, Set<Long>> userItems;
-
protected SimpleObjectManager(DataManager dataManager, Class<T> baseClass) {
super(dataManager, baseClass);
}
- public final Set<Long> getUserItems(long userId) {
- try {
- readLock();
- Set<Long> result = userItems.get(userId);
- if (result != null) {
- return new HashSet<>(result);
- } else {
- return new HashSet<>();
- }
- } finally {
- readUnlock();
- }
- }
-
- public Set<Long> getManagedItems(long userId) {
- Set<Long> result = getUserItems(userId);
- for (long managedUserId : Context.getUsersManager().getUserItems(userId)) {
- result.addAll(getUserItems(managedUserId));
- }
- return result;
- }
-
- public final boolean checkItemPermission(long userId, long itemId) {
- return getUserItems(userId).contains(itemId);
- }
-
- @Override
- public void refreshItems() {
- super.refreshItems();
- refreshUserItems();
- }
-
- public final void refreshUserItems() {
- if (getDataManager() != null) {
- try {
- writeLock();
- userItems = new ConcurrentHashMap<>();
- for (Permission permission : getDataManager().getPermissions(User.class, getBaseClass())) {
- Set<Long> items = userItems.computeIfAbsent(permission.getOwnerId(), key -> new HashSet<>());
- items.add(permission.getPropertyId());
- }
- } catch (StorageException | ClassNotFoundException error) {
- LOGGER.warn("Error getting permissions", error);
- } finally {
- writeUnlock();
- }
- }
- }
-
- @Override
- public void removeItem(long itemId) throws StorageException {
- super.removeItem(itemId);
- refreshUserItems();
- }
-
}
diff --git a/src/main/java/org/traccar/database/UsersManager.java b/src/main/java/org/traccar/database/UsersManager.java
deleted file mode 100644
index a54226cfe..000000000
--- a/src/main/java/org/traccar/database/UsersManager.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright 2017 - 2020 Anton Tananaev (anton@traccar.org)
- * Copyright 2017 Andrey Kunitsyn (andrey@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.database;
-
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.traccar.model.User;
-import org.traccar.storage.StorageException;
-
-public class UsersManager extends SimpleObjectManager<User> {
-
- private Map<String, User> usersTokens;
-
- public UsersManager(DataManager dataManager) {
- super(dataManager, User.class);
- if (usersTokens == null) {
- usersTokens = new ConcurrentHashMap<>();
- }
- }
-
- private void putToken(User user) {
- if (usersTokens == null) {
- usersTokens = new ConcurrentHashMap<>();
- }
- if (user.getToken() != null) {
- usersTokens.put(user.getToken(), user);
- }
- }
-
- @Override
- protected void addNewItem(User user) {
- super.addNewItem(user);
- putToken(user);
- }
-
- @Override
- protected void updateCachedItem(User user) {
- User cachedUser = getById(user.getId());
- super.updateCachedItem(user);
- putToken(user);
- if (cachedUser.getToken() != null && !cachedUser.getToken().equals(user.getToken())) {
- usersTokens.remove(cachedUser.getToken());
- }
- }
-
- @Override
- public void addItem(User user) throws StorageException {
- super.addItem(user);
- getDataManager().updateUserPassword(user);
- }
-
- @Override
- public void updateItem(User user) throws StorageException {
- if (user.getHashedPassword() != null) {
- getDataManager().updateUserPassword(user);
- }
- super.updateItem(user);
- }
-
- @Override
- protected void removeCachedItem(long userId) {
- User cachedUser = getById(userId);
- if (cachedUser != null) {
- String userToken = cachedUser.getToken();
- super.removeCachedItem(userId);
- if (userToken != null) {
- usersTokens.remove(userToken);
- }
- }
- }
-
- @Override
- public Set<Long> getManagedItems(long userId) {
- Set<Long> result = getUserItems(userId);
- result.add(userId);
- return result;
- }
-
- public User getUserByToken(String token) {
- return usersTokens.get(token);
- }
-
-}