Commit b7895e29 authored by Javier Ernesto Flores Robles's avatar Javier Ernesto Flores Robles Committed by Commit Bot

[iOS][Credential-Provider] ArchivableStore Persistence

Implements persistence in ArchivableStore. Writing and loading is
done in the working operation queue.

Bug: 1045457
Change-Id: Id66a13e419b47aae9e67de3fc74ff43e69bb24f3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2126288
Commit-Queue: Javier Ernesto Flores Robles <javierrobles@chromium.org>
Reviewed-by: default avatarDavid Jean <djean@chromium.org>
Cr-Commit-Position: refs/heads/master@{#754602}
parent 9844f844
......@@ -74,7 +74,25 @@
}
- (void)saveDataWithCompletion:(void (^)(NSError* error))completion {
// TODO(crbug.com/1045456): Implement.
dispatch_barrier_async(self.workingQueue, ^{
if (!self.fileURL) {
return;
}
NSError* error = nil;
NSData* data =
[NSKeyedArchiver archivedDataWithRootObject:self.memoryStorage
requiringSecureCoding:YES
error:&error];
DCHECK(!error) << error.debugDescription.UTF8String;
if (error) {
completion(error);
return;
}
[data writeToURL:self.fileURL options:NSDataWritingAtomic error:&error];
DCHECK(!error) << error.debugDescription.UTF8String;
completion(error);
});
}
#pragma mark - Getters
......@@ -93,8 +111,33 @@
// Loads the store from disk.
- (NSMutableDictionary<NSString*, ArchivableCredential*>*)loadStorage {
// TODO(crbug.com/1045456): Implement.
return [[NSMutableDictionary alloc] init];
#if !defined(NDEBUG)
dispatch_assert_queue(self.workingQueue);
#endif // !defined(NDEBUG)
if (!self.fileURL) {
return [[NSMutableDictionary alloc] init];
}
NSError* error = nil;
[self.fileURL checkResourceIsReachableAndReturnError:&error];
if (error) {
if (error.code == NSFileReadNoSuchFileError) {
// File has not been created, return a fresh mutable set.
return [[NSMutableDictionary alloc] init];
}
NOTREACHED();
}
NSData* data = [NSData dataWithContentsOfURL:self.fileURL
options:0
error:&error];
DCHECK(!error) << error.debugDescription.UTF8String;
NSSet* classes = [NSSet setWithObjects:[ArchivableCredential class],
[NSMutableDictionary class], nil];
NSMutableDictionary<NSString*, ArchivableCredential*>* dictionary =
[NSKeyedUnarchiver unarchivedObjectOfClasses:classes
fromData:data
error:&error];
DCHECK(!error) << error.debugDescription.UTF8String;
return dictionary;
}
@end
......@@ -15,12 +15,29 @@
namespace {
using ArchivableCredentialStoreTest = PlatformTest;
using base::test::ios::WaitUntilConditionOrTimeout;
using base::test::ios::kWaitForFileOperationTimeout;
NSURL* testStorageFileURL() {
return nil;
NSURL* temporaryDirectory = [NSURL fileURLWithPath:NSTemporaryDirectory()];
NSURL* URL = [temporaryDirectory URLByAppendingPathComponent:@"credentials"];
return URL;
}
class ArchivableCredentialStoreTest : public PlatformTest {
protected:
void SetUp() override {
PlatformTest::SetUp();
[[NSFileManager defaultManager] removeItemAtURL:testStorageFileURL()
error:nil];
}
void TearDown() override {
PlatformTest::TearDown();
[[NSFileManager defaultManager] removeItemAtURL:testStorageFileURL()
error:nil];
}
};
ArchivableCredential* TestCredential() {
return [[ArchivableCredential alloc] initWithFavicon:@"favicon"
keychainIdentifier:@"keychainIdentifier"
......@@ -87,4 +104,31 @@ TEST_F(ArchivableCredentialStoreTest, remove) {
EXPECT_EQ(0u, credentialStore.credentials.count);
}
// Tests that ArchivableCredentialStore can save and retrieve from URLs.
TEST_F(ArchivableCredentialStoreTest, persist) {
ArchivableCredentialStore* credentialStore =
[[ArchivableCredentialStore alloc] initWithFileURL:testStorageFileURL()];
EXPECT_TRUE(credentialStore);
ArchivableCredential* credential = TestCredential();
[credentialStore addCredential:credential];
EXPECT_EQ(1u, credentialStore.credentials.count);
__block BOOL blockWaitCompleted = false;
[credentialStore saveDataWithCompletion:^(NSError* error) {
EXPECT_FALSE(error);
blockWaitCompleted = true;
}];
EXPECT_TRUE(WaitUntilConditionOrTimeout(kWaitForFileOperationTimeout, ^bool {
return blockWaitCompleted;
}));
ArchivableCredentialStore* freshCredentialStore =
[[ArchivableCredentialStore alloc] initWithFileURL:testStorageFileURL()];
EXPECT_TRUE(freshCredentialStore);
EXPECT_TRUE(freshCredentialStore.credentials);
EXPECT_EQ(1u, freshCredentialStore.credentials.count);
EXPECT_TRUE(
[credential isEqual:freshCredentialStore.credentials.firstObject]);
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment