Browse Source

Redirect to error page when password reset or activation link is expired

pull/11578/head
ViacheslavKlimov 2 years ago
parent
commit
a8afd8929b
  1. 33
      application/src/main/java/org/thingsboard/server/controller/AuthController.java
  2. 17
      application/src/main/java/org/thingsboard/server/controller/BaseController.java
  3. 6
      application/src/test/java/org/thingsboard/server/controller/AuthControllerTest.java

33
application/src/main/java/org/thingsboard/server/controller/AuthController.java

@ -58,9 +58,6 @@ import org.thingsboard.server.service.security.model.UserPrincipal;
import org.thingsboard.server.service.security.model.token.JwtTokenFactory;
import org.thingsboard.server.service.security.system.SystemSecurityService;
import java.net.URI;
import java.net.URISyntaxException;
@RestController
@TbCoreComponent
@RequestMapping("/api")
@ -132,7 +129,7 @@ public class AuthController extends BaseController {
notes = "Checks the activation token and forwards user to 'Create Password' page. " +
"If token is valid, returns '303 See Other' (redirect) response code with the correct address of 'Create Password' page and same 'activateToken' specified in the URL parameters. " +
"If token is not valid, returns '409 Conflict'. " +
"If token is expired, returns '410 Gone'.")
"If token is expired, redirects to error page.")
@GetMapping(value = "/noauth/activate", params = {"activateToken"})
public ResponseEntity<?> checkActivateToken(
@Parameter(description = "The activate token string.")
@ -141,18 +138,9 @@ public class AuthController extends BaseController {
if (userCredentials == null) {
return response(HttpStatus.CONFLICT);
} else if (userCredentials.isActivationTokenExpired()) {
return response(HttpStatus.GONE);
}
String createURI = "/login/createPassword";
try {
URI location = new URI(createURI + "?activateToken=" + activateToken);
return ResponseEntity.status(HttpStatus.SEE_OTHER)
.location(location).build();
} catch (URISyntaxException e) {
log.error("Unable to create URI with address [{}]", createURI);
return response(HttpStatus.BAD_REQUEST);
return redirectTo("/activationLinkExpired");
}
return redirectTo("/login/createPassword?activateToken=" + activateToken);
}
@ApiOperation(value = "Request reset password email (requestResetPasswordByEmail)",
@ -181,7 +169,7 @@ public class AuthController extends BaseController {
notes = "Checks the password reset token and forwards user to 'Reset Password' page. " +
"If token is valid, returns '303 See Other' (redirect) response code with the correct address of 'Reset Password' page and same 'resetToken' specified in the URL parameters. " +
"If token is not valid, returns '409 Conflict'. " +
"If token is expired, returns '410 Gone'.")
"If token is expired, redirects to error page.")
@GetMapping(value = "/noauth/resetPassword", params = {"resetToken"})
public ResponseEntity<?> checkResetToken(
@Parameter(description = "The reset token string.")
@ -190,21 +178,12 @@ public class AuthController extends BaseController {
if (userCredentials == null) {
return response(HttpStatus.CONFLICT);
} else if (userCredentials.isResetTokenExpired()) {
return response(HttpStatus.GONE);
return redirectTo("/passwordResetLinkExpired");
}
if (!rateLimitService.checkRateLimit(LimitedApi.PASSWORD_RESET, userCredentials.getUserId(), defaultLimitsConfiguration)) {
return response(HttpStatus.TOO_MANY_REQUESTS);
}
String resetURI = "/login/resetPassword";
try {
URI location = new URI(resetURI + "?resetToken=" + resetToken);
return ResponseEntity.status(HttpStatus.SEE_OTHER)
.location(location).build();
} catch (URISyntaxException e) {
log.error("Unable to create URI with address [{}]", resetURI);
return response(HttpStatus.BAD_REQUEST);
}
return redirectTo("/login/resetPassword?resetToken=" + resetToken);
}
@ApiOperation(value = "Activate User",

17
application/src/main/java/org/thingsboard/server/controller/BaseController.java

@ -134,8 +134,8 @@ import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.exception.IncorrectParameterException;
import org.thingsboard.server.dao.mobile.MobileAppService;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.oauth2.OAuth2ConfigTemplateService;
import org.thingsboard.server.dao.oauth2.OAuth2ClientService;
import org.thingsboard.server.dao.oauth2.OAuth2ConfigTemplateService;
import org.thingsboard.server.dao.ota.OtaPackageService;
import org.thingsboard.server.dao.queue.QueueService;
import org.thingsboard.server.dao.relation.RelationService;
@ -172,8 +172,8 @@ import org.thingsboard.server.service.sync.vc.EntitiesVersionControlService;
import org.thingsboard.server.service.telemetry.AlarmSubscriptionService;
import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@ -918,6 +918,19 @@ public abstract class BaseController {
return ResponseEntity.status(status).build();
}
protected <T> ResponseEntity<T> redirectTo(String location) {
URI uri;
try {
uri = URI.create(location);
} catch (IllegalArgumentException e) {
log.error("Failed to create URI from '{}'", location, e);
throw e;
}
return ResponseEntity.status(HttpStatus.SEE_OTHER)
.location(uri)
.build();
}
protected List<OAuth2ClientId> getOAuth2ClientIds(UUID[] ids) throws ThingsboardException {
if (ids == null) {
return Collections.emptyList();

6
application/src/test/java/org/thingsboard/server/controller/AuthControllerTest.java

@ -195,7 +195,8 @@ public class AuthControllerTest extends AbstractControllerTest {
userCredentialsDao.save(tenantId, userCredentials);
doGet("/api/noauth/resetPassword?resetToken={resetToken}", this.currentResetPasswordToken)
.andExpect(status().isGone());
.andExpect(status().isSeeOther())
.andExpect(header().string(HttpHeaders.LOCATION, "/passwordResetLinkExpired"));
JsonNode resetPasswordRequest = JacksonUtil.newObjectNode()
.put("resetToken", this.currentResetPasswordToken)
.put("password", "wefwefe");
@ -229,7 +230,8 @@ public class AuthControllerTest extends AbstractControllerTest {
userCredentials.setActivateTokenExpTime(System.currentTimeMillis() - 1);
userCredentialsDao.save(tenantId, userCredentials);
doGet("/api/noauth/activate?activateToken={activateToken}", initialActivationToken)
.andExpect(status().isGone());
.andExpect(status().isSeeOther())
.andExpect(header().string(HttpHeaders.LOCATION, "/activationLinkExpired"));
doPost("/api/noauth/activate", JacksonUtil.newObjectNode()
.put("activateToken", initialActivationToken)
.put("password", "wefewe")).andExpect(status().isBadRequest())

Loading…
Cancel
Save