LocalData/Sources/LocalData/Models/KeychainAccessControl.swift

77 lines
2.6 KiB
Swift

import Foundation
import Security
/// Defines additional access control requirements for keychain items.
/// These flags can require user authentication before accessing the item.
public enum KeychainAccessControl: Equatable, Sendable, CaseIterable {
/// Requires any form of user presence (biometric or passcode).
case userPresence
/// Requires biometric authentication only (Face ID or Touch ID).
/// Falls back to nothing if biometry is not available.
case biometryAny
/// Requires the currently enrolled biometric.
/// If biometric enrollment changes, item becomes inaccessible.
case biometryCurrentSet
/// Requires device passcode entry.
case devicePasscode
/// Requires biometric or device passcode.
/// Biometric is preferred, passcode is fallback.
case biometryAnyOrDevicePasscode
/// Requires current biometric or device passcode.
/// If biometric changes, still accessible via passcode.
case biometryCurrentSetOrDevicePasscode
/// Creates a SecAccessControl object with the specified accessibility.
/// - Parameter accessibility: The base accessibility level.
/// - Returns: A configured SecAccessControl, or nil if creation fails.
func accessControl(accessibility: KeychainAccessibility) -> SecAccessControl? {
let accessibilityValue = accessibility.cfString
let flags: SecAccessControlCreateFlags
switch self {
case .userPresence:
flags = .userPresence
case .biometryAny:
flags = .biometryAny
case .biometryCurrentSet:
flags = .biometryCurrentSet
case .devicePasscode:
flags = .devicePasscode
case .biometryAnyOrDevicePasscode:
flags = [.biometryAny, .or, .devicePasscode]
case .biometryCurrentSetOrDevicePasscode:
flags = [.biometryCurrentSet, .or, .devicePasscode]
}
return SecAccessControlCreateWithFlags(
nil,
accessibilityValue,
flags,
nil
)
}
/// Human-readable description for UI display.
public var displayName: String {
switch self {
case .userPresence:
return "User Presence"
case .biometryAny:
return "Biometry (Any)"
case .biometryCurrentSet:
return "Biometry (Current Set)"
case .devicePasscode:
return "Device Passcode"
case .biometryAnyOrDevicePasscode:
return "Biometry or Passcode"
case .biometryCurrentSetOrDevicePasscode:
return "Current Biometry or Passcode"
}
}
}