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

[iOS][Credential-Provider] Credential Model

Credential protocol to be used independently of the type of underlying
object. This way we can switch them easily to managed objects, if
archivable objects are not fast enough for searching / loading.

Bug: 1045456
Change-Id: I3e97535b19ba33e2304ec72dee36cd5569b70980
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2120581
Commit-Queue: Javier Ernesto Flores Robles <javierrobles@chromium.org>
Reviewed-by: default avatarOlivier Robin <olivierrobin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#753615}
parent 363dc227
# Copyright 2020 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/buildflag_header.gni")
import("//build/config/ios/ios_sdk.gni")
source_set("credential_provider") {
configs += [ "//build/config/compiler:enable_arc" ]
sources = [
"archivable_credential.h",
"archivable_credential.mm",
]
deps = [ ":ui" ]
libs = [ "Foundation.framework" ]
}
source_set("ui") {
configs += [ "//build/config/compiler:enable_arc" ]
sources = [ "credential.h" ]
libs = [ "Foundation.framework" ]
}
source_set("unit_tests") {
configs += [ "//build/config/compiler:enable_arc" ]
testonly = true
sources = [ "archivable_credential_unittest.mm" ]
deps = [
":credential_provider",
"//base/test:test_support",
"//testing/gtest",
]
}
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IOS_CHROME_COMMON_CREDENTIAL_PROVIDER_ARCHIVABLE_CREDENTIAL_H_
#define IOS_CHROME_COMMON_CREDENTIAL_PROVIDER_ARCHIVABLE_CREDENTIAL_H_
#import <Foundation/Foundation.h>
#import "ios/chrome/common/credential_provider/credential.h"
@interface ArchivableCredential : NSObject <Credential, NSSecureCoding>
- (instancetype)initWithFavicon:(NSString*)favicon
keychainIdentifier:(NSString*)keychainIdentifier
rank:(int64_t)rank
recordIdentifier:(NSString*)recordIdentifier
serviceIdentifier:(NSString*)serviceIdentifier
serviceName:(NSString*)serviceName
user:(NSString*)user
validationIdentifier:(NSString*)validationIdentifier
NS_DESIGNATED_INITIALIZER;
- (instancetype)init NS_UNAVAILABLE;
@end
#endif // IOS_CHROME_COMMON_CREDENTIAL_PROVIDER_ARCHIVABLE_CREDENTIAL_H_
// Copyright 2020 The Chromium Authors. All rights reserved.
// 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/archivable_credential.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
// Keys used to serialize properties.
NSString* const kACFaviconKey = @"favicon";
NSString* const kACKeychainIdentifierKey = @"keychainIdentifier";
NSString* const kACRankKey = @"rank";
NSString* const kACRecordIdentifierKey = @"recordIdentifier";
NSString* const kACServiceIdentifierKey = @"serviceIdentifier";
NSString* const kACServiceNameKey = @"serviceName";
NSString* const kACUserKey = @"user";
NSString* const kACValidationIdentifierKey = @"validationIdentifier";
} // namespace
@implementation ArchivableCredential
@synthesize favicon = _favicon;
@synthesize keychainIdentifier = _keychainIdentifier;
@synthesize rank = _rank;
@synthesize recordIdentifier = _recordIdentifier;
@synthesize serviceIdentifier = _serviceIdentifier;
@synthesize serviceName = _serviceName;
@synthesize user = _user;
@synthesize validationIdentifier = _validationIdentifier;
- (instancetype)initWithFavicon:(NSString*)favicon
keychainIdentifier:(NSString*)keychainIdentifier
rank:(int64_t)rank
recordIdentifier:(NSString*)recordIdentifier
serviceIdentifier:(NSString*)serviceIdentifier
serviceName:(NSString*)serviceName
user:(NSString*)user
validationIdentifier:(NSString*)validationIdentifier {
self = [super init];
if (self) {
_favicon = favicon;
_keychainIdentifier = keychainIdentifier;
_rank = rank;
_recordIdentifier = recordIdentifier;
_serviceIdentifier = serviceIdentifier;
_serviceName = serviceName;
_user = user;
_validationIdentifier = validationIdentifier;
}
return self;
}
#pragma mark - NSSecureCoding
+ (BOOL)supportsSecureCoding {
return YES;
}
- (void)encodeWithCoder:(NSCoder*)coder {
[coder encodeObject:self.favicon forKey:kACFaviconKey];
[coder encodeObject:self.keychainIdentifier forKey:kACKeychainIdentifierKey];
[coder encodeInt64:self.rank forKey:kACRankKey];
[coder encodeObject:self.recordIdentifier forKey:kACRecordIdentifierKey];
[coder encodeObject:self.serviceIdentifier forKey:kACServiceIdentifierKey];
[coder encodeObject:self.serviceName forKey:kACServiceNameKey];
[coder encodeObject:self.user forKey:kACUserKey];
[coder encodeObject:self.validationIdentifier
forKey:kACValidationIdentifierKey];
}
- (instancetype)initWithCoder:(NSCoder*)coder {
return [self
initWithFavicon:[coder decodeObjectForKey:kACFaviconKey]
keychainIdentifier:[coder decodeObjectForKey:kACKeychainIdentifierKey]
rank:[coder decodeInt64ForKey:kACRankKey]
recordIdentifier:[coder decodeObjectForKey:kACRecordIdentifierKey]
serviceIdentifier:[coder decodeObjectForKey:kACServiceIdentifierKey]
serviceName:[coder decodeObjectForKey:kACServiceNameKey]
user:[coder decodeObjectForKey:kACUserKey]
validationIdentifier:[coder
decodeObjectForKey:kACValidationIdentifierKey]];
}
@end
// Copyright 2020 The Chromium Authors. All rights reserved.
// 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/archivable_credential.h"
#import "base/test/ios/wait_util.h"
#include "testing/gtest_mac.h"
#include "testing/platform_test.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
using ArchivableCredentialTest = PlatformTest;
ArchivableCredential* TestCredential() {
return [[ArchivableCredential alloc] initWithFavicon:@"favicon"
keychainIdentifier:@"keychainIdentifier"
rank:5
recordIdentifier:@"recordIdentifier"
serviceIdentifier:@"serviceIdentifier"
serviceName:@"serviceName"
user:@"user"
validationIdentifier:@"validationIdentifier"];
}
// Tests that an ArchivableCredential can be created.
TEST_F(ArchivableCredentialTest, create) {
ArchivableCredential* credential =
[[ArchivableCredential alloc] initWithFavicon:@"favicon"
keychainIdentifier:@"keychainIdentifier"
rank:5
recordIdentifier:@"recordIdentifier"
serviceIdentifier:@"serviceIdentifier"
serviceName:@"serviceName"
user:@"user"
validationIdentifier:@"validationIdentifier"];
EXPECT_TRUE(credential);
}
// Tests that an ArchivableCredential can be converted to NSData.
TEST_F(ArchivableCredentialTest, createData) {
ArchivableCredential* credential = TestCredential();
EXPECT_TRUE(credential);
NSError* error = nil;
NSData* data = [NSKeyedArchiver archivedDataWithRootObject:credential
requiringSecureCoding:YES
error:&error];
EXPECT_TRUE(data);
EXPECT_FALSE(error);
}
// Tests that an ArchivableCredential can be retrieved from NSData.
TEST_F(ArchivableCredentialTest, retrieveData) {
ArchivableCredential* credential = TestCredential();
NSError* error = nil;
NSData* data = [NSKeyedArchiver archivedDataWithRootObject:credential
requiringSecureCoding:YES
error:&error];
EXPECT_TRUE(data);
EXPECT_FALSE(error);
ArchivableCredential* unarchivedCredential =
[NSKeyedUnarchiver unarchivedObjectOfClass:[ArchivableCredential class]
fromData:data
error:&error];
EXPECT_TRUE(unarchivedCredential);
EXPECT_TRUE(
[unarchivedCredential isKindOfClass:[ArchivableCredential class]]);
EXPECT_NSEQ(credential.favicon, unarchivedCredential.favicon);
EXPECT_NSEQ(credential.keychainIdentifier,
unarchivedCredential.keychainIdentifier);
EXPECT_EQ(credential.rank, unarchivedCredential.rank);
EXPECT_NSEQ(credential.recordIdentifier,
unarchivedCredential.recordIdentifier);
EXPECT_NSEQ(credential.serviceIdentifier,
unarchivedCredential.serviceIdentifier);
EXPECT_NSEQ(credential.serviceName, unarchivedCredential.serviceName);
EXPECT_NSEQ(credential.user, unarchivedCredential.user);
EXPECT_NSEQ(credential.validationIdentifier,
unarchivedCredential.validationIdentifier);
}
}
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IOS_CHROME_COMMON_CREDENTIAL_PROVIDER_CREDENTIAL_H_
#define IOS_CHROME_COMMON_CREDENTIAL_PROVIDER_CREDENTIAL_H_
#import <Foundation/Foundation.h>
// Contains the data for a Credential that can be used with iOS AutoFill.
@protocol Credential
// Associated favicon name.
@property(nonatomic, readonly) NSString* favicon;
// Identifier used to look up the secret in the Keychain.
@property(nonatomic, readonly) NSString* keychainIdentifier;
// Importance ranking of this credential.
@property(nonatomic, readonly) int64_t rank;
// Identifier to use with ASCredentialIdentityStore.
@property(nonatomic, readonly) NSString* recordIdentifier;
// Service identifier of this credential. Should match
// ASCredentialServiceIdentifier.
@property(nonatomic, readonly) NSString* serviceIdentifier;
// Human readable name of the associated service.
@property(nonatomic, readonly) NSString* serviceName;
// Username of the service.
@property(nonatomic, readonly) NSString* user;
// ID to validate the credential before providing it to the system.
@property(nonatomic, readonly) NSString* validationIdentifier;
@end
#endif // IOS_CHROME_COMMON_CREDENTIAL_PROVIDER_CREDENTIAL_H_
...@@ -20,6 +20,7 @@ source_set("ui") { ...@@ -20,6 +20,7 @@ source_set("ui") {
"stale_credentials_view_controller.mm", "stale_credentials_view_controller.mm",
] ]
deps = [ deps = [
"//ios/chrome/common/credential_provider",
"//ios/chrome/common/ui/colors", "//ios/chrome/common/ui/colors",
"//ios/chrome/common/ui/confirmation_alert", "//ios/chrome/common/ui/confirmation_alert",
"//ios/chrome/credential_provider_extension/ui/resources", "//ios/chrome/credential_provider_extension/ui/resources",
......
...@@ -316,6 +316,7 @@ test("ios_chrome_unittests") { ...@@ -316,6 +316,7 @@ test("ios_chrome_unittests") {
"//ios/chrome/browser/web_state_list/web_usage_enabler:unit_tests", "//ios/chrome/browser/web_state_list/web_usage_enabler:unit_tests",
"//ios/chrome/browser/webui:unit_tests", "//ios/chrome/browser/webui:unit_tests",
"//ios/chrome/common:unit_tests", "//ios/chrome/common:unit_tests",
"//ios/chrome/common/credential_provider:unit_tests",
"//ios/chrome/common/ui/reauthentication:unit_tests", "//ios/chrome/common/ui/reauthentication:unit_tests",
"//ios/chrome/common/ui/util:unit_tests", "//ios/chrome/common/ui/util:unit_tests",
"//ios/chrome/content_widget_extension:unit_tests", "//ios/chrome/content_widget_extension:unit_tests",
......
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