Merge pull request #159 from Doha2012/master

separate front end
This commit is contained in:
Eugen 2015-03-09 22:20:34 +02:00
commit fee0f90b8e
25 changed files with 35 additions and 1036 deletions

View File

@ -1,35 +0,0 @@
package org.baeldung.persistence.service;
import org.baeldung.persistence.model.PasswordResetToken;
import org.baeldung.persistence.model.User;
import org.baeldung.persistence.model.VerificationToken;
import org.baeldung.validation.EmailExistsException;
public interface IUserService {
User registerNewUserAccount(UserDto accountDto) throws EmailExistsException;
User getUser(String verificationToken);
void saveRegisteredUser(User user);
void deleteUser(User user);
void createVerificationTokenForUser(User user, String token);
VerificationToken getVerificationToken(String VerificationToken);
VerificationToken generateNewVerificationToken(String token);
void createPasswordResetTokenForUser(User user, String token);
User findUserByEmail(String email);
PasswordResetToken getPasswordResetToken(String token);
User getUserByPasswordResetToken(String token);
User getUserByID(long id);
void changeUserPassword(User user, String password);
}

View File

@ -1,88 +0,0 @@
package org.baeldung.persistence.service;
import javax.validation.constraints.NotNull;
import org.baeldung.validation.PasswordMatches;
import org.baeldung.validation.ValidEmail;
import org.hibernate.validator.constraints.NotEmpty;
@PasswordMatches
public class UserDto {
@NotNull
@NotEmpty
private String firstName;
@NotNull
@NotEmpty
private String lastName;
@NotNull
@NotEmpty
private String password;
@NotNull
@NotEmpty
private String matchingPassword;
@ValidEmail
@NotNull
@NotEmpty
private String email;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
private Integer role;
public Integer getRole() {
return role;
}
public void setRole(Integer role) {
this.role = role;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getMatchingPassword() {
return matchingPassword;
}
public void setMatchingPassword(String matchingPassword) {
this.matchingPassword = matchingPassword;
}
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
builder.append("User [firstName=").append(firstName).append("]").append("[lastName=").append(lastName).append("]").append("[email").append(email).append("]").append("[password").append(password).append("]");
return builder.toString();
}
}

View File

@ -1,131 +0,0 @@
package org.baeldung.persistence.service;
import java.util.Arrays;
import java.util.UUID;
import javax.transaction.Transactional;
import org.baeldung.persistence.dao.PasswordResetTokenRepository;
import org.baeldung.persistence.dao.RoleRepository;
import org.baeldung.persistence.dao.UserRepository;
import org.baeldung.persistence.dao.VerificationTokenRepository;
import org.baeldung.persistence.model.PasswordResetToken;
import org.baeldung.persistence.model.User;
import org.baeldung.persistence.model.VerificationToken;
import org.baeldung.validation.EmailExistsException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
@Service
@Transactional
public class UserService implements IUserService {
@Autowired
private UserRepository repository;
@Autowired
private VerificationTokenRepository tokenRepository;
@Autowired
private PasswordResetTokenRepository passwordTokenRepository;
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private RoleRepository roleRepository;
// API
@Override
public User registerNewUserAccount(final UserDto accountDto) throws EmailExistsException {
if (emailExist(accountDto.getEmail())) {
throw new EmailExistsException("There is an account with that email adress: " + accountDto.getEmail());
}
final User user = new User();
user.setFirstName(accountDto.getFirstName());
user.setLastName(accountDto.getLastName());
user.setPassword(passwordEncoder.encode(accountDto.getPassword()));
user.setEmail(accountDto.getEmail());
user.setRoles(Arrays.asList(roleRepository.findByName("ROLE_USER")));
return repository.save(user);
}
@Override
public User getUser(final String verificationToken) {
final User user = tokenRepository.findByToken(verificationToken).getUser();
return user;
}
@Override
public VerificationToken getVerificationToken(final String VerificationToken) {
return tokenRepository.findByToken(VerificationToken);
}
@Override
public void saveRegisteredUser(final User user) {
repository.save(user);
}
@Override
public void deleteUser(final User user) {
repository.delete(user);
}
@Override
public void createVerificationTokenForUser(final User user, final String token) {
final VerificationToken myToken = new VerificationToken(token, user);
tokenRepository.save(myToken);
}
@Override
public VerificationToken generateNewVerificationToken(final String existingVerificationToken) {
VerificationToken vToken = tokenRepository.findByToken(existingVerificationToken);
vToken.updateToken(UUID.randomUUID().toString());
vToken = tokenRepository.save(vToken);
return vToken;
}
@Override
public void createPasswordResetTokenForUser(final User user, final String token) {
final PasswordResetToken myToken = new PasswordResetToken(token, user);
passwordTokenRepository.save(myToken);
}
@Override
public User findUserByEmail(final String email) {
return repository.findByEmail(email);
}
@Override
public PasswordResetToken getPasswordResetToken(final String token) {
return passwordTokenRepository.findByToken(token);
}
@Override
public User getUserByPasswordResetToken(final String token) {
return passwordTokenRepository.findByToken(token).getUser();
}
@Override
public User getUserByID(final long id) {
return repository.findOne(id);
}
@Override
public void changeUserPassword(final User user, final String password) {
user.setPassword(passwordEncoder.encode(password));
repository.save(user);
}
private boolean emailExist(final String email) {
final User user = repository.findByEmail(email);
if (user != null) {
return true;
}
return false;
}
}

