109 lines · 5.1 KB · Swift
RawDownload
import Foundationimport Testing@testable import CodexBarCore @Suite(.serialized)struct ClaudeOAuthCredentialsStoreSecurityCLIFallbackPolicyTests {    private func makeCredentialsData(accessToken: String, expiresAt: Date) -> Data {        let millis = Int(expiresAt.timeIntervalSince1970 * 1000)        let json = """        {          "claudeAiOauth": {            "accessToken": "\(accessToken)",            "expiresAt": \(millis),            "scopes": ["user:profile"]          }        }        """        return Data(json.utf8)    }     @Test    func `experimental reader blocks background fallback per stored policy`() {        let fallbackData = self.makeCredentialsData(            accessToken: "fallback-should-be-blocked",            expiresAt: Date(timeIntervalSinceNow: 3600))         let hasCredentials = KeychainAccessGate.withTaskOverrideForTesting(false) {            ClaudeOAuthKeychainReadStrategyPreference.withTaskOverrideForTesting(                .securityCLIExperimental,                operation: {                    ClaudeOAuthKeychainPromptPreference.withTaskOverrideForTesting(                        .onlyOnUserAction,                        operation: {                            ProviderInteractionContext.$current.withValue(.background) {                                ClaudeOAuthCredentialsStore.withClaudeKeychainOverridesForTesting(                                    data: fallbackData,                                    fingerprint: nil)                                {                                    ClaudeOAuthCredentialsStore.withSecurityCLIReadOverrideForTesting(                                        .nonZeroExit)                                    {                                        ClaudeOAuthCredentialsStore.hasClaudeKeychainCredentialsWithoutPrompt()                                    }                                }                            }                        })                })        }         #expect(hasCredentials == false)    }     @Test    func `experimental reader sync from claude keychain without prompt background fallback blocked by stored policy`() {        let service = "com.steipete.codexbar.cache.tests.\(UUID().uuidString)"        KeychainCacheStore.withServiceOverrideForTesting(service) {            KeychainAccessGate.withTaskOverrideForTesting(false) {                KeychainCacheStore.setTestStoreForTesting(true)                defer { KeychainCacheStore.setTestStoreForTesting(false) }                 ClaudeOAuthCredentialsStore.withIsolatedMemoryCacheForTesting {                    ClaudeOAuthCredentialsStore.invalidateCache()                    defer { ClaudeOAuthCredentialsStore.invalidateCache() }                     let fallbackData = self.makeCredentialsData(                        accessToken: "sync-fallback-should-be-blocked",                        expiresAt: Date(timeIntervalSinceNow: 3600))                    final class Counter: @unchecked Sendable {                        var value = 0                    }                    let preflightCalls = Counter()                    let preflightOverride: (String, String?) -> KeychainAccessPreflight.Outcome = { _, _ in                        preflightCalls.value += 1                        return .allowed                    }                     let synced = KeychainAccessPreflight.withCheckGenericPasswordOverrideForTesting(                        preflightOverride,                        operation: {                            ClaudeOAuthKeychainReadStrategyPreference.withTaskOverrideForTesting(                                .securityCLIExperimental,                                operation: {                                    ClaudeOAuthKeychainPromptPreference.withTaskOverrideForTesting(                                        .onlyOnUserAction,                                        operation: {                                            ProviderInteractionContext.$current.withValue(.background) {                                                ClaudeOAuthCredentialsStore.withClaudeKeychainOverridesForTesting(                                                    data: fallbackData,                                                    fingerprint: nil)                                                {                                                    ClaudeOAuthCredentialsStore.withSecurityCLIReadOverrideForTesting(                                                        .timedOut)                                                    {                                                        ClaudeOAuthCredentialsStore                                                            .syncFromClaudeKeychainWithoutPrompt(now: Date())                                                    }                                                }                                            }                                        })                                })                        })                     #expect(synced == false)                    #expect(preflightCalls.value == 0)                }            }        }    }}