| // Copyright 2021 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #import "ios/chrome/common/credential_provider/memory_credential_store.h" |
| |
| #import "base/apple/foundation_util.h" |
| #import "base/check.h" |
| #import "base/notreached.h" |
| #import "base/strings/sys_string_conversions.h" |
| #import "ios/chrome/common/credential_provider/archivable_credential.h" |
| |
| @interface MemoryCredentialStore () |
| |
| // Working queue used to sync the mutable set operations. |
| @property(nonatomic) dispatch_queue_t workingQueue; |
| |
| // The in-memory storage. |
| @property(nonatomic, strong) |
| NSMutableDictionary<NSString*, ArchivableCredential*>* memoryStorage; |
| |
| @end |
| |
| @implementation MemoryCredentialStore |
| |
| #pragma mark - Public |
| |
| - (instancetype)init { |
| self = [super init]; |
| if (self) { |
| _workingQueue = dispatch_queue_create(nullptr, DISPATCH_QUEUE_CONCURRENT); |
| } |
| return self; |
| } |
| |
| #pragma mark - CredentialStore |
| |
| - (NSArray<id<Credential>>*)credentials { |
| __block NSArray<id<Credential>>* credentials; |
| dispatch_sync(self.workingQueue, ^{ |
| credentials = [self.memoryStorage allValues]; |
| }); |
| return credentials; |
| } |
| |
| - (void)saveDataWithCompletion:(void (^)(NSError* error))completion { |
| // No-op. |
| completion(nil); |
| } |
| |
| - (void)removeAllCredentials { |
| dispatch_barrier_async(self.workingQueue, ^{ |
| [self.memoryStorage removeAllObjects]; |
| }); |
| } |
| |
| - (void)addCredential:(id<Credential>)credential { |
| DCHECK(credential.recordIdentifier) |
| << "credential must have a record identifier"; |
| dispatch_barrier_async(self.workingQueue, ^{ |
| self.memoryStorage[credential.recordIdentifier] = |
| base::apple::ObjCCastStrict<ArchivableCredential>(credential); |
| }); |
| } |
| |
| - (void)updateCredential:(id<Credential>)credential { |
| [self removeCredentialWithRecordIdentifier:credential.recordIdentifier]; |
| [self addCredential:credential]; |
| } |
| |
| - (void)removeCredentialWithRecordIdentifier:(NSString*)recordIdentifier { |
| DCHECK(recordIdentifier.length) << "Invalid `recordIdentifier` was passed."; |
| dispatch_barrier_async(self.workingQueue, ^{ |
| self.memoryStorage[recordIdentifier] = nil; |
| }); |
| } |
| |
| - (id<Credential>)credentialWithRecordIdentifier:(NSString*)recordIdentifier { |
| DCHECK(recordIdentifier.length); |
| __block id<Credential> credential; |
| dispatch_sync(self.workingQueue, ^{ |
| credential = self.memoryStorage[recordIdentifier]; |
| }); |
| return credential; |
| } |
| |
| #pragma mark - Getters |
| |
| - (NSMutableDictionary<NSString*, ArchivableCredential*>*)memoryStorage { |
| #if !defined(NDEBUG) |
| dispatch_assert_queue(self.workingQueue); |
| #endif // !defined(NDEBUG) |
| if (!_memoryStorage) { |
| _memoryStorage = [self loadStorage]; |
| } |
| return _memoryStorage; |
| } |
| |
| #pragma mark - Subclassing |
| |
| // Loads the store from disk. |
| - (NSMutableDictionary<NSString*, ArchivableCredential*>*)loadStorage { |
| return [[NSMutableDictionary alloc] init]; |
| } |
| |
| @end |