aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Tananaev <anton.tananaev@gmail.com>2017-07-25 18:59:29 +1200
committerGitHub <noreply@github.com>2017-07-25 18:59:29 +1200
commit234223a179d3f5e390cf8a649158676f8c349e5c (patch)
treee40066f50ead2270bda27fd9ce2cbf4a702c09fd
parent6253fa291c3a2962fef2076c0cbb0f4e1ca8a3b4 (diff)
parent68af658ea2ff9593e5be7a2b2cfcb75c744fd749 (diff)
downloadtrackermap-server-234223a179d3f5e390cf8a649158676f8c349e5c.tar.gz
trackermap-server-234223a179d3f5e390cf8a649158676f8c349e5c.tar.bz2
trackermap-server-234223a179d3f5e390cf8a649158676f8c349e5c.zip
Merge pull request #3388 from Abyss777/optimize_users
Move users management to separate manager
-rw-r--r--src/org/traccar/Context.java13
-rw-r--r--src/org/traccar/api/resource/SessionResource.java2
-rw-r--r--src/org/traccar/api/resource/UserResource.java20
-rw-r--r--src/org/traccar/database/DeviceManager.java4
-rw-r--r--src/org/traccar/database/PermissionsManager.java149
-rw-r--r--src/org/traccar/database/SimpleObjectManager.java4
-rw-r--r--src/org/traccar/database/UsersManager.java83
7 files changed, 149 insertions, 126 deletions
diff --git a/src/org/traccar/Context.java b/src/org/traccar/Context.java
index a4fc5b679..47472b1d4 100644
--- a/src/org/traccar/Context.java
+++ b/src/org/traccar/Context.java
@@ -38,6 +38,7 @@ import org.traccar.database.NotificationManager;
import org.traccar.database.PermissionsManager;
import org.traccar.database.GeofenceManager;
import org.traccar.database.StatisticsManager;
+import org.traccar.database.UsersManager;
import org.traccar.geocoder.BingMapsGeocoder;
import org.traccar.geocoder.FactualGeocoder;
import org.traccar.geocoder.GeocodeFarmGeocoder;
@@ -98,6 +99,12 @@ public final class Context {
return mediaManager;
}
+ private static UsersManager usersManager;
+
+ public static UsersManager getUsersManager() {
+ return usersManager;
+ }
+
private static DeviceManager deviceManager;
public static DeviceManager getDeviceManager() {
@@ -233,6 +240,10 @@ public final class Context {
}
if (dataManager != null) {
+ usersManager = new UsersManager(dataManager);
+ }
+
+ if (dataManager != null) {
deviceManager = new DeviceManager(dataManager);
}
@@ -298,7 +309,7 @@ public final class Context {
webServer = new WebServer(config, dataManager.getDataSource());
}
- permissionsManager = new PermissionsManager(dataManager);
+ permissionsManager = new PermissionsManager(dataManager, usersManager);
connectionManager = new ConnectionManager();
diff --git a/src/org/traccar/api/resource/SessionResource.java b/src/org/traccar/api/resource/SessionResource.java
index acdbb7c87..fa2a14c6f 100644
--- a/src/org/traccar/api/resource/SessionResource.java
+++ b/src/org/traccar/api/resource/SessionResource.java
@@ -80,7 +80,7 @@ public class SessionResource extends BaseResource {
request.getSession().setAttribute(USER_ID_KEY, userId);
}
} else if (token != null) {
- User user = Context.getPermissionsManager().getUserByToken(token);
+ User user = Context.getUsersManager().getUserByToken(token);
if (user != null) {
userId = user.getId();
request.getSession().setAttribute(USER_ID_KEY, userId);
diff --git a/src/org/traccar/api/resource/UserResource.java b/src/org/traccar/api/resource/UserResource.java
index 98395e3cc..d3d82f99d 100644
--- a/src/org/traccar/api/resource/UserResource.java
+++ b/src/org/traccar/api/resource/UserResource.java
@@ -17,6 +17,7 @@ package org.traccar.api.resource;
import org.traccar.Context;
import org.traccar.api.BaseResource;
+import org.traccar.database.UsersManager;
import org.traccar.model.ManagedUser;
import org.traccar.model.User;
@@ -35,6 +36,7 @@ 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)
@@ -43,17 +45,21 @@ public class UserResource extends BaseResource {
@GET
public Collection<User> get(@QueryParam("userId") long userId) throws SQLException {
+ UsersManager usersManager = Context.getUsersManager();
+ Set<Long> result = null;
if (Context.getPermissionsManager().isAdmin(getUserId())) {
if (userId != 0) {
- return Context.getPermissionsManager().getUsers(userId);
+ result = usersManager.getManagedItems(userId);
} else {
- return Context.getPermissionsManager().getAllUsers();
+ result = usersManager.getAllItems();
}
} else if (Context.getPermissionsManager().isManager(getUserId())) {
- return Context.getPermissionsManager().getManagedUsers(getUserId());
+ result = usersManager.getManagedItems(getUserId());
+ result.add(getUserId());
} else {
throw new SecurityException("Admin or manager access required");
}
+ return usersManager.getItems(User.class, result);
}
@PermitAll
@@ -73,11 +79,11 @@ public class UserResource extends BaseResource {
}
}
}
- Context.getPermissionsManager().addUser(entity);
+ Context.getUsersManager().addItem(entity);
if (Context.getPermissionsManager().isManager(getUserId())) {
Context.getDataManager().linkObject(User.class, getUserId(), ManagedUser.class, entity.getId(), true);
}
- Context.getPermissionsManager().refreshUserPermissions();
+ Context.getUsersManager().refreshUserItems();
if (Context.getNotificationManager() != null) {
Context.getNotificationManager().refresh();
}
@@ -91,7 +97,7 @@ public class UserResource extends BaseResource {
User before = Context.getPermissionsManager().getUser(entity.getId());
Context.getPermissionsManager().checkUser(getUserId(), entity.getId());
Context.getPermissionsManager().checkUserUpdate(getUserId(), before, entity);
- Context.getPermissionsManager().updateUser(entity);
+ Context.getUsersManager().updateItem(entity);
if (Context.getNotificationManager() != null) {
Context.getNotificationManager().refresh();
}
@@ -103,7 +109,7 @@ public class UserResource extends BaseResource {
public Response remove(@PathParam("id") long id) throws SQLException {
Context.getPermissionsManager().checkReadonly(getUserId());
Context.getPermissionsManager().checkUser(getUserId(), id);
- Context.getPermissionsManager().removeUser(id);
+ Context.getUsersManager().removeItem(id);
if (Context.getGeofenceManager() != null) {
Context.getGeofenceManager().refreshUserItems();
}
diff --git a/src/org/traccar/database/DeviceManager.java b/src/org/traccar/database/DeviceManager.java
index 6637df91c..995aa8ac3 100644
--- a/src/org/traccar/database/DeviceManager.java
+++ b/src/org/traccar/database/DeviceManager.java
@@ -192,7 +192,7 @@ public class DeviceManager implements IdentityManager {
public Collection<Device> getManagedDevices(long userId) throws SQLException {
Collection<Device> devices = new HashSet<>();
devices.addAll(getDevices(userId));
- for (long managedUserId : Context.getPermissionsManager().getUserPermissions(userId)) {
+ for (long managedUserId : Context.getUsersManager().getManagedItems(userId)) {
devices.addAll(getDevices(managedUserId));
}
return devices;
@@ -340,7 +340,7 @@ public class DeviceManager implements IdentityManager {
public Collection<Group> getManagedGroups(long userId) throws SQLException {
Collection<Group> groups = new ArrayList<>();
groups.addAll(getGroups(userId));
- for (long managedUserId : Context.getPermissionsManager().getUserPermissions(userId)) {
+ for (long managedUserId : Context.getUsersManager().getManagedItems(userId)) {
groups.addAll(getGroups(managedUserId));
}
return groups;
diff --git a/src/org/traccar/database/PermissionsManager.java b/src/org/traccar/database/PermissionsManager.java
index 70969d749..b38ecf9bf 100644
--- a/src/org/traccar/database/PermissionsManager.java
+++ b/src/org/traccar/database/PermissionsManager.java
@@ -30,29 +30,33 @@ import org.traccar.model.User;
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();
+ refreshPermissions();
+ }
+
+ public User getUser(long userId) {
+ return (User) usersManager.getById(userId);
+ }
public Set<Long> getGroupPermissions(long userId) {
if (!groupPermissions.containsKey(userId)) {
@@ -82,47 +86,14 @@ 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.getObjects(User.class)) {
- 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 (Permission permission : dataManager.getPermissions(User.class, User.class)) {
- getUserPermissions(permission.getOwnerId()).add(permission.getPropertyId());
- }
- } catch (SQLException | ClassNotFoundException error) {
- Log.warning(error);
- }
- }
-
public final void refreshPermissions() {
groupPermissions.clear();
devicePermissions.clear();
@@ -165,7 +136,8 @@ public class PermissionsManager {
}
public boolean isAdmin(long userId) {
- return users.containsKey(userId) && users.get(userId).getAdmin();
+ User user = getUser(userId);
+ return user != null && user.getAdmin();
}
public void checkAdmin(long userId) throws SecurityException {
@@ -175,7 +147,8 @@ public class PermissionsManager {
}
public boolean isManager(long userId) {
- return users.containsKey(userId) && users.get(userId).getUserLimit() != 0;
+ User user = getUser(userId);
+ return user != null && user.getUserLimit() != 0;
}
public void checkManager(long userId) throws SecurityException {
@@ -186,20 +159,20 @@ public class PermissionsManager {
public void checkManager(long userId, long managedUserId) throws SecurityException {
checkManager(userId);
- if (!getUserPermissions(userId).contains(managedUserId)) {
+ if (!usersManager.getManagedItems(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.getManagedItems(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)) {
@@ -214,11 +187,13 @@ public class PermissionsManager {
}
public boolean isReadonly(long userId) {
- return users.containsKey(userId) && users.get(userId).getReadonly();
+ User user = getUser(userId);
+ return user != null && user.getReadonly();
}
public boolean isDeviceReadonly(long userId) {
- return users.containsKey(userId) && users.get(userId).getDeviceReadonly();
+ User user = getUser(userId);
+ return user != null && user.getDeviceReadonly();
}
public void checkReadonly(long userId) throws SecurityException {
@@ -235,6 +210,9 @@ public class PermissionsManager {
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");
}
@@ -249,9 +227,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()
@@ -275,7 +254,7 @@ public class PermissionsManager {
public void checkGroup(long userId, long groupId) throws SecurityException {
if (!getGroupPermissions(userId).contains(groupId) && !isAdmin(userId)) {
checkManager(userId);
- for (long managedUserId : getUserPermissions(userId)) {
+ for (long managedUserId : usersManager.getManagedItems(userId)) {
if (getGroupPermissions(managedUserId).contains(groupId)) {
return;
}
@@ -287,7 +266,7 @@ public class PermissionsManager {
public void checkDevice(long userId, long deviceId) throws SecurityException {
if (!getDevicePermissions(userId).contains(deviceId) && !isAdmin(userId)) {
checkManager(userId);
- for (long managedUserId : getUserPermissions(userId)) {
+ for (long managedUserId : usersManager.getManagedItems(userId)) {
if (getDevicePermissions(managedUserId).contains(deviceId)) {
return;
}
@@ -326,7 +305,7 @@ public class PermissionsManager {
if (manager != null && !manager.checkItemPermission(userId, objectId) && !isAdmin(userId)) {
checkManager(userId);
- for (long managedUserId : getUserPermissions(userId)) {
+ for (long managedUserId : usersManager.getManagedItems(userId)) {
if (manager.checkItemPermission(managedUserId, objectId)) {
return;
}
@@ -350,7 +329,7 @@ public class PermissionsManager {
refreshPermissions();
refreshAllExtendedPermissions();
} else if (permission.getPropertyClass().equals(ManagedUser.class)) {
- refreshUserPermissions();
+ usersManager.refreshUserItems();
} else if (permission.getPropertyClass().equals(Geofence.class) && Context.getGeofenceManager() != null) {
Context.getGeofenceManager().refreshUserItems();
} else if (permission.getPropertyClass().equals(Driver.class)) {
@@ -380,71 +359,15 @@ public class PermissionsManager {
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.addObject(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.removeObject(User.class, 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);
Object preference;
@@ -454,7 +377,7 @@ public class PermissionsManager {
Method method = null;
method = User.class.getMethod(methodName, (Class<?>[]) null);
if (method != null) {
- userPreference = method.invoke(users.get(userId), (Object[]) null);
+ userPreference = method.invoke(getUser(userId), (Object[]) null);
}
method = null;
method = Server.class.getMethod(methodName, (Class<?>[]) null);
diff --git a/src/org/traccar/database/SimpleObjectManager.java b/src/org/traccar/database/SimpleObjectManager.java
index 282dea46e..124178a05 100644
--- a/src/org/traccar/database/SimpleObjectManager.java
+++ b/src/org/traccar/database/SimpleObjectManager.java
@@ -166,10 +166,10 @@ public abstract class SimpleObjectManager {
return items.keySet();
}
- public final Set<Long> getManagedItems(long userId) {
+ public Set<Long> getManagedItems(long userId) {
Set<Long> result = new HashSet<>();
result.addAll(getUserItems(userId));
- for (long managedUserId : Context.getPermissionsManager().getUserPermissions(userId)) {
+ for (long managedUserId : Context.getUsersManager().getManagedItems(userId)) {
result.addAll(getUserItems(managedUserId));
}
return result;
diff --git a/src/org/traccar/database/UsersManager.java b/src/org/traccar/database/UsersManager.java
new file mode 100644
index 000000000..3c9c8b280
--- /dev/null
+++ b/src/org/traccar/database/UsersManager.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2017 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.BaseModel;
+import org.traccar.model.User;
+
+public class UsersManager extends SimpleObjectManager {
+
+ private Map<String, Long> usersTokens;
+
+ public UsersManager(DataManager dataManager) {
+ super(dataManager, User.class);
+ }
+
+ private void putToken(User user) {
+ if (usersTokens == null) {
+ usersTokens = new ConcurrentHashMap<>();
+ }
+ if (user.getToken() != null) {
+ usersTokens.put(user.getToken(), user.getId());
+ }
+ }
+
+ @Override
+ protected void addNewItem(BaseModel item) {
+ super.addNewItem(item);
+ putToken((User) item);
+ }
+
+ @Override
+ protected void updateCachedItem(BaseModel item) {
+ User user = (User) item;
+ User cachedUser = (User) getById(item.getId());
+ super.updateCachedItem(item);
+ if (user.getToken() != null) {
+ usersTokens.put(user.getToken(), user.getId());
+ }
+ if (cachedUser.getToken() != null && !cachedUser.getToken().equals(user.getToken())) {
+ usersTokens.remove(cachedUser.getToken());
+ }
+ }
+
+ @Override
+ protected void removeCachedItem(long userId) {
+ User cachedUser = (User) 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) {
+ return getUserItems(userId);
+ }
+
+ public User getUserByToken(String token) {
+ return (User) getById(usersTokens.get(token));
+ }
+
+}