Class CaldavConnectionIdentityService
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 -
Method Summary
Modifier and TypeMethodDescriptionlongactiveUsersWithoutIdentityOn(long serverId) How many users holding an active pair on a server have no identity recorded for that server.static StringcanonicalPrincipal(String principal) A principal in the one form it is recorded and compared in: the formCalendarCollectioncompares aDAV:ownerin, so a stored principal and an owner a listing reports meet on the same spelling.voidforgetPrincipal(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).voidrecordPrincipal(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.
-
Constructor Details
-
CaldavConnectionIdentityService
public CaldavConnectionIdentityService()
-
-
Method Details
-
canonicalPrincipal
A principal in the one form it is recorded and compared in: the formCalendarCollectioncompares aDAV:ownerin, 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
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
utf8mb3column 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 discoveredserverId- the server key the user's pairs use, zero for an account attached before registrations existedprincipal- thecurrent-user-principalas 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
The eXo users connected as exactly one principal on one server.- Parameters:
serverId- the server keyprincipal- 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
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 countserverId- the server keyprincipal- 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
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 userserverId- 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
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
-