diff options
author | Anton Tananaev <anton@traccar.org> | 2022-08-02 20:40:29 -0700 |
---|---|---|
committer | Anton Tananaev <anton@traccar.org> | 2022-08-02 20:40:29 -0700 |
commit | 62e4876406de1951705e76f85c1e099c36d48a87 (patch) | |
tree | ad577555851a03a2758fdfef26ede770a691bcf9 /src/main/java/org/traccar/api | |
parent | ab6970135850655313e257cf44fb68c67e9f1e80 (diff) | |
download | trackermap-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')
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)); } |