/*******************************************************************************
* 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.security.Principal;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.packagedrone.sec.DatabaseDetails;
import org.eclipse.packagedrone.sec.UserInformation;
import org.eclipse.packagedrone.sec.UserInformationPrincipal;
import org.eclipse.packagedrone.sec.service.LoginException;
import org.eclipse.packagedrone.sec.service.SecurityService;
import org.eclipse.packagedrone.sec.web.filter.SecurityFilter;
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.controller.form.FormData;
import org.eclipse.scada.utils.ExceptionHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Controller
@ViewResolver ( "/WEB-INF/views/%s.jsp" )
@RequestMapping ( "/login" )
public class LoginController
{
private final static Logger logger = LoggerFactory.getLogger ( LoginController.class );
private SecurityService service;
public void setService ( final SecurityService service )
{
this.service = service;
}
@RequestMapping ( method = RequestMethod.GET )
public ModelAndView login ( final HttpServletRequest request )
{
final Map<String, Object> model = new HashMap<> ();
final LoginData data = new LoginData ();
final Cookie[] cookies = request.getCookies ();
if ( cookies != null )
{
for ( final Cookie cookie : cookies )
{
if ( cookie.getName ().equals ( SecurityFilter.COOKIE_EMAIL ) )
{
data.setEmail ( cookie.getValue () );
}
}
}
model.put ( "command", data );
model.put ( "showAdminMode", needShowAdminMode () );
return new ModelAndView ( "login/form", model );
}
@RequestMapping ( method = RequestMethod.POST )
public ModelAndView loginPost ( @FormData ( "command" ) final LoginData data, final HttpServletRequest request, final HttpServletResponse response)
{
try
{
request.setAttribute ( SecurityFilter.ATTR_REMEMBER_ME, data.isRememberMeSafe () );
request.login ( data.getEmail (), data.getPassword () );
if ( data.isRememberMeSafe () )
{
final Principal p = request.getUserPrincipal ();
if ( p instanceof UserInformationPrincipal )
{
final UserInformationPrincipal uip = (UserInformationPrincipal)p;
final UserInformation ui = uip.getUserInformation ();
if ( ui != null )
{
final DatabaseDetails dd = ui.getDetails ( DatabaseDetails.class );
final String token = ui.getRememberMeToken ();
if ( token != null )
{
Cookie cookie = new Cookie ( SecurityFilter.COOKIE_REMEMBER_ME, token );
cookie.setMaxAge ( (int)TimeUnit.DAYS.toSeconds ( 90 ) );
response.addCookie ( cookie );
if ( dd != null && dd.getEmail () != null )
{
cookie = new Cookie ( SecurityFilter.COOKIE_EMAIL, dd.getEmail () );
cookie.setMaxAge ( (int)TimeUnit.DAYS.toSeconds ( 360 ) );
response.addCookie ( cookie );
}
}
}
}
}
}
catch ( final ServletException e )
{
final Map<String, Object> model = new HashMap<> ();
final Throwable root = ExceptionHelper.getRootCause ( e );
if ( root instanceof LoginException )
{
model.put ( "errorTitle", root.getMessage () );
model.put ( "details", ( (LoginException)root ).getDetails () );
final long failures = Sessions.incrementLoginFailCounter ( request.getSession () );
model.put ( "failureCount", failures );
}
else
{
logger.warn ( "Login error", e );
model.put ( "errorTitle", "Internal error!" );
model.put ( "details", String.format ( "Failed to log in: %s", root.getClass ().getSimpleName () ) );
}
model.put ( "showAdminMode", needShowAdminMode () );
return new ModelAndView ( "login/form", model );
}
Sessions.resetLoginFailCounter ( request.getSession () );
return new ModelAndView ( "redirect:/" );
}
private boolean needShowAdminMode ()
{
return !this.service.hasUserBase ();
}
}