001/**
002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003 *
004 * Copyright (c) 2011-2016 ForgeRock AS. All Rights Reserved
005 *
006 * The contents of this file are subject to the terms
007 * of the Common Development and Distribution License
008 * (the License). You may not use this file except in
009 * compliance with the License.
010 *
011 * You can obtain a copy of the License at
012 * http://forgerock.org/license/CDDLv1.0.html
013 * See the License for the specific language governing
014 * permission and limitations under the License.
015 *
016 * When distributing Covered Code, include this CDDL
017 * Header Notice in each file and include the License file
018 * at http://forgerock.org/license/CDDLv1.0.html
019 * If applicable, add the following below the CDDL Header,
020 * with the fields enclosed by brackets [] replaced by
021 * your own identifying information:
022 * "Portions Copyrighted [year] [name of copyright owner]"
023 *
024 */
025package org.forgerock.openam.authentication.service;
026
027import com.iplanet.dpro.session.SessionException;
028import com.iplanet.dpro.session.service.InternalSession;
029import org.forgerock.openam.sso.providers.stateless.StatelessSession;
030
031import java.util.Enumeration;
032import java.util.Set;
033
034/**
035 * This class is used in case of session upgrade for copying session properties
036 * from the old session into the new one. Subclasses should implement
037 * {@link #shouldCopy(java.lang.String)} in order to control which properties
038 * are needed to copy into the new session.
039 * In case you want to modify the copyable session property you are encouraged
040 * to override {@link #updateProperty(com.iplanet.dpro.session.service.InternalSession,
041 * java.lang.String, java.lang.String)} method.
042 *
043 * @supported.all.api
044 */
045public abstract class SessionPropertyUpgrader {
046
047    /**
048     * Entry point for LoginState. This method is called during session upgrade
049     * in order to copy session attributes from one session to another.
050     *
051     * @param oldSession The previous session
052     * @param newSession The new session
053     * @param forceAuth Whether the authentication was forced
054     */
055    public final void populateProperties(InternalSession oldSession, InternalSession newSession, boolean forceAuth) {
056        Enumeration<String> allProperties = oldSession.getPropertyNames();
057        while (allProperties.hasMoreElements()) {
058            String key = allProperties.nextElement();
059            String value = (String) oldSession.getProperty(key);
060            if (shouldCopy(key)) {
061                if (!forceAuth) {
062                    updateProperty(newSession, key, value);
063                } else {
064                    updateProperty(oldSession, key, value);
065                }
066            }
067        }
068    }
069
070    /**
071     * Entry point for LoginState. This method is called during session upgrade
072     * in order to copy session attributes from one session to another.
073     *
074     * @param oldSession The previous (stateless) session
075     * @param newSession The new session
076     */
077    public final void populatePropertiesFromStateless(StatelessSession oldSession,
078                                                      InternalSession newSession) throws SessionException {
079        Set<String> allProperties = oldSession.getPropertyNames();
080        for (String key : allProperties) {
081            String value = oldSession.getProperty(key);
082            if (shouldCopy(key)) {
083                if (value != null) {
084                    newSession.putProperty(key, value);
085                }
086            }
087        }
088    }
089
090    /**
091     * This method updates a session property in the session with the given value.
092     * Override this method if you want to change some properties during the
093     * upgrade process.
094     *
095     * NOTE: If you override this, you SHOULD call super.updateProperty(..)
096     * at the end of your implementation with the updated values.
097     *
098     * @param session Session object where the property should be set
099     * @param property Name of the property to set
100     * @param value Value of the given session property
101     */
102    public void updateProperty(InternalSession session, String property, String value) {
103        if (value != null) {
104            session.putProperty(property, value);
105        }
106    }
107
108    /**
109     * This method decides whether a given session property should be copied to
110     * the new session.
111     * 
112     * @param key The name of the session property which we want to decide to copy
113     * @return <code>true</code> if the property with the given key should be
114     * copied into the new session
115     */
116    public abstract boolean shouldCopy(String key);
117}