Commit 195332f4 authored by Aleksandr Sharaban's avatar Aleksandr Sharaban Committed by Matija Obreza
Browse files

Feature #33886 - Add account login type,

Feature #33887 - Set password.
parent 77214e54
package org.genesys2.server.model.impl;
public enum LoginType {
PASSWORD("PASSWORD"),
GOOGLE("GOOGLE");
LoginType(String loginType) {
this.loginType = loginType;
}
private String loginType;
public String getLoginType() {
return loginType;
}
public void setLoginType(String loginType) {
this.loginType = loginType;
}
}
......@@ -81,6 +81,10 @@ public class User extends BusinessModel {
@Column(name = "name", nullable = false)
private String name;
@Enumerated(EnumType.STRING)
@Column(name = "loginType")
private LoginType loginType;
// validation
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@ElementCollection
......@@ -133,6 +137,14 @@ public class User extends BusinessModel {
this.name = name;
}
public LoginType getLoginType() {
return loginType;
}
public void setLoginType(LoginType loginType) {
this.loginType = loginType;
}
public Set<UserRole> getRoles() {
return roles;
}
......
......@@ -20,6 +20,7 @@ import java.util.List;
import org.genesys2.server.exception.UserException;
import org.genesys2.server.model.UserRole;
import org.genesys2.server.model.impl.LoginType;
import org.genesys2.server.model.impl.User;
import org.genesys2.server.model.wrapper.UserWrapper;
import org.genesys2.server.service.PasswordPolicy.PasswordPolicyException;
......@@ -35,7 +36,7 @@ public interface UserService {
@PreAuthorize("hasRole('ADMINISTRATOR')")
void addUser(User user) throws UserException, PasswordPolicyException;
User createAccount(String email, String initialPassword, String fullName) throws PasswordPolicyException;
User createAccount(String email, String initialPassword, String fullName, LoginType loginType) throws PasswordPolicyException;
@PreAuthorize("hasRole('ADMINISTRATOR') || hasPermission(#user, 'WRITE')")
void updateUser(User user) throws UserException;
......@@ -71,6 +72,8 @@ public interface UserService {
Page<User> listUsers(Pageable pageable);
boolean checkPasswordsMatch(String rawPassword, String encodedPassword);
void setAccountLock(String uuid, boolean locked);
void setAccountEnabled(String uuid, boolean enabled);
......
......@@ -34,6 +34,7 @@ import org.genesys2.server.exception.NoUserFoundException;
import org.genesys2.server.exception.NotUniqueUserException;
import org.genesys2.server.exception.UserException;
import org.genesys2.server.model.UserRole;
import org.genesys2.server.model.impl.LoginType;
import org.genesys2.server.model.impl.User;
import org.genesys2.server.model.wrapper.UserWrapper;
import org.genesys2.server.persistence.domain.UserPersistence;
......@@ -202,10 +203,11 @@ public class UserServiceImpl implements UserService {
@Override
@Transactional(readOnly = false)
public User createAccount(String email, String initialPassword, String fullName) throws PasswordPolicyException {
public User createAccount(String email, String initialPassword, String fullName, LoginType loginType) throws PasswordPolicyException {
final User user = new User();
user.setEmail(email);
user.setName(fullName);
user.setLoginType(loginType);
user.getRoles().add(UserRole.USER);
setPassword(user, initialPassword);
......@@ -223,7 +225,8 @@ public class UserServiceImpl implements UserService {
@Transactional(readOnly = false, rollbackFor = NotUniqueUserException.class)
public void addUser(User user) throws UserException, PasswordPolicyException {
try {
if (user.isSystemAccount()) {
if (user.isSystemAccount() || user.getPassword() == null
|| user.getLoginType() == LoginType.GOOGLE) {
user.setPassword("THIS-IS-NOT-A-PASSWORD");
} else {
setPassword(user, user.getPassword());
......@@ -323,12 +326,29 @@ public class UserServiceImpl implements UserService {
setAccountLockLocal(uuid, locked);
}
/**
* Checks if the passwords are equal.
*
* @param rawPassword password entered by user
* @param encodedPassword current encoded user's password
* @return true if passwords are equal
*/
@Override
public boolean checkPasswordsMatch(String rawPassword, String encodedPassword) {
return passwordEncoder.matches(rawPassword, encodedPassword);
}
/**
* Set the password hash on User
*
* @throws PasswordPolicyException when password is not matching policy
*/
private void setPassword(User user, String rawPassword) throws PasswordPolicyException {
if (user.getLoginType() == LoginType.GOOGLE) {
user.setPassword("THIS-IS-NOT-A-PASSWORD");
return;
}
passwordPolicy.assureGoodPassword(rawPassword);
// encrypt password
......
......@@ -22,7 +22,7 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.RandomStringUtils;
import org.genesys2.server.model.impl.LoginType;
import org.genesys2.server.model.impl.User;
import org.genesys2.server.service.PasswordPolicy.PasswordPolicyException;
import org.genesys2.server.service.UserService;
......@@ -81,8 +81,7 @@ public class GoogleSocialController extends BaseController {
final Person userInfo = google.plusOperations().getGoogleProfile();
if (!userService.exists(userInfo.getAccountEmail())) {
final String pwd = RandomStringUtils.randomAlphanumeric(20) + "!@#$%^&*()<>";
final User user = userService.createAccount(userInfo.getAccountEmail(), pwd, userInfo.getDisplayName());
final User user = userService.createAccount(userInfo.getAccountEmail(), null, userInfo.getDisplayName(), LoginType.GOOGLE);
userService.userEmailValidated(user.getUuid());
}
......
......@@ -22,6 +22,7 @@ import java.util.Locale;
import javax.servlet.http.HttpServletRequest;
import org.genesys2.server.model.UserRole;
import org.genesys2.server.model.impl.LoginType;
import org.genesys2.server.model.impl.User;
import org.genesys2.server.service.ContentService;
import org.genesys2.server.service.CropService;
......@@ -143,7 +144,7 @@ public class HtmlController extends BaseController {
try {
if (!bindingResult.hasErrors()) {
if (!userService.exists(user.getEmail())) {
final User newUser = userService.createAccount(user.getEmail(), user.getPassword(), user.getName());
final User newUser = userService.createAccount(user.getEmail(), user.getPassword(), user.getName(), LoginType.PASSWORD);
emailVerificationService.sendVerificationEmail(newUser);
......
......@@ -24,6 +24,7 @@ import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.genesys2.server.exception.NotUniqueUserException;
import org.genesys2.server.exception.UserException;
import org.genesys2.server.model.impl.LoginType;
import org.genesys2.server.model.impl.User;
import org.genesys2.server.service.ContentService;
import org.genesys2.server.service.EMailVerificationService;
......@@ -168,6 +169,12 @@ public class UserProfileController extends BaseController {
try {
final User user = userService.getUserByEmail(email);
if (user != null && user.getLoginType() == LoginType.GOOGLE) {
_logger.warn("Password for users with login type GOOGLE can't be reset!");
redirectAttributes.addFlashAttribute("error", "errors.reset-password.invalid-login-type");
return "redirect:/profile/forgot-password";
}
if (user != null) {
emailVerificationService.sendPasswordResetEmail(user);
}
......@@ -213,8 +220,10 @@ public class UserProfileController extends BaseController {
@RequestMapping(value = "/{uuid:.+}/update", method = { RequestMethod.POST })
@PreAuthorize("hasRole('ADMINISTRATOR') || principal.user.uuid == #uuid")
public String update(ModelMap model, @PathVariable("uuid") String uuid, @RequestParam("name") String name, @RequestParam("email") String email, @RequestParam("pwd1") String pwd1,
@RequestParam("pwd2") String pwd2, RedirectAttributes redirectAttributes) {
public String update(ModelMap model, @PathVariable("uuid") String uuid, @RequestParam("name") String name,
@RequestParam("email") String email, @RequestParam(value = "currentPwd", required = false) String currentPwd,
@RequestParam(value = "pwd1", required = false) String pwd1, @RequestParam(value = "pwd2", required = false) String pwd2,
RedirectAttributes redirectAttributes) {
final User user = userService.getUserByUuid(uuid);
if (user == null) {
throw new ResourceNotFoundException();
......@@ -230,7 +239,18 @@ public class UserProfileController extends BaseController {
return "redirect:/profile/" + user.getUuid() + "/edit";
}
if (StringUtils.isNotBlank(pwd1)) {
if (StringUtils.isNotBlank(pwd1) || StringUtils.isNotBlank(pwd2)) {
if (user.getLoginType() == LoginType.GOOGLE) {
redirectAttributes.addFlashAttribute("emailError", "Password for users with login type GOOGLE can't be set!");
return "redirect:/profile/" + user.getUuid() + "/edit";
}
if (StringUtils.isBlank(currentPwd) || !userService.checkPasswordsMatch(currentPwd, user.getPassword())) {
redirectAttributes.addFlashAttribute("emailError", "Current password is incorrect");
return "redirect:/profile/" + user.getUuid() + "/edit";
}
if (pwd1.equals(pwd2)) {
try {
_logger.info("Updating password for " + user);
......@@ -239,13 +259,16 @@ public class UserProfileController extends BaseController {
} catch (final UserException e) {
redirectAttributes.addFlashAttribute("emailError", e.getMessage());
_logger.error(e.getMessage(), e);
return "redirect:/profile/" + user.getUuid() + "/edit";
} catch (PasswordPolicyException e) {
redirectAttributes.addFlashAttribute("emailError", e.getMessage());
_logger.error(e.getMessage());
return "redirect:/profile/" + user.getUuid() + "/edit";
}
} else {
_logger.warn("Passwords didn't match for " + user);
redirectAttributes.addFlashAttribute("emailError", "Passwords didn't match for " + user);
return "redirect:/profile/" + user.getUuid() + "/edit";
}
}
......
......@@ -45,12 +45,14 @@ registration.invalid-credentials=Invalid credentials.
registration.user-exists=Username already taken.
registration.email=E-mail
registration.password=Password
registration.current-password=Current password
registration.confirm-password=Repeat password
registration.full-name=Your full name
registration.create-account=Create account
captcha.text=Captcha text
errors.badCaptcha=Captcha check failed.
errors.no-such-user=Genesys does not have a user account with provided email address.
errors.reset-password.invalid-login-type=Password for users with login type GOOGLE can't be reset!
id=ID
......@@ -130,6 +132,7 @@ user.account-status=Account Status
user.account-disabled=Account disabled
user.account-locked-until=Account locked until
user.roles=User roles
user.login-type=Login Type
userprofile.page.title=User profile
userprofile.page.intro=As a community, Genesys relies on its users to be successful. Whether you’re an individual researcher or represent a larger institution, you can update your profile here to show your interests and the data in your collection.
userprofile.update.title=Update your profile
......
......@@ -45,6 +45,7 @@ registration.invalid-credentials=Неверные данные для входа
registration.user-exists=Имя пользователя уже занято.
registration.email=Адрес электронной почты
registration.password=Пароль
registration.current-password=Текущий пароль
registration.confirm-password=Повторите пароль
registration.full-name=Ваше полное имя
registration.create-account=Создать учетную запись
......@@ -128,6 +129,7 @@ user.account-status=Статус учетной записи
user.account-disabled=Учетная запись заблокирована
user.account-locked-until=Учетная запись заблокирована до
user.roles=Роли пользователя
user.login-type=Тип входа
userprofile.page.title=Профиль пользователя
userprofile.page.intro=Успех сообщества Genesys зиждется на его пользователях. Все равно, представляете ли вы крупную организацию или являетесь самостоятельным исследователем — вы можете обновлять свой профиль так, чтобы он отражал ваши интересы и данные вашей коллекции.
userprofile.update.title=Обновить профиль
......
......@@ -26,19 +26,26 @@
</div>
</div>
<div class="form-group">
<label for="password" class="col-lg-2 control-label"><spring:message code="registration.password" /></label>
<div class="col-lg-3">
<input type="password" id="password" name="pwd1" class="span3 form-control" autocomplete="off" />
<c:if test="${user.loginType eq 'PASSWORD'}">
<div class="form-group">
<label for="currentPassword" class="col-lg-2 control-label"><spring:message code="registration.current-password" /></label>
<div class="col-lg-3">
<input type="password" id="currentPassword" name="currentPwd" class="span3 form-control" autocomplete="off" />
</div>
</div>
</div>
<div class="form-group">
<label for="confirm_password" class="col-lg-2 control-label"><spring:message code="registration.confirm-password" /></label>
<div class="col-lg-3">
<input type="password" id="confirm_password" name="pwd2" class="span3 required form-control" autocomplete="off" equalTo="#pwd1" />
<div class="form-group">
<label for="password" class="col-lg-2 control-label"><spring:message code="registration.password" /></label>
<div class="col-lg-3">
<input type="password" id="password" name="pwd1" class="span3 form-control" autocomplete="off" />
</div>
</div>
</div>
<div class="form-group">
<label for="confirm_password" class="col-lg-2 control-label"><spring:message code="registration.confirm-password" /></label>
<div class="col-lg-3">
<input type="password" id="confirm_password" name="pwd2" class="span3 required form-control" autocomplete="off" equalTo="#pwd1" />
</div>
</div>
</c:if>
<div class="form-group">
<div class="col-lg-offset-2 col-lg-10">
......
......@@ -30,19 +30,26 @@
</div>
</div>
<div class="form-group">
<label for="password" class="col-lg-2 control-label"><spring:message code="registration.password" /></label>
<div class="col-lg-3">
<input type="password" id="password" name="pwd1" class="span3 form-control" autocomplete="off" />
<c:if test="${user.loginType eq 'PASSWORD'}">
<div class="form-group">
<label for="currentPassword" class="col-lg-2 control-label"><spring:message code="registration.current-password" /></label>
<div class="col-lg-3">
<input type="password" id="currentPassword" name="currentPwd" class="span3 form-control" autocomplete="off" />
</div>
</div>
</div>
<div class="form-group">
<label for="confirm_password" class="col-lg-2 control-label"><spring:message code="registration.confirm-password" /></label>
<div class="col-lg-3">
<input type="password" id="confirm_password" name="pwd2" class="span3 required form-control" autocomplete="off" equalTo="#pwd1" />
<div class="form-group">
<label for="password" class="col-lg-2 control-label"><spring:message code="registration.password" /></label>
<div class="col-lg-3">
<input type="password" id="password" name="pwd1" class="span3 form-control" autocomplete="off" />
</div>
</div>
</div>
<div class="form-group">
<label for="confirm_password" class="col-lg-2 control-label"><spring:message code="registration.confirm-password" /></label>
<div class="col-lg-3">
<input type="password" id="confirm_password" name="pwd2" class="span3 required form-control" autocomplete="off" equalTo="#pwd1" />
</div>
</div>
</c:if>
<div class="form-group">
<div class="col-lg-offset-2 col-lg-10">
......
......@@ -36,6 +36,11 @@
</div>
</div>
<div class="form-group">
<label class="col-lg-2 control-label"><spring:message code="user.login-type" /></label>
<div class="col-lg-5"><c:out value="${user.loginType}" /></div>
</div>
<div class="form-group">
<label class="col-lg-2 control-label"><spring:message code="user.roles" /></label>
<div class="col-lg-10">
......
......@@ -18,6 +18,7 @@ package org.genesys2.tests.unit;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import java.util.ArrayList;
......@@ -27,6 +28,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.genesys2.server.exception.UserException;
import org.genesys2.server.model.UserRole;
import org.genesys2.server.model.impl.LoginType;
import org.genesys2.server.model.impl.User;
import org.genesys2.server.model.wrapper.UserWrapper;
import org.genesys2.server.security.AuthUserDetails;
......@@ -47,11 +49,13 @@ import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
// FIXME Transactional?
@Ignore
//@Ignore
public class UserServiceTest extends AbstractServicesTest {
private static final Log LOG = LogFactory.getLog(UserServiceTest.class);
private static final String SYSTEM_PASSWORD = "THIS-IS-NOT-A-PASSWORD";
private String email;
private String initialPassword;
......@@ -63,7 +67,7 @@ public class UserServiceTest extends AbstractServicesTest {
@Before
public void setUp() {
email = "test@example.com";
initialPassword = "Alexandr19011990";
initialPassword = "Alexandr19011990!";
fullName = "Alechandro";
user = new User();
......@@ -183,7 +187,7 @@ public class UserServiceTest extends AbstractServicesTest {
LOG.info("Start test-method createAccountTest");
User newUser = userService.createAccount(email, initialPassword, fullName);
User newUser = userService.createAccount(email, initialPassword, fullName, LoginType.PASSWORD);
assertNotNull("User is ull", newUser);
......@@ -276,7 +280,7 @@ public class UserServiceTest extends AbstractServicesTest {
User userFromDB = userService.getUserByEmail(email);
assertTrue(userService.getUserByEmail(email).getPassword().equals(initialPassword));
initialPassword = "This is new password";
initialPassword = "This is new password1!";
userService.updatePassword(userFromDB.getId(), initialPassword);
userFromDB = userService.getUserByEmail(email);
......@@ -553,4 +557,78 @@ public class UserServiceTest extends AbstractServicesTest {
}
LOG.info("Test autocompleteUserTest passed!");
}
@Test
public void createUserWithPasswordTypeTest() throws PasswordPolicyException {
LOG.info("Start test-method createUserWithPasswordTypeTest");
LoginType loginType = LoginType.PASSWORD;
User createdUser = userService.createAccount(email, initialPassword, fullName, loginType);
assertEquals(createdUser.getLoginType(), loginType);
LOG.info("Test createUserWithPasswordTypeTest passed!");
}
@Test
public void createUserWithGoogleTypeTest() throws PasswordPolicyException {
LOG.info("Start test-method createUserWithGoogleTypeTest");
LoginType loginType = LoginType.GOOGLE;
User createdUser = userService.createAccount(email, initialPassword, fullName, loginType);
assertEquals(createdUser.getLoginType(), loginType);
assertEquals("Password must be equal to 'THIS-IS-NOT-A-PASSWORD'", createdUser.getPassword(), SYSTEM_PASSWORD);
LOG.info("Test createUserWithGoogleTypeTest passed!");
}
@Test
public void changePasswordForUserWithPasswordTypeTest() throws PasswordPolicyException {
LOG.info("Start test-method changePasswordForUserWithPasswordTypeTest");
LoginType loginType = LoginType.PASSWORD;
User createdUser = userService.createAccount(email, initialPassword, fullName, loginType);
String newPassword = "New password1!";
try {
userService.updatePassword(createdUser.getId(), newPassword);
} catch (UserException e) {
fail(e.getMessage());
}
try {
createdUser = userService.getUserById(createdUser.getId());
} catch (UserException e) {
fail(e.getMessage());
}
assertEquals(createdUser.getPassword(), newPassword);
LOG.info("Test changePasswordForUserWithPasswordTypeTest passed!");
}
@Test
public void changePasswordForUserWithGoogleTypeTest() throws PasswordPolicyException {
LOG.info("Start test-method changePasswordForUserWithGoogleTypeTest");
LoginType loginType = LoginType.GOOGLE;
User createdUser = userService.createAccount(email, initialPassword, fullName, loginType);
String newPassword = "New password";
try {
userService.updatePassword(createdUser.getId(), newPassword);
} catch (UserException e) {
fail(e.getMessage());
}
try {
createdUser = userService.getUserById(createdUser.getId());
} catch (UserException e) {
fail(e.getMessage());
}
assertEquals(createdUser.getPassword(), SYSTEM_PASSWORD);
LOG.info("Test changePasswordForUserWithGoogleTypeTest passed!");
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment