UserRegistrationController.java
/*
* Copyright 2019 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.genesys.server.api.v1;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.validator.routines.EmailValidator;
import org.genesys.blocks.model.JsonViews;
import org.genesys.blocks.security.NotUniqueUserException;
import org.genesys.blocks.security.UserException;
import org.genesys.blocks.security.model.BasicUser;
import org.genesys.blocks.security.service.PasswordPolicy.PasswordPolicyException;
import org.genesys.server.api.ApiBaseController;
import org.genesys.server.exception.InvalidApiUsageException;
import org.genesys.server.model.impl.User;
import org.genesys.server.service.EMailVerificationService;
import org.genesys.server.service.TokenVerificationService.NoSuchVerificationTokenException;
import org.genesys.server.service.TokenVerificationService.TokenExpiredException;
import org.genesys.server.service.UserService;
import org.genesys.spring.CaptchaChecker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.annotation.JsonView;
import io.swagger.annotations.Api;
/**
* @author Maxym Borodenko
*/
@RestController("userRegistrationApi1")
@PreAuthorize("isAuthenticated()")
@RequestMapping(value = { UserRegistrationController.CONTROLLER_URL })
@Api(tags = { "user-registration" })
public class UserRegistrationController {
/** The Constant LOG. */
private static final Logger LOG = LoggerFactory.getLogger(UserRegistrationController.class);
/** The Constant CONTROLLER_URL. */
public static final String CONTROLLER_URL = ApiBaseController.APIv1_BASE + "/user";
@Autowired
private UserService userService;
@Autowired
private EMailVerificationService emailVerificationService;
@Autowired
private CaptchaChecker captchaChecker;
private final EmailValidator emailValidator = EmailValidator.getInstance();
@JsonView(JsonViews.Public.class)
@RequestMapping(value = "/register", method = RequestMethod.POST, produces = { MediaType.APPLICATION_JSON_VALUE })
public User registerUser(@RequestParam(value = "g-recaptcha-response", required = true) final String captchaResponse,
@RequestParam(name = "email", required = true) final String email, @RequestParam(name = "pass", required = true) final String password,
@RequestParam(name = "fullName", required = true) final String fullName, final HttpServletRequest request) throws Exception {
// Validate the reCAPTCHA
captchaChecker.assureValidResponseForClient(captchaResponse, request.getRemoteAddr());
try {
if (!emailValidator.isValid(email)) {
LOG.warn("Invalid email provided: {}", email);
throw new UserException("Invalid email provided: " + email);
}
final User newUser = userService.createUser(email, fullName, password, BasicUser.AccountType.LOCAL);
emailVerificationService.sendVerificationEmail(newUser);
return newUser;
} catch (final PasswordPolicyException e) {
LOG.error(e.getMessage());
throw new PasswordPolicyException(e.getMessage());
} catch (final DataIntegrityViolationException e) {
LOG.error(e.getMessage());
throw new NotUniqueUserException("E-mail already taken: " + email);
} catch (final Exception e) {
LOG.error(e.getMessage());
throw e;
}
}
@RequestMapping(value = "/{tokenUuid:.+}/validate", method = RequestMethod.POST, produces = { MediaType.APPLICATION_JSON_VALUE })
public boolean validateEMail(@PathVariable("tokenUuid") String tokenUuid, @RequestParam(value = "key", required = true) String key) throws Exception {
try {
emailVerificationService.validateEMail(tokenUuid, key);
return true;
} catch (final NoSuchVerificationTokenException e) {
throw new InvalidApiUsageException("Verification token was already used or is not valid!");
} catch (final TokenExpiredException e) {
throw new InvalidApiUsageException("Verification token has expired!");
}
}
@PostMapping(value = "/{tokenUuid:.+}/cancel")
public boolean cancelValidation(@PathVariable("tokenUuid") String tokenUuid, HttpServletRequest req, @RequestParam(value = "g-recaptcha-response", required = false) String response) throws Exception {
// Validate the reCAPTCHA
captchaChecker.assureValidResponseForClient(response, req.getRemoteAddr());
// Cancel validation
emailVerificationService.cancelValidation(tokenUuid);
return true;
}
}