Class BlueMindRestSession
call), every call carrying the key it answered.
Extracted from BlueMindAclClient (EXO-90253) when a second
conversation needed it (EXO-90307, the ICS import channel), so that both
share one transport, one authentication path and one set of rules:
- Same server, never another. The REST root is the scheme, host
and port of the endpoint minted from the server registry for the DAV calls,
with the
/apiroot BlueMind serves its REST API under (RestServiceApiDescriptionParser.javaprefixes every path with/api;bluemind-vhosts.confproxieslocation /api/). Nothing a caller passes can name a host; redirects are never followed. - The account's own credentials, from storage. The login and password are the ones the configured credentials provider produces for the account's DAV requests, taken from its Basic header; a provider producing anything else is not a login this API accepts.
- A session, reused for a short while.
POST /api/auth/login?login=…with the password as a JSON string under exactlyContent-Type: application/json— what BlueMind's own client proxy sends (ClientProxyGenerator.java,ByMimeTypeCodec.encode); BlueMind picks the body codec by the exactContent-Typevalue (DefaultBodyParameterCodecs.java), so atext/plaincarrying a charset parameter would be read as JSON, refused with a 500 and logged by BlueMind with the password in it — answers aLoginResponsewhoseauthKeytravels in theX-BM-ApiKeyheader (parent/core/net.bluemind.core.rest/.../base/RestRootHandler.javareads it,BasicClientProxy.javasends it). Since EXO-90397 that key is kept for a few minutes, in this node's own memory and nowhere else (BlueMindSessionCache), so the next read costs one request rather than three; the rules that follow from it are oncall(org.exoplatform.caldav.client.CalDavEndpoint, java.util.function.Function<org.exoplatform.caldav.client.bluemind.BlueMindRestSession.Session, T>). The key and the password are never logged, never written to the database, never handed to a caller —BlueMindRestSession.Sessionexposes who the session is, not what authenticates it — and never part of an exception message. - Bounded answers. Every body is read up to a fixed size and refused beyond it: nothing this add-on reads from this API is large.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final recordAn answer: status and body text.final classAn open session: the REST root and the key every call carries. -
Field Summary
Fields -
Constructor Summary
ConstructorsConstructorDescriptionBlueMindRestSession(CaldavCredentialsResolver caldavCredentialsResolver, BlueMindSessionCache sessions) The transport Spring builds: no redirects, bounded timeouts. -
Method Summary
Modifier and TypeMethodDescriptionbooleanacceptsCredentials(CalDavEndpoint endpoint) Whether the account's configured credentials are a login and password this API can take, without calling the server.<T> Tcall(CalDavEndpoint endpoint, Function<BlueMindRestSession.Session, T> job) Runs one job inside a REST session opened as the account: the session kept for that account when there is one, a fresh login otherwise.static StringencodeSegment(String segment) One path segment, percent-encoded outside the unreserved set.voidDrops the session kept for one account and closes it, because eXo itself changed what that account is: new credentials, a reconnection, a disconnection.voidDrops every kept session, because the declared servers changed under them.open(CalDavEndpoint endpoint) Opens a REST session as the account, for as many calls as one service call needs, kept or reused ascall(CalDavEndpoint, Function)describes;BlueMindRestSession.Session.close()logs out a session nothing keeps, and leaves a kept one in the store.tools.jackson.databind.JsonNodeParses a JSON answer.static StringOne text member of a JSON object.
-
Field Details
-
API_KEY_HEADER
The header BlueMind's REST API reads a session key from.- See Also:
-
JSON_MEDIA_TYPE
The media type BlueMind's REST API reads and answers.- See Also:
-
-
Constructor Details
-
BlueMindRestSession
@Autowired public BlueMindRestSession(CaldavCredentialsResolver caldavCredentialsResolver, BlueMindSessionCache sessions) The transport Spring builds: no redirects, bounded timeouts.- Parameters:
caldavCredentialsResolver- the seam producing the account's credentialssessions- the short-lived sessions kept per account
-
-
Method Details
-
acceptsCredentials
Whether the account's configured credentials are a login and password this API can take, without calling the server.- Parameters:
endpoint- the account's endpoint, minted from the registry- Returns:
- true when the provider produces a Basic login and password
-
call
Runs one job inside a REST session opened as the account: the session kept for that account when there is one, a fresh login otherwise.What is reused, and for whom. The session is looked up by the account it acts as — the declared server, the eXo login the credentials are produced for, and the account those credentials address on that server (
BlueMindSessionCache.Key) — so no session ever serves an account other than the one it was minted for. An endpoint minted from a DAV account name rather than for an eXo user carries no login to key on, and neither does one whose provider cannot name the account it would address: such a call opens its own session and closes it, as every call did before EXO-90397.Never to another address. The kept session records the REST root it was opened at; an endpoint that now resolves elsewhere — an administrator changed the declared server's URL — does not reuse it. The key is a credential of one host and is never sent to another.
An expired or refused session re-logs in once. BlueMind expires a session on its own clock, and this add-on does not measure it (EXO-89647 is where that measurement lands), so the kept entry's lifetime is set well below any plausible server-side one and the refusal is handled rather than predicted: a 401 on a reused session drops the entry, opens another and sends the request again — once per call, tracked on the session itself, so a server refusing everything costs one extra login and never a loop.
Logout. A session nothing keeps is logged out when the job ends, as before — and nothing keeps it covers three cases, not one: the endpoint that cannot be keyed at all, the store that had no room for another account (
maxAccounts), and the session another thread's took the place of. A kept one is not closed: it is closed when eXo drops it on purpose (forget(long, java.lang.String)), and otherwise expires on BlueMind's own clock when the entry expires here first — the same fallback a failed logout has always relied on. A session refused by BlueMind is already closed on its side and is dropped without one.- Type Parameters:
T- what the job produces- Parameters:
endpoint- the account's DAV endpoint, minted from the registryjob- the calls to make with the session- Returns:
- what the job produced
- Throws:
UnsupportedOperationException- when the configured credentials are not a login and passwordCalDavAuthenticationException- when BlueMind refuses the loginCalDavUnreachableException- when the server cannot be reachedCalDavException- when the login answers anything else
-
open
Opens a REST session as the account, for as many calls as one service call needs, kept or reused ascall(CalDavEndpoint, Function)describes;BlueMindRestSession.Session.close()logs out a session nothing keeps, and leaves a kept one in the store. The exceptions are those ofcall(CalDavEndpoint, Function)for the login half.- Parameters:
endpoint- the account's DAV endpoint, minted from the registry- Returns:
- the session, to close
-
forget
Drops the session kept for one account and closes it, because eXo itself changed what that account is: new credentials, a reconnection, a disconnection.The logout is best-effort and never fails the caller: a session that could not be closed expires on BlueMind's own clock.
- Parameters:
serverId- the declared server registration, zero for the legacy deployment propertyexoLogin- the eXo login whose session goes
-
forgetAll
public void forgetAll()Drops every kept session, because the declared servers changed under them. The sessions are not closed — the entries carrying them are gone — so they expire on BlueMind's own clock. -
parse
Parses a JSON answer.- Parameters:
body- the bodyuri- the request, for the message- Returns:
- the tree
- Throws:
CalDavException- when the body is not JSON
-
textOf
One text member of a JSON object.- Parameters:
node- the objectname- the member- Returns:
- its text, or null when absent, null or not a value
-
encodeSegment
One path segment, percent-encoded outside the unreserved set.- Parameters:
segment- the decoded segment- Returns:
- the encoded segment
-