Establish secure account and managed AI backend

Provide the production foundation for Apple identity, immutable credits, referrals, integrity checks, managed providers, and hardened Docker deployment.
This commit is contained in:
Rocky
2026-08-16 14:46:23 +08:00
commit 0af35d44f4
124 changed files with 21052 additions and 0 deletions
@@ -0,0 +1,123 @@
package com.osglab.account.features.auth
import com.osglab.account.config.AppleConfig
import io.kotest.assertions.throwables.shouldThrow
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.shouldBe
import io.ktor.client.HttpClient
import io.ktor.client.engine.mock.MockEngine
import io.ktor.client.engine.mock.respond
import io.ktor.client.plugins.HttpTimeout
import io.ktor.client.request.forms.FormDataContent
import io.ktor.http.HttpHeaders
import io.ktor.http.HttpStatusCode
import io.ktor.http.headersOf
import java.net.SocketTimeoutException
class AppleTokenClientTest : FunSpec({
test("authorization code exchange uses the replaceable HTTP boundary") {
val engine = MockEngine { request ->
request.url.toString() shouldBe "https://appleid.apple.com/auth/token"
val form = (request.body as FormDataContent).formData
form["client_id"] shouldBe "com.example.ios"
form["client_secret"] shouldBe "signed-client-secret"
form["code"] shouldBe "one-time-code"
form["grant_type"] shouldBe "authorization_code"
respond(
content = """{"refresh_token":"refresh","id_token":"identity"}""",
status = HttpStatusCode.OK,
headers = headersOf(HttpHeaders.ContentType, "application/json"),
)
}
val client = HttpClient(engine) { install(HttpTimeout) }
val apple = HttpAppleTokenClient(
client,
appleTokenClientConfig(),
AppleClientSecretSigner { "signed-client-secret" },
)
apple.exchangeAuthorizationCode("one-time-code") shouldBe
AppleTokenExchange("refresh", "identity")
client.close()
}
test("provider timeout is mapped to a retryable failure") {
val engine = MockEngine {
throw SocketTimeoutException("simulated provider timeout")
}
val client = HttpClient(engine) { install(HttpTimeout) }
val apple = HttpAppleTokenClient(
httpClient = client,
config = appleTokenClientConfig(),
clientSecretProvider = AppleClientSecretSigner { "signed-client-secret" },
requestTimeoutMillis = 10,
)
shouldThrow<AppleTokenEndpointException> {
apple.exchangeAuthorizationCode("one-time-code")
}.retryable shouldBe true
client.close()
}
test("authorization code exchange rejects a response without a refresh token") {
val engine = MockEngine {
respond(
content = """{"id_token":"identity"}""",
status = HttpStatusCode.OK,
headers = headersOf(HttpHeaders.ContentType, "application/json"),
)
}
val client = HttpClient(engine) { install(HttpTimeout) }
val apple = HttpAppleTokenClient(
client,
appleTokenClientConfig(),
AppleClientSecretSigner { "signed-client-secret" },
)
shouldThrow<AppleTokenEndpointException> {
apple.exchangeAuthorizationCode("one-time-code")
}.retryable shouldBe false
client.close()
}
test("rate limiting is retryable without reflecting the provider response") {
val engine = MockEngine {
respond(
content = "upstream detail that must not be reflected",
status = HttpStatusCode.TooManyRequests,
)
}
val client = HttpClient(engine) { install(HttpTimeout) }
val apple = HttpAppleTokenClient(
client,
appleTokenClientConfig(),
AppleClientSecretSigner { "signed-client-secret" },
)
val failure = shouldThrow<AppleTokenEndpointException> {
apple.exchangeAuthorizationCode("one-time-code")
}
failure.retryable shouldBe true
failure.message shouldBe "Apple rejected the authorization code"
client.close()
}
test("token exchange values are redacted from string rendering") {
AppleTokenExchange("refresh-secret", "identity-secret").toString() shouldBe
"AppleTokenExchange(refreshToken=[REDACTED], identityToken=[REDACTED])"
}
})
private fun appleTokenClientConfig() = AppleConfig(
teamId = "TEAM",
keyId = "KEY",
clientId = "com.example.ios",
privateKeyPem = "unused-by-test-signer",
jwksUrl = "https://appleid.apple.com/auth/keys",
tokenUrl = "https://appleid.apple.com/auth/token",
revokeUrl = "https://appleid.apple.com/auth/revoke",
)