aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/traccar/api
diff options
context:
space:
mode:
authorAnton Tananaev <anton@traccar.org>2022-08-02 20:40:29 -0700
committerAnton Tananaev <anton@traccar.org>2022-08-02 20:40:29 -0700
commit62e4876406de1951705e76f85c1e099c36d48a87 (patch)
treead577555851a03a2758fdfef26ede770a691bcf9 /src/main/java/org/traccar/api
parentab6970135850655313e257cf44fb68c67e9f1e80 (diff)
downloadtrackermap-server-62e4876406de1951705e76f85c1e099c36d48a87.tar.gz
trackermap-server-62e4876406de1951705e76f85c1e099c36d48a87.tar.bz2
trackermap-server-62e4876406de1951705e76f85c1e099c36d48a87.zip
New tokens for password reset
Diffstat (limited to 'src/main/java/org/traccar/api')
-rw-r--r--src/main/java/org/traccar/api/resource/PasswordResource.java33
-rw-r--r--src/main/java/org/traccar/api/resource/SessionResource.java3
-rw-r--r--src/main/java/org/traccar/api/signature/TokenManager.java9
3 files changed, 25 insertions, 20 deletions
diff --git a/src/main/java/org/traccar/api/resource/PasswordResource.java b/src/main/java/org/traccar/api/resource/PasswordResource.java
index 91c2d8ecf..1fb08b02a 100644
--- a/src/main/java/org/traccar/api/resource/PasswordResource.java
+++ b/src/main/java/org/traccar/api/resource/PasswordResource.java
@@ -16,6 +16,7 @@
package org.traccar.api.resource;
import org.traccar.api.BaseResource;
+import org.traccar.api.signature.TokenManager;
import org.traccar.mail.MailManager;
import org.traccar.model.User;
import org.traccar.notification.TextTemplateFormatter;
@@ -34,35 +35,34 @@ import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
-import java.util.UUID;
+import java.io.IOException;
+import java.security.GeneralSecurityException;
@Path("password")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public class PasswordResource extends BaseResource {
- private static final String PASSWORD_RESET_TOKEN = "passwordToken";
-
@Inject
private MailManager mailManager;
@Inject
+ private TokenManager tokenManager;
+
+ @Inject
private TextTemplateFormatter textTemplateFormatter;
@Path("reset")
@PermitAll
@POST
- public Response reset(@FormParam("email") String email) throws StorageException, MessagingException {
+ public Response reset(@FormParam("email") String email)
+ throws StorageException, MessagingException, GeneralSecurityException, IOException {
+
User user = storage.getObject(User.class, new Request(
new Columns.All(), new Condition.Equals("email", "email", email)));
if (user != null) {
- String token = UUID.randomUUID().toString().replaceAll("-", "");
- user.set(PASSWORD_RESET_TOKEN, token);
- storage.updateObject(user, new Request(
- new Columns.Include("attributes"), new Condition.Equals("id", "id")));
-
var velocityContext = textTemplateFormatter.prepareContext(permissionsService.getServer(), user);
- velocityContext.put("token", token);
+ velocityContext.put("token", tokenManager.generateToken(user.getId(), null));
var fullMessage = textTemplateFormatter.formatMessage(velocityContext, "passwordReset", "full");
mailManager.sendMessage(user, fullMessage.getSubject(), fullMessage.getBody());
}
@@ -73,15 +73,16 @@ public class PasswordResource extends BaseResource {
@PermitAll
@POST
public Response update(
- @FormParam("token") String token, @FormParam("password") String password) throws StorageException {
- User user = storage.getObjects(User.class, new Request(new Columns.All())).stream()
- .filter(it -> token.equals(it.getString(PASSWORD_RESET_TOKEN)))
- .findFirst().orElse(null);
+ @FormParam("token") String token, @FormParam("password") String password)
+ throws StorageException, GeneralSecurityException, IOException {
+
+ long userId = tokenManager.verifyToken(token);
+ User user = storage.getObject(User.class, new Request(
+ new Columns.All(), new Condition.Equals("id", "id", userId)));
if (user != null) {
- user.getAttributes().remove(PASSWORD_RESET_TOKEN);
user.setPassword(password);
storage.updateObject(user, new Request(
- new Columns.Include("attributes", "hashedPassword", "salt"), new Condition.Equals("id", "id")));
+ new Columns.Include("hashedPassword", "salt"), new Condition.Equals("id", "id")));
return Response.ok().build();
}
return Response.status(Response.Status.NOT_FOUND).build();
diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java
index f70b67cde..61c3a5885 100644
--- a/src/main/java/org/traccar/api/resource/SessionResource.java
+++ b/src/main/java/org/traccar/api/resource/SessionResource.java
@@ -156,9 +156,6 @@ public class SessionResource extends BaseResource {
@POST
public String requestToken(
@FormParam("expiration") Date expiration) throws StorageException, GeneralSecurityException, IOException {
- if (expiration == null) {
- expiration = new Date(System.currentTimeMillis() + TimeUnit.DAYS.toMillis(7));
- }
return tokenManager.generateToken(getUserId(), expiration);
}
diff --git a/src/main/java/org/traccar/api/signature/TokenManager.java b/src/main/java/org/traccar/api/signature/TokenManager.java
index 3f39d5380..a51234a95 100644
--- a/src/main/java/org/traccar/api/signature/TokenManager.java
+++ b/src/main/java/org/traccar/api/signature/TokenManager.java
@@ -24,9 +24,12 @@ import javax.inject.Inject;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Date;
+import java.util.concurrent.TimeUnit;
public class TokenManager {
+ private static final int DEFAULT_EXPIRATION_DAYS = 7;
+
private final ObjectMapper objectMapper;
private final CryptoManager cryptoManager;
@@ -47,7 +50,11 @@ public class TokenManager {
long userId, Date expiration) throws IOException, GeneralSecurityException, StorageException {
Data data = new Data();
data.userId = userId;
- data.expiration = expiration;
+ if (expiration != null) {
+ data.expiration = expiration;
+ } else {
+ data.expiration = new Date(System.currentTimeMillis() + TimeUnit.DAYS.toMillis(DEFAULT_EXPIRATION_DAYS));
+ }
byte[] encoded = objectMapper.writeValueAsBytes(data);
return Base64.encodeBase64URLSafeString(cryptoManager.sign(encoded));
}