View File

@ -1,33 +0,0 @@
package org.baeldung.registration;
import java.util.Locale;
import org.baeldung.persistence.model.User;
import org.springframework.context.ApplicationEvent;
@SuppressWarnings("serial")
public class OnRegistrationCompleteEvent extends ApplicationEvent {
private final String appUrl;
private final Locale locale;
private final User user;
public OnRegistrationCompleteEvent(User user, Locale locale, String appUrl) {
super(user);
this.user = user;
this.locale = locale;
this.appUrl = appUrl;
}
public String getAppUrl() {
return appUrl;
}
public Locale getLocale() {
return locale;
}
public User getUser() {
return user;
}
}

View File

@ -1,63 +0,0 @@
package org.baeldung.registration.listener;
import java.util.UUID;
import org.baeldung.persistence.model.User;
import org.baeldung.persistence.service.IUserService;
import org.baeldung.registration.OnRegistrationCompleteEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.MessageSource;
import org.springframework.core.env.Environment;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Component;
@Component
public class RegistrationListener implements ApplicationListener<OnRegistrationCompleteEvent> {
@Autowired
private IUserService service;
@Autowired
private MessageSource messages;
@Autowired
private JavaMailSender mailSender;
@Autowired
private Environment env;
// API
@Override
public void onApplicationEvent(final OnRegistrationCompleteEvent event) {
this.confirmRegistration(event);
}
private void confirmRegistration(final OnRegistrationCompleteEvent event) {
final User user = event.getUser();
final String token = UUID.randomUUID().toString();
service.createVerificationTokenForUser(user, token);
final SimpleMailMessage email = constructEmailMessage(event, user, token);
mailSender.send(email);
}
//
private final SimpleMailMessage constructEmailMessage(final OnRegistrationCompleteEvent event, final User user, final String token) {
final String recipientAddress = user.getEmail();
final String subject = "Registration Confirmation";
final String confirmationUrl = event.getAppUrl() + "/regitrationConfirm.html?token=" + token;
final String message = messages.getMessage("message.regSucc", null, event.getLocale());
final SimpleMailMessage email = new SimpleMailMessage();
email.setTo(recipientAddress);
email.setSubject(subject);
email.setText(message + " \r\n" + confirmationUrl);
email.setFrom(env.getProperty("support.email"));
System.out.println("ddddd");
System.out.println(email.getText());
return email;
}
}

View File

