diff options
Diffstat (limited to 'src/org/traccar/database/PermissionsManager.java')
-rw-r--r-- | src/org/traccar/database/PermissionsManager.java | 373 |
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 { |