aboutsummaryrefslogtreecommitdiff
path: root/src/org/traccar/database/PermissionsManager.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/traccar/database/PermissionsManager.java')
-rw-r--r--src/org/traccar/database/PermissionsManager.java373
1 files changed, 183 insertions, 190 deletions
diff --git a/src/org/traccar/database/PermissionsManager.java b/src/org/traccar/database/PermissionsManager.java
index 9a82efd48..07b60ba58 100644
--- a/src/org/traccar/database/PermissionsManager.java
+++ b/src/org/traccar/database/PermissionsManager.java
@@ -17,39 +17,48 @@ package org.traccar.database;
import org.traccar.Context;
import org.traccar.helper.Log;
+import org.traccar.model.Attribute;
+import org.traccar.model.BaseModel;
+import org.traccar.model.Calendar;
+import org.traccar.model.Command;
import org.traccar.model.Device;
-import org.traccar.model.DevicePermission;
+import org.traccar.model.Driver;
+import org.traccar.model.Geofence;
import org.traccar.model.Group;
-import org.traccar.model.GroupPermission;
+import org.traccar.model.ManagedUser;
+import org.traccar.model.Notification;
+import org.traccar.model.Permission;
import org.traccar.model.Server;
import org.traccar.model.User;
-import org.traccar.model.UserPermission;
-import java.lang.reflect.Method;
import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
public class PermissionsManager {
private final DataManager dataManager;
+ private final UsersManager usersManager;
private volatile Server server;
- private final Map<Long, User> users = new ConcurrentHashMap<>();
- private final Map<String, Long> usersTokens = new HashMap<>();
-
private final Map<Long, Set<Long>> groupPermissions = new HashMap<>();
private final Map<Long, Set<Long>> devicePermissions = new HashMap<>();
private final Map<Long, Set<Long>> deviceUsers = new HashMap<>();
private final Map<Long, Set<Long>> groupDevices = new HashMap<>();
- private final Map<Long, Set<Long>> userPermissions = new HashMap<>();
+ public PermissionsManager(DataManager dataManager, UsersManager usersManager) {
+ this.dataManager = dataManager;
+ this.usersManager = usersManager;
+ refreshServer();
+ refreshDeviceAndGroupPermissions();
+ }
+
+ public User getUser(long userId) {
+ return (User) usersManager.getById(userId);
+ }
public Set<Long> getGroupPermissions(long userId) {
if (!groupPermissions.containsKey(userId)) {
@@ -79,76 +88,45 @@ public class PermissionsManager {
return groupDevices.get(groupId);
}
- public Set<Long> getUserPermissions(long userId) {
- if (!userPermissions.containsKey(userId)) {
- userPermissions.put(userId, new HashSet<Long>());
- }
- return userPermissions.get(userId);
- }
-
- public PermissionsManager(DataManager dataManager) {
- this.dataManager = dataManager;
- refreshUsers();
- refreshPermissions();
- refreshUserPermissions();
- }
-
- public final void refreshUsers() {
- users.clear();
- usersTokens.clear();
+ public void refreshServer() {
try {
server = dataManager.getServer();
- for (User user : dataManager.getUsers()) {
- users.put(user.getId(), user);
- if (user.getToken() != null) {
- usersTokens.put(user.getToken(), user.getId());
- }
- }
- } catch (SQLException error) {
- Log.warning(error);
- }
- }
-
- public final void refreshUserPermissions() {
- userPermissions.clear();
- try {
- for (UserPermission permission : dataManager.getUserPermissions()) {
- getUserPermissions(permission.getUserId()).add(permission.getManagedUserId());
- }
} catch (SQLException error) {
Log.warning(error);
}
}
- public final void refreshPermissions() {
+ public final void refreshDeviceAndGroupPermissions() {
groupPermissions.clear();
devicePermissions.clear();
try {
- GroupTree groupTree = new GroupTree(Context.getDeviceManager().getAllGroups(),
+ GroupTree groupTree = new GroupTree(Context.getGroupsManager().getItems(
+ Context.getGroupsManager().getAllItems()),
Context.getDeviceManager().getAllDevices());
- for (GroupPermission permission : dataManager.getGroupPermissions()) {
- Set<Long> userGroupPermissions = getGroupPermissions(permission.getUserId());
- Set<Long> userDevicePermissions = getDevicePermissions(permission.getUserId());
- userGroupPermissions.add(permission.getGroupId());
- for (Group group : groupTree.getGroups(permission.getGroupId())) {
+ for (Permission groupPermission : dataManager.getPermissions(User.class, Group.class)) {
+ Set<Long> userGroupPermissions = getGroupPermissions(groupPermission.getOwnerId());
+ Set<Long> userDevicePermissions = getDevicePermissions(groupPermission.getOwnerId());
+ userGroupPermissions.add(groupPermission.getPropertyId());
+ for (Group group : groupTree.getGroups(groupPermission.getPropertyId())) {
userGroupPermissions.add(group.getId());
}
- for (Device device : groupTree.getDevices(permission.getGroupId())) {
+ for (Device device : groupTree.getDevices(groupPermission.getPropertyId())) {
userDevicePermissions.add(device.getId());
}
}
- for (DevicePermission permission : dataManager.getDevicePermissions()) {
- getDevicePermissions(permission.getUserId()).add(permission.getDeviceId());
+
+ for (Permission devicePermission : dataManager.getPermissions(User.class, Device.class)) {
+ getDevicePermissions(devicePermission.getOwnerId()).add(devicePermission.getPropertyId());
}
groupDevices.clear();
- for (Group group : Context.getDeviceManager().getAllGroups()) {
- for (Device device : groupTree.getDevices(group.getId())) {
- getGroupDevices(group.getId()).add(device.getId());
+ for (long groupId : Context.getGroupsManager().getAllItems()) {
+ for (Device device : groupTree.getDevices(groupId)) {
+ getGroupDevices(groupId).add(device.getId());
}
}
- } catch (SQLException error) {
+ } catch (SQLException | ClassNotFoundException error) {
Log.warning(error);
}
@@ -160,48 +138,50 @@ public class PermissionsManager {
}
}
- public boolean isAdmin(long userId) {
- return users.containsKey(userId) && users.get(userId).getAdmin();
+ public boolean getUserAdmin(long userId) {
+ User user = getUser(userId);
+ return user != null && user.getAdmin();
}
public void checkAdmin(long userId) throws SecurityException {
- if (!isAdmin(userId)) {
+ if (!getUserAdmin(userId)) {
throw new SecurityException("Admin access required");
}
}
- public boolean isManager(long userId) {
- return users.containsKey(userId) && users.get(userId).getUserLimit() != 0;
+ public boolean getUserManager(long userId) {
+ User user = getUser(userId);
+ return user != null && user.getUserLimit() != 0;
}
public void checkManager(long userId) throws SecurityException {
- if (!isManager(userId)) {
+ if (!getUserManager(userId)) {
throw new SecurityException("Manager access required");
}
}
public void checkManager(long userId, long managedUserId) throws SecurityException {
checkManager(userId);
- if (!getUserPermissions(userId).contains(managedUserId)) {
+ if (!usersManager.getUserItems(userId).contains(managedUserId)) {
throw new SecurityException("User access denied");
}
}
public void checkUserLimit(long userId) throws SecurityException {
- int userLimit = users.get(userId).getUserLimit();
- if (userLimit != -1 && getUserPermissions(userId).size() >= userLimit) {
+ int userLimit = getUser(userId).getUserLimit();
+ if (userLimit != -1 && usersManager.getUserItems(userId).size() >= userLimit) {
throw new SecurityException("Manager user limit reached");
}
}
public void checkDeviceLimit(long userId) throws SecurityException, SQLException {
- int deviceLimit = users.get(userId).getDeviceLimit();
+ int deviceLimit = getUser(userId).getDeviceLimit();
if (deviceLimit != -1) {
int deviceCount = 0;
- if (isManager(userId)) {
- deviceCount = Context.getDeviceManager().getManagedDevices(userId).size();
+ if (getUserManager(userId)) {
+ deviceCount = Context.getDeviceManager().getManagedItems(userId).size();
} else {
- deviceCount = getDevicePermissions(userId).size();
+ deviceCount = Context.getDeviceManager().getUserItems(userId).size();
}
if (deviceCount >= deviceLimit) {
throw new SecurityException("User device limit reached");
@@ -209,28 +189,50 @@ public class PermissionsManager {
}
}
- public boolean isReadonly(long userId) {
- return users.containsKey(userId) && users.get(userId).getReadonly();
+ public boolean getUserReadonly(long userId) {
+ User user = getUser(userId);
+ return user != null && user.getReadonly();
}
- public boolean isDeviceReadonly(long userId) {
- return users.containsKey(userId) && users.get(userId).getDeviceReadonly();
+ public boolean getUserDeviceReadonly(long userId) {
+ User user = getUser(userId);
+ return user != null && user.getDeviceReadonly();
+ }
+
+ public boolean getUserLimitCommands(long userId) {
+ User user = getUser(userId);
+ return user != null && user.getLimitCommands();
}
public void checkReadonly(long userId) throws SecurityException {
- if (!isAdmin(userId) && (server.getReadonly() || isReadonly(userId))) {
+ if (!getUserAdmin(userId) && (server.getReadonly() || getUserReadonly(userId))) {
throw new SecurityException("Account is readonly");
}
}
public void checkDeviceReadonly(long userId) throws SecurityException {
- if (!isAdmin(userId) && (server.getDeviceReadonly() || isDeviceReadonly(userId))) {
+ if (!getUserAdmin(userId) && (server.getDeviceReadonly() || getUserDeviceReadonly(userId))) {
throw new SecurityException("Account is device readonly");
}
}
+ public void checkLimitCommands(long userId) throws SecurityException {
+ if (!getUserAdmin(userId) && (server.getLimitCommands() || getUserLimitCommands(userId))) {
+ throw new SecurityException("Account has limit sending commands");
+ }
+ }
+
+ public void checkUserDeviceCommand(long userId, long deviceId, long commandId) throws SecurityException {
+ if (!getUserAdmin(userId) && Context.getCommandsManager().checkDeviceCommand(deviceId, commandId)) {
+ throw new SecurityException("Command can not be sent to this device");
+ }
+ }
+
public void checkUserEnabled(long userId) throws SecurityException {
User user = getUser(userId);
+ if (user == null) {
+ throw new SecurityException("Unknown account");
+ }
if (user.getDisabled()) {
throw new SecurityException("Account is disabled");
}
@@ -245,9 +247,10 @@ public class PermissionsManager {
|| before.getUserLimit() != after.getUserLimit()) {
checkAdmin(userId);
}
- if (users.containsKey(userId) && users.get(userId).getExpirationTime() != null
+ User user = getUser(userId);
+ if (user != null && user.getExpirationTime() != null
&& (after.getExpirationTime() == null
- || users.get(userId).getExpirationTime().compareTo(after.getExpirationTime()) < 0)) {
+ || user.getExpirationTime().compareTo(after.getExpirationTime()) < 0)) {
checkAdmin(userId);
}
if (before.getReadonly() != after.getReadonly()
@@ -256,22 +259,22 @@ public class PermissionsManager {
if (userId == after.getId()) {
checkAdmin(userId);
}
- if (!isAdmin(userId)) {
+ if (!getUserAdmin(userId)) {
checkManager(userId);
}
}
}
public void checkUser(long userId, long managedUserId) throws SecurityException {
- if (userId != managedUserId && !isAdmin(userId)) {
+ if (userId != managedUserId && !getUserAdmin(userId)) {
checkManager(userId, managedUserId);
}
}
public void checkGroup(long userId, long groupId) throws SecurityException {
- if (!getGroupPermissions(userId).contains(groupId) && !isAdmin(userId)) {
+ if (!getGroupPermissions(userId).contains(groupId) && !getUserAdmin(userId)) {
checkManager(userId);
- for (long managedUserId : getUserPermissions(userId)) {
+ for (long managedUserId : usersManager.getUserItems(userId)) {
if (getGroupPermissions(managedUserId).contains(groupId)) {
return;
}
@@ -281,10 +284,10 @@ public class PermissionsManager {
}
public void checkDevice(long userId, long deviceId) throws SecurityException {
- if (!getDevicePermissions(userId).contains(deviceId) && !isAdmin(userId)) {
+ if (!Context.getDeviceManager().getUserItems(userId).contains(deviceId) && !getUserAdmin(userId)) {
checkManager(userId);
- for (long managedUserId : getUserPermissions(userId)) {
- if (getDevicePermissions(managedUserId).contains(deviceId)) {
+ for (long managedUserId : usersManager.getUserItems(userId)) {
+ if (Context.getDeviceManager().getUserItems(managedUserId).contains(deviceId)) {
return;
}
}
@@ -293,44 +296,105 @@ public class PermissionsManager {
}
public void checkRegistration(long userId) {
- if (!server.getRegistration() && !isAdmin(userId)) {
+ if (!server.getRegistration() && !getUserAdmin(userId)) {
throw new SecurityException("Registration disabled");
}
}
- public void checkGeofence(long userId, long geofenceId) throws SecurityException {
- if (!Context.getGeofenceManager().checkGeofence(userId, geofenceId) && !isAdmin(userId)) {
- checkManager(userId);
- for (long managedUserId : getUserPermissions(userId)) {
- if (Context.getGeofenceManager().checkGeofence(managedUserId, geofenceId)) {
- return;
- }
- }
- throw new SecurityException("Geofence access denied");
+ 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 if (object.equals(Group.class)) {
+ checkGroup(userId, objectId);
+ } else if (object.equals(User.class) || object.equals(ManagedUser.class)) {
+ checkUser(userId, objectId);
+ } else if (object.equals(Geofence.class)) {
+ manager = Context.getGeofenceManager();
+ } else if (object.equals(Attribute.class)) {
+ manager = Context.getAttributesManager();
+ } else if (object.equals(Driver.class)) {
+ manager = Context.getDriversManager();
+ } else if (object.equals(Calendar.class)) {
+ manager = Context.getCalendarManager();
+ } else if (object.equals(Command.class)) {
+ manager = Context.getCommandsManager();
+ } else if (object.equals(Notification.class)) {
+ manager = Context.getNotificationManager();
+ } else {
+ throw new IllegalArgumentException("Unknown object type");
}
- }
- public void checkAttribute(long userId, long attributeId) throws SecurityException {
- if (!Context.getAttributesManager().checkAttribute(userId, attributeId) && !isAdmin(userId)) {
+ if (manager != null && !manager.checkItemPermission(userId, objectId) && !getUserAdmin(userId)) {
checkManager(userId);
- for (long managedUserId : getUserPermissions(userId)) {
- if (Context.getAttributesManager().checkAttribute(managedUserId, attributeId)) {
+ for (long managedUserId : usersManager.getManagedItems(userId)) {
+ if (manager.checkItemPermission(managedUserId, objectId)) {
return;
}
}
- throw new SecurityException("Attribute access denied");
- }
- }
-
- public void checkCalendar(long userId, long calendarId) throws SecurityException {
- if (!Context.getCalendarManager().checkCalendar(userId, calendarId) && !isAdmin(userId)) {
- checkManager(userId);
- for (long managedUserId : getUserPermissions(userId)) {
- if (Context.getCalendarManager().checkCalendar(managedUserId, calendarId)) {
- return;
- }
+ throw new SecurityException("Type " + object + " access denied");
+ }
+ }
+
+ public void refreshAllUsersPermissions() {
+ if (Context.getGeofenceManager() != null) {
+ Context.getGeofenceManager().refreshUserItems();
+ }
+ Context.getCalendarManager().refreshUserItems();
+ Context.getDriversManager().refreshUserItems();
+ Context.getAttributesManager().refreshUserItems();
+ Context.getCommandsManager().refreshUserItems();
+ if (Context.getNotificationManager() != null) {
+ Context.getNotificationManager().refreshUserItems();
+ }
+ }
+
+ public void refreshAllExtendedPermissions() {
+ if (Context.getGeofenceManager() != null) {
+ Context.getGeofenceManager().refreshExtendedPermissions();
+ }
+ Context.getDriversManager().refreshExtendedPermissions();
+ Context.getAttributesManager().refreshExtendedPermissions();
+ Context.getCommandsManager().refreshExtendedPermissions();
+ }
+
+ public void refreshPermissions(Permission permission) {
+ if (permission.getOwnerClass().equals(User.class)) {
+ if (permission.getPropertyClass().equals(Device.class)
+ || permission.getPropertyClass().equals(Group.class)) {
+ refreshDeviceAndGroupPermissions();
+ refreshAllExtendedPermissions();
+ } else if (permission.getPropertyClass().equals(ManagedUser.class)) {
+ usersManager.refreshUserItems();
+ } else if (permission.getPropertyClass().equals(Geofence.class) && Context.getGeofenceManager() != null) {
+ Context.getGeofenceManager().refreshUserItems();
+ } else if (permission.getPropertyClass().equals(Driver.class)) {
+ Context.getDriversManager().refreshUserItems();
+ } else if (permission.getPropertyClass().equals(Attribute.class)) {
+ Context.getAttributesManager().refreshUserItems();
+ } else if (permission.getPropertyClass().equals(Calendar.class)) {
+ Context.getCalendarManager().refreshUserItems();
+ } else if (permission.getPropertyClass().equals(Command.class)) {
+ Context.getCommandsManager().refreshUserItems();
+ } else if (permission.getPropertyClass().equals(Notification.class)
+ && Context.getNotificationManager() != null) {
+ Context.getNotificationManager().refreshUserItems();
+ }
+ } else if (permission.getOwnerClass().equals(Device.class) || permission.getOwnerClass().equals(Group.class)) {
+ if (permission.getPropertyClass().equals(Geofence.class) && Context.getGeofenceManager() != null) {
+ Context.getGeofenceManager().refreshExtendedPermissions();
+ } else if (permission.getPropertyClass().equals(Driver.class)) {
+ Context.getDriversManager().refreshExtendedPermissions();
+ } else if (permission.getPropertyClass().equals(Attribute.class)) {
+ Context.getAttributesManager().refreshExtendedPermissions();
+ } else if (permission.getPropertyClass().equals(Command.class)) {
+ Context.getCommandsManager().refreshExtendedPermissions();
+ } else if (permission.getPropertyClass().equals(Notification.class)
+ && Context.getNotificationManager() != null) {
+ Context.getNotificationManager().refreshExtendedPermissions();
}
- throw new SecurityException("Calendar access denied");
}
}
@@ -339,94 +403,23 @@ public class PermissionsManager {
}
public void updateServer(Server server) throws SQLException {
- dataManager.updateServer(server);
+ dataManager.updateObject(server);
this.server = server;
}
- public Collection<User> getAllUsers() {
- return users.values();
- }
-
- public Collection<User> getUsers(long userId) {
- Collection<User> result = new ArrayList<>();
- for (long managedUserId : getUserPermissions(userId)) {
- result.add(users.get(managedUserId));
- }
- return result;
- }
-
- public Collection<User> getManagedUsers(long userId) {
- Collection<User> result = getUsers(userId);
- result.add(users.get(userId));
- return result;
- }
-
- public User getUser(long userId) {
- return users.get(userId);
- }
-
- public void addUser(User user) throws SQLException {
- dataManager.addUser(user);
- users.put(user.getId(), user);
- if (user.getToken() != null) {
- usersTokens.put(user.getToken(), user.getId());
- }
- refreshPermissions();
- }
-
- public void updateUser(User user) throws SQLException {
- dataManager.updateUser(user);
- User old = users.get(user.getId());
- users.put(user.getId(), user);
- if (user.getToken() != null) {
- usersTokens.put(user.getToken(), user.getId());
- }
- if (old.getToken() != null && !old.getToken().equals(user.getToken())) {
- usersTokens.remove(old.getToken());
- }
- refreshPermissions();
- }
-
- public void removeUser(long userId) throws SQLException {
- dataManager.removeUser(userId);
- usersTokens.remove(users.get(userId).getToken());
- users.remove(userId);
- refreshPermissions();
- refreshUserPermissions();
- }
-
public User login(String email, String password) throws SQLException {
User user = dataManager.login(email, password);
if (user != null) {
checkUserEnabled(user.getId());
- return users.get(user.getId());
+ return getUser(user.getId());
}
return null;
}
- public User getUserByToken(String token) {
- return users.get(usersTokens.get(token));
- }
-
- public Object lookupPreference(long userId, String key, Object defaultValue) {
- String methodName = "get" + key.substring(0, 1).toUpperCase() + key.substring(1);
+ public Object lookupAttribute(long userId, String key, Object defaultValue) {
Object preference;
- Object serverPreference = null;
- Object userPreference = null;
- try {
- Method method = null;
- method = User.class.getMethod(methodName, (Class<?>[]) null);
- if (method != null) {
- userPreference = method.invoke(users.get(userId), (Object[]) null);
- }
- method = null;
- method = Server.class.getMethod(methodName, (Class<?>[]) null);
- if (method != null) {
- serverPreference = method.invoke(server, (Object[]) null);
- }
- } catch (ReflectiveOperationException | SecurityException | IllegalArgumentException exception) {
- return defaultValue;
- }
+ Object serverPreference = server.getAttributes().get(key);
+ Object userPreference = getUser(userId).getAttributes().get(key);
if (server.getForceSettings()) {
preference = serverPreference != null ? serverPreference : userPreference;
} else {