Class CaldavConnectionIdentityService

java.lang.Object
org.exoplatform.caldav.service.CaldavConnectionIdentityService

@Service public class CaldavConnectionIdentityService extends Object
Who each connected eXo user is on their CalDAV server, and which eXo users are connected as a given principal (EXO-90243).

The problem. The engine knew "the account" only as the parent path of a calendar's href, and a path cannot tell two eXo users on one login (EXO-90190) from a colleague's calendar the server lists in the user's own home (EXO-90235). On the rig that confusion named bob in the shared-account warning of alice's account, because bob had a share of alice's calendar under alice's home; and the owner of a share the server reported could only ever be shown as a name, never as the eXo user it is. The server already answers the discriminator on every discovery — the current-user-principal — and nothing kept it.

What is recorded, and when. The principal of each discovery the account's first step makes (CaldavOutboundService#bindPersonalCalendars, run on connect and at the start of every pass), so recording it costs no request. It is forgotten when the account is connected again — the credentials just changed, and the identity recorded under the previous ones must not outlive a first discovery that fails — and when it is disconnected. There is no backfill: a user is known by identity from their first pass after the upgrade. Until then the shared-account warning is only late — it names what it finds and is asked again every pass — while the owner of a share could be misread: a login two eXo users share would look like one user's as long as only one of them is recorded. So no share owner on a server is mapped to an eXo user while any user holding an active pair there has no identity recorded for it (activeUsersWithoutIdentityOn(long)). Two residuals follow. A connected user holding no pair at all is not seen by that check. And a user who keeps active pairs on a server without ever being recorded for it — pointed at another server without disconnecting, a principal the column cannot hold, settings removed without the pairs being paused, a discovery failing for good — keeps every share on that server named by its principal alone, for as long as that lasts: the safe direction, said at info by the owner lookup.

What is believed. A user matched by principal counts only while their settings still hold a connected account on the same server. The row is forgotten on disconnect through the kernel bridge, and that resolution can fail; a row left behind must not keep naming someone who is no longer connected. The recorded principal of a user who connected another account on the same server is forgotten when they connect it and recorded again by the next discovery after it; a pass already running for that user on another node at that moment may write the previous principal back, and it then stands until that user's next discovery, one pass later.

Never allowed to fail a connection, a pass or a listing: recording and forgetting absorb their own failures, and a lookup that fails is the caller's to degrade.

  • Constructor Summary

    Constructors
    Constructor
    Description
     
  • Method Summary

    Modifier and Type
    Method
    Description
    long
    How many users holding an active pair on a server have no identity recorded for that server.
    static String
    A principal in the one form it is recorded and compared in: the form CalendarCollection compares a DAV:owner in, so a stored principal and an owner a listing reports meet on the same spelling.
    void
    forgetPrincipal(long userIdentityId)
    Forgets the principal recorded for a user: their account was connected again, or disconnected.
    otherUsersConnectedAs(long userIdentityId, long serverId, String principal)
    The eXo users other than one connected as exactly one principal on one server — the users who connected the same account.
    principalOf(long userIdentityId, long serverId)
    The principal one user is connected as on one server, believed only while their settings still hold a connected account there (EXO-90253).
    principalsOn(long serverId)
    The principals of every user still connected to one server, by user, lowest identity first, as far as the storage's bound reads (EXO-90253).
    void
    recordPrincipal(long userIdentityId, long serverId, String principal)
    Records the principal a discovery found for a user's account.
    usersConnectedAs(long serverId, String principal)
    The eXo users connected as exactly one principal on one server.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • CaldavConnectionIdentityService

      public CaldavConnectionIdentityService()
  • Method Details

    • canonicalPrincipal

      public static String canonicalPrincipal(String principal)
      A principal in the one form it is recorded and compared in: the form CalendarCollection compares a DAV:owner in, so a stored principal and an owner a listing reports meet on the same spelling.
      Parameters:
      principal - a principal path as a server answered it, may be null
      Returns:
      the canonical path, or null when there is none to speak of
    • recordPrincipal

      public void recordPrincipal(long userIdentityId, long serverId, String principal)
      Records the principal a discovery found for a user's account.

      A principal the server did not name, or one the column cannot hold faithfully — longer than it, or carrying a character outside the Basic Multilingual Plane, which MySQL's utf8mb3 column refuses or, out of strict mode, truncates — is recorded as unknown: whatever was stored before is removed rather than left to describe an account nobody confirmed, and a principal is never cut down into somebody else's. A second node recording the same user at the same instant meets the unique index; its row is then updated instead, the end state being the same.

      Parameters:
      userIdentityId - the eXo user whose account was discovered
      serverId - the server key the user's pairs use, zero for an account attached before registrations existed
      principal - the current-user-principal as the discovery answered it, may be null
    • forgetPrincipal

      public void forgetPrincipal(long userIdentityId)
      Forgets the principal recorded for a user: their account was connected again, or disconnected.

      Absorbs its own failure, because the two acts calling it must succeed whatever happens here; a row it could not remove is ignored by every reader once the account is no longer connected, and replaced by the next discovery when it is.

      Parameters:
      userIdentityId - the eXo user
    • activeUsersWithoutIdentityOn

      public long activeUsersWithoutIdentityOn(long serverId)
      How many users holding an active pair on a server have no identity recorded for that server.

      Zero is what makes "exactly one user is connected as this principal" true rather than merely what the table says: until then, a second user of the same login may simply not be recorded yet — or may never be, for the shapes the class documentation lists.

      Parameters:
      serverId - the server key
      Returns:
      the number of such users, zero when nobody synchronising with that server is missing
      Throws:
      RuntimeException - when the question itself fails; the caller degrades
    • usersConnectedAs

      public List<Long> usersConnectedAs(long serverId, String principal)
      The eXo users connected as exactly one principal on one server.
      Parameters:
      serverId - the server key
      principal - the principal in any spelling a server answers
      Returns:
      the users, lowest identity first, each still connected to that server; empty when nobody is, or the principal names nobody
      Throws:
      RuntimeException - when the lookup itself fails; the caller degrades
    • otherUsersConnectedAs

      public List<Long> otherUsersConnectedAs(long userIdentityId, long serverId, String principal)
      The eXo users other than one connected as exactly one principal on one server — the users who connected the same account.
      Parameters:
      userIdentityId - the user asking, who does not count
      serverId - the server key
      principal - the principal in any spelling a server answers
      Returns:
      the other users, lowest identity first, each still connected to that server
      Throws:
      RuntimeException - when the lookup itself fails; the caller degrades
    • principalOf

      public String principalOf(long userIdentityId, long serverId)
      The principal one user is connected as on one server, believed only while their settings still hold a connected account there (EXO-90253).

      What a sharee is named by in an access control entry: nothing else ties an eXo user to a principal, and a principal is never guessed from a login.

      Parameters:
      userIdentityId - the eXo user
      serverId - the server key
      Returns:
      the canonical principal, or null when none is recorded for that server or the user is no longer connected to it
      Throws:
      RuntimeException - when the lookup itself fails; the caller degrades
    • principalsOn

      public Map<Long,String> principalsOn(long serverId)
      The principals of every user still connected to one server, by user, lowest identity first, as far as the storage's bound reads (EXO-90253).
      Parameters:
      serverId - the server key
      Returns:
      user identity to canonical principal
      Throws:
      RuntimeException - when the lookup itself fails; the caller degrades