package org.molgenis.ui.admin.user;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.molgenis.auth.User;
import org.molgenis.data.i18n.LanguageService;
import org.molgenis.security.user.MolgenisUserException;
import org.molgenis.security.user.UserAccountService;
import org.molgenis.ui.MolgenisPluginController;
import org.molgenis.util.CountryCodes;
import org.molgenis.util.ErrorMessageResponse;
import org.molgenis.util.ErrorMessageResponse.ErrorMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.Collections;
import static java.util.Objects.requireNonNull;
import static org.molgenis.security.user.UserAccountService.MIN_PASSWORD_LENGTH;
import static org.molgenis.ui.admin.user.UserAccountController.URI;
@Controller
@RequestMapping(URI)
public class UserAccountController extends MolgenisPluginController
{
private static final Logger LOG = LoggerFactory.getLogger(UserAccountController.class);
public static final String ID = "useraccount";
public static final String URI = MolgenisPluginController.PLUGIN_URI_PREFIX + ID;
private final UserAccountService userAccountService;
private final LanguageService languageService;
@Autowired
public UserAccountController(UserAccountService userAccountService, LanguageService languageService)
{
super(URI);
this.userAccountService = requireNonNull(userAccountService);
this.languageService = requireNonNull(languageService);
}
@RequestMapping(method = RequestMethod.GET)
public String showAccount(Model model)
{
model.addAttribute("user", userAccountService.getCurrentUser());
model.addAttribute("countries", CountryCodes.get());
model.addAttribute("groups", Lists.newArrayList(userAccountService.getCurrentUserGroups()));
model.addAttribute("min_password_length", MIN_PASSWORD_LENGTH);
return "view-useraccount";
}
@RequestMapping(value = "/language/update", method = RequestMethod.POST)
@ResponseStatus(HttpStatus.OK)
public void updateUserLanguage(@RequestParam("languageCode") String languageCode)
{
try
{
if (!languageService.hasLanguageCode(languageCode))
{
throw new MolgenisUserException("Unknown language code '" + languageCode + "'");
}
User user = userAccountService.getCurrentUser();
user.setLanguageCode(languageCode);
userAccountService.updateCurrentUser(user);
}
catch (Exception e)
{
e.printStackTrace();
}
}
@RequestMapping(value = "/update", method = RequestMethod.POST, headers = "Content-Type=application/x-www-form-urlencoded")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void updateAccount(@Valid @NotNull AccountUpdateRequest updateRequest)
{
// validate new password
String newPassword = updateRequest.getNewpwd();
if (!StringUtils.isEmpty(newPassword))
{
String oldPassword = updateRequest.getOldpwd();
String newPasswordConfirm = updateRequest.getNewpwd2();
// validate password for current user
if (oldPassword == null || oldPassword.isEmpty())
{
throw new MolgenisUserException("Please enter old password to update your password.");
}
boolean valid = userAccountService.validateCurrentUserPassword(oldPassword);
if (!valid) throw new MolgenisUserException("The password you entered is incorrect.");
// validate new password against new password confirmation
if (!newPassword.equals(newPasswordConfirm))
{
throw new MolgenisUserException("'New password' does not match 'Repeat new password'.");
}
// TODO implement http://www.molgenis.org/ticket/2145
// TODO define minimum password length in one location (org.molgenis.security.account.RegisterRequest)
if (newPassword.length() < MIN_PASSWORD_LENGTH)
{
throw new MolgenisUserException("New password must consist of at least 6 characters.");
}
}
// update current user
User user = userAccountService.getCurrentUser();
if (StringUtils.isNotEmpty(newPassword)) user.setPassword(newPassword);
if (StringUtils.isNotEmpty(updateRequest.getPhone())) user.setPhone(updateRequest.getPhone());
if (StringUtils.isNotEmpty(updateRequest.getFax())) user.setFax(updateRequest.getFax());
if (StringUtils.isNotEmpty(updateRequest.getTollFreePhone()))
{
user.setTollFreePhone(updateRequest.getTollFreePhone());
}
if (StringUtils.isNotEmpty(updateRequest.getAddress())) user.setAddress(updateRequest.getAddress());
if (StringUtils.isNotEmpty(updateRequest.getTitle())) user.setTitle(updateRequest.getTitle());
if (StringUtils.isNotEmpty(updateRequest.getFirstname())) user.setFirstName(updateRequest.getFirstname());
if (StringUtils.isNotEmpty(updateRequest.getMiddleNames())) user.setMiddleNames(updateRequest.getMiddleNames());
if (StringUtils.isNotEmpty(updateRequest.getLastname())) user.setLastName(updateRequest.getLastname());
if (StringUtils.isNotEmpty(updateRequest.getInstitute())) user.setAffiliation(updateRequest.getInstitute());
if (StringUtils.isNotEmpty(updateRequest.getDepartment())) user.setDepartment(updateRequest.getDepartment());
if (StringUtils.isNotEmpty(updateRequest.getPosition())) user.setRole(updateRequest.getPosition());
if (StringUtils.isNotEmpty(updateRequest.getCity())) user.setCity(updateRequest.getCity());
if (StringUtils.isNotEmpty(updateRequest.getCountry()))
{
user.setCountry(CountryCodes.get(updateRequest.getCountry()));
}
userAccountService.updateCurrentUser(user);
}
@ExceptionHandler(MolgenisUserException.class)
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
@ResponseBody
private ErrorMessageResponse handleMolgenisUserException(MolgenisUserException e)
{
LOG.debug("", e);
return new ErrorMessageResponse(Collections.singletonList(new ErrorMessage(e.getMessage())));
}
@ExceptionHandler(RuntimeException.class)
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
private ErrorMessageResponse handleRuntimeException(RuntimeException e)
{
LOG.error("", e);
return new ErrorMessageResponse(Collections.singletonList(new ErrorMessage(e.getMessage())));
}
private static class AccountUpdateRequest
{
private String oldpwd;
private String newpwd;
private String newpwd2;
private String phone;
private String fax;
private String tollFreePhone;
private String address;
private String title;
private String firstname;
private String middleNames;
private String lastname;
private String institute;
private String department;
private String position;
private String city;
private String country;
public String getOldpwd()
{
return oldpwd;
}
@SuppressWarnings("unused")
public void setOldpwd(String oldpwd)
{
this.oldpwd = oldpwd;
}
public String getNewpwd()
{
return newpwd;
}
@SuppressWarnings("unused")
public void setNewpwd(String newpwd)
{
this.newpwd = newpwd;
}
public String getNewpwd2()
{
return newpwd2;
}
@SuppressWarnings("unused")
public void setNewpwd2(String newpwd2)
{
this.newpwd2 = newpwd2;
}
public String getPhone()
{
return phone;
}
@SuppressWarnings("unused")
public void setPhone(String phone)
{
this.phone = phone;
}
public String getFax()
{
return fax;
}
@SuppressWarnings("unused")
public void setFax(String fax)
{
this.fax = fax;
}
public String getTollFreePhone()
{
return tollFreePhone;
}
@SuppressWarnings("unused")
public void setTollFreePhone(String tollFreePhone)
{
this.tollFreePhone = tollFreePhone;
}
public String getAddress()
{
return address;
}
@SuppressWarnings("unused")
public void setAddress(String address)
{
this.address = address;
}
public String getTitle()
{
return title;
}
@SuppressWarnings("unused")
public void setTitle(String title)
{
this.title = title;
}
public String getFirstname()
{
return firstname;
}
@SuppressWarnings("unused")
public void setFirstname(String firstname)
{
this.firstname = firstname;
}
public String getMiddleNames()
{
return middleNames;
}
@SuppressWarnings("unused")
public void setMiddleNames(String middleNames)
{
this.middleNames = middleNames;
}
public String getLastname()
{
return lastname;
}
@SuppressWarnings("unused")
public void setLastname(String lastname)
{
this.lastname = lastname;
}
public String getInstitute()
{
return institute;
}
@SuppressWarnings("unused")
public void setInstitute(String institute)
{
this.institute = institute;
}
public String getDepartment()
{
return department;
}
@SuppressWarnings("unused")
public void setDepartment(String department)
{
this.department = department;
}
public String getPosition()
{
return position;
}
@SuppressWarnings("unused")
public void setPosition(String position)
{
this.position = position;
}
public String getCity()
{
return city;
}
@SuppressWarnings("unused")
public void setCity(String city)
{
this.city = city;
}
public String getCountry()
{
return country;
}
@SuppressWarnings("unused")
public void setCountry(String country)
{
this.country = country;
}
}
}