/*
Copyright 2009 Under Dusken
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package no.dusken.aranea.admin.control;
import no.dusken.aranea.admin.editor.GenericCollectionEditor;
import no.dusken.aranea.model.LoginDetails;
import no.dusken.aranea.model.Role;
import no.dusken.aranea.service.LoginDetailsService;
import no.dusken.aranea.service.RoleService;
import no.dusken.aranea.util.PasswordGenerator;
import no.dusken.common.control.MailController;
import no.dusken.common.model.Mail;
import no.dusken.common.util.MailSender;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.validation.BindException;
import org.springframework.validation.Errors;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.multipart.support.ByteArrayMultipartFileEditor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Marvin B. Lillehaug <lillehau@underdusken.no>
* Create and edit LoginDetails
*/
public class EditLoginDetailsController extends GenericEditController<LoginDetails> {
private MailSender mailSender;
private RoleService roleService;
private Logger log = LoggerFactory.getLogger(this.getClass());
private GenericCollectionEditor<Role, List> rolesEditor;
public EditLoginDetailsController() {
super(LoginDetails.class);
}
@Override
@SuppressWarnings("unchecked")
protected Object formBackingObject(HttpServletRequest request) {
LoginDetails loginDetails = (LoginDetails) super.formBackingObject(request);
//if this is a new object
if (loginDetails.getUsername() == null) {
//check if we are trying to create a new user with a specified username
String username = ServletRequestUtils.getStringParameter(request, "username", null);
if(username != null){
loginDetails.setUsername(username);
//check if we are giving a email too
String email = ServletRequestUtils.getStringParameter(request, "email", null);
if(email != null){
loginDetails.setEmail(email);
}
}
}
return loginDetails;
}
@Override
protected Map referenceData(HttpServletRequest request, Object object,
Errors errors) throws Exception {
//noinspection unchecked
Map<String, Object> map = super.referenceData(request, object, errors);
map.put("roles", roleService.getRoles());
return map;
}
@Override
protected ModelAndView onSubmit(HttpServletRequest request,
HttpServletResponse response, Object object,
BindException errors) throws Exception {
LoginDetails loginDetails = (LoginDetails) object;
LoginDetailsService loginDetailsService = (LoginDetailsService) genericService;
Map<String, Object> map = new HashMap<String,Object>();
//reset password?
if(request.getParameter("pwreset") != null){
log.info("Reseting password for user: {}", loginDetails.getUsername());
//reset password
String password = PasswordGenerator.generatePassword(10);
loginDetails.setPassword(password);
loginDetailsService.resetPassword(loginDetails);
//send mail to the user about pw reset
Mail mail = new Mail();
mail.setFromAddress("www@underdusken.no");
mail.setFromName("Aranea");
mail.setToAddress(loginDetails.getEmail());
mail.setSubject("Passordreset for aranea");
Map mailMap = new HashMap();
mailMap.put("user", loginDetails);
mailMap.put("password", password);
mailSender.sendEmail(mail, mailMap, "no/dusken/aranea/base/admin/mail/resetPassword.vm");
// redirect to the same form
response.sendRedirect(request.getRequestURL() + "?ID=" + loginDetails.getID());
return null;
}
LoginDetails old = null;
try {
old = (LoginDetails) loginDetailsService.loadUserByUsername(loginDetails.getUsername());
} catch (UsernameNotFoundException e) {// the user doesnt exist with loginDetails
if(loginDetails.getEmail() == null){//default
loginDetails.setEmail(loginDetails.getUsername() + "@underdusken.no");
}
loginDetails = createUser(loginDetails);
response.sendRedirect(request.getRequestURL() + "?ID=" + loginDetails.getID());
return null;
}
// If the user exists, it is trying to change password
String oldpw = loginDetails.getPassword(); //if the user has typed it, it is in cleartext
String pw1 = ServletRequestUtils.getStringParameter(request, "password1");
String pw2 = ServletRequestUtils.getStringParameter(request, "password2");
if(pw1 != null && pw2 != null && !pw1.equals(pw2)){
map.put("unequalpw", true);
}else{
changePassword(oldpw, pw1);
}
// redirect to the same form
response.sendRedirect(request.getRequestURL() + "?ID=" + loginDetails.getID());
return null;
}
protected void initBinder(HttpServletRequest request,
ServletRequestDataBinder binder) throws Exception {
super.initBinder(request, binder);
binder.registerCustomEditor(List.class, "roles", rolesEditor);
// to actually be able to convert Multipart instance to byte[]
// we have to register a custom editor
binder.registerCustomEditor(byte[].class, new ByteArrayMultipartFileEditor());
binder.setBindEmptyMultipartFiles(false);
}
@Required
@Autowired
public void setRoleService(RoleService roleService) {
this.roleService = roleService;
}
@Required
public void setRolesEditor(GenericCollectionEditor<Role, List> rolesEditor) {
this.rolesEditor = rolesEditor;
}
private LoginDetails createUser(LoginDetails user){
LoginDetailsService loginDetailsService = (LoginDetailsService) genericService;
String password = PasswordGenerator.generatePassword(10);
user.setPassword(password);
loginDetailsService.createLoginDetails(user);
Mail mail = new Mail();
mail.setFromAddress("www@underdusken.no");
mail.setFromName("Aranea");
mail.setToAddress(user.getEmail());
mail.setSubject("Login details for aranea");
Map mailMap = new HashMap();
mailMap.put("user", user);
mailMap.put("password", password);
mailSender.sendEmail(mail, mailMap, "no/dusken/aranea/base/admin/mail/newUser.vm");
return user;
}
/**
* Creates a LoginDetail and sends mail with a generated password.
* @param username - the wanted username
* @param email - a valid e-mail
* @param roles - the roles the user has
*/
public LoginDetails createUser(String username, String email, List<Role> roles){
LoginDetails user = new LoginDetails();
user.setUsername(username);
user.setEmail(email);
user.setRoles(roles);
//duplicate code
String password = PasswordGenerator.generatePassword(10);
user.setPassword(password);
LoginDetailsService loginDetailsService = (LoginDetailsService) genericService;
user = loginDetailsService.createLoginDetails(user);
Mail mail = new Mail();
mail.setFromAddress("www@underdusken.no");
mail.setFromName("Aranea");
mail.setToAddress(user.getEmail());
mail.setSubject("Login details for aranea");
Map mailMap = new HashMap();
mailMap.put("user", user);
mailMap.put("password", password);
mailSender.sendEmail(mail, mailMap, "no/dusken/aranea/base/admin/mail/newUser.vm");
return user;
}
private void changePassword(String oldPassword, String newPassword){
LoginDetailsService loginDetailsService = (LoginDetailsService) genericService;
loginDetailsService.changePassword(oldPassword, newPassword);
}
@Required
public void setMailSender(MailController mailSender) {
this.mailSender = mailSender;
}
}