Package org.apache.cocoon.auth.impl

Source Code of org.apache.cocoon.auth.impl.StandardApplicationManager

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.cocoon.auth.impl;

import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;

import org.apache.cocoon.auth.Application;
import org.apache.cocoon.auth.ApplicationManager;
import org.apache.cocoon.auth.ApplicationUtil;
import org.apache.cocoon.auth.SecurityHandler;
import org.apache.cocoon.auth.User;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.processing.ProcessInfoProvider;
import org.apache.cocoon.spring.configurator.WebAppContextUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;

/**
* This is the default implementation of the
* {@link org.apache.cocoon.auth.ApplicationManager}.
*
* This implementation is heavily tied to Spring. This has been done to make
* the configuration of the application manager easier.
*
* @version $Id: StandardApplicationManager.java 587757 2007-10-24 02:52:49Z vgritsenko $
*/
public class StandardApplicationManager
    implements ApplicationManager, BeanFactoryAware {

    /** The key used to store the login information in the session. */
    protected static final String LOGIN_INFO_KEY =
                     StandardApplicationManager.class.getName() + "/logininfo";

    /** The prefix used to store the application data object in the session. */
    protected static final String APPLICATION_KEY_PREFIX =
                     StandardApplicationManager.class.getName() + "/app:";

    /** The prefix used to register applications. */
    protected static final String APPLICATION_BEAN_NAME_PREFIX = Application.class.getName() + '/';

    /** The prefix used to register security handler. */
    protected static final String SECURITYHANDLER_BEAN_NAME_PREFIX = SecurityHandler.class.getName() + '/';

    /** By default we use the logger for this class. */
    private Log logger = LogFactory.getLog(getClass());

    /** The process info provider. */
    protected ProcessInfoProvider processInfoProvider;

    /** A map containing all applications. */
    protected Map applications = Collections.synchronizedMap(new HashMap());

    public Log getLogger() {
        return this.logger;
    }

    public void setLogger(Log l) {
        this.logger = l;
    }

    /**
     * @see org.springframework.beans.factory.BeanFactoryAware#setBeanFactory(org.springframework.beans.factory.BeanFactory)
     */
    public void setBeanFactory(BeanFactory factory) throws BeansException {
        this.processInfoProvider = (ProcessInfoProvider)factory.getBean(ProcessInfoProvider.ROLE);
        // put map with applications into servlet context
        final ServletContext servletContext = (ServletContext)factory.getBean(ServletContext.class.getName());
        servletContext.setAttribute(StandardApplicationManager.class.getName(), this.applications);
    }

    /**
     * Return the application with the name.
     */
    protected Application getApplication(final String appName) {
        final Application app = (Application) WebAppContextUtils.getCurrentWebApplicationContext().getBean(Application.class.getName() + '/' + appName);
        if ( !this.applications.containsKey(appName) ) {
            this.applications.put(appName, app);
        }
        return app;
    }

    protected String getKey(SecurityHandler handler) {
        return handler.getId();
    }

    /**
     * @see org.apache.cocoon.auth.ApplicationManager#isLoggedIn(String)
     */
    public boolean isLoggedIn(final String appName) {
        Object appData = null;
        final Map objectModel = this.processInfoProvider.getObjectModel();
        final Request req = ObjectModelHelper.getRequest(objectModel);
        final HttpSession session = req.getSession(false);
        if ( session != null ) {
            appData = session.getAttribute(APPLICATION_KEY_PREFIX + appName);

            // if the user is logged in, we set the current application, data and user
            if ( appData != null ) {
                try {
                    final Application application = this.getApplication(appName);
                    final User user = (User)session.getAttribute(USER + '-' + appName);
                    final Application oldApp = (Application)objectModel.get(ApplicationManager.APPLICATION);
                    objectModel.put(ApplicationManager.APPLICATION, application);
                    objectModel.put(ApplicationManager.APPLICATION_DATA, appData);
                    objectModel.put(ApplicationManager.USER, user);
                    // notify application
                    // The application is only notified once per request.
                    if ( oldApp == null || oldApp != application ) {
                        application.userIsAccessing(user);
                    }
                } catch (Exception ignore) {
                    throw new RuntimeException("Unable to get application '"
                                               + appName + "'", ignore);
                }
            }
        }

        return (appData != null);
    }

    /**
     * @see org.apache.cocoon.auth.ApplicationManager#login(String, java.util.Map)
     */
    public User login(final String appName, final Map loginContext) throws Exception {
        final Map objectModel = this.processInfoProvider.getObjectModel();
        final Application application = this.getApplication(appName);
        final String securityHandlerKey = this.getKey(application.getSecurityHandler());

        User user = null;

        // first check, if we are already logged in
        if ( this.isLoggedIn(appName) ) {
            user = ApplicationUtil.getUser(objectModel);
        } else {
            final Request req = ObjectModelHelper.getRequest(objectModel);
            HttpSession session = req.getSession(false);

            LoginInfo info = null;
            Map loginInfos = null;

            if ( session != null ) {
                // is the user already logged in on the security handler?
                loginInfos = (Map)session.getAttribute(LOGIN_INFO_KEY);
                if ( loginInfos != null && loginInfos.containsKey(securityHandlerKey)) {
                    info = (LoginInfo)loginInfos.get(securityHandlerKey);
                    user = info.user;
                }
            }
            if ( user == null ) {
                user = application.getSecurityHandler().login(loginContext);
                if ( user != null ) {
                    // create new login info
                    session = req.getSession();
                    loginInfos = (Map)session.getAttribute(LOGIN_INFO_KEY);
                    if ( loginInfos == null ) {
                        loginInfos = new HashMap();
                    }
                    info = new LoginInfo(user);
                    loginInfos.put(securityHandlerKey, info);
                }
            }

            // user can be null, if login failed
            if ( user != null ) {
                info.incUsageCounter(appName);
                session.setAttribute(LOGIN_INFO_KEY, loginInfos);

                // set the user in the session
                session.setAttribute(USER + '-' + appName, user);
                objectModel.put(ApplicationManager.USER, user);

                // set the application in the object model
                objectModel.put(ApplicationManager.APPLICATION, application);

                // set the application data in the session
                Object data = ObjectUtils.NULL;
                if ( application.getApplicationStore() != null ) {
                    data = application.getApplicationStore().loadApplicationData(user, application);
                }
                session.setAttribute(APPLICATION_KEY_PREFIX + appName, data);
                objectModel.put(ApplicationManager.APPLICATION_DATA, data);

                // notify the application about successful login
                application.userDidLogin(user, loginContext);

                // notify the application about accessing
                application.userIsAccessing(user);
            }
        }

        return user;
    }

    /**
     * @see org.apache.cocoon.auth.ApplicationManager#logout(String, java.util.Map)
     */
    public void logout(final String appName, final Map logoutContext) {
        final Map objectModel = this.processInfoProvider.getObjectModel();
        final Request req = ObjectModelHelper.getRequest(objectModel);
        final HttpSession session = req.getSession(false);
        if ( session != null ) {
            // remove application data from session
            session.removeAttribute(APPLICATION_KEY_PREFIX + appName);

            final Application application = this.getApplication(appName);
            final String securityHandlerKey = this.getKey(application.getSecurityHandler());

            // remove application from object model
            if ( application.equals( ApplicationUtil.getApplication(objectModel) ) ) {
                objectModel.remove(ApplicationManager.APPLICATION);
                objectModel.remove(ApplicationManager.APPLICATION_DATA);
                objectModel.remove(ApplicationManager.USER);
            }

            // remove user
            session.removeAttribute(USER + '-' + appName);

            // decrement logininfo counter
            final Map loginInfos = (Map)session.getAttribute(LOGIN_INFO_KEY);
            if ( loginInfos != null ) {
                final LoginInfo info = (LoginInfo)loginInfos.get(securityHandlerKey);
                if ( info != null ) {
                    // notify the application
                    application.userWillLogout(info.user, logoutContext);

                    info.decUsageCounter(appName);
                    if ( info.isUsed() ) {
                        session.setAttribute(LOGIN_INFO_KEY, loginInfos);
                    } else {
                        // logout from security handler
                        application.getSecurityHandler().logout(logoutContext, info.user);
                        // remove user info
                        loginInfos.remove(securityHandlerKey);
                        if ( loginInfos.size() > 0 ) {
                            session.setAttribute(LOGIN_INFO_KEY, loginInfos);
                        } else {
                            session.removeAttribute(LOGIN_INFO_KEY);
                            // the user has left all applications, test the mode:
                            String mode = null;
                            if ( logoutContext != null ) {
                                mode = (String)logoutContext.get(LOGOUT_CONTEXT_MODE_KEY);
                            }
                            if ( mode == null
                                 || mode.equals(LOGOUT_MODE_TERMINATE_SESSION_IF_UNUSED) ) {
                                session.invalidate();
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * Logs the user out of all applications.
     * This method has not been tested yet.
     * @param session The corresponding session
     */
    public static void logoutFromAllApplications(final HttpSession session) {
        final Map loginInfos = (Map)session.getAttribute(LOGIN_INFO_KEY);
        if ( loginInfos != null ) {
            final Map applications = (Map)session.getServletContext().getAttribute(StandardApplicationManager.class.getName());
            final Iterator i = loginInfos.values().iterator();
            while ( i.hasNext() ) {
                final LoginInfo info = (LoginInfo)i.next();
                if ( info.isUsed() ) {
                    final Iterator appIter = info.getApplications().iterator();
                    SecurityHandler handler = null;
                    while ( appIter.hasNext() ) {
                        final String appName = (String)appIter.next();
                        try {
                            final Application app = (Application)applications.get(appName);
                            app.userWillLogout(info.getUser(), Collections.EMPTY_MAP);
                            handler = app.getSecurityHandler();
                        } catch (Exception ignore) {
                            // we ignore this
                        }
                    }
                    if ( handler != null ) {
                        handler.logout(Collections.EMPTY_MAP, info.getUser());
                    }
                }
            }
        }
    }
}
TOP

Related Classes of org.apache.cocoon.auth.impl.StandardApplicationManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.