001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (https://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: https://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: https://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 optional label of the client this session was created for. */ 067 private String m_clientLabel; 068 069 /** The maximum time, in seconds, this session info is allowed to be inactive. */ 070 private int m_maxInactiveInterval; 071 072 /** The fully qualified name of the organizational unit. */ 073 private String m_ouFqn; 074 075 /** The current project id of the user. */ 076 private CmsUUID m_projectId; 077 078 /** The id of the (http) session this session info belongs to. */ 079 private CmsUUID m_sessionId; 080 081 /** The current site of the user. */ 082 private String m_siteRoot; 083 084 /** The time this session info was created. */ 085 private long m_timeCreated; 086 087 /** The time this session info was last updated. */ 088 private long m_timeUpdated; 089 090 /** The time of the last user action. */ 091 private long m_timeLastAction; 092 093 /** The id of user to which this session info belongs. */ 094 private CmsUUID m_userId; 095 096 /** 097 * Creates a new CmsSessionInfo object.<p> 098 * 099 * @param context the user context to create this session info for 100 * @param sessionId OpenCms id of the (http) session this session info belongs to 101 * @param maxInactiveInterval the maximum time, in seconds, this session info is allowed to be inactive 102 */ 103 public CmsSessionInfo(CmsRequestContext context, CmsUUID sessionId, int maxInactiveInterval) { 104 105 m_timeCreated = System.currentTimeMillis(); 106 m_sessionId = sessionId; 107 m_maxInactiveInterval = maxInactiveInterval; 108 m_userId = context.getCurrentUser().getId(); 109 m_clientLabel = (String)context.getAttribute(CmsRequestContext.ATTRIBUTE_CLIENT_LABEL); 110 update(context); 111 } 112 113 /** 114 * Returns a string for given time.<p> 115 * 116 * @param time as timestamp 117 * @return string array containing string for hours, minutes, seconds 118 */ 119 public static String[] getHourMinuteSecondTimeString(long time) { 120 121 int hours = (int)time / (1000 * 60 * 60); 122 int min = (int)(time - (hours * 1000 * 60 * 60)) / (1000 * 60); 123 int sec = (int)(time - (hours * 1000 * 60 * 60) - (min * 1000 * 60)) / 1000; 124 125 return new String[] {getTwoDigitsString(hours), getTwoDigitsString(min), getTwoDigitsString(sec)}; 126 } 127 128 /** 129 * Formats an integer to a two chars string.<p> 130 * 131 * @param number to be formatted 132 * @return the string representation 133 */ 134 private static String getTwoDigitsString(int number) { 135 136 return number < 10 ? "0" + number : String.valueOf(number); 137 } 138 139 /** 140 * Allows sorting session info according to the user names.<p> 141 * 142 * @see java.lang.Comparable#compareTo(java.lang.Object) 143 */ 144 public int compareTo(CmsSessionInfo obj) { 145 146 if (obj == this) { 147 return 0; 148 } 149 return m_userId.compareTo(obj.getUserId()); 150 } 151 152 /** 153 * @see java.lang.Object#equals(java.lang.Object) 154 */ 155 @Override 156 public boolean equals(Object obj) { 157 158 if (obj == this) { 159 return true; 160 } 161 if (obj instanceof CmsSessionInfo) { 162 return m_userId.equals(((CmsSessionInfo)obj).getUserId()); 163 } 164 return false; 165 } 166 167 /** 168 * Gets the age of the session formattet as HOURS:MINUTES.<p> 169 * 170 * @return string representation of session age 171 */ 172 public String getAgeOfSession() { 173 174 String[] ret = getHourMinuteSecondTimeString(System.currentTimeMillis() - m_timeCreated); 175 return ret[0] + ":" + ret[1]; 176 177 } 178 179 /** 180 * Returns the broadcast queue of the user to which this session info belongs.<p> 181 * 182 * @return the broadcast queue of the user to which this session info belongs 183 */ 184 public Buffer getBroadcastQueue() { 185 186 if (m_broadcastQueue == null) { 187 m_broadcastQueue = BufferUtils.synchronizedBuffer(new UnboundedFifoBuffer(QUEUE_SIZE)); 188 } 189 return m_broadcastQueue; 190 } 191 192 /** 193 * Returns the optional label of the client this session was created for, taken once at session 194 * creation from the {@link CmsRequestContext#ATTRIBUTE_CLIENT_LABEL} context attribute.<p> 195 * 196 * @return the client label, or <code>null</code> for a session created without one 197 */ 198 public String getClientLabel() { 199 200 return m_clientLabel; 201 } 202 203 /** 204 * Returns the maximum time, in seconds, this session info is allowed to be inactive.<p> 205 * 206 * The inactive time is the time since the last call to the {@link #update(CmsRequestContext)} 207 * method. If the inactive time is greater then the maximum allowed time, this 208 * session info will be removed from the session manager.<p> 209 * 210 * @return the maximum time, in seconds, this session info is allowed to be inactive 211 * 212 * @see jakarta.servlet.http.HttpSession#getMaxInactiveInterval() 213 */ 214 public int getMaxInactiveInterval() { 215 216 return m_maxInactiveInterval; 217 } 218 219 /** 220 * Returns the fully qualified name of the organizational unit for this session.<p> 221 * 222 * @return the fully qualified name of the organizational unit for this session 223 */ 224 public String getOrganizationalUnitFqn() { 225 226 return m_ouFqn; 227 } 228 229 /** 230 * Returns the id of the project of the user.<p> 231 * 232 * @return the id of the project 233 */ 234 public CmsUUID getProject() { 235 236 return m_projectId; 237 } 238 239 /** 240 * Returns the id of the OpenCms (http) session this session info belongs to.<p> 241 * 242 * @return the id of the OpenCms (http) session this session info belongs to 243 * 244 * @see jakarta.servlet.http.HttpSession#getId() 245 */ 246 public CmsUUID getSessionId() { 247 248 return m_sessionId; 249 } 250 251 /** 252 * Returns the current site root of the user.<p> 253 * 254 * @return the current site root of the user 255 */ 256 public String getSiteRoot() { 257 258 return m_siteRoot; 259 } 260 261 /** 262 * Returns the time, in milliseconds, this session has been active, 263 * that is the time of the last update minus the creation time.<p> 264 * 265 * @return the time, in milliseconds, this session has been active 266 */ 267 public long getTimeActive() { 268 269 return m_timeUpdated - m_timeCreated; 270 } 271 272 /** 273 * Returns the time this session info was created.<p> 274 * 275 * @return the time this session info was created 276 */ 277 public long getTimeCreated() { 278 279 return m_timeCreated; 280 } 281 282 /** 283 * Returns the time of the last user action.<p> 284 * 285 * @return the list user action time 286 */ 287 public long getTimeLastAction() { 288 289 return m_timeLastAction; 290 } 291 292 /** 293 * Returns the time this session info was last updated.<p> 294 * 295 * @return the time this session info was last updated 296 */ 297 public long getTimeUpdated() { 298 299 return m_timeUpdated; 300 } 301 302 /** 303 * Returns the id of the user to which this session info belongs.<p> 304 * 305 * @return the id of the user to which this session info belongs 306 */ 307 public CmsUUID getUserId() { 308 309 return m_userId; 310 } 311 312 /** 313 * @see java.lang.Object#hashCode() 314 */ 315 @Override 316 public int hashCode() { 317 318 return m_userId.hashCode(); 319 } 320 321 /** 322 * Returns <code>true</code> if this session info has expired, that 323 * is it has not been updated in the time set by the maximum inactivity interval.<p> 324 * 325 * @return <code>true</code> if this session info has expired 326 */ 327 public boolean isExpired() { 328 329 return ((System.currentTimeMillis() - m_timeUpdated) / 1000) > m_maxInactiveInterval; 330 } 331 332 /** 333 * @see java.lang.Object#toString() 334 */ 335 @Override 336 public String toString() { 337 338 StringBuffer str = new StringBuffer(64); 339 str.append("["); 340 str.append("sessionId: ").append(m_sessionId).append(", "); 341 str.append("userId: ").append(m_userId).append(", "); 342 str.append("projectId: ").append(m_projectId).append(", "); 343 str.append("siteRoot: ").append(m_siteRoot).append(", "); 344 str.append("timeCreated: ").append(m_timeCreated).append(", "); 345 str.append("timeUpdated: ").append(m_timeUpdated).append(", "); 346 str.append("maxInactiveInterval: ").append(m_maxInactiveInterval); 347 str.append("ouFqn: ").append(m_ouFqn); 348 str.append("]"); 349 return str.toString(); 350 } 351 352 /** 353 * Sets the id of the current project of the user of this session info.<p> 354 * 355 * @param projectId the project id to set 356 */ 357 protected void setProject(CmsUUID projectId) { 358 359 m_projectId = projectId; 360 } 361 362 /** 363 * Updates the session info object with the information from 364 * the given request context.<p> 365 * 366 * @param context the request context to update the session with 367 */ 368 protected void update(CmsRequestContext context) { 369 370 update(context, false); 371 } 372 373 /** 374 * Updates the session info object with the information from 375 * the given request context.<p> 376 * 377 * @param context the request context to update the session with 378 * @param isHeartBeatRequest in case of heart beat requests 379 */ 380 protected void update(CmsRequestContext context, boolean isHeartBeatRequest) { 381 382 m_timeUpdated = System.currentTimeMillis(); 383 if (!isHeartBeatRequest) { 384 m_timeLastAction = m_timeUpdated; 385 } 386 m_siteRoot = context.getSiteRoot(); 387 setProject(context.getCurrentProject().getUuid()); 388 m_ouFqn = context.getOuFqn(); 389 } 390}