Changes September
This commit is contained in:
parent
7f8eea622e
commit
53c0dbbbdd
|
@ -4,5 +4,5 @@ import org.springframework.data.jpa.repository.JpaRepository;
|
|||
import org.baeldung.persistence.model.User;
|
||||
|
||||
public interface UserRepository extends JpaRepository<User, Long> {
|
||||
public User findByUsername(String username);
|
||||
public User findByEmail(String email);
|
||||
}
|
||||
|
|
|
@ -21,8 +21,8 @@ public class User {
|
|||
private String firstName;
|
||||
@Column(name = "lastName")
|
||||
private String lastName;
|
||||
@Column(name = "username")
|
||||
private String username;
|
||||
@Column(name = "email")
|
||||
private String email;
|
||||
@Column(name = "password")
|
||||
private String password;
|
||||
|
||||
|
@ -53,12 +53,12 @@ public class User {
|
|||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
|
@ -81,7 +81,7 @@ public class User {
|
|||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((username == null) ? 0 : username.hashCode());
|
||||
result = prime * result + ((email == null) ? 0 : email.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,7 @@ public class User {
|
|||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
final User user = (User) obj;
|
||||
if (!username.equals(user.username))
|
||||
if (!email.equals(user.email))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ public class User {
|
|||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
builder.append("User [firstName=").append(firstName).append("]").append("[lastName=").append(lastName).append("]").append("[username").append(username).append("]");
|
||||
builder.append("User [firstName=").append(firstName).append("]").append("[lastName=").append(lastName).append("]").append("[email").append(email).append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
|
@ -6,13 +6,13 @@ import java.util.regex.Pattern;
|
|||
import javax.validation.ConstraintValidator;
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
|
||||
public class UsernameValidator implements ConstraintValidator<ValidUsername, String> {
|
||||
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(ValidUsername constraintAnnotation) {
|
||||
public void initialize(ValidEmail constraintAnnotation) {
|
||||
}
|
||||
|
||||
@Override
|
|
@ -0,0 +1,9 @@
|
|||
package org.baeldung.persistence.service;
|
||||
|
||||
import org.baeldung.persistence.model.User;
|
||||
|
||||
public interface IUserService {
|
||||
|
||||
public User registerNewUserAccount(UserDto userAccountData) throws EmailExistsException;
|
||||
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
package org.baeldung.persistence.service;
|
||||
|
||||
import javax.transaction.Transactional;
|
||||
import org.baeldung.persistence.dao.UserRepository;
|
||||
import org.baeldung.persistence.model.Role;
|
||||
import org.baeldung.persistence.model.User;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class RepositoryService implements UserService {
|
||||
@Autowired
|
||||
private UserRepository repository;
|
||||
@Autowired
|
||||
private Environment env;
|
||||
|
||||
@Autowired
|
||||
public RepositoryService(UserRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public User registerNewUserAccount(UserDto userAccountData) throws EmailExistsException {
|
||||
if (emailExist(userAccountData.getUsername())) {
|
||||
|
||||
throw new EmailExistsException("There is an account with that email adress: " + userAccountData.getUsername());
|
||||
}
|
||||
User user = new User();
|
||||
user.setFirstName(userAccountData.getFirstName());
|
||||
user.setLastName(userAccountData.getLastName());
|
||||
user.setPassword(userAccountData.getPassword());
|
||||
user.setUsername(userAccountData.getUsername());
|
||||
user.setRole(new Role(userAccountData.getRole(), user));
|
||||
return repository.save(user);
|
||||
}
|
||||
|
||||
private boolean emailExist(String email) {
|
||||
User user = repository.findByUsername(email);
|
||||
if (user != null) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -16,10 +16,18 @@ public class UserDto {
|
|||
@NotNull
|
||||
@NotEmpty
|
||||
private String matchingPassword;
|
||||
@ValidUsername
|
||||
@ValidEmail
|
||||
@NotNull
|
||||
@NotEmpty
|
||||
private String username;
|
||||
private String email;
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
private Integer role;
|
||||
|
||||
public Integer getRole() {
|
||||
|
@ -30,14 +38,6 @@ public class UserDto {
|
|||
this.role = role;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ public class UserDto {
|
|||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
builder.append("User [firstName=").append(firstName).append("]").append("[lastName=").append(lastName).append("]").append("[username").append(username).append("]").append("[password").append(password).append("]");
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,39 @@
|
|||
package org.baeldung.persistence.service;
|
||||
|
||||
import javax.transaction.Transactional;
|
||||
import org.baeldung.persistence.dao.UserRepository;
|
||||
import org.baeldung.persistence.model.Role;
|
||||
import org.baeldung.persistence.model.User;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
public interface UserService {
|
||||
@Service
|
||||
public class UserService implements IUserService {
|
||||
@Autowired
|
||||
private UserRepository repository;
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public User registerNewUserAccount(UserDto userAccountData) throws EmailExistsException {
|
||||
if (emailExist(userAccountData.getEmail())) {
|
||||
|
||||
public User registerNewUserAccount(UserDto userAccountData) throws EmailExistsException;
|
||||
throw new EmailExistsException("There is an account with that email adress: " + userAccountData.getEmail());
|
||||
}
|
||||
User user = new User();
|
||||
user.setFirstName(userAccountData.getFirstName());
|
||||
user.setLastName(userAccountData.getLastName());
|
||||
user.setPassword(userAccountData.getPassword());
|
||||
user.setEmail(userAccountData.getEmail());
|
||||
//ROLE WILL ALWAYS BE USER. HARDCODING IT
|
||||
user.setRole(new Role(Integer.valueOf(1),user));
|
||||
return repository.save(user);
|
||||
}
|
||||
|
||||
private boolean emailExist(String email) {
|
||||
User user = repository.findByEmail(email);
|
||||
if (user != null) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,9 +12,9 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
|||
|
||||
@Target({ TYPE, FIELD, ANNOTATION_TYPE })
|
||||
@Retention(RUNTIME)
|
||||
@Constraint(validatedBy = UsernameValidator.class)
|
||||
@Constraint(validatedBy = EmailValidator.class)
|
||||
@Documented
|
||||
public @interface ValidUsername {
|
||||
public @interface ValidEmail {
|
||||
|
||||
String message() default "Invalid Email";
|
||||
|
|
@ -21,19 +21,20 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
@Transactional
|
||||
public class MyUserDetailsService implements UserDetailsService {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(UserDetailsService.class);
|
||||
|
||||
private UserRepository userRepository;
|
||||
private final Logger LOGGER = LoggerFactory.getLogger(getClass());
|
||||
|
||||
@Autowired
|
||||
public MyUserDetailsService(UserRepository repository) {
|
||||
this.userRepository = repository;
|
||||
}
|
||||
private UserRepository userRepository;
|
||||
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||
// @Autowired
|
||||
// public MyUserDetailsService(UserRepository repository) {
|
||||
// this.userRepository = repository;
|
||||
// }
|
||||
|
||||
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
|
||||
try {
|
||||
LOGGER.debug("Loading user by username: {}", username);
|
||||
User user = userRepository.findByUsername(username);
|
||||
LOGGER.debug("Loading user by username: {}", email);
|
||||
User user = userRepository.findByEmail(email);
|
||||
LOGGER.debug("Found user: {}", user);
|
||||
if (user == null) {
|
||||
// throw new UsernameNotFoundException("No user found with username: " + username);
|
||||
|
@ -44,7 +45,7 @@ public class MyUserDetailsService implements UserDetailsService {
|
|||
boolean accountNonExpired = true;
|
||||
boolean credentialsNonExpired = true;
|
||||
boolean accountNonLocked = true;
|
||||
return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword().toLowerCase(), enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, getAuthorities(user.getRole().getRole()));
|
||||
return new org.springframework.security.core.userdetails.User(user.getEmail(), user.getPassword().toLowerCase(), enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, getAuthorities(user.getRole().getRole()));
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
|
|
|
@ -3,7 +3,7 @@ package org.baeldung.spring;
|
|||
import java.util.Locale;
|
||||
|
||||
import org.baeldung.persistence.service.PasswordMatchesValidator;
|
||||
import org.baeldung.persistence.service.UsernameValidator;
|
||||
import org.baeldung.persistence.service.EmailValidator;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
@ -85,8 +85,8 @@ public class MvcConfig extends WebMvcConfigurerAdapter {
|
|||
}
|
||||
|
||||
@Bean
|
||||
public UsernameValidator usernameValidator() {
|
||||
UsernameValidator userNameValidator = new UsernameValidator();
|
||||
public EmailValidator usernameValidator() {
|
||||
EmailValidator userNameValidator = new EmailValidator();
|
||||
return userNameValidator;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
package org.baeldung.web.controller;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
import org.baeldung.persistence.model.User;
|
||||
import org.baeldung.persistence.service.EmailExistsException;
|
||||
import org.baeldung.persistence.service.UserDto;
|
||||
import org.baeldung.persistence.service.UserService;
|
||||
import org.baeldung.persistence.service.IUserService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
@ -23,12 +24,12 @@ import org.springframework.web.servlet.ModelAndView;
|
|||
public class RegistrationController {
|
||||
|
||||
private final Logger LOGGER = LoggerFactory.getLogger(getClass());
|
||||
private UserService service;
|
||||
private IUserService service;
|
||||
@Autowired
|
||||
private MessageSource messages;
|
||||
|
||||
@Autowired
|
||||
public RegistrationController(UserService service) {
|
||||
public RegistrationController(IUserService service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
|
@ -47,12 +48,20 @@ public class RegistrationController {
|
|||
if (!result.hasErrors())
|
||||
registered = createUserAccount(userAccountData, result);
|
||||
if (registered == null) {
|
||||
result.rejectValue("username", "message.regError");
|
||||
result.rejectValue("email", "message.regError");
|
||||
}
|
||||
if (result.hasErrors()) {
|
||||
return new ModelAndView("registration", "user", userAccountData);
|
||||
} else {
|
||||
// Will show the success registration page--ORIGINAL
|
||||
return new ModelAndView("successRegister", "user", userAccountData);
|
||||
|
||||
// Will redirect to login view (not in url as login.html) and user model can be accessed
|
||||
// return new ModelAndView("login","user", userAccountData);
|
||||
|
||||
|
||||
// Will redirect to login html but no model object---we send a success param to the login form
|
||||
//return new ModelAndView("redirect:/login.html?success=true", "", null);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,12 +10,22 @@ message.regError=An account for that username/email already exists. Please enter
|
|||
message.lastName=Last name is required
|
||||
message.firstName=First name required
|
||||
message.badEmail=Invalid email address
|
||||
label.user.email=Email
|
||||
label.user.firstName=First name
|
||||
label.user.lastName=Last name
|
||||
label.user.password=Password
|
||||
label.user.email=Email:
|
||||
label.user.firstName=First name:
|
||||
label.user.lastName=Last name:
|
||||
label.user.password=Password:
|
||||
label.user.confirmPass=Confirm password
|
||||
label.form.submit=Submit
|
||||
label.form.title=Registration Form
|
||||
label.form.loginLink=Back to login
|
||||
label.login=Login here
|
||||
ValidUsername.user.username=Invalid Username (Email)
|
||||
label.form.loginTitle=Login
|
||||
label.form.loginEmail=Email
|
||||
label.form.loginPass=Password
|
||||
label.form.loginEnglish=English
|
||||
label.form.loginSpanish=Spanish
|
||||
label.form.loginSignUp=Sign up
|
||||
ValidEmail.user.email=Invalid email address!
|
||||
UniqueUsername.user.username=An account with that username/email already exists
|
||||
NotNull.user.firstName=First name required
|
||||
NotEmpty.user.firstName=First name required
|
||||
|
@ -28,4 +38,4 @@ NotEmpty.user.password=Password required
|
|||
NotNull.user.matchingPassword=Required
|
||||
NotEmpty.user.matchingPassword=Required
|
||||
PasswordMatches.user:Password does not match!
|
||||
Email.user.username=Invalid Username (Email)
|
||||
Email.user.email=Invalid Username (Email)
|
|
@ -10,12 +10,22 @@ message.regError=Ya existe una cuenta con ese nombre de usuario. Ingrese un nomb
|
|||
message.lastName=Por favor ingrese su apellido
|
||||
message.firstName=Por favor ingrese su nombre
|
||||
message.badEmail=Direccion de correo no es valida
|
||||
label.user.email=Email
|
||||
label.user.firstName=Nombre
|
||||
label.user.lastName=Apellido
|
||||
label.user.password=Clave
|
||||
label.user.email=Correo Electronico:
|
||||
label.user.firstName=Nombre:
|
||||
label.user.lastName=Apellido:
|
||||
label.user.password=Contrasenia:
|
||||
label.user.confirmPass=Confirme la contrasenia
|
||||
label.form.submit=Enviar
|
||||
label.form.title=Formulario de Registro
|
||||
label.login=Autehtifiquese aqui
|
||||
ValidUsername.user.username=Email no es valido
|
||||
label.form.loginTitle=Ingreso
|
||||
label.form.loginLink=Regrese a autentificacion
|
||||
label.form.loginEmail=Correo Electronico
|
||||
label.form.loginPass=Contrasenia
|
||||
label.form.loginEnglish=Ingles
|
||||
label.form.loginSpanish=Espaniol
|
||||
label.form.loginSignUp=Registrese
|
||||
ValidEmail.user.email=Cuenta correo invlida!
|
||||
UniqueUsername.user.username=Ya existe una cuenta con ese nombre de usuario
|
||||
NotNull.user.firstName=Por favor ingrese su nombre
|
||||
NotEmpty.user.firstName=Por favor ingrese su nombre
|
||||
|
@ -24,8 +34,8 @@ NotEmpty.user.lastName=Por favor ingrese su apellido
|
|||
NotNull.user.username=Por favor ingrese su cuenta de email
|
||||
NotEmpty.user.username=Por favor ingrese su cuenta de email
|
||||
NotNull.user.password=Por favor ingrese su clave
|
||||
NotEmpty.user.password=Por favor ingrese su clave
|
||||
NotEmpty.user.password=Por favor ingrese su contraseña
|
||||
NotNull.user.matchingPassword=Campo obligatirio
|
||||
NotEmpty.user.matchingPassword=Campo obligatrio
|
||||
PasswordMatches.user:Las claves no coinciden!
|
||||
Email.user.username=Email no es valido
|
||||
Email.user.email=Email no es valido
|
||||
|
|
|
@ -28,12 +28,9 @@
|
|||
class="org.baeldung.security.MySimpleUrlAuthenticationSuccessHandler" />
|
||||
<authentication-manager>
|
||||
<authentication-provider user-service-ref="userDetailsService">
|
||||
<!-- <password-encoder ref="passwordEncoder"/> -->
|
||||
|
||||
</authentication-provider>
|
||||
</authentication-manager>
|
||||
<beans:bean id="passwordEncoder"
|
||||
class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"
|
||||
autowire="constructor" />
|
||||
<beans:bean id="userDetailsService" class="org.baeldung.security.MyUserDetailsService"
|
||||
autowire="constructor" />
|
||||
</beans:beans>
|
|
@ -37,28 +37,28 @@
|
|||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Login</h1>
|
||||
<a href="?lang=en">English</a> |
|
||||
<a href="?lang=es_ES">Spanish</a>
|
||||
<h1><spring:message code="label.form.loginTitle"></spring:message></h1>
|
||||
<a href="?lang=en"><spring:message code="label.form.loginEnglish"></spring:message></a> |
|
||||
<a href="?lang=es_ES"><spring:message code="label.form.loginSpanish"></spring:message></a>
|
||||
<form name='f' action="j_spring_security_check" method='POST' onsubmit="return validate();">
|
||||
<table>
|
||||
<tr>
|
||||
<td>User:</td>
|
||||
<td><label><spring:message code="label.form.loginEmail"></spring:message></label></td>
|
||||
<td><input type='text' name='j_username' value=''></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Password:</td>
|
||||
<td><label><spring:message code="label.form.loginPass"></spring:message></label></td>
|
||||
<td><input type='password' name='j_password' /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input name="submit" type="submit" value="submit" /></td>
|
||||
<td><input name="submit" type="submit" value=<spring:message code="label.form.submit"></spring:message> /></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</form>
|
||||
<br> Current Locale : ${pageContext.response.locale}
|
||||
<br>
|
||||
<a href="<c:url value="/user/registration" />">Sign Up</a>
|
||||
<a href="<c:url value="/user/registration" />"><spring:message code="label.form.loginSignUp"></spring:message></a>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -9,43 +9,42 @@
|
|||
<head>
|
||||
<link href="<c:url value="/resources/bootstrap.css" />" rel="stylesheet">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Registration</title>
|
||||
<title><spring:message code="label.form.title"></spring:message></title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<H1>This is the registration page</H1>
|
||||
<form:form modelAttribute="user" method="POST" enctype="utf8" role="form">
|
||||
<H1><spring:message code="label.form.title"></spring:message></H1>
|
||||
<form:form modelAttribute="user" method="POST" enctype="utf8" >
|
||||
<br>
|
||||
<tr>
|
||||
<td><label>First Name:</label></td>
|
||||
<td><label><spring:message code="label.user.firstName"></spring:message></label></td>
|
||||
<td><form:input path="firstName" value="" /></td>
|
||||
<form:errors path="firstName" cssClass="alert alert-error" element="div" />
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label>Last Name:</label></td>
|
||||
<td><label><spring:message code="label.user.lastName"></spring:message></label></td>
|
||||
<td><form:input path="lastName" value="" /></td>
|
||||
<form:errors path="lastName" cssClass="alert alert-error" element="div" />
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label>Username (your e-mail address):</label></td>
|
||||
<td><form:input path="username" value="" /></td>
|
||||
<form:errors path="username" cssClass="alert alert-error" element="div" />
|
||||
<td><label><spring:message code="label.user.email"></spring:message></label></td>
|
||||
<td><form:input path="email" value="" /></td>
|
||||
<form:errors path="email" cssClass="alert alert-error" element="div" />
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label>Password:</label></td>
|
||||
<td><label><spring:message code="label.user.password"></spring:message></label></td>
|
||||
<td><form:input path="password" value="" type="password" /></td>
|
||||
<form:errors path="password" cssClass="alert alert-error" element="div" />
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label>Re-enter password:</label></td>
|
||||
<td><label><spring:message code="label.user.confirmPass"></spring:message></label></td>
|
||||
<td><form:input path="matchingPassword" value="" type="password"/></td>
|
||||
<form:errors cssClass="alert alert-error" element="div" />
|
||||
</tr>
|
||||
<input type="hidden" name="role" value="1" />
|
||||
<button type="submit">submit</button>
|
||||
<button type="submit"><spring:message code="label.form.submit"></spring:message></button>
|
||||
</form:form>
|
||||
<br>
|
||||
<a href="<c:url value="login.html" />">Back to Login</a>
|
||||
<a href="<c:url value="login.html" />"><spring:message code="label.form.loginLink"></spring:message></a>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -13,9 +13,9 @@
|
|||
<title>Registration Success</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>
|
||||
<div id="success">
|
||||
<spring:message code="message.regSucc"></spring:message>
|
||||
</h1>
|
||||
</div>
|
||||
<a href="<c:url value="login.html" />"><spring:message code="label.login"></spring:message></a>
|
||||
</body>
|
||||
|
||||
|
|
Loading…
Reference in New Issue