/* This file is part of Cyclos (www.cyclos.org). A project of the Social Trade Organisation (www.socialtrade.org). Cyclos is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Cyclos is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Cyclos; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package nl.strohalm.cyclos.controls.access; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.HashMap; import java.util.Map; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import nl.strohalm.cyclos.annotations.Inject; import nl.strohalm.cyclos.controls.BasePublicFormAction; import nl.strohalm.cyclos.entities.access.Channel; import nl.strohalm.cyclos.entities.access.MemberUser; import nl.strohalm.cyclos.entities.access.User; import nl.strohalm.cyclos.entities.settings.LocalSettings; import nl.strohalm.cyclos.exceptions.PermissionDeniedException; import nl.strohalm.cyclos.services.access.exceptions.AlreadyConnectedException; import nl.strohalm.cyclos.services.access.exceptions.BlockedCredentialsException; import nl.strohalm.cyclos.services.access.exceptions.InactiveMemberException; import nl.strohalm.cyclos.services.access.exceptions.LoginException; import nl.strohalm.cyclos.utils.LoginHelper; import org.apache.commons.lang.StringUtils; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; /** * Action used to login the user from within external sites * @author luis */ public class ExternalLoginAction extends BasePublicFormAction { /** * The possible statuses * @author luis */ public static enum Status { SUCCESS(null), MISSING_USERNAME("errors.required", "login.username"), ALREADY_CONNECTED("login.error.alreadyConnected"), MISSING_PASSWORD("errors.required", "login.password"), INVALID("login.error"), BLOCKED("login.error.blocked"), INACTIVE("login.error.inactive"), PERMISSION_DENIED("error.accessDenied"), UNKNOWN_ERROR("error.general"); private final String key; private final String argument; private Status(final String key) { this(key, null); } private Status(final String key, final String argument) { this.key = key; this.argument = argument; } public String getArgument() { return argument; } public String getKey() { return key; } } private LoginHelper loginHelper; @Override public void prepareForm(final ActionMapping mapping, final ActionForm actionForm, final HttpServletRequest request, final HttpServletResponse response) { // Resolve the translation messages for each status final Map<String, String> statusMessages = new HashMap<String, String>(); for (final Status status : Status.values()) { final String key = status.getKey(); if (key != null) { String argument = status.getArgument(); if (argument != null) { // The argument is actually a key to another message argument = messageHelper.message(argument); } statusMessages.put(status.name(), messageHelper.message(key, argument)); } } request.setAttribute("statusMessages", statusMessages); // Store a cookie in order to know where to go after logout String afterLogout = request.getParameter("afterLogout"); afterLogout = StringUtils.trimToEmpty(afterLogout); try { final LocalSettings settings = settingsService.getLocalSettings(); afterLogout = URLEncoder.encode(StringUtils.trimToEmpty(afterLogout), settings.getCharset()); } catch (final UnsupportedEncodingException e) { } final Cookie cookie = new Cookie("afterLogout", afterLogout); cookie.setPath(request.getContextPath()); response.addCookie(cookie); } @Inject public final void setLoginHelper(final LoginHelper loginHelper) { this.loginHelper = loginHelper; } @Override protected ActionForward handleDisplay(final ActionMapping mapping, final ActionForm actionForm, final HttpServletRequest request, final HttpServletResponse response) throws Exception { final User loggedUser = LoginHelper.getLoggedUser(request); if (loggedUser != null) { final HttpSession session = request.getSession(); return new ActionForward(session.getAttribute("pathPrefix") + "/home", true); } return super.handleDisplay(mapping, actionForm, request, response); } @Override protected ActionForward handleSubmit(final ActionMapping mapping, final ActionForm actionForm, final HttpServletRequest request, final HttpServletResponse response) throws Exception { final Status status = doLogin(actionForm, request, response); if (status == Status.SUCCESS) { final User user = LoginHelper.getLoggedUser(request); if (user instanceof MemberUser && elementService.shallAcceptAgreement(((MemberUser) user).getMember())) { // Should accept a registration agreement first request.getSession().setAttribute("shallAcceptRegistrationAgreement", true); } } responseHelper.setTextNoCache(response); response.getWriter().print(status.name()); return null; } private Status doLogin(final ActionForm actionForm, final HttpServletRequest request, final HttpServletResponse response) { final LoginForm form = (LoginForm) actionForm; final HttpSession session = request.getSession(); // Get the parameters final String member = StringUtils.trimToNull(form.getMember()); final String principal = StringUtils.trimToNull(form.getPrincipal()); final String password = StringUtils.trimToNull(form.getPassword()); // Check for missing parameters if (principal == null) { return Status.MISSING_USERNAME; } else if (password == null) { return Status.MISSING_PASSWORD; } // Perform the login try { loginHelper.login(User.class, form.getPrincipalType(), member, principal, password, Channel.WEB, request, response); return Status.SUCCESS; } catch (final BlockedCredentialsException e) { return Status.BLOCKED; } catch (final InactiveMemberException e) { return Status.INACTIVE; } catch (final AlreadyConnectedException e) { return Status.ALREADY_CONNECTED; } catch (final PermissionDeniedException e) { session.invalidate(); return Status.PERMISSION_DENIED; } catch (final LoginException e) { return Status.INVALID; } catch (final Exception e) { actionHelper.generateLog(request, getServlet().getServletContext(), e); return Status.UNKNOWN_ERROR; } } }