com.hypersocket.auth.json.LogonController.java Source code

Java tutorial

Introduction

Here is the source code for com.hypersocket.auth.json.LogonController.java

Source

/*******************************************************************************
 * Copyright (c) 2013 Hypersocket Limited.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v3.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/gpl.html
 ******************************************************************************/
package com.hypersocket.auth.json;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import com.hypersocket.auth.AuthenticationServiceImpl;
import com.hypersocket.auth.AuthenticationState;
import com.hypersocket.json.AuthenticationRequiredResult;
import com.hypersocket.json.AuthenticationResult;
import com.hypersocket.permissions.AccessDeniedException;
import com.hypersocket.session.Session;
import com.hypersocket.session.json.SessionTimeoutException;
import com.hypersocket.session.json.SessionUtils;

@Controller
public class LogonController extends AuthenticatedController {

    @RequestMapping(value = "logon/reset", method = RequestMethod.GET, produces = "application/json")
    @ResponseBody
    @ResponseStatus(value = HttpStatus.OK)
    public AuthenticationResult resetLogon(HttpServletRequest request, HttpServletResponse response,
            @RequestParam(required = false) Boolean redirect)
            throws AccessDeniedException, UnauthorizedException, IOException, RedirectException {
        AuthenticationState state = (AuthenticationState) request.getSession()
                .getAttribute(AUTHENTICATION_STATE_KEY);
        return resetLogon(request, response,
                state == null ? AuthenticationServiceImpl.BROWSER_AUTHENTICATION_RESOURCE_KEY
                        : state.getScheme().getResourceKey(),
                redirect);
    }

    @RequestMapping(value = "logon/reset/{scheme}", method = RequestMethod.GET, produces = "application/json")
    @ResponseBody
    @ResponseStatus(value = HttpStatus.OK)
    public AuthenticationResult resetLogon(HttpServletRequest request, HttpServletResponse response,
            @PathVariable String scheme, @RequestParam(required = false) Boolean redirect)
            throws AccessDeniedException, UnauthorizedException, IOException, RedirectException {
        request.getSession().setAttribute(AUTHENTICATION_STATE_KEY, null);
        AuthenticationResult result = logon(request, response, scheme);
        if (Boolean.TRUE.equals(redirect)) {
            /**
             * This resets back to zero so the logon UI does not show
             * any error messages.
             */
            AuthenticationState state = (AuthenticationState) request.getSession()
                    .getAttribute(AUTHENTICATION_STATE_KEY);
            state.clean();
            throw new RedirectException(System.getProperty("hypersocket.uiPath", "/hypersocket/ui"));
        } else {
            return result;
        }

    }

    public AuthenticationState resetAuthenticationState(HttpServletRequest request, HttpServletResponse response,
            String scheme) throws AccessDeniedException, UnsupportedEncodingException {
        request.getSession().setAttribute(AUTHENTICATION_STATE_KEY, null);
        return createAuthenticationState(scheme, request, response);
    }

    @RequestMapping(value = "logon", method = { RequestMethod.GET, RequestMethod.POST }, produces = {
            "application/json" })
    @ResponseBody
    @ResponseStatus(value = HttpStatus.OK)
    public AuthenticationResult logon(HttpServletRequest request, HttpServletResponse response)
            throws AccessDeniedException, UnauthorizedException, UnsupportedEncodingException {
        return logon(request, response, null);
    }

