001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software GmbH & Co. KG, please see the
018 * company website: http://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: http://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.main;
029
030import org.opencms.file.CmsRequestContext;
031import org.opencms.util.CmsUUID;
032
033import java.io.Serializable;
034
035import org.apache.commons.collections.Buffer;
036import org.apache.commons.collections.BufferUtils;
037import org.apache.commons.collections.buffer.UnboundedFifoBuffer;
038
039/**
040 * Stores information about a user that has authenticated himself the OpenCms security system.<p>
041 *
042 * This object is used to provide information about all authenticated users in the system
043 * with the {@link org.opencms.main.CmsSessionManager}.<p>
044 *
045 * This object is available for all authenticated users after login.
046 * If a user has not logged in, he may have a session on the servlet engine,
047 * but he will have no session info object attached. For example the "Guest" user
048 * may have multiple sessions, but no session info is created for him.<p>
049 *
050 * @since 6.0.0
051 */
052public class CmsSessionInfo implements Comparable<CmsSessionInfo>, Serializable {
053
054    /** Name of the http session attribute the OpenCms session id is stored in. */
055    public static final String ATTRIBUTE_SESSION_ID = "__org.opencms.main.CmsSessionInfo#m_sessionId";
056
057    /** Maximum size of the broadcast queue for one user. */
058    public static final int QUEUE_SIZE = 10;
059
060    /** Serial version UID required for safe serialization. */
061    private static final long serialVersionUID = 927301527031117920L;
062
063    /** The broadcast queue buffer for the user of this session info. */
064    private transient Buffer m_broadcastQueue;
065
066    /** The maximum time, in seconds, this session info is allowed to be inactive. */
067    private int m_maxInactiveInterval;
068
069    /** The fully qualified name of the organizational unit. */
070    private String m_ouFqn;
071
072    /** The current project id of the user. */
073    private CmsUUID m_projectId;
074
075    /** The id of the (http) session this session info belongs to. */
076    private CmsUUID m_sessionId;
077
078    /** The current site of the user. */
079    private String m_siteRoot;
080
081    /** The time this session info was created. */
082    private long m_timeCreated;
083
084    /** The time this session info was last updated. */
085    private long m_timeUpdated;
086
087    /** The id of user to which this session info belongs. */
088    private CmsUUID m_userId;
089
090    /**
091     * Creates a new CmsSessionInfo object.<p>
092     *
093     * @param context the user context to create this session info for
094     * @param sessionId OpenCms id of the (http) session this session info belongs to
095     * @param maxInactiveInterval the maximum time, in seconds, this session info is allowed to be inactive
096     */
097    public CmsSessionInfo(CmsRequestContext context, CmsUUID sessionId, int maxInactiveInterval) {
098
099        m_timeCreated = System.currentTimeMillis();
100        m_sessionId = sessionId;
101        m_maxInactiveInterval = maxInactiveInterval;
102        m_userId = context.getCurrentUser().getId();
103        update(context);
104    }
105
106    /**
107     * Returns a string for given time.<p>
108     *
109     * @param time as timestamp
110     * @return string array containing string for hours, minutes, seconds
111     */
112    public static String[] getHourMinuteSecondTimeString(long time) {
113
114        int hours = (int)time / (1000 * 60 * 60);
115        int min = (int)(time - (hours * 1000 * 60 * 60)) / (1000 * 60);
116        int sec = (int)(time - (hours * 1000 * 60 * 60) - (min * 1000 * 60)) / 1000;
117
118        return new String[] {getTwoDigitsString(hours), getTwoDigitsString(min), getTwoDigitsString(sec)};
119    }
120
121    /**
122     * Formats an integer to a two chars string.<p>
123     *
124     * @param number to be formatted
125     * @return the string representation
126     */
127    private static String getTwoDigitsString(int number) {
128
129        return number < 10 ? "0" + number : String.valueOf(number);
130    }
131
132    /**
133     * Allows sorting session info according to the user names.<p>
134     *
135     * @see java.lang.Comparable#compareTo(java.lang.Object)
136     */
137    public int compareTo(CmsSessionInfo obj) {
138
139        if (obj == this) {
140            return 0;
141        }
142        return m_userId.compareTo(obj.getUserId());
143    }
144
145    /**
146     * @see java.lang.Object#equals(java.lang.Object)
147     */
148    @Override
149    public boolean equals(Object obj) {
150
151        if (obj == this) {
152            return true;
153        }
154        if (obj instanceof CmsSessionInfo) {
155            return m_userId.equals(((CmsSessionInfo)obj).getUserId());
156        }
157        return false;
158    }
159
160    /**
161     * Gets the age of the session formattet as HOURS:MINUTES.<p>
162     *
163     * @return string representation of session age
164     */
165    public String getAgeOfSession() {
166
167        String[] ret = getHourMinuteSecondTimeString(System.currentTimeMillis() - m_timeCreated);
168        return ret[0] + ":" + ret[1];
169
170    }
171
172    /**
173     * Returns the broadcast queue of the user to which this session info belongs.<p>
174     *
175     * @return the broadcast queue of the user to which this session info belongs
176     */
177    public Buffer getBroadcastQueue() {
178
179        if (m_broadcastQueue == null) {
180            m_broadcastQueue = BufferUtils.synchronizedBuffer(new UnboundedFifoBuffer(QUEUE_SIZE));
181        }
182        return m_broadcastQueue;
183    }
184
185    /**
186     * Returns the maximum time, in seconds, this session info is allowed to be inactive.<p>
187     *
188     * The inactive time is the time since the last call to the {@link #update(CmsRequestContext)}
189     * method. If the inactive time is greater then the maximum allowed time, this
190     * session info will be removed from the session manager.<p>
191     *
192     * @return the maximum time, in seconds, this session info is allowed to be inactive
193     *
194     * @see javax.servlet.http.HttpSession#getMaxInactiveInterval()
195     */
196    public int getMaxInactiveInterval() {
197
198        return m_maxInactiveInterval;
199    }
200
201    /**
202     * Returns the fully qualified name of the organizational unit for this session.<p>
203     *
204     * @return the fully qualified name of the organizational unit for this session
205     */
206    public String getOrganizationalUnitFqn() {
207
208        return m_ouFqn;
209    }
210
211    /**
212     * Returns the id of the project of the user.<p>
213     *
214     * @return the id of the project
215     */
216    public CmsUUID getProject() {
217
218        return m_projectId;
219    }
220
221    /**
222     * Returns the id of the OpenCms (http) session this session info belongs to.<p>
223     *
224     * @return the id of the OpenCms (http) session this session info belongs to
225     *
226     * @see javax.servlet.http.HttpSession#getId()
227     */
228    public CmsUUID getSessionId() {
229
230        return m_sessionId;
231    }
232
233    /**
234     * Returns the current site root of the user.<p>
235     *
236     * @return the current site root of the user
237     */
238    public String getSiteRoot() {
239
240        return m_siteRoot;
241    }
242
243    /**
244     * Returns the time, in milliseconds, this session has been active,
245     * that is the time of the last update minus the creation time.<p>
246     *
247     * @return the time, in milliseconds, this session has been active
248     */
249    public long getTimeActive() {
250
251        return m_timeUpdated - m_timeCreated;
252    }
253
254    /**
255     * Returns the time this session info was created.<p>
256     *
257     * @return the time this session info was created
258     */
259    public long getTimeCreated() {
260
261        return m_timeCreated;
262    }
263
264    /**
265     * Returns the time this session info was last updated.<p>
266     *
267     * @return the time this session info was last updated
268     */
269    public long getTimeUpdated() {
270
271        return m_timeUpdated;
272    }
273
274    /**
275     * Returns the id of the user to which this session info belongs.<p>
276     *
277     * @return the id of the user to which this session info belongs
278     */
279    public CmsUUID getUserId() {
280
281        return m_userId;
282    }
283
284    /**
285     * @see java.lang.Object#hashCode()
286     */
287    @Override
288    public int hashCode() {
289
290        return m_userId.hashCode();
291    }
292
293    /**
294     * Returns <code>true</code> if this session info has expired, that
295     * is it has not been updated in the time set by the maximum inactivity interval.<p>
296     *
297     * @return <code>true</code> if this session info has expired
298     */
299    public boolean isExpired() {
300
301        return ((System.currentTimeMillis() - m_timeUpdated) / 1000) > m_maxInactiveInterval;
302    }
303
304    /**
305     * @see java.lang.Object#toString()
306     */
307    @Override
308    public String toString() {
309
310        StringBuffer str = new StringBuffer(64);
311        str.append("[");
312        str.append("sessionId: ").append(m_sessionId).append(", ");
313        str.append("userId: ").append(m_userId).append(", ");
314        str.append("projectId: ").append(m_projectId).append(", ");
315        str.append("siteRoot: ").append(m_siteRoot).append(", ");
316        str.append("timeCreated: ").append(m_timeCreated).append(", ");
317        str.append("timeUpdated: ").append(m_timeUpdated).append(", ");
318        str.append("maxInactiveInterval: ").append(m_maxInactiveInterval);
319        str.append("ouFqn: ").append(m_ouFqn);
320        str.append("]");
321        return str.toString();
322    }
323
324    /**
325     * Sets the id of the current project of the user of this session info.<p>
326     *
327     * @param projectId the project id to set
328     */
329    protected void setProject(CmsUUID projectId) {
330
331        m_projectId = projectId;
332    }
333
334    /**
335     * Updates the session info object with the information from
336     * the given request context.<p>
337     *
338     * @param context the request context to update the session with
339     */
340    protected void update(CmsRequestContext context) {
341
342        m_timeUpdated = System.currentTimeMillis();
343        m_siteRoot = context.getSiteRoot();
344        setProject(context.getCurrentProject().getUuid());
345        m_ouFqn = context.getOuFqn();
346    }
347}