@ -12,7 +12,6 @@ import org.baeldung.persistence.dao.UserRepository;
import org.baeldung.persistence.model.Privilege; import org.baeldung.persistence.model.Privilege;
import org.baeldung.persistence.model.Role; import org.baeldung.persistence.model.Role;
import org.baeldung.persistence.model.User; import org.baeldung.persistence.model.User;
import org.baeldung.persistence.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource; import org.springframework.context.MessageSource;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
@ -29,8 +28,7 @@ public class MyUserDetailsService implements UserDetailsService {
@Autowired @Autowired
private UserRepository userRepository; private UserRepository userRepository;
@Autowired
private IUserService service;
@Autowired @Autowired
private MessageSource messages; private MessageSource messages;
@Autowired @Autowired
@ -50,7 +48,7 @@ public class MyUserDetailsService implements UserDetailsService {
@Override @Override
public UserDetails loadUserByUsername(final String email) throws UsernameNotFoundException { public UserDetails loadUserByUsername(final String email) throws UsernameNotFoundException {
String ip = request.getRemoteAddr(); final String ip = request.getRemoteAddr();
if (loginAttemptService.isBlocked(ip)) { if (loginAttemptService.isBlocked(ip)) {
throw new RuntimeException("blocked"); throw new RuntimeException("blocked");
} }
@ -76,7 +74,7 @@ public class MyUserDetailsService implements UserDetailsService {
private final List<String> getPrivileges(final Collection<Role> roles) { private final List<String> getPrivileges(final Collection<Role> roles) {
final List<String> privileges = new ArrayList<String>(); final List<String> privileges = new ArrayList<String>();
final List<Privilege> collection = new ArrayList<Privilege>(); final List<Privilege> collection = new ArrayList<Privilege>();
for (Role role : roles) { for (final Role role : roles) {
collection.addAll(role.getPrivileges()); collection.addAll(role.getPrivileges());
} }
for (final Privilege item : collection) { for (final Privilege item : collection) {

View File

@ -1,44 +0,0 @@
package org.baeldung.spring;
import java.util.Properties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.env.Environment;
import org.springframework.mail.javamail.JavaMailSenderImpl;
@Configuration
@ComponentScan(basePackages = { "org.baeldung.registration" })
@PropertySource("classpath:email.properties")
public class AppConfig {
@Autowired
private Environment env;
// beans
@Bean
public static PropertySourcesPlaceholderConfigurer propertyPlaceHolderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
@Bean
public JavaMailSenderImpl javaMailSenderImpl() {
JavaMailSenderImpl mailSenderImpl = new JavaMailSenderImpl();
mailSenderImpl.setHost(env.getProperty("smtp.host"));
mailSenderImpl.setPort(env.getProperty("smtp.port", Integer.class));
mailSenderImpl.setProtocol(env.getProperty("smtp.protocol"));
mailSenderImpl.setUsername(env.getProperty("smtp.username"));
mailSenderImpl.setPassword(env.getProperty("smtp.password"));
Properties javaMailProps = new Properties();
javaMailProps.put("mail.smtp.auth", true);
javaMailProps.put("mail.smtp.starttls.enable", true);
mailSenderImpl.setJavaMailProperties(javaMailProps);
return mailSenderImpl;
}
}

View File

@ -2,11 +2,8 @@ package org.baeldung.spring;
import java.util.Locale; import java.util.Locale;
import org.baeldung.validation.EmailValidator;
import org.baeldung.validation.PasswordMatchesValidator;
import org.springframework.context.MessageSource; import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ReloadableResourceBundleMessageSource; import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.LocaleResolver;
@ -22,7 +19,7 @@ import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView; import org.springframework.web.servlet.view.JstlView;
@Configuration @Configuration
@ComponentScan(basePackages = { "org.baeldung.web" }) // @ComponentScan(basePackages = { "org.baeldung.web" })
@EnableWebMvc @EnableWebMvc
public class MvcConfig extends WebMvcConfigurerAdapter { public class MvcConfig extends WebMvcConfigurerAdapter {
@ -91,14 +88,4 @@ public class MvcConfig extends WebMvcConfigurerAdapter {
return messageSource; return messageSource;
} }
@Bean
public EmailValidator usernameValidator() {
return new EmailValidator();
}
@Bean
public PasswordMatchesValidator passwordMatchesValidator() {
return new PasswordMatchesValidator();
}
} }

View File

@ -1,17 +0,0 @@
package org.baeldung.test;
import org.baeldung.spring.PersistenceJPAConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@ComponentScan({ "org.baeldung.persistence.dao" })
public class TestConfig extends PersistenceJPAConfig {
@Bean
public PasswordEncoder encoder() {
return new BCryptPasswordEncoder(11);
}
}

View File

@ -1,9 +0,0 @@
package org.baeldung.validation;
@SuppressWarnings("serial")
public class EmailExistsException extends Throwable {
public EmailExistsException(String message) {
super(message);
}
}

View File

@ -1,28 +0,0 @@
package org.baeldung.validation;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class EmailValidator implements ConstraintValidator<ValidEmail, String> {
private Pattern pattern;
private Matcher matcher;
private static final String EMAIL_PATTERN = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@" + "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
@Override
public void initialize(ValidEmail constraintAnnotation) {
}
@Override
public boolean isValid(String username, ConstraintValidatorContext context) {
return (validateEmail(username));
}
private boolean validateEmail(String email) {
pattern = Pattern.compile(EMAIL_PATTERN);
matcher = pattern.matcher(email);
return matcher.matches();
}
}

View File

@ -1,24 +0,0 @@
package org.baeldung.validation;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Target({ TYPE, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Constraint(validatedBy = PasswordMatchesValidator.class)
@Documented
public @interface PasswordMatches {
String message() default "Passwords don't match";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}

View File

@ -1,19 +0,0 @@
package org.baeldung.validation;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import org.baeldung.persistence.service.UserDto;
public class PasswordMatchesValidator implements ConstraintValidator<PasswordMatches, Object> {
@Override
public void initialize(PasswordMatches constraintAnnotation) {
}
@Override
public boolean isValid(Object obj, ConstraintValidatorContext context) {
UserDto user = (UserDto) obj;
return user.getPassword().equals(user.getMatchingPassword());
}
}

View File

@ -1,23 +0,0 @@
package org.baeldung.validation;
import org.baeldung.persistence.service.UserDto;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
public class UserValidator implements Validator {
@Override
public boolean supports(Class<?> clazz) {
return UserDto.class.isAssignableFrom(clazz);
}
@Override
public void validate(Object obj, Errors errors) {
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "firstName", "message.firstName", "Firstname is required.");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "lastName", "message.lastName", "LastName is required.");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "password", "message.password", "LastName is required.");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "username", "message.username", "UserName is required.");
}
}

View File

@ -1,24 +0,0 @@
package org.baeldung.validation;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Target({ TYPE, FIELD, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Constraint(validatedBy = EmailValidator.class)
@Documented
public @interface ValidEmail {
String message() default "Invalid Email";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}

View File

@ -1,207 +0,0 @@
package org.baeldung.web.controller;
import java.util.Calendar;
import java.util.Locale;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import org.baeldung.persistence.model.PasswordResetToken;
import org.baeldung.persistence.model.User;
import org.baeldung.persistence.model.VerificationToken;
import org.baeldung.persistence.service.IUserService;
import org.baeldung.persistence.service.UserDto;
import org.baeldung.registration.OnRegistrationCompleteEvent;
import org.baeldung.validation.EmailExistsException;
import org.baeldung.web.error.UserNotFoundException;
import org.baeldung.web.util.GenericResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.MessageSource;
import org.springframework.core.env.Environment;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
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.ResponseBody;
@Controller
public class RegistrationController {
private final Logger LOGGER = LoggerFactory.getLogger(getClass());
@Autowired
private IUserService userService;
@Autowired
private MessageSource messages;
@Autowired
private JavaMailSender mailSender;
@Autowired
private ApplicationEventPublisher eventPublisher;
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private Environment env;
public RegistrationController() {
}
// Registration
@RequestMapping(value = "/user/registration", method = RequestMethod.POST)
@ResponseBody
public GenericResponse registerUserAccount(@Valid final UserDto accountDto, final BindingResult result, final HttpServletRequest request) {
LOGGER.debug("Registering user account with information: {}", accountDto);
if (result.hasErrors()) {
return new GenericResponse(result.getFieldErrors(), result.getGlobalErrors());
}
final User registered = createUserAccount(accountDto);
if (registered == null) {
return new GenericResponse("email", messages.getMessage("message.regError", null, request.getLocale()));
}
final String appUrl = "http://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();
eventPublisher.publishEvent(new OnRegistrationCompleteEvent(registered, request.getLocale(), appUrl));
return new GenericResponse("success");
}
@RequestMapping(value = "/regitrationConfirm", method = RequestMethod.GET)
public String confirmRegistration(final Locale locale, final Model model, @RequestParam("token") final String token) {
final VerificationToken verificationToken = userService.getVerificationToken(token);
if (verificationToken == null) {
final String message = messages.getMessage("auth.message.invalidToken", null, locale);
model.addAttribute("message", message);
return "redirect:/badUser.html?lang=" + locale.getLanguage();
}
final User user = verificationToken.getUser();
final Calendar cal = Calendar.getInstance();
if ((verificationToken.getExpiryDate().getTime() - cal.getTime().getTime()) <= 0) {
model.addAttribute("message", messages.getMessage("auth.message.expired", null, locale));
model.addAttribute("expired", true);
model.addAttribute("token", token);
return "redirect:/badUser.html?lang=" + locale.getLanguage();
}
user.setEnabled(true);
userService.saveRegisteredUser(user);
model.addAttribute("message", messages.getMessage("message.accountVerified", null, locale));
return "redirect:/login.html?lang=" + locale.getLanguage();
}
// user activation - verification
@RequestMapping(value = "/user/resendRegistrationToken", method = RequestMethod.GET)
@ResponseBody
public GenericResponse resendRegistrationToken(final HttpServletRequest request, @RequestParam("token") final String existingToken) {
final VerificationToken newToken = userService.generateNewVerificationToken(existingToken);
final User user = userService.getUser(newToken.getToken());
final String appUrl = "http://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();
final SimpleMailMessage email = constructResendVerificationTokenEmail(appUrl, request.getLocale(), newToken, user);
mailSender.send(email);
return new GenericResponse(messages.getMessage("message.resendToken", null, request.getLocale()));
}
// Reset password
@RequestMapping(value = "/user/resetPassword", method = RequestMethod.POST)
@ResponseBody
public GenericResponse resetPassword(final HttpServletRequest request, @RequestParam("email") final String userEmail) {
final User user = userService.findUserByEmail(userEmail);
if (user == null) {
throw new UserNotFoundException();
}
final String token = UUID.randomUUID().toString();
userService.createPasswordResetTokenForUser(user, token);
final String appUrl = "http://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();
final SimpleMailMessage email = constructResetTokenEmail(appUrl, request.getLocale(), token, user);
mailSender.send(email);
return new GenericResponse(messages.getMessage("message.resetPasswordEmail", null, request.getLocale()));
}
@RequestMapping(value = "/user/changePassword", method = RequestMethod.GET)
public String showChangePasswordPage(final Locale locale, final Model model, @RequestParam("id") final long id, @RequestParam("token") final String token) {
final PasswordResetToken passToken = userService.getPasswordResetToken(token);
final User user = passToken.getUser();
if (passToken == null || user.getId() != id) {
final String message = messages.getMessage("auth.message.invalidToken", null, locale);
model.addAttribute("message", message);
return "redirect:/login.html?lang=" + locale.getLanguage();
}
final Calendar cal = Calendar.getInstance();
if ((passToken.getExpiryDate().getTime() - cal.getTime().getTime()) <= 0) {
model.addAttribute("message", messages.getMessage("auth.message.expired", null, locale));
return "redirect:/login.html?lang=" + locale.getLanguage();
}
final Authentication auth = new UsernamePasswordAuthenticationToken(user, null, userDetailsService.loadUserByUsername(user.getEmail()).getAuthorities());
SecurityContextHolder.getContext().setAuthentication(auth);
return "redirect:/updatePassword.html?lang=" + locale.getLanguage();
}
@RequestMapping(value = "/user/savePassword", method = RequestMethod.POST)
@PreAuthorize("hasRole('READ_PRIVILEGE')")
@ResponseBody
public GenericResponse savePassword(final Locale locale, @RequestParam("password") final String password) {
final User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
userService.changeUserPassword(user, password);
return new GenericResponse(messages.getMessage("message.resetPasswordSuc", null, locale));
}
// NON-API
private final SimpleMailMessage constructResendVerificationTokenEmail(final String contextPath, final Locale locale, final VerificationToken newToken, final User user) {
final String confirmationUrl = contextPath + "/regitrationConfirm.html?token=" + newToken.getToken();
final String message = messages.getMessage("message.resendToken", null, locale);
final SimpleMailMessage email = new SimpleMailMessage();
email.setSubject("Resend Registration Token");
email.setText(message + " \r\n" + confirmationUrl);
email.setTo(user.getEmail());
email.setFrom(env.getProperty("support.email"));
return email;
}
private final SimpleMailMessage constructResetTokenEmail(final String contextPath, final Locale locale, final String token, final User user) {
final String url = contextPath + "/user/changePassword?id=" + user.getId() + "&token=" + token;
final String message = messages.getMessage("message.resetPassword", null, locale);
final SimpleMailMessage email = new SimpleMailMessage();
email.setTo(user.getEmail());
email.setSubject("Reset Password");
email.setText(message + " \r\n" + url);
email.setFrom(env.getProperty("support.email"));
return email;
}
private User createUserAccount(final UserDto accountDto) {
User registered = null;
try {
registered = userService.registerNewUserAccount(accountDto);
} catch (final EmailExistsException e) {
return null;
}
return registered;
}
}

View File

@ -1,48 +0,0 @@
package org.baeldung.web.error;
import org.baeldung.web.util.GenericResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.mail.MailAuthenticationException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
@ControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
@Autowired
private MessageSource messages;
public RestResponseEntityExceptionHandler() {
super();
}
// 404
@ExceptionHandler({ UserNotFoundException.class })
public ResponseEntity<Object> handleUserNotFound(final RuntimeException ex, final WebRequest request) {
logger.error("404 Status Code", ex);
final GenericResponse bodyOfResponse = new GenericResponse(messages.getMessage("message.userNotFound", null, request.getLocale()), "UserNotFound");
return handleExceptionInternal(ex, bodyOfResponse, new HttpHeaders(), HttpStatus.NOT_FOUND, request);
}
// 500
@ExceptionHandler({ MailAuthenticationException.class })
public ResponseEntity<Object> handleMail(final RuntimeException ex, final WebRequest request) {
logger.error("500 Status Code", ex);
final GenericResponse bodyOfResponse = new GenericResponse(messages.getMessage("message.email.config.error", null, request.getLocale()), "MailError");
return handleExceptionInternal(ex, bodyOfResponse, new HttpHeaders(), HttpStatus.BAD_REQUEST, request);
}
@ExceptionHandler({ Exception.class })
public ResponseEntity<Object> handleInternal(final RuntimeException ex, final WebRequest request) {
logger.error("500 Status Code", ex);
final GenericResponse bodyOfResponse = new GenericResponse(messages.getMessage("message.error", null, request.getLocale()), "InternalError");
return handleExceptionInternal(ex, bodyOfResponse, new HttpHeaders(), HttpStatus.BAD_REQUEST, request);
}
}

View File

@ -1,23 +0,0 @@
package org.baeldung.web.error;
public final class UserNotFoundException extends RuntimeException {
private static final long serialVersionUID = 5861310537366287163L;
public UserNotFoundException() {
super();
}
public UserNotFoundException(final String message, final Throwable cause) {
super(message, cause);
}
public UserNotFoundException(final String message) {
super(message);
}
public UserNotFoundException(final Throwable cause) {
super(cause);
}
}

View File

@ -1,54 +0,0 @@
package org.baeldung.web.util;
import java.util.List;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class GenericResponse {
private String message;
private String error;
public GenericResponse(final String message) {
super();
this.message = message;
}
public GenericResponse(final String message, final String error) {
super();
this.message = message;
this.error = error;
}
public GenericResponse(final List<FieldError> fieldErrors, final List<ObjectError> globalErrors) {
super();
final ObjectMapper mapper = new ObjectMapper();
try {
this.message = mapper.writeValueAsString(fieldErrors);
this.error = mapper.writeValueAsString(globalErrors);
} catch (final JsonProcessingException e) {
this.message = "";
this.error = "";
}
}
public String getMessage() {
return message;
}
public void setMessage(final String message) {
this.message = message;
}
public String getError() {
return error;
}
public void setError(final String error) {
this.error = error;
}
}

View File

@ -33,7 +33,7 @@
<script type="text/javascript"> <script type="text/javascript">
function resetPass(){ function resetPass(){
var email = $("#email").val(); var email = $("#email").val();
$.post("<c:url value="/user/resetPassword"></c:url>",{email: email} ,function(data){ $.post("/spring-security-login-and-registration/user/resetPassword",{email: email} ,function(data){
window.location.href = "<c:url value="/login.html"></c:url>" + "?message=" + data.message; window.location.href = "<c:url value="/login.html"></c:url>" + "?message=" + data.message;
}) })
.fail(function(data) { .fail(function(data) {

View File

@ -59,7 +59,7 @@
function register(){ function register(){
$(".alert").html("").hide(); $(".alert").html("").hide();
var formData= $('form').serialize(); var formData= $('form').serialize();
$.post("<c:url value="/user/registration"></c:url>",formData ,function(data){ $.post("/spring-security-login-and-registration/user/registration",formData ,function(data){
if(data.message == "success"){ if(data.message == "success"){
window.location.href = "<c:url value="/successRegister.html"></c:url>"; window.location.href = "<c:url value="/successRegister.html"></c:url>";
} }

View File

@ -46,7 +46,7 @@ function savePass(){
$("#error").show(); $("#error").show();
return; return;
} }
$.post("<c:url value="/user/savePassword"></c:url>",{password: pass} ,function(data){ $.post("/spring-security-login-and-registration/user/savePassword",{password: pass} ,function(data){
window.location.href = "<c:url value="/login.html"></c:url>" + "?message="+data.message; window.location.href = "<c:url value="/login.html"></c:url>" + "?message="+data.message;
}) })
.fail(function(data) { .fail(function(data) {

View File

@ -1,121 +0,0 @@
package org.baeldung.test;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import java.util.ArrayList;
import java.util.Arrays;
import org.baeldung.persistence.dao.PrivilegeRepository;
import org.baeldung.persistence.dao.RoleRepository;
import org.baeldung.persistence.dao.UserRepository;
import org.baeldung.persistence.model.Privilege;
import org.baeldung.persistence.model.Role;
import org.baeldung.persistence.model.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.transaction.annotation.Transactional;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { TestConfig.class }, loader = AnnotationConfigContextLoader.class)
@Transactional
@TransactionConfiguration
public class SpringSecurityRolesTest {
@Autowired
private UserRepository userRepository;
@Autowired
private RoleRepository roleRepository;
@Autowired
private PrivilegeRepository privilegeRepository;
@Autowired
private PasswordEncoder passwordEncoder;
private User user;
private Role role;
private Privilege privilege;
// tests
@Test
public void testDeleteUser() {
role = new Role("TEST_ROLE");
roleRepository.save(role);
user = new User();
user.setFirstName("John");
user.setLastName("Doe");
user.setPassword(passwordEncoder.encode("123"));
user.setEmail("john@doe.com");
user.setRoles(Arrays.asList(role));
user.setEnabled(true);
userRepository.save(user);
assertNotNull(userRepository.findByEmail(user.getEmail()));
assertNotNull(roleRepository.findByName(role.getName()));
user.setRoles(null);
userRepository.delete(user);
assertNull(userRepository.findByEmail(user.getEmail()));
assertNotNull(roleRepository.findByName(role.getName()));
}
@Test
public void testDeleteRole() {
privilege = new Privilege("TEST_PRIVILEGE");
privilegeRepository.save(privilege);
role = new Role("TEST_ROLE");
role.setPrivileges(Arrays.asList(privilege));
roleRepository.save(role);
user = new User();
user.setFirstName("John");
user.setLastName("Doe");
user.setPassword(passwordEncoder.encode("123"));
user.setEmail("john@doe.com");
user.setRoles(Arrays.asList(role));
user.setEnabled(true);
userRepository.save(user);
assertNotNull(privilegeRepository.findByName(privilege.getName()));
assertNotNull(userRepository.findByEmail(user.getEmail()));
assertNotNull(roleRepository.findByName(role.getName()));
user.setRoles(new ArrayList<Role>());
role.setPrivileges(new ArrayList<Privilege>());
roleRepository.delete(role);
assertNull(roleRepository.findByName(role.getName()));
assertNotNull(privilegeRepository.findByName(privilege.getName()));
assertNotNull(userRepository.findByEmail(user.getEmail()));
}
@Test
public void testDeletePrivilege() {
privilege = new Privilege("TEST_PRIVILEGE");
privilegeRepository.save(privilege);
role = new Role("TEST_ROLE");
role.setPrivileges(Arrays.asList(privilege));
roleRepository.save(role);
assertNotNull(roleRepository.findByName(role.getName()));
assertNotNull(privilegeRepository.findByName(privilege.getName()));
role.setPrivileges(new ArrayList<Privilege>());
privilegeRepository.delete(privilege);
assertNull(privilegeRepository.findByName(privilege.getName()));
assertNotNull(roleRepository.findByName(role.getName()));
}
}

View File

@ -32,12 +32,10 @@ import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.validation.BindingResult; import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
@Controller @Controller
public class RegistrationController { public class RegistrationController {
@ -67,34 +65,21 @@ public class RegistrationController {
// Registration // Registration
@RequestMapping(value = "/user/registration", method = RequestMethod.GET)
public String showRegistrationPage(final Model model) {
LOGGER.debug("Rendering registration page.");
final UserDto accountDto = new UserDto();
model.addAttribute("user", accountDto);
return "registration";
}
@RequestMapping(value = "/user/registration", method = RequestMethod.POST) @RequestMapping(value = "/user/registration", method = RequestMethod.POST)
public ModelAndView registerUserAccount(@ModelAttribute("user") @Valid final UserDto accountDto, final BindingResult result, final HttpServletRequest request) { @ResponseBody
public GenericResponse registerUserAccount(@Valid final UserDto accountDto, final BindingResult result, final HttpServletRequest request) {
LOGGER.debug("Registering user account with information: {}", accountDto); LOGGER.debug("Registering user account with information: {}", accountDto);
if (result.hasErrors()) { if (result.hasErrors()) {
return new ModelAndView("registration", "user", accountDto); return new GenericResponse(result.getFieldErrors(), result.getGlobalErrors());
} }
final User registered = createUserAccount(accountDto); final User registered = createUserAccount(accountDto);
if (registered == null) { if (registered == null) {
result.rejectValue("email", "message.regError"); return new GenericResponse("email", messages.getMessage("message.regError", null, request.getLocale()));
return new ModelAndView("registration", "user", accountDto);
} }
try {
final String appUrl = "http://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath(); final String appUrl = "http://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();
eventPublisher.publishEvent(new OnRegistrationCompleteEvent(registered, request.getLocale(), appUrl)); eventPublisher.publishEvent(new OnRegistrationCompleteEvent(registered, request.getLocale(), appUrl));
} catch (final Exception ex) {
LOGGER.warn("Unable to register user", ex); return new GenericResponse("success");
return new ModelAndView("emailError", "user", accountDto);
}
return new ModelAndView("successRegister", "user", accountDto);
} }
@RequestMapping(value = "/regitrationConfirm", method = RequestMethod.GET) @RequestMapping(value = "/regitrationConfirm", method = RequestMethod.GET)

View File

@ -1,5 +1,13 @@
package org.baeldung.web.util; package org.baeldung.web.util;
import java.util.List;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class GenericResponse { public class GenericResponse {
private String message; private String message;
private String error; private String error;
@ -15,6 +23,18 @@ public class GenericResponse {
this.error = error; this.error = error;
} }
public GenericResponse(final List<FieldError> fieldErrors, final List<ObjectError> globalErrors) {
super();
final ObjectMapper mapper = new ObjectMapper();
try {
this.message = mapper.writeValueAsString(fieldErrors);
this.error = mapper.writeValueAsString(globalErrors);
} catch (final JsonProcessingException e) {
this.message = "";
this.error = "";
}
}
public String getMessage() { public String getMessage() {
return message; return message;
} }