Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to set keychain service and access group #1155

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions AWSCore/Authentication/AWSCredentialsProvider.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,21 @@ typedef NS_ENUM(NSInteger, AWSCognitoCredentialsProviderErrorType) {
identityPoolId:(NSString *)identityPoolId
identityProviderManager:(nullable id<AWSIdentityProviderManager>)identityProviderManager;

/**
Initializer for credentials provider with enhanced authentication flow. This is the recommended method for first time Amazon Cognito developers. Will create an instance of `AWSEnhancedCognitoIdentityProvider`.

@param regionType The region in which your identity pool exists.
@param identityPoolId The identity pool id for this provider. Value is used to communicate with Amazon Cognito as well as namespace values stored in the keychain.
@param identityProviderManager An object that conforms to the `AWSIdentityProviderManager` protocol. It should return a valid `login` dictionary when requested. Can be nil if identity is unauthenticated.
@param keychainService A key whose value is a string indicating the keychain service to store credentials.
@param keychainAccessGroup A key whose value is a string indicating the keychaing access group to store credentials.
*/
- (instancetype)initWithRegionType:(AWSRegionType)regionType
identityPoolId:(NSString *)identityPoolId
identityProviderManager:(nullable id<AWSIdentityProviderManager>)identityProviderManager
keychainService:(nullable NSString *)keychainService
keychainAccessGroup:(nullable NSString *)keychainAccessGroup;

/**
Initializer for credentials provider with pre-created `AWSCognitoCredentialsProviderHelper`. Use this method when using developer authenticated identities.

Expand All @@ -211,6 +226,19 @@ typedef NS_ENUM(NSInteger, AWSCognitoCredentialsProviderErrorType) {
- (instancetype)initWithRegionType:(AWSRegionType)regionType
identityProvider:(id<AWSCognitoCredentialsProviderHelper>)identityProvider;

/**
Initializer for credentials provider with pre-created `AWSCognitoCredentialsProviderHelper`. Use this method when using developer authenticated identities.

@param regionType The region in which your identity pool exists.
@param identityPoolId The identity pool id for this provider. Value is used to communicate with Amazon Cognito as well as namespace values stored in the keychain.
@param keychainService A key whose value is a string indicating the keychain service to store credentials.
@param keychainAccessGroup A key whose value is a string indicating the keychaing access group to store credentials.
*/
- (instancetype)initWithRegionType:(AWSRegionType)regionType
identityPoolId:(NSString *)identityPoolId
keychainService:(nullable NSString *)keychainService
keychainAccessGroup:(nullable NSString *)keychainAccessGroup;

/**
Initializer for credentials provider with pre-created `AWSCognitoCredentialsProviderHelper`. Only use this method if you need to set your IAM roles client side and use developer authenticated identities

Expand Down
78 changes: 70 additions & 8 deletions AWSCore/Authentication/AWSCredentialsProvider.m
Original file line number Diff line number Diff line change
Expand Up @@ -288,15 +288,39 @@ - (instancetype)initWithRegionType:(AWSRegionType)regionType
[self setUpWithRegionType:regionType
identityProvider:identityProvider
unauthRoleArn:nil
authRoleArn:nil];
authRoleArn:nil
keychainService:nil
keychainAccessGroup:nil];
}

return self;
}

- (instancetype)initWithRegionType:(AWSRegionType)regionType
identityPoolId:(NSString *)identityPoolId
identityProviderManager:(nullable id<AWSIdentityProviderManager>)identityProviderManager {
keychainService:(nullable NSString *)keychainService
keychainAccessGroup:(nullable NSString *)keychainAccessGroup {
if (self = [super init]) {
AWSCognitoCredentialsProviderHelper *identityProvider = [[AWSCognitoCredentialsProviderHelper alloc] initWithRegionType:regionType
identityPoolId:identityPoolId
useEnhancedFlow:YES
identityProviderManager:nil];
[self setUpWithRegionType:regionType
identityProvider:identityProvider
unauthRoleArn:nil
authRoleArn:nil
keychainService:keychainService
keychainAccessGroup:keychainAccessGroup];
}

return self;
}

- (instancetype)initWithRegionType:(AWSRegionType)regionType
identityPoolId:(NSString *)identityPoolId
identityProviderManager:(nullable id<AWSIdentityProviderManager>)identityProviderManager
keychainService:(nullable NSString *)keychainService
keychainAccessGroup:(nullable NSString *)keychainAccessGroup {
if (self = [super init]) {
AWSCognitoCredentialsProviderHelper *identityProvider = [[AWSCognitoCredentialsProviderHelper alloc] initWithRegionType:regionType
identityPoolId:identityPoolId
Expand All @@ -305,19 +329,42 @@ - (instancetype)initWithRegionType:(AWSRegionType)regionType
[self setUpWithRegionType:regionType
identityProvider:identityProvider
unauthRoleArn:nil
authRoleArn:nil];
authRoleArn:nil
keychainService:keychainService
keychainAccessGroup:keychainAccessGroup];
}

return self;
}

- (instancetype)initWithRegionType:(AWSRegionType)regionType
identityPoolId:(NSString *)identityPoolId
identityProviderManager:(nullable id<AWSIdentityProviderManager>)identityProviderManager {
if (self = [super init]) {
AWSCognitoCredentialsProviderHelper *identityProvider = [[AWSCognitoCredentialsProviderHelper alloc] initWithRegionType:regionType
identityPoolId:identityPoolId
useEnhancedFlow:YES
identityProviderManager:identityProviderManager];
[self setUpWithRegionType:regionType
identityProvider:identityProvider
unauthRoleArn:nil
authRoleArn:nil
keychainService:nil
keychainAccessGroup:nil];
}

return self;
}

- (instancetype)initWithRegionType:(AWSRegionType)regionType
identityProvider:(id<AWSCognitoCredentialsProviderHelper>)identityProvider {
if (self = [super init]) {
[self setUpWithRegionType:regionType
identityProvider:identityProvider
unauthRoleArn:nil
authRoleArn:nil];
authRoleArn:nil
keychainService:nil
keychainAccessGroup:nil];
}

return self;
Expand All @@ -331,7 +378,9 @@ - (instancetype)initWithRegionType:(AWSRegionType)regionType
[self setUpWithRegionType:regionType
identityProvider:identityProvider
unauthRoleArn:unauthRoleArn
authRoleArn:authRoleArn];
authRoleArn:authRoleArn
keychainService:nil
keychainAccessGroup:nil];
}

return self;
Expand All @@ -350,7 +399,9 @@ - (instancetype)initWithRegionType:(AWSRegionType)regionType
[self setUpWithRegionType:regionType
identityProvider:identityProvider
unauthRoleArn:unauthRoleArn
authRoleArn:authRoleArn];
authRoleArn:authRoleArn
keychainService:nil
keychainAccessGroup:nil];
}

return self;
Expand All @@ -359,7 +410,9 @@ - (instancetype)initWithRegionType:(AWSRegionType)regionType
- (void)setUpWithRegionType:(AWSRegionType)regionType
identityProvider:(id<AWSCognitoCredentialsProviderHelper>)identityProvider
unauthRoleArn:(NSString *)unauthRoleArn
authRoleArn:(NSString *)authRoleArn {
authRoleArn:(NSString *)authRoleArn
keychainService:(NSString *)keychainService
keychainAccessGroup:(NSString *)keychainAccessGroup {
_refreshExecutor = [AWSExecutor executorWithOperationQueue:[NSOperationQueue new]];
_refreshingCredentials = NO;
_semaphore = dispatch_semaphore_create(0);
Expand All @@ -370,7 +423,16 @@ - (void)setUpWithRegionType:(AWSRegionType)regionType
_useEnhancedFlow = !unauthRoleArn && !authRoleArn;

// initialize keychain - name spaced by app bundle and identity pool id
_keychain = [AWSUICKeyChainStore keyChainStoreWithService:[NSString stringWithFormat:@"%@.%@.%@", [NSBundle mainBundle].bundleIdentifier, [AWSCognitoCredentialsProvider class], identityProvider.identityPoolId]];

NSString *keyChainStoreService;
if (!keychainService) {
keyChainStoreService = [NSString stringWithFormat:@"%@.%@.%@", [NSBundle mainBundle].bundleIdentifier, [AWSCognitoCredentialsProvider class], identityProvider.identityPoolId];
} else {
keyChainStoreService = [NSString stringWithFormat:@"%@.%@.%@", keychainService, [AWSCognitoCredentialsProvider class], identityProvider.identityPoolId];
}

_keychain = [AWSUICKeyChainStore keyChainStoreWithService:keyChainStoreService
accessGroup:keychainAccessGroup];

// If the identity provider has an identity id, use it
if (identityProvider.identityId) {
Expand Down
8 changes: 7 additions & 1 deletion AWSCore/Service/AWSInfo.m
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@

static NSString *const AWSInfoRoot = @"AWS";
static NSString *const AWSInfoCredentialsProvider = @"CredentialsProvider";
static NSString *const AWSInfoKeychainService = @"KeychainService";
static NSString *const AWSInfoKeychainAccessGroup = @"KeychainAccessGroup";
static NSString *const AWSInfoRegion = @"Region";
static NSString *const AWSInfoUserAgent = @"UserAgent";
static NSString *const AWSInfoCognitoIdentity = @"CognitoIdentity";
Expand Down Expand Up @@ -90,9 +92,13 @@ - (instancetype)init {
NSDictionary <NSString *, id> *defaultCredentialsProviderDictionary = [[[_rootInfoDictionary objectForKey:AWSInfoCredentialsProvider] objectForKey:AWSInfoCognitoIdentity] objectForKey:AWSInfoDefault];
NSString *cognitoIdentityPoolID = [defaultCredentialsProviderDictionary objectForKey:AWSInfoCognitoIdentityPoolId];
AWSRegionType cognitoIdentityRegion = [[defaultCredentialsProviderDictionary objectForKey:AWSInfoRegion] aws_regionTypeValue];
NSString *keychainService = [defaultCredentialsProviderDictionary objectForKey:AWSInfoKeychainService];
NSString *keychainAccessGroup = [defaultCredentialsProviderDictionary objectForKey:AWSInfoKeychainAccessGroup];
if (cognitoIdentityPoolID && cognitoIdentityRegion != AWSRegionUnknown) {
_defaultCognitoCredentialsProvider = [[AWSCognitoCredentialsProvider alloc] initWithRegionType:cognitoIdentityRegion
identityPoolId:cognitoIdentityPoolID];
identityPoolId:cognitoIdentityPoolID
keychainService:keychainService
keychainAccessGroup:keychainAccessGroup];
}

_defaultRegion = [[defaultInfoDictionary objectForKey:AWSInfoRegion] aws_regionTypeValue];
Expand Down
35 changes: 35 additions & 0 deletions AWSCoreTests/AWSCognitoCredentialsProviderTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,41 @@ - (void)testEnhancedProviderKeychain {
}] waitUntilFinished];
}

- (void)testEnhancedProviderCustomKeychain {
AWSCognitoCredentialsProvider *provider1 = [[AWSCognitoCredentialsProvider alloc] initWithRegionType:AWSRegionUSEast1
identityPoolId:_identityPoolIdAuth
identityProviderManager:[AWSTestFacebookIdentityProvider new]
keychainService:@"TestKeychain"
keychainAccessGroup:@"TestAccessGroup"];

__block AWSCognitoCredentialsProvider *provider2 = nil;

[[[[[[provider1 credentials] continueWithSuccessBlock:^id(AWSTask *task) {
XCTAssertNil(task.error);
XCTAssertNotNil(provider1.identityId, @"Unable to get identityId");

provider2 = [[AWSCognitoCredentialsProvider alloc] initWithRegionType:AWSRegionUSEast1
identityPoolId:_identityPoolIdAuth];
return [provider2 getIdentityId];
}] continueWithSuccessBlock:^id _Nullable(AWSTask * _Nonnull task) {
return [provider2 credentials];
}] continueWithBlock:^id(AWSTask *task) {
XCTAssertNil(task.error);
XCTAssertEqualObjects(provider1.identityId, provider2.identityId);

AWSCredentials *credentials = task.result;
XCTAssertNotNil(credentials.accessKey);
XCTAssertNotNil(credentials.secretKey);
XCTAssertNotNil(credentials.sessionKey);
XCTAssertNotNil(credentials.expiration);

return [provider2 credentials];
}] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) {
XCTAssertNil(task.error);
return nil;
}] waitUntilFinished];
}

- (void)testEnhancedProviderFailure {
AWSTestFacebookIdentityProvider *identityProvider = [[AWSTestFacebookIdentityProvider alloc] initWithLoggedIn:YES];
AWSCognitoCredentialsProvider *provider = [[AWSCognitoCredentialsProvider alloc] initWithRegionType:AWSRegionUSEast1
Expand Down