diff options
-rw-r--r-- | schema/changelog-3.8.xml | 5 | ||||
-rw-r--r-- | setup/default.xml | 5 | ||||
-rw-r--r-- | src/org/traccar/api/resource/SessionResource.java | 6 | ||||
-rw-r--r-- | src/org/traccar/api/resource/UserResource.java | 3 | ||||
-rw-r--r-- | src/org/traccar/database/PermissionsManager.java | 26 | ||||
-rw-r--r-- | src/org/traccar/model/User.java | 25 |
6 files changed, 67 insertions, 3 deletions
diff --git a/schema/changelog-3.8.xml b/schema/changelog-3.8.xml index ba591f192..f53673eae 100644 --- a/schema/changelog-3.8.xml +++ b/schema/changelog-3.8.xml @@ -116,6 +116,11 @@ <addColumn tableName="users"> <column name="devicelimit" type="INT" defaultValueNumeric="0" /> </addColumn> + <addColumn tableName="users"> + <column name="token" type="VARCHAR(128)" /> + </addColumn> + + <addUniqueConstraint tableName="users" columnNames="token" constraintName="uk_user_token" /> </changeSet> </databaseChangeLog> diff --git a/setup/default.xml b/setup/default.xml index a9d7684d4..e6d701f4c 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -62,8 +62,8 @@ </entry> <entry key='database.insertUser'> - INSERT INTO users (name, email, hashedPassword, salt, admin, map, distanceUnit, speedUnit, latitude, longitude, zoom, twelveHourFormat, coordinateFormat, disabled, expirationTime, deviceLimit, attributes) - VALUES (:name, :email, :hashedPassword, :salt, :admin, :map, :distanceUnit, :speedUnit, :latitude, :longitude, :zoom, :twelveHourFormat, :coordinateFormat, :disabled, :expirationTime, :deviceLimit, :attributes) + INSERT INTO users (name, email, hashedPassword, salt, admin, map, distanceUnit, speedUnit, latitude, longitude, zoom, twelveHourFormat, coordinateFormat, disabled, expirationTime, deviceLimit, token, attributes) + VALUES (:name, :email, :hashedPassword, :salt, :admin, :map, :distanceUnit, :speedUnit, :latitude, :longitude, :zoom, :twelveHourFormat, :coordinateFormat, :disabled, :expirationTime, :deviceLimit, :token, :attributes) </entry> <entry key='database.updateUser'> @@ -82,6 +82,7 @@ disabled = :disabled, expirationTime = :expirationTime, deviceLimit = :deviceLimit, + token = :token, attributes = :attributes WHERE id = :id </entry> diff --git a/src/org/traccar/api/resource/SessionResource.java b/src/org/traccar/api/resource/SessionResource.java index a61738c7e..6c5263123 100644 --- a/src/org/traccar/api/resource/SessionResource.java +++ b/src/org/traccar/api/resource/SessionResource.java @@ -69,6 +69,12 @@ public class SessionResource extends BaseResource { userId = user.getId(); request.getSession().setAttribute(USER_ID_KEY, userId); } + } else if (request.getParameter("token") != null) { + User user = Context.getPermissionsManager().getUserByToken(request.getParameter("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 c6e84c918..094de2812 100644 --- a/src/org/traccar/api/resource/UserResource.java +++ b/src/org/traccar/api/resource/UserResource.java @@ -66,7 +66,8 @@ public class UserResource extends BaseResource { || old.getAdmin() != entity.getAdmin() || old.getReadonly() != entity.getReadonly() || old.getDisabled() != entity.getDisabled() - || old.getDeviceLimit() != entity.getDeviceLimit()) { + || old.getDeviceLimit() != entity.getDeviceLimit() + || !old.getToken().equals(entity.getToken())) { Context.getPermissionsManager().checkAdmin(getUserId()); } else { Context.getPermissionsManager().checkUser(getUserId(), entity.getId()); diff --git a/src/org/traccar/database/PermissionsManager.java b/src/org/traccar/database/PermissionsManager.java index 1c995a11d..269dfc7bf 100644 --- a/src/org/traccar/database/PermissionsManager.java +++ b/src/org/traccar/database/PermissionsManager.java @@ -29,6 +29,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -39,6 +40,7 @@ public class PermissionsManager { private volatile Server server; private final Map<Long, User> users = new ConcurrentHashMap<>(); + private final Map<Long, String> usersTokens = new HashMap<>(); private final Map<Long, Set<Long>> groupPermissions = new HashMap<>(); private final Map<Long, Set<Long>> devicePermissions = new HashMap<>(); @@ -81,10 +83,14 @@ public class PermissionsManager { public final void refreshUsers() { users.clear(); + usersTokens.clear(); try { server = dataManager.getServer(); for (User user : dataManager.getUsers()) { users.put(user.getId(), user); + if (user.getToken() != null) { + usersTokens.put(user.getId(), user.getToken()); + } } } catch (SQLException error) { Log.warning(error); @@ -210,18 +216,27 @@ public class PermissionsManager { public void addUser(User user) throws SQLException { dataManager.addUser(user); users.put(user.getId(), user); + if (user.getToken() != null) { + usersTokens.put(user.getId(), user.getToken()); + } refreshPermissions(); } public void updateUser(User user) throws SQLException { dataManager.updateUser(user); users.put(user.getId(), user); + if (user.getToken() != null) { + usersTokens.put(user.getId(), user.getToken()); + } else if (usersTokens.containsKey(user.getId())) { + usersTokens.remove(user.getId()); + } refreshPermissions(); } public void removeUser(long userId) throws SQLException { dataManager.removeUser(userId); users.remove(userId); + usersTokens.remove(userId); refreshPermissions(); } @@ -234,4 +249,15 @@ public class PermissionsManager { return null; } + public User getUserByToken(String token) { + if (usersTokens.containsValue(token)) { + for (Entry<Long, String> entry : usersTokens.entrySet()) { + if (entry.getValue().equals(token)) { + return users.get(entry.getKey()); + } + } + } + return null; + } + } diff --git a/src/org/traccar/model/User.java b/src/org/traccar/model/User.java index a36fa0e31..816f49da9 100644 --- a/src/org/traccar/model/User.java +++ b/src/org/traccar/model/User.java @@ -180,6 +180,31 @@ public class User extends Extensible { this.deviceLimit = deviceLimit; } + private String token; + + public String getToken() { + return token; + } + + public void setToken(String token) { + if (token != null && !token.isEmpty()) { + if (validateToken(token)) { + this.token = token; + } else { + throw new IllegalArgumentException("Bad token"); + } + } else { + this.token = null; + } + } + + public static boolean validateToken(String token) { + if (token.length() < 16 || !token.matches("^[a-zA-Z0-9]+$")) { + return false; + } + return true; + } + public String getPassword() { return null; } |