    @RequestMapping(value = "logon/{scheme}", method = { RequestMethod.GET, RequestMethod.POST }, produces = {
            "application/json" })
    @ResponseBody
    @ResponseStatus(value = HttpStatus.OK)
    public AuthenticationResult logon(HttpServletRequest request, HttpServletResponse response,
            @PathVariable String scheme)
            throws AccessDeniedException, UnauthorizedException, UnsupportedEncodingException {

        setupSystemContext();

        try {
            Session session;

            String flash = (String) request.getSession().getAttribute("flash");
            request.getSession().removeAttribute("flash");

            try {
                session = sessionUtils.touchSession(request, response);

                if (session != null) {
                    return getSuccessfulResult(session, flash);
                }
            } catch (UnauthorizedException e) {
                // We are already in login so just continue
            } catch (SessionTimeoutException ex) {
                // Previous session has timed out
            }

            AuthenticationState state = (AuthenticationState) request.getSession()
                    .getAttribute(AUTHENTICATION_STATE_KEY);

            if (state == null
                    || (!StringUtils.isEmpty(scheme) && !state.getScheme().getResourceKey().equals(scheme))) {
                // We have not got login state so create
                state = createAuthenticationState(
                        scheme == null ? AuthenticationServiceImpl.BROWSER_AUTHENTICATION_RESOURCE_KEY : scheme,
                        request, response);
            }

            boolean success = authenticationService.logon(state, decodeParameters(request.getParameterMap()));

            if (state.isAuthenticationComplete() && !state.hasPostAuthenticationStep()) {

                // We have authenticated!
                request.getSession().removeAttribute(AUTHENTICATION_STATE_KEY);

                attachSession(state.getSession(), request, response);

                return getSuccessfulResult(state.getSession(), flash, state.getHomePage());
            } else {

                return new AuthenticationRequiredResult(
                        configurationService.getValue(state.getRealm(), "logon.banner"), state.getLastErrorMsg(),
                        state.getLastErrorIsResourceKey(),
                        !state.isAuthenticationComplete()
                                ? authenticationService.nextAuthenticationTemplate(state, request.getParameterMap())
                                : authenticationService.nextPostAuthenticationStep(state),
                        configurationService.hasUserLocales(), state.isNew(), !state.hasNextStep(),
                        success || state.isNew());
            }
        } finally {
            clearSystemContext();
        }
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    private Map decodeParameters(Map parameterMap) throws UnsupportedEncodingException {

        Map params = new HashMap();
        for (Object key : parameterMap.keySet()) {
            Object val = parameterMap.get(key);
            if (val instanceof String[]) {
                String[] arr = (String[]) val;
                if (arr.length == 1) {
                    params.put(key, arr[0]);
                } else {
                    for (int i = 0; i < arr.length; i++) {
                        arr[i] = arr[i];
                    }
                    params.put(key, arr);
                }
            } else if (val instanceof String) {
                params.put(key, (String) val);
            }
        }
        return params;
    }

    @RequestMapping(value = "logoff")
    @ResponseBody
    @ResponseStatus(value = HttpStatus.OK)
    public void logoff(HttpServletRequest request, HttpServletResponse response)
            throws UnauthorizedException, SessionTimeoutException {

        setupAuthenticatedContext(sessionUtils.getSession(request), sessionUtils.getLocale(request));

        try {
            Session session = sessionUtils.touchSession(request, response);
            if (session != null && sessionService.isLoggedOn(session, false)) {
                sessionService.closeSession(session);
                request.getSession().removeAttribute(SessionUtils.AUTHENTICATED_SESSION);
            }
        } finally {
            clearAuthenticatedContext();
        }
    }

    private void attachSession(Session session, HttpServletRequest request, HttpServletResponse response) {

        request.getSession().setAttribute(SessionUtils.AUTHENTICATED_SESSION, session);

        sessionUtils.addAPISession(request, response, session);
    }

    @RequestMapping(value = "attach/{authCode}/{sessionId}")
    @ResponseBody
    @ResponseStatus(value = HttpStatus.OK)
    public void attachSession(HttpServletRequest request, HttpServletResponse response,
            @PathVariable String authCode, @PathVariable String sessionId, @RequestParam String location)
            throws UnauthorizedException, SessionTimeoutException, RedirectException {

        Session session = sessionService.getSession(sessionId);
        Session authSession = sessionService.getSessionTokenResource(authCode, Session.class);

        if (!authSession.equals(session)) {
            throw new UnauthorizedException();
        }

        setupAuthenticatedContext(session, sessionUtils.getLocale(request));

        try {
            attachSession(authSession, request, response);

            if (StringUtils.isEmpty(location)) {
                throw new RedirectException(System.getProperty("hypersocket.uiPath", "/hypersocket/ui"));
            } else {
                throw new RedirectException(location);
            }
        } finally {
            clearAuthenticatedContext();
        }
    }

    @RequestMapping(value = "logoff/{id}")
    @ResponseBody
    @ResponseStatus(value = HttpStatus.OK)
    public void logoffSession(HttpServletRequest request, HttpServletResponse response, @PathVariable String id)
            throws UnauthorizedException, SessionTimeoutException {

        setupAuthenticatedContext(sessionUtils.getSession(request), sessionUtils.getLocale(request));

        try {
            Session session = sessionService.getSession(id);
            if (session != null && sessionService.isLoggedOn(session, false)) {
                sessionService.closeSession(session);
            }
        } finally {
            clearAuthenticatedContext();
        }
    }

    private AuthenticationResult getSuccessfulResult(Session session, String info, String homePage) {
        return new AuthenticationSuccessResult(info, configurationService.hasUserLocales(), session, homePage);
    }

    private AuthenticationResult getSuccessfulResult(Session session, String info) {
        return new AuthenticationSuccessResult(info, configurationService.hasUserLocales(), session, "");
    }

}