/*******************************************************************************
* Copyright (c) 2015 IBH SYSTEMS GmbH.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBH SYSTEMS GmbH - initial API and implementation
*******************************************************************************/
package org.eclipse.packagedrone.sec.web.ui;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import org.eclipse.packagedrone.repo.MetaKey;
import org.eclipse.packagedrone.repo.manage.core.CoreService;
import org.eclipse.packagedrone.sec.CreateUser;
import org.eclipse.packagedrone.sec.DatabaseUserInformation;
import org.eclipse.packagedrone.sec.web.captcha.CaptchaResult;
import org.eclipse.packagedrone.web.Controller;
import org.eclipse.packagedrone.web.ModelAndView;
import org.eclipse.packagedrone.web.RequestMapping;
import org.eclipse.packagedrone.web.RequestMethod;
import org.eclipse.packagedrone.web.ViewResolver;
import org.eclipse.packagedrone.web.common.CommonController;
import org.eclipse.packagedrone.web.controller.ControllerBinder;
import org.eclipse.packagedrone.web.controller.ControllerBinderParameter;
import org.eclipse.packagedrone.web.controller.binding.BindingResult;
import org.eclipse.packagedrone.web.controller.binding.RequestParameter;
import org.eclipse.packagedrone.web.controller.form.FormData;
@Controller
@ViewResolver ( "/WEB-INF/views/%s.jsp" )
@RequestMapping ( "/signup" )
public class SignupController extends AbstractUserCreationController
{
private CoreService coreService;
public void setCoreService ( final CoreService coreService )
{
this.coreService = coreService;
}
@RequestMapping ( method = RequestMethod.GET )
public ModelAndView signup ()
{
if ( !isSelfRegistrationAllowed () )
{
return new ModelAndView ( "signup/notAllowed" );
}
final ModelAndView model = new ModelAndView ( "signup/form" );
model.put ( "command", new CreateUser () );
return model;
}
private boolean isSelfRegistrationAllowed ()
{
return Boolean.parseBoolean ( this.coreService.getCoreProperty ( new MetaKey ( "core", "allow-self-registration" ) ) );
}
@RequestMapping ( method = RequestMethod.POST )
@ControllerBinder ( value = CaptchaBinder.class,
parameters = { @ControllerBinderParameter ( key = "name", value = "captcha" ) })
public ModelAndView signupPost ( @Valid @FormData ( "command" ) final CreateUser data, final BindingResult result, final HttpServletRequest request, final CaptchaResult captchaResult)
{
if ( !isSelfRegistrationAllowed () )
{
return new ModelAndView ( "signup/notAllowed" );
}
if ( result.hasErrors () )
{
final Map<String, Object> model = new HashMap<> ( 2 );
model.put ( "command", data );
model.put ( "duplicateEmail", result.hasMarker ( "duplicateEmail" ) );
return new ModelAndView ( "signup/form", model );
}
final DatabaseUserInformation newUser = this.storage.createUser ( data, false );
return new ModelAndView ( String.format ( "signup/success", newUser.getId () ) );
}
@RequestMapping ( value = "/verifyEmail", method = RequestMethod.GET )
public ModelAndView verify ( @RequestParameter ( "userId" ) final String userId, @RequestParameter ( "token" ) final String token)
{
final String error = this.storage.verifyEmail ( userId, token );
if ( error == null )
{
return new ModelAndView ( "signup/emailVerified" );
}
return new ModelAndView ( "signup/verificationFailed", "error", error );
}
@RequestMapping ( value = "/requestEmail", method = RequestMethod.GET )
public String requestEmail ()
{
return "signup/requestEmail";
}
@RequestMapping ( value = "/requestEmail", method = RequestMethod.POST )
public ModelAndView requestEmailPost ( @Valid @FormData ( "command" ) final RequestEmail data, final BindingResult result)
{
final Map<String, Object> model = new HashMap<> ();
if ( result.hasErrors () )
{
model.put ( "command", data );
return new ModelAndView ( "signup/requestEmail", model );
}
final String error = this.storage.reRequestEmail ( data.getEmail () );
if ( error != null )
{
model.put ( "error", error );
return new ModelAndView ( "signup/requestFailed", model );
}
return new ModelAndView ( "signup/emailRequested", model );
}
@RequestMapping ( value = "/reset", method = RequestMethod.GET )
public ModelAndView resetPassword ()
{
return new ModelAndView ( "signup/reset", "command", new RequestEmail () );
}
@RequestMapping ( value = "/reset", method = RequestMethod.POST )
public ModelAndView resetPasswordPost ( @Valid @FormData ( "command" ) final RequestEmail data, final BindingResult binding)
{
if ( binding.hasErrors () )
{
return new ModelAndView ( "signup/reset" );
}
final String error = this.storage.resetPassword ( data.getEmail () );
if ( error != null )
{
final Map<String, Object> model = new HashMap<> ();
model.put ( "error", error );
return new ModelAndView ( "signup/passwordResetResult", model );
}
return new ModelAndView ( "signup/passwordResetResult" );
}
@RequestMapping ( value = "/newPassword", method = RequestMethod.GET )
public ModelAndView newPassword ( @RequestParameter ( "email" ) final String email, @RequestParameter ( "token" ) final String token)
{
// TODO: check token first! Will be re-checked and enforced later, but gives better feedback
final NewPassword data = new NewPassword ();
data.setEmail ( email );
data.setToken ( token );
return new ModelAndView ( "signup/newPassword", "command", data );
}
@RequestMapping ( value = "/newPassword", method = RequestMethod.POST )
public ModelAndView newPasswordPost ( @Valid @FormData ( "command" ) final NewPassword data, final BindingResult binding)
{
if ( binding.hasErrors () )
{
return new ModelAndView ( "signup/newPassword" );
}
try
{
this.storage.changePassword ( data.getEmail (), data.getToken (), data.getPassword () );
}
catch ( final Exception e )
{
return CommonController.createError ( "Password change", "Failed to change password", e );
}
return new ModelAndView ( "signup/passwordChangeResult" );
}
}