aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--schema/changelog-3.8.xml5
-rw-r--r--setup/default.xml5
-rw-r--r--src/org/traccar/api/resource/SessionResource.java9
-rw-r--r--src/org/traccar/api/resource/UserResource.java4
-rw-r--r--src/org/traccar/database/PermissionsManager.java20
-rw-r--r--src/org/traccar/model/User.java15
6 files changed, 54 insertions, 4 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..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,6 +70,12 @@ public class SessionResource extends BaseResource {
userId = user.getId();
request.getSession().setAttribute(USER_ID_KEY, userId);
}
+ } else if (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..2ff1639f6 100644
--- a/src/org/traccar/api/resource/UserResource.java
+++ b/src/org/traccar/api/resource/UserResource.java
@@ -66,7 +66,9 @@ 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() == 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 1c995a11d..71633f6ef 100644
--- a/src/org/traccar/database/PermissionsManager.java
+++ b/src/org/traccar/database/PermissionsManager.java
@@ -39,6 +39,7 @@ public class PermissionsManager {
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<>();
@@ -81,10 +82,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.getToken(), user.getId());
+ }
}
} catch (SQLException error) {
Log.warning(error);
@@ -210,17 +215,28 @@ 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.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();
}
@@ -234,4 +250,8 @@ public class PermissionsManager {
return null;
}
+ public User getUserByToken(String token) {
+ return users.get(usersTokens.get(token));
+ }
+
}
diff --git a/src/org/traccar/model/User.java b/src/org/traccar/model/User.java
index a36fa0e31..aa24b795e 100644
--- a/src/org/traccar/model/User.java
+++ b/src/org/traccar/model/User.java
@@ -180,6 +180,21 @@ 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 (!token.matches("^[a-zA-Z0-9]{16,}$")) {
+ throw new IllegalArgumentException("Illegal token");
+ }
+ this.token = token;
+ }
+ }
+
public String getPassword() {
return null;
}