From c9b67d19132b687bea9130f39f13a5515b120e5e Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Fri, 18 Nov 2016 16:05:35 +0500 Subject: Implement users tokens --- schema/changelog-3.8.xml | 5 +++++ setup/default.xml | 5 +++-- src/org/traccar/api/resource/SessionResource.java | 6 ++++++ src/org/traccar/api/resource/UserResource.java | 3 ++- src/org/traccar/database/PermissionsManager.java | 26 +++++++++++++++++++++++ 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 @@ + + + + + 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 @@ - 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) @@ -82,6 +82,7 @@ disabled = :disabled, expirationTime = :expirationTime, deviceLimit = :deviceLimit, + token = :token, attributes = :attributes WHERE id = :id 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 users = new ConcurrentHashMap<>(); + private final Map usersTokens = new HashMap<>(); private final Map> groupPermissions = new HashMap<>(); private final Map> 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 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; } -- cgit v1.2.3 From 670c8c7041163a2232d3edb4ef413af70182ea0a Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Fri, 18 Nov 2016 18:08:52 +0500 Subject: - Flip user-token map - Fix null check - Combine validation to setter --- src/org/traccar/api/resource/SessionResource.java | 5 +++-- src/org/traccar/api/resource/UserResource.java | 3 ++- src/org/traccar/database/PermissionsManager.java | 26 +++++++++-------------- src/org/traccar/model/User.java | 14 +++--------- 4 files changed, 18 insertions(+), 30 deletions(-) diff --git a/src/org/traccar/api/resource/SessionResource.java b/src/org/traccar/api/resource/SessionResource.java index 6c5263123..db8a5c837 100644 --- a/src/org/traccar/api/resource/SessionResource.java +++ b/src/org/traccar/api/resource/SessionResource.java @@ -29,6 +29,7 @@ import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; @@ -48,7 +49,7 @@ public class SessionResource extends BaseResource { @PermitAll @GET - public User get() throws SQLException { + public User get(@QueryParam("token") String token) throws SQLException { Long userId = (Long) request.getSession().getAttribute(USER_ID_KEY); if (userId == null) { Cookie[] cookies = request.getCookies(); @@ -69,7 +70,7 @@ public class SessionResource extends BaseResource { userId = user.getId(); request.getSession().setAttribute(USER_ID_KEY, userId); } - } else if (request.getParameter("token") != null) { + } else if (token != null) { User user = Context.getPermissionsManager().getUserByToken(request.getParameter("token")); if (user != null) { userId = user.getId(); diff --git a/src/org/traccar/api/resource/UserResource.java b/src/org/traccar/api/resource/UserResource.java index 094de2812..2ff1639f6 100644 --- a/src/org/traccar/api/resource/UserResource.java +++ b/src/org/traccar/api/resource/UserResource.java @@ -67,7 +67,8 @@ public class UserResource extends BaseResource { || old.getReadonly() != entity.getReadonly() || old.getDisabled() != entity.getDisabled() || old.getDeviceLimit() != entity.getDeviceLimit() - || !old.getToken().equals(entity.getToken())) { + || old.getToken() == null && entity.getToken() != null + || old.getToken() != null && !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 269dfc7bf..71633f6ef 100644 --- a/src/org/traccar/database/PermissionsManager.java +++ b/src/org/traccar/database/PermissionsManager.java @@ -29,7 +29,6 @@ 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; @@ -40,7 +39,7 @@ public class PermissionsManager { private volatile Server server; private final Map users = new ConcurrentHashMap<>(); - private final Map usersTokens = new HashMap<>(); + private final Map usersTokens = new HashMap<>(); private final Map> groupPermissions = new HashMap<>(); private final Map> devicePermissions = new HashMap<>(); @@ -89,7 +88,7 @@ public class PermissionsManager { for (User user : dataManager.getUsers()) { users.put(user.getId(), user); if (user.getToken() != null) { - usersTokens.put(user.getId(), user.getToken()); + usersTokens.put(user.getToken(), user.getId()); } } } catch (SQLException error) { @@ -217,26 +216,28 @@ public class PermissionsManager { dataManager.addUser(user); users.put(user.getId(), user); if (user.getToken() != null) { - usersTokens.put(user.getId(), user.getToken()); + 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.getId(), user.getToken()); - } else if (usersTokens.containsKey(user.getId())) { - usersTokens.remove(user.getId()); + 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); - usersTokens.remove(userId); refreshPermissions(); } @@ -250,14 +251,7 @@ public class PermissionsManager { } public User getUserByToken(String token) { - if (usersTokens.containsValue(token)) { - for (Entry entry : usersTokens.entrySet()) { - if (entry.getValue().equals(token)) { - return users.get(entry.getKey()); - } - } - } - return null; + return users.get(usersTokens.get(token)); } } diff --git a/src/org/traccar/model/User.java b/src/org/traccar/model/User.java index 816f49da9..e6b9d663f 100644 --- a/src/org/traccar/model/User.java +++ b/src/org/traccar/model/User.java @@ -188,23 +188,15 @@ public class User extends Extensible { public void setToken(String token) { if (token != null && !token.isEmpty()) { - if (validateToken(token)) { - this.token = token; - } else { - throw new IllegalArgumentException("Bad token"); + if (!token.matches("^[a-zA-Z0-9]{16,}$")) { + throw new IllegalArgumentException("Illegal token"); } + this.token = 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; } -- cgit v1.2.3 From e21cc32bb74d998246b52faaf49b6ea742e4d6e3 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Fri, 18 Nov 2016 18:51:39 +0500 Subject: Remove useless else --- src/org/traccar/model/User.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/org/traccar/model/User.java b/src/org/traccar/model/User.java index e6b9d663f..aa24b795e 100644 --- a/src/org/traccar/model/User.java +++ b/src/org/traccar/model/User.java @@ -192,8 +192,6 @@ public class User extends Extensible { throw new IllegalArgumentException("Illegal token"); } this.token = token; - } else { - this.token = null; } } -- cgit v1.2.3