Package com.oorian

Class OorianSession

java.lang.Object
com.oorian.OorianSession
All Implemented Interfaces:
OorianThreadListener

public final class OorianSession extends Object implements OorianThreadListener
Central session management class for the Oorian framework.

OorianSession wraps a OorianHttpSession and provides Oorian-specific session behavior, including page caching, client profile management, and worker thread coordination. It serves as the primary mechanism for accessing session data throughout an Oorian application.

Key Features:

  • Thread-local storage for accessing the current session from anywhere in the application
  • Page caching for maintaining page state across AJAX requests
  • Client profile management for device and browser information
  • Worker thread coordination for background processing
  • Typed attribute accessors for convenient session data retrieval

Usage:


 // Get the current session from anywhere in the application
 OorianSession session = OorianSession.get();

 // Store and retrieve typed attributes
 session.setAttribute("userId", 12345);
 Integer userId = session.getAttributeAsInt("userId");

 // Access client profile information
 ClientProfile profile = session.getClientProfile();
 
Since:
2021
Version:
1.0
Author:
Marvin P. Warble Jr.
See Also:
  • Method Details

    • setAppContext

      public static void setAppContext(AppContext context)
      Sets the application context for resource access.

      Called once during application initialization by the thin library.

      Parameters:
      context - the application context
    • getAppContext

      public static AppContext getAppContext()
      Returns the application context.
      Returns:
      the application context
    • register

      public static void register(OorianHttpRequest request)
      Registers the OorianSession for a web request to the current thread.

      This method creates or retrieves the OorianSession for the request's session and registers it to the current thread for later retrieval via get(). It also updates the client profile with information from the request.

      Parameters:
      request - the web request
    • register

      public static OorianSession register(OorianHttpSession webSession)
      Registers the OorianSession for a session to the current thread.

      If an OorianSession doesn't exist for this session, a new one is created and stored as a session attribute. The session is then registered to the current thread for later retrieval.

      Parameters:
      webSession - the web session
      Returns:
      the OorianSession for this session
    • isValid

      public static boolean isValid()
      Checks if a valid OorianSession is registered to the current thread.
      Returns:
      true if a session is available, false otherwise
    • get

      public static OorianSession get()
      Returns the OorianSession registered to the current thread.

      This method provides thread-safe access to the session for the current request. It should be called after register(HttpServletRequest) has been invoked for the current thread.

      Returns:
      the current OorianSession, or null if none is registered
    • getSessions

      public static Collection<OorianSession> getSessions()
      Returns all active OorianSessions.

      The returned collection is a live view backed by a ConcurrentHashMap, so it is safe to iterate while sessions are being added or removed concurrently.

      Returns:
      a collection of all active sessions
    • removeSession

      public static void removeSession(String sessionId)
      Removes a session from the active sessions map.

      Called by the session monitor when a session is destroyed (timeout or invalidation) to ensure the session is cleaned up from the active sessions map.

      Parameters:
      sessionId - the ID of the session to remove
    • setCurrentPage

      public HtmlPage setCurrentPage(String pageId)
      Sets the current page by its unique identifier and returns it.
      Parameters:
      pageId - the unique identifier of the page
      Returns:
      the HtmlPage instance, or null if not found
    • setCurrentPage

      public void setCurrentPage(HtmlPage page)
      Sets the specified page as the current page.
      Parameters:
      page - the page to set as current
    • getClientProfile

      public ClientProfile getClientProfile()
      Returns the client profile for this session.

      The client profile contains information about the user's device, browser, screen dimensions, and other client-side details.

      Returns:
      the client profile
    • getCreationTime

      public long getCreationTime()
      Returns the time the session was created.
      Returns:
      the creation time in milliseconds since epoch
    • getId

      public String getId()
      Returns the unique session identifier.
      Returns:
      the session ID string
    • getLastAccessedTime

      public long getLastAccessedTime()
      Returns the time of last client access.
      Returns:
      the last access time in milliseconds since epoch
    • getContextPath

      public String getContextPath()
      Returns the context path of the web application.
      Returns:
      the context path
    • getResourceAsStream

      public InputStream getResourceAsStream(String path)
      Returns an input stream for reading the specified application resource.
      Parameters:
      path - the resource path (e.g., "/WEB-INF/config.xml")
      Returns:
      an input stream for the resource, or null if not found
    • getRealPath

      public String getRealPath(String path)
      Returns the real filesystem path for the specified virtual path.
      Parameters:
      path - the virtual path (e.g., "/WEB-INF/config.xml")
      Returns:
      the real path, or null if the translation cannot be performed
    • setMaxInactiveInterval

      public void setMaxInactiveInterval(int interval)
      Sets the maximum time interval between requests before the session expires.
      Parameters:
      interval - the interval in seconds
    • getMaxInactiveInterval

      public int getMaxInactiveInterval()
      Returns the maximum inactive interval for this session.
      Returns:
      the interval in seconds
    • getAttribute

      public Object getAttribute(String name)
      Returns the session attribute with the specified name.
      Parameters:
      name - the attribute name
      Returns:
      the attribute value, or null if not found
    • getAttributeAsString

      public String getAttributeAsString(String name)
      Returns an attribute as a String.
      Parameters:
      name - the attribute name
      Returns:
      the String value, or null if not found
    • getAttributeAsString

      public String getAttributeAsString(String name, String defValue)
      Returns an attribute as a String with a default value.
      Parameters:
      name - the attribute name
      defValue - the default value if attribute is not found
      Returns:
      the String value, or defValue if not found
    • getAttributeAsInt

      public Integer getAttributeAsInt(String name)
      Returns an attribute as an Integer.
      Parameters:
      name - the attribute name
      Returns:
      the Integer value, or null if not found
    • getAttributeAsInt

      public Integer getAttributeAsInt(String name, Integer defValue)
      Returns an attribute as an Integer with a default value.
      Parameters:
      name - the attribute name
      defValue - the default value if attribute is not found
      Returns:
      the Integer value, or defValue if not found
    • getAttributeAsLong

      public Long getAttributeAsLong(String name)
      Returns an attribute as a Long.
      Parameters:
      name - the attribute name
      Returns:
      the Long value, or null if not found
    • getAttributeAsLong

      public Long getAttributeAsLong(String name, Long defValue)
      Returns an attribute as a Long with a default value.
      Parameters:
      name - the attribute name
      defValue - the default value if attribute is not found
      Returns:
      the Long value, or defValue if not found
    • getAttributeAsShort

      public Short getAttributeAsShort(String name)
      Returns an attribute as a Short.
      Parameters:
      name - the attribute name
      Returns:
      the Short value, or null if not found
    • getAttributeAsShort

      public Short getAttributeAsShort(String name, Short defValue)
      Returns an attribute as a Short with a default value.
      Parameters:
      name - the attribute name
      defValue - the default value if attribute is not found
      Returns:
      the Short value, or defValue if not found
    • getAttributeAsFloat

      public Float getAttributeAsFloat(String name)
      Returns an attribute as a Float.
      Parameters:
      name - the attribute name
      Returns:
      the Float value, or null if not found
    • getAttributeAsFloat

      public Float getAttributeAsFloat(String name, Float defValue)
      Returns an attribute as a Float with a default value.
      Parameters:
      name - the attribute name
      defValue - the default value if attribute is not found
      Returns:
      the Float value, or defValue if not found
    • getAttributeAsDouble

      public Double getAttributeAsDouble(String name)
      Returns an attribute as a Double.
      Parameters:
      name - the attribute name
      Returns:
      the Double value, or null if not found
    • getAttributeAsDouble

      public Double getAttributeAsDouble(String name, Double defValue)
      Returns an attribute as a Double with a default value.
      Parameters:
      name - the attribute name
      defValue - the default value if attribute is not found
      Returns:
      the Double value, or defValue if not found
    • getAttributeAsBoolean

      public Boolean getAttributeAsBoolean(String name)
      Returns an attribute as a Boolean.
      Parameters:
      name - the attribute name
      Returns:
      the Boolean value, or null if not found
    • getAttributeAsBoolean

      public Boolean getAttributeAsBoolean(String name, Boolean defValue)
      Returns an attribute as a Boolean with a default value.
      Parameters:
      name - the attribute name
      defValue - the default value if attribute is not found
      Returns:
      the Boolean value, or defValue if not found
    • getAttributeNames

      public Enumeration<String> getAttributeNames()
      Returns an enumeration of all attribute names in this session.
      Returns:
      enumeration of attribute names
    • setAttribute

      public void setAttribute(String name, Object value)
      Sets a session attribute.
      Parameters:
      name - the attribute name
      value - the attribute value
    • removeAttribute

      public void removeAttribute(String name)
      Removes a session attribute.
      Parameters:
      name - the attribute name to remove
    • login

      public void login(UserPrincipal principal)
      Logs in the specified user principal, marking this session as authenticated.

      This method stores the principal in the session and regenerates the CSRF token to prevent session fixation attacks. For full session ID rotation, use rotateSession() before calling this method (requires OOR-303).

      Usage:

      
       OorianAuthenticator auth = Application.getAuthenticator();
       UserPrincipal principal = auth.authenticate(username, password);
      
       if (principal != null)
       {
           OorianSession.get().login(principal);
           navigateTo("/dashboard");
       }
       
      Parameters:
      principal - the authenticated user principal (must not be null)
      Throws:
      IllegalArgumentException - if the principal is null
      See Also:
    • logout

      public void logout()
      Logs out the current user and invalidates this session.

      This method clears the authenticated principal and invalidates the underlying HTTP session, removing all session attributes and unbinding all objects. After calling this method, the session can no longer be used.

      See Also:
    • getPrincipal

      public UserPrincipal getPrincipal()
      Returns the authenticated user principal for this session.
      Returns:
      the UserPrincipal, or null if no user is authenticated
      See Also:
    • isAuthenticated

      public boolean isAuthenticated()
      Checks whether a user is currently authenticated in this session.
      Returns:
      true if a user is logged in, false otherwise
      See Also:
    • invalidate

      public void invalidate()
      Invalidates this session and unbinds all objects bound to it.
    • isNew

      public boolean isNew()
      Checks if the session was newly created.
      Returns:
      true if the session is new, false otherwise
    • getCurrentPage

      public HtmlPage getCurrentPage()
      Returns the current page for this session.
      Returns:
      the current HtmlPage, or null if none is set
    • getPage

      public HtmlPage getPage(String pageId)
      Returns a cached page by its unique identifier.
      Parameters:
      pageId - the page identifier
      Returns:
      the HtmlPage, or null if not found
    • onThreadComplete

      public void onThreadComplete()
      Called when the current thread's request processing is complete.

      This method performs cleanup operations in the following order:

      1. Releases the page cache thread lock
      2. Starts any queued worker threads
      3. Removes this session from thread-local storage
      Specified by:
      onThreadComplete in interface OorianThreadListener
    • getCsrfToken

      public String getCsrfToken()
      Returns the CSRF token for this session, creating one if it doesn't exist.

      The CSRF token is a unique identifier that is generated once per session and used to validate that requests originate from pages served by this application. The token is included in the page as a meta tag and must be sent with all AJAX and WebSocket requests when CSRF protection is enabled.

      This method is thread-safe and will always return the same token for a given session.

      Returns:
      The CSRF token for this session.
      See Also:
    • validateCsrfToken

      public boolean validateCsrfToken(String token)
      Validates a CSRF token against the session's stored token.

      This method compares the provided token with the session's CSRF token using a constant-time comparison to prevent timing attacks.

      Parameters:
      token - The token to validate (typically from a request parameter).
      Returns:
      true if the token is valid, false otherwise.
      See Also:
    • regenerateCsrfToken

      public String regenerateCsrfToken()
      Regenerates the CSRF token for this session.

      This method should be called after sensitive operations such as login or privilege escalation to prevent session fixation attacks. After calling this method, any pages loaded before the regeneration will have an invalid token and will need to be refreshed.

      Returns:
      The new CSRF token.
    • rotateSession

      public void rotateSession()
      Rotates the session ID and regenerates the CSRF token to prevent session fixation attacks.

      This method should be called after successful authentication (login) to ensure that an attacker who obtained a session ID before authentication cannot use it afterward. The session attributes and internal Oorian state (page cache, client profile, etc.) are preserved.

      What happens:

      1. The servlet container generates a new session ID (attributes are preserved)
      2. The active sessions map is updated with the new ID
      3. The CSRF token is regenerated

      Usage:

      
       // After successful login
       OorianSession.get().rotateSession();
       

      This method must be called during request processing (e.g., from a page event handler). Calling it outside of a request context will throw an IllegalStateException.

      Throws:
      IllegalStateException - if called outside of a request context
      See Also:
    • isExpired

      public boolean isExpired()
      Checks whether this session has expired based on the application-wide timeout settings.

      A session is considered expired if either:

      If both timeouts are set to 0 (the default), this method always returns false, deferring to the servlet container's session timeout.

      Returns:
      true if the session has expired, false otherwise
    • setUserId

      public void setUserId(String userId)
      Sets the user identifier for this session, enabling concurrent session control.

      When a user ID is set, the session is tracked in the user-to-sessions map. If ApplicationDefaults.getMaxConcurrentSessions() is configured and the user exceeds the limit, the oldest session for that user is automatically invalidated.

      Call this method after successful authentication. To clear the user association (e.g., on logout), pass null.

      Parameters:
      userId - the user identifier, or null to clear
      See Also:
    • getUserId

      public String getUserId()
      Returns the user identifier associated with this session.
      Returns:
      the user ID, or null if no user is associated
    • invalidateSession

      public void invalidateSession()
      Invalidates this session.

      Removes the session from the active sessions map and the user session tracking map, then invalidates the underlying HTTP session.

    • checkRateLimit

      public boolean checkRateLimit()
      Checks whether the current request is within the configured rate limit.

      If rate limiting is disabled (max requests = 0), this method always returns true. The rate limiter is created lazily on first use, using the application-wide rate limit configuration from ApplicationDefaults.

      Returns:
      true if the request is allowed, false if the rate limit is exceeded
    • registerListener

      public void registerListener(SessionEventListener listener, Class<? extends SessionEvent>... eventTypes)
      Registers a listener for one or more SessionEvent types on this session.

      When a matching SessionEvent is dispatched to this session, the listener's onEvent method will be called.

      Parameters:
      listener - The listener to register.
      eventTypes - One or more SessionEvent classes to listen for.
    • registerListener

      public void registerListener(ApplicationEventListener listener, Class<? extends ApplicationEvent>... eventTypes)
      Registers a listener for one or more ApplicationEvent types on this session.

      When a matching ApplicationEvent is dispatched application-wide, the listener's onEvent method will be called for this session.

      Parameters:
      listener - The listener to register.
      eventTypes - One or more ApplicationEvent classes to listen for.
    • dispatchEvent

      public void dispatchEvent(SessionEvent event)
      Dispatches a SessionEvent to all listeners registered on this session for that event type.
      Parameters:
      event - The SessionEvent to dispatch.
    • dispatchApplicationEvent

      public static void dispatchApplicationEvent(ApplicationEvent event)
      Dispatches an ApplicationEvent to all active sessions.

      Iterates over all active OorianSession instances and dispatches the event to each session's registered listeners. This enables application-wide broadcasting of events across all user sessions.

      Parameters:
      event - The ApplicationEvent to dispatch.