Repository navigation
feat: add credential properties. - #46
Conversation
Signed-off-by: 秋雨落 <i@rain.cx>
Reviewer's GuideThe PR adds a property-based metadata mechanism to the API by extending HyperZoneCredential with IPropertiesHolder, then exposes the normalized Yggdrasil entry ID as the public Sequence diagram for Yggdrasil credential property initializationsequenceDiagram
participant Caller
participant YggdrasilHyperZoneCredential
participant IPropertiesHolder
Caller->>YggdrasilHyperZoneCredential: create(entryId, authenticatedUUID)
YggdrasilHyperZoneCredential->>IPropertiesHolder: setProperty(YGGDRASIL_ENTRY_ID_PROPERTY, entryId.lowercase(Locale.getDefault()))
IPropertiesHolder-->>YggdrasilHyperZoneCredential: property stored
Caller->>YggdrasilHyperZoneCredential: getProperty(YGGDRASIL_ENTRY_ID_PROPERTY)
YggdrasilHyperZoneCredential-->>Caller: normalized entryId
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 3 issues
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="api/src/main/kotlin/icu/h2l/api/util/IPropertiesHolder.kt" line_range="26" />
<code_context>
+
+interface IPropertiesHolder {
+ val properties: HashMap<String, String>
+ get() = HashMap()
+
+ fun getProperty(key: String): String {
</code_context>
<issue_to_address>
**Credential properties disappear**
When a credential uses the inherited default `properties` getter, `properties` returns a fresh `HashMap` on each access, so `setProperty` writes to a discarded map and later `hasProperty` or `getProperty` calls cannot see the value; callers cannot retrieve the Yggdrasil entry ID.
Keep one persistent backing map per credential instead of creating a new map on each access.
Also at `auth-yggd/src/main/kotlin/icu/h2l/login/auth/online/credential/YggdrasilHyperZoneCredential.kt:40`.
</issue_to_address>
### Comment 2
<location path="api/src/main/kotlin/icu/h2l/api/profile/HyperZoneCredential.kt" line_range="33" />
<code_context>
* 是否已绑定、如何绑定到 Profile,都由各认证模块自己的实现负责。
*/
-interface HyperZoneCredential {
+interface HyperZoneCredential : IPropertiesHolder {
/**
* 认证渠道唯一标识,由子模块负责稳定定义。
</code_context>
<issue_to_address>
**Java credential implementations break**
When a Java module has an existing `HyperZoneCredential` implementation compiled against this API, a Java credential implementation compiled against the previous API has no implementations of the newly inherited property methods; with Kotlin’s default JVM interface mode, calls to those methods fail with `AbstractMethodError`, and recompiling the implementation requires adding them.
Preserve Java implementor compatibility by emitting JVM default methods for the new interface API or by providing a compatibility adapter that does not require new implementation methods.
</issue_to_address>
### Comment 3
<location path="auth-yggd/src/main/kotlin/icu/h2l/login/auth/online/credential/YggdrasilHyperZoneCredential.kt" line_range="40" />
<code_context>
override val credentialId: String = "$entryId:$authenticatedUUID"
+ init {
+ setProperty(YGGDRASIL_ENTRY_ID_PROPERTY, entryId.lowercase(Locale.getDefault()))
+ }
+
</code_context>
<issue_to_address>
**Entry IDs stop matching**
When the default locale is Turkish and an entry ID contains uppercase `I`, `entryId.lowercase(Locale.getDefault())` produces a dotless `ı`, while `EntryTableManager` normalizes IDs with locale-independent `lowercase()`; consumers receive a property value that does not match the registered entry ID.
Normalize the entry ID with locale-independent lowercasing.
</issue_to_address>Sourcery assessment
Approval pending. 3 findings to address first.
Blocking findings: api/src/main/kotlin/icu/h2l/api/util/IPropertiesHolder.kt:26, api/src/main/kotlin/icu/h2l/api/profile/HyperZoneCredential.kt:33, auth-yggd/src/main/kotlin/icu/h2l/login/auth/online/credential/YggdrasilHyperZoneCredential.kt:40
|
|
||
| interface IPropertiesHolder { | ||
| val properties: HashMap<String, String> | ||
| get() = HashMap() |
There was a problem hiding this comment.
🟠 High · Credential properties disappear
When a credential uses the inherited default properties getter, properties returns a fresh HashMap on each access, so setProperty writes to a discarded map and later hasProperty or getProperty calls cannot see the value; callers cannot retrieve the Yggdrasil entry ID.
Keep one persistent backing map per credential instead of creating a new map on each access.
Also at auth-yggd/src/main/kotlin/icu/h2l/login/auth/online/credential/YggdrasilHyperZoneCredential.kt:40.
Prompt for AI agents
In `api/src/main/kotlin/icu/h2l/api/util/IPropertiesHolder.kt` at line 26:
**Credential properties disappear**
When a credential uses the inherited default `properties` getter, `properties` returns a fresh `HashMap` on each access, so `setProperty` writes to a discarded map and later `hasProperty` or `getProperty` calls cannot see the value; callers cannot retrieve the Yggdrasil entry ID.
Keep one persistent backing map per credential instead of creating a new map on each access.
Also at `auth-yggd/src/main/kotlin/icu/h2l/login/auth/online/credential/YggdrasilHyperZoneCredential.kt:40`.| * 是否已绑定、如何绑定到 Profile,都由各认证模块自己的实现负责。 | ||
| */ | ||
| interface HyperZoneCredential { | ||
| interface HyperZoneCredential : IPropertiesHolder { |
There was a problem hiding this comment.
🟡 Medium · Java credential implementations break
When a Java module has an existing HyperZoneCredential implementation compiled against this API, a Java credential implementation compiled against the previous API has no implementations of the newly inherited property methods; with Kotlin’s default JVM interface mode, calls to those methods fail with AbstractMethodError, and recompiling the implementation requires adding them.
Preserve Java implementor compatibility by emitting JVM default methods for the new interface API or by providing a compatibility adapter that does not require new implementation methods.
Prompt for AI agents
In `api/src/main/kotlin/icu/h2l/api/profile/HyperZoneCredential.kt` at line 33:
**Java credential implementations break**
When a Java module has an existing `HyperZoneCredential` implementation compiled against this API, a Java credential implementation compiled against the previous API has no implementations of the newly inherited property methods; with Kotlin’s default JVM interface mode, calls to those methods fail with `AbstractMethodError`, and recompiling the implementation requires adding them.
Preserve Java implementor compatibility by emitting JVM default methods for the new interface API or by providing a compatibility adapter that does not require new implementation methods.| override val credentialId: String = "$entryId:$authenticatedUUID" | ||
|
|
||
| init { | ||
| setProperty(YGGDRASIL_ENTRY_ID_PROPERTY, entryId.lowercase(Locale.getDefault())) |
There was a problem hiding this comment.
🟡 Medium · Entry IDs stop matching
When the default locale is Turkish and an entry ID contains uppercase I, entryId.lowercase(Locale.getDefault()) produces a dotless ı, while EntryTableManager normalizes IDs with locale-independent lowercase(); consumers receive a property value that does not match the registered entry ID.
Normalize the entry ID with locale-independent lowercasing.
Prompt for AI agents
In `auth-yggd/src/main/kotlin/icu/h2l/login/auth/online/credential/YggdrasilHyperZoneCredential.kt` at line 40:
**Entry IDs stop matching**
When the default locale is Turkish and an entry ID contains uppercase `I`, `entryId.lowercase(Locale.getDefault())` produces a dotless `ı`, while `EntryTableManager` normalizes IDs with locale-independent `lowercase()`; consumers receive a property value that does not match the registered entry ID.
Normalize the entry ID with locale-independent lowercasing.
变更说明
为Credential增加Properties,用于特定信息的跨模块传递需求。
为
YggdrasilHyperZoneCredential增加yggdrasil-entry-id属性,用于标识yggdrasil的entryId,作为公开API的一部分。关联范围
openvcauth-yggdauth-offlinedata-mergeprofile-skinapi变更类型
测试与验证
请说明你做了哪些验证,例如:
兼容性与风险
无兼容性风险。
其他补充
N/A
Summary by Sourcery
Enable credentials to carry extensible properties and expose the associated Yggdrasil entry identifier.
New Features:
yggdrasil-entry-idcredential property.