Files
wehub-resource-sync 1d1286fadb
Build / Build and test (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:18:38 +08:00

81 lines
3.3 KiB
Swift

import XCTest
@testable import MacTools
final class PluginTrustValidatorTests: XCTestCase {
private let hostURL = URL(fileURLWithPath: "/tmp/MacTools.app")
private let pluginURL = URL(fileURLWithPath: "/tmp/Example.mactoolsplugin")
/// Controllable signature/team source so the validator can be exercised
/// without touching the real Security framework.
private struct FakeCodeSignatureInfoProvider: CodeSignatureInfoProviding {
var hostURL: URL
var hostTeam: String?
var pluginTeam: String?
var pluginSignatureValid = true
func validateCodeSignature(at url: URL) throws {
if !pluginSignatureValid {
throw PluginTrustValidatorError.signatureCheckFailed("fake")
}
}
func teamIdentifier(for url: URL) throws -> String? {
url == hostURL ? hostTeam : pluginTeam
}
}
private func makeValidator(
hostTeam: String?,
pluginTeam: String?,
allowsUntrustedHostTeam: Bool
) -> SameTeamPluginTrustValidator {
let provider = FakeCodeSignatureInfoProvider(
hostURL: hostURL,
hostTeam: hostTeam,
pluginTeam: pluginTeam
)
return SameTeamPluginTrustValidator(
hostBundleURL: hostURL,
codeSignatureInfoProvider: provider,
allowsUntrustedHostTeam: allowsUntrustedHostTeam
)
}
func testRejectsPluginWhenHostTeamUnavailableAndEnforcing() {
// Release-style behavior: an unreadable host team must NOT silently
// accept any validly-signed bundle (fail closed).
let validator = makeValidator(hostTeam: nil, pluginTeam: "ATTACKERTEAM", allowsUntrustedHostTeam: false)
XCTAssertThrowsError(try validator.validatePluginBundle(at: pluginURL)) { error in
XCTAssertEqual(error as? PluginTrustValidatorError, .hostTeamIdentifierUnavailable)
}
}
func testAllowsPluginWhenHostTeamUnavailableAndPermissive() {
// DEBUG-style behavior: local dev host has no team, keep loading plugins.
let validator = makeValidator(hostTeam: nil, pluginTeam: "ANYTEAM", allowsUntrustedHostTeam: true)
XCTAssertNoThrow(try validator.validatePluginBundle(at: pluginURL))
}
func testRejectsTeamMismatchWhenHostTeamKnown() {
let validator = makeValidator(hostTeam: "HOSTTEAM", pluginTeam: "OTHERTEAM", allowsUntrustedHostTeam: false)
XCTAssertThrowsError(try validator.validatePluginBundle(at: pluginURL)) { error in
XCTAssertEqual(
error as? PluginTrustValidatorError,
.teamIdentifierMismatch(expected: "HOSTTEAM", actual: "OTHERTEAM")
)
}
}
func testAcceptsMatchingTeam() {
let validator = makeValidator(hostTeam: "SAMETEAM", pluginTeam: "SAMETEAM", allowsUntrustedHostTeam: false)
XCTAssertNoThrow(try validator.validatePluginBundle(at: pluginURL))
}
func testRejectsPluginWithMissingTeamWhenHostTeamKnown() {
let validator = makeValidator(hostTeam: "HOSTTEAM", pluginTeam: nil, allowsUntrustedHostTeam: false)
XCTAssertThrowsError(try validator.validatePluginBundle(at: pluginURL)) { error in
XCTAssertEqual(error as? PluginTrustValidatorError, .teamIdentifierUnavailable(pluginURL))
}
}
}