/* * The contents of this file are subject to the terms of the Common Development and * Distribution License (the License). You may not use this file except in compliance with the * License. * * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the * specific language governing permission and limitations under the License. * * When distributing Covered Software, include this CDDL Header Notice in each file and include * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL * Header, with the fields enclosed by brackets [] replaced by your own identifying * information: "Portions copyright [year] [name of copyright owner]". * * Copyright 2014-2016 ForgeRock AS. */ package com.iplanet.dpro.session.utils; import static org.forgerock.openam.session.SessionConstants.TOKEN_RESTRICTION_PROP; import java.text.MessageFormat; import com.iplanet.dpro.session.SessionException; import com.iplanet.dpro.session.SessionID; import com.iplanet.dpro.session.SessionTimedOutException; import com.iplanet.dpro.session.TokenRestriction; import com.iplanet.dpro.session.TokenRestrictionFactory; import com.iplanet.dpro.session.service.InternalSession; import com.iplanet.dpro.session.service.SessionState; import com.iplanet.dpro.session.share.SessionBundle; import com.iplanet.dpro.session.share.SessionInfo; /** * Responsible for providing a collection of utility functions for * manipulating InternalSessions. */ public class SessionInfoFactory { public static final String INVALID_SESSION_STATE = "invalidSessionState"; public static final String SESSION_TIMED_OUT = "sessionTimedOut"; private static final String ERROR_FORMAT = "{0} {1}"; /** * Generates a SessionInfo which is a summary state of the Session used to * refresh remote instances of a Session. * * @param internalSession Non null InternalSession to summarise. * @param sessionID SessionID of the caller making the request. * @return Non null SessionInfo. * * @throws SessionException If there was a problem accessing the underlying Session. */ public SessionInfo getSessionInfo(InternalSession internalSession, SessionID sessionID) throws SessionException { validateSession(internalSession, sessionID); return makeSessionInfo(internalSession, sessionID); } /** * Validates the state of an Internal Session against a Session ID. * * Performs two checks, firstly that the Session matches the SessionID * and secondly that the InternalSession is not timed out. * * @param internalSession InternalSession to check. * @param sid SessionID to check with the InternalSession. * * @throws SessionException If the InternalSession has timed out. * * @throws IllegalArgumentException If the SessionID of the InternalSession * and provided SessionID do not match. */ public void validateSession(InternalSession internalSession, SessionID sid) throws SessionException { if (!sid.equals(internalSession.getID()) && internalSession.getRestrictionForToken(sid) == null) { throw new IllegalArgumentException("Session id mismatch"); } if (internalSession.getState() != SessionState.VALID) { if (internalSession.isTimedOut()) { throw new SessionTimedOutException(MessageFormat.format(ERROR_FORMAT, SessionBundle.getString(SESSION_TIMED_OUT), sid)); } else { throw new SessionException(MessageFormat.format(ERROR_FORMAT, SessionBundle.getString(INVALID_SESSION_STATE), sid)); } } } /** * Generates a SessionInfo object from the given InternalSession. * * @param internalSession Non null InternalSession to use. * @param sid Session ID for the user performing the action. * @return A non null SessionInfo instance if valid. * * @throws SessionException If there was an error storing the TokenRestriction on the SessionInfo. * * @throws IllegalAccessException If this method has not been called in-conjunction with * SessionInfoFactory#validateSession */ public SessionInfo makeSessionInfo(InternalSession internalSession, SessionID sid) throws SessionException { SessionInfo info = internalSession.toSessionInfo(); TokenRestriction restriction = internalSession.getRestrictionForToken(sid); if (restriction != null) { try { info.getProperties().put(TOKEN_RESTRICTION_PROP, TokenRestrictionFactory.marshal(restriction)); } catch (Exception e) { throw new SessionException(e); } } else if (!sid.equals(internalSession.getID())) { throw new IllegalArgumentException("Session id mismatch"); } // replace master sid with the sid from the request (either master or // restricted) in order not to leak the master sid info.setSessionID(sid.toString()); return info; } }