1313// limitations under the License.
1414
1515@testable import FirebaseAuth
16+ import FirebaseCoreInternal
1617import Foundation
1718import XCTest
1819
19- /** @class AuthKeychainStorage
20- @brief The utility class to update the real keychain
21- */
20+ /// The utility class to update the real keychain
2221@available ( iOS 13 , tvOS 13 , macOS 10 . 15 , macCatalyst 13 , watchOS 7 , * )
23- class FakeAuthKeychainStorage : AuthKeychainStorage {
22+ final class FakeAuthKeychainStorage : AuthKeychainStorage {
2423 // Fake Keychain. It's a dictionary, keyed by service name, for each key-value store dictionary
25- private var fakeKeychain : [ String : [ String : Any ] ] = [ : ]
24+ private let fakeKeychain = FIRAllocatedUnfairLock < [ String : [ String : Any ] ] > ( initialState : [ : ] )
2625
27- private var fakeLegacyKeychain : [ String : Any ] = [ : ]
26+ private let fakeLegacyKeychain = FIRAllocatedUnfairLock < [ String : Any ] > ( initialState : [ : ] )
2827
2928 func get( query: [ String : Any ] , result: inout AnyObject ? ) -> OSStatus {
3029 if let service = queryService ( query) {
31- guard let value = fakeKeychain [ service] ? [ queryKey ( query) ] else {
30+ guard let value = fakeKeychain. value ( ) [ service] ? [ queryKey ( query) ] else {
3231 return errSecItemNotFound
3332 }
3433 let returnArrayofDictionary = [ [ kSecValueData as String : value] ]
3534 result = returnArrayofDictionary as AnyObject
3635 return noErr
3736 } else {
38- guard let value = fakeLegacyKeychain [ queryKey ( query) ] else {
37+ guard let value = fakeLegacyKeychain. value ( ) [ queryKey ( query) ] else {
3938 return errSecItemNotFound
4039 }
4140 let returnArrayofDictionary = [ [ kSecValueData as String : value] ]
@@ -46,9 +45,9 @@ class FakeAuthKeychainStorage: AuthKeychainStorage {
4645
4746 func add( query: [ String : Any ] ) -> OSStatus {
4847 if let service = queryService ( query) {
49- fakeKeychain [ service] ? [ queryKey ( query) ] = query [ kSecValueData as String ]
48+ fakeKeychain. withLock { $0 [ service] ? [ queryKey ( query) ] = query [ kSecValueData as String ] }
5049 } else {
51- fakeLegacyKeychain [ queryKey ( query) ] = query [ kSecValueData as String ]
50+ fakeLegacyKeychain. withLock { $0 [ queryKey ( query) ] = query [ kSecValueData as String ] }
5251 }
5352 return noErr
5453 }
@@ -59,9 +58,9 @@ class FakeAuthKeychainStorage: AuthKeychainStorage {
5958
6059 @discardableResult func delete( query: [ String : Any ] ) -> OSStatus {
6160 if let service = queryService ( query) {
62- fakeKeychain [ service] ? [ queryKey ( query) ] = nil
61+ fakeKeychain. withLock { $0 [ service] ? [ queryKey ( query) ] = nil }
6362 } else {
64- fakeLegacyKeychain [ queryKey ( query) ] = nil
63+ fakeLegacyKeychain. withLock { $0 [ queryKey ( query) ] = nil }
6564 }
6665 return noErr
6766 }
@@ -79,8 +78,10 @@ class FakeAuthKeychainStorage: AuthKeychainStorage {
7978 guard let service = query [ kSecAttrService as String ] as? String else {
8079 return nil
8180 }
82- if fakeKeychain [ service] == nil {
83- fakeKeychain [ service] = [ : ]
81+ fakeKeychain. withLock { fakeKeychain in
82+ if fakeKeychain [ service] == nil {
83+ fakeKeychain [ service] = [ : ]
84+ }
8485 }
8586 return service
8687 }
0 commit comments