Class ServerCredentialStore
cloud_credential entry of
<server root>/.ultikits/credentials.json, always through CredentialStore.
The entry is {credential, credentialId, serverId, userId, serverName, linkedAt}. Saving it
removes the 6.3.0 user token (cloud_token) in the same atomic write, because a server holds
only its server credential from protocol v2 on. Every other key -- the 32-hex uuid install
id among them -- is carried through unchanged.
Why these writes cannot overwrite operator content. credentials.json is
framework-owned state, not operator configuration: CredentialStore is its sole owner, it is
created and maintained by the framework alone (owner-only file mode), and no operator workflow
edits it. Both write paths here change only the two framework keys named above inside one
CredentialStore.update(java.util.function.UnaryOperator<java.util.Map<java.lang.String, java.lang.Object>>) call, and CredentialStore.update(java.util.function.UnaryOperator<java.util.Map<java.lang.String, java.lang.Object>>) refuses to write over a
file it cannot parse, so a hand-damaged file is never replaced.
- Since:
- 6.3.1
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescription(package private) static enum -
Field Summary
FieldsModifier and TypeFieldDescription(package private) static final StringThe document key of the server credential.(package private) static final StringThe document key of the 6.3.0 user OAuth token, which a successful link removes.private static final AtomicBooleanWhether the current malformed entry was already reported, so one bad file warns once. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescription(package private) static booleandelete()Removes only theKEYentry.(package private) static booleandeleteIfMatches(String credentialId) Removes the credential only if its public id still matches the rejected connection's id.(package private) static ServerCredentialload()(package private) static ServerCredentialStore.LegacyTokenRemovalRemoves the unusable pre-v2 token only when it exists.(package private) static booleanReplaces the secret and its public id of the stored credential with a rotated pair (plan 22-21, D-10), in oneCredentialStore.update(java.util.function.UnaryOperator<java.util.Map<java.lang.String, java.lang.Object>>)-- one atomic, owner-only write.(package private) static voidsave(ServerCredential credential)
-
Field Details
-
KEY
The document key of the server credential.- See Also:
-
LEGACY_TOKEN_KEY
The document key of the 6.3.0 user OAuth token, which a successful link removes.- See Also:
-
REPORTED_MALFORMED
Whether the current malformed entry was already reported, so one bad file warns once.
-
-
Constructor Details
-
ServerCredentialStore
private ServerCredentialStore()
-
-
Method Details
-
load
- Returns:
- the stored credential, or
nullwhen the file is absent or unreadable, the key is missing, or the entry is malformed (reported once with a WARNING that names the file, never the content)
-
save
WritescredentialunderKEYand removesLEGACY_TOKEN_KEY, in one atomic write. Framework-owned state only; see the class javadoc for why this cannot overwrite operator content.- Parameters:
credential- the credential to persist- Throws:
DataAccessException- if the write fails or the current file cannot be parsed
-
replace
Replaces the secret and its public id of the stored credential with a rotated pair (plan 22-21, D-10), in oneCredentialStore.update(java.util.function.UnaryOperator<java.util.Map<java.lang.String, java.lang.Object>>)-- one atomic, owner-only write. Every other field of the entry (the server id among them) and every other key of the file is kept. Nothing is written when no valid credential is stored, or when the stored one belongs to another server identity, because a rotation can only replace the credential the rotating session holds. Called only byCloudSession.rotateCredential(java.lang.String, java.lang.String), which updates its in-memory credential in the same monitor region (the session is the one owner of the current credential). Framework-owned state only; see the class javadoc for why this cannot overwrite operator content. The secret is never logged.- Parameters:
serverId- the server id of the credential being rotatedcredential- the newucs_secretcredentialId- the new credential's public id- Returns:
truewhen the new credential is stored- Throws:
DataAccessException- if the write fails or the current file cannot be parsed
-
deleteIfMatches
Removes the credential only if its public id still matches the rejected connection's id. The comparison and removal share one CredentialStore lock acquisition, so a newer login or rotation cannot be erased by a late rejection. Framework-owned state only; see the class javadoc for why this cannot overwrite operator content.- Parameters:
credentialId- the id used by the rejected connection- Returns:
- whether that entry was removed
-
removeLegacyToken
Removes the unusable pre-v2 token only when it exists. CredentialStore is the sole owner of this framework state, not operator configuration; the hard cut retained no old signing key and supports no token exchange. No token means no update, preserving the file's exact bytes.- Returns:
- whether the token was removed and a server credential was present beside it
-
delete
static boolean delete()Removes only theKEYentry. The file is not rewritten when the entry is absent. Framework-owned state only; see the class javadoc.- Returns:
trueif an entry existed and was removed
-