Skip to content

Commit

Permalink
Merged PR 9144: Updates iOS sample for the 0.12 release.
Browse files Browse the repository at this point in the history
This addresses changes needed for the platform initialization / application registration updates in the 0.12 release.
  • Loading branch information
darkorm committed Jun 20, 2018
1 parent 5ba1531 commit f4ee8c4
Show file tree
Hide file tree
Showing 18 changed files with 136 additions and 90 deletions.
37 changes: 0 additions & 37 deletions iOS/samples/account-provider-sample/CMakeLists.txt

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ typedef NS_ENUM(NSInteger, AADMSAAccountProviderSignInState)
// only the first scope in scopes[] passed to for getAccessTokenForUserAccountIdAsync: and onAccessTokenError:, is used
//
// msaClientId is a guid from the app's registration in the msa apps portal
// msaScopeOverrides is a map for the app to specify special scopes to replace the default ones
// aadApplicationId is a guid from the app's registration in the azure portal
// aadRedirectUri is a Uri specified in the azure portal
@interface AADMSAAccountProvider : NSObject <MCDUserAccountProvider>
Expand All @@ -33,6 +34,7 @@ typedef NS_ENUM(NSInteger, AADMSAAccountProviderSignInState)
@property(readonly, nonatomic, copy, nonnull) NSString* aadApplicationId;

- (nullable instancetype)initWithMsaClientId:(nonnull NSString*)msaClientId
msaScopeOverrides:(nullable NSDictionary<NSString*, NSArray<NSString*>*>*) scopes
aadApplicationId:(nonnull NSString*)aadApplicationId
aadRedirectUri:(nonnull NSURL*)aadRedirectUri;
- (void)signInMSAWithCompletionCallback:(nonnull SampleAccountProviderCompletionBlock)callback;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@
* Follows OAuth2.0 protocol, but automatically refreshes tokens when they are close to expiring.
*/
@interface MSAAccountProvider : NSObject <SingleUserAccountProvider>

// @brief clientId is a guid from the app's registration in the msa portal
- (nullable instancetype)initWithClientId:(nonnull NSString*)clientId;
// scopeOverrides is a map for the app to specify special scopes to replace the default ones
- (nullable instancetype)initWithClientId:(nonnull NSString*)clientId
scopeOverrides:(nullable NSDictionary<NSString*, NSArray<NSString*>*>*)scopes;

@property(readonly, nonatomic, copy, nonnull) NSString* clientId;

@end
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@ @implementation AADMSAAccountProvider
@synthesize userAccountChanged = _userAccountChanged;

- (instancetype)initWithMsaClientId:(NSString*)msaClientId
msaScopeOverrides:(NSDictionary<NSString*, NSArray<NSString*>*>*)scopes
aadApplicationId:(NSString*)aadApplicationId
aadRedirectUri:(NSURL*)aadRedirectUri
{
if (self = [super init])
{
_userAccountChanged = [MCDUserAccountChangedEvent new];
_msaProvider = [[MSAAccountProvider alloc] initWithClientId:msaClientId];
_msaProvider = [[MSAAccountProvider alloc] initWithClientId:msaClientId scopeOverrides:scopes];
_aadProvider = [[AADAccountProvider alloc] initWithClientId:aadApplicationId redirectUri:aadRedirectUri];

if (_msaProvider.signedIn && _aadProvider.signedIn)
Expand Down
37 changes: 29 additions & 8 deletions iOS/samples/account-provider-sample/src/MSAAccountProvider.m
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,13 @@
// CDP's SDK currently requires authorization for all features, otherwise platform initialization will fail.
// As such, the user must sign in/consent for the following scopes. This may change to become more modular in the future.
static NSString* const MsaRequiredScopes = //
@"wl.offline_access+" // read and update user info at any time
@"ccs.ReadWrite+" // device commanding scope
@"dds.read+" // device discovery scope (discover other devices)
@"dds.register+" // device discovery scope (allow discovering this device)
@"wns.connect+" // notification scope
@"wl.offline_access+" // read and update user info at any time
@"https://activity.windows.com/UserActivity.ReadWrite.CreatedByApp+" // user activities scope
@"asimovrome.telemetry"; // asimov token scope
@"wns.connect+" // push notification scope
@"asimovrome.telemetry+" // asimov token scope
@"https://activity.windows.com/UserActivity.ReadWrite.CreatedByApp"; // default useractivities scope

// OAuth URLs
static NSString* const MsaRedirectUrl = @"https://login.live.com/oauth20_desktop.srf";
Expand All @@ -88,9 +88,9 @@
@interface MSAAccountProvider () <MSATokenCacheDelegate, UIWebViewDelegate>
{
NSString* _clientId;
NSDictionary<NSString*, NSArray<NSString*>*>* _scopeOverrides;
MCDUserAccount* _account;
MSATokenCache* _tokenCache;

BOOL _signInSignOutInProgress;
SampleAccountProviderCompletionBlock _signInSignOutCallback;
UIWebView* _webView;
Expand All @@ -102,12 +102,14 @@ @implementation MSAAccountProvider
@synthesize userAccountChanged = _userAccountChanged;

- (instancetype)initWithClientId:(NSString*)clientId
scopeOverrides:(NSDictionary<NSString*, NSArray<NSString*>*>*)scopes
{
NSLog(@"MSAAccountProvider initWithClientId");

if (self = [super init])
{
_clientId = clientId;
_clientId = [clientId copy];
_scopeOverrides = [scopes copy];

_tokenCache = [MSATokenCache cacheWithClientId:_clientId delegate:self];

Expand All @@ -130,6 +132,24 @@ - (instancetype)initWithClientId:(NSString*)clientId
}

#pragma mark - Private Helpers
- (NSString*)_getAuthScopes: (NSArray<NSString*>*) incoming
{
NSMutableArray<NSString*>* scopes = [NSMutableArray new];
for (NSString* scope in incoming)
{
NSArray<NSString*>* replacements = [_scopeOverrides objectForKey:scope];
if (replacements)
{
[scopes addObjectsFromArray:replacements];
}
else
{
[scopes addObject:scope];
}
}
return [scopes componentsJoinedByString:@"+"];
}

- (void)_raiseAccountChangedEvent
{
NSLog(@"Raise Account changed event");
Expand Down Expand Up @@ -275,8 +295,9 @@ - (void)signInWithCompletionCallback:(SampleAccountProviderCompletionBlock)signI
_signInSignOutInProgress = YES;

// issue request to sign in
NSArray* scopes = [MsaRequiredScopes componentsSeparatedByString:@"+"];
[self _loadWebRequest:[NSString stringWithFormat:@"%@?redirect_uri=%@&response_type=code&client_id=%@&scope=%@", MsaAuthorizeUrl,
MsaRedirectUrl, _clientId, MsaRequiredScopes]];
MsaRedirectUrl, _clientId, [self _getAuthScopes:scopes]]];
}
}

Expand Down Expand Up @@ -415,7 +436,7 @@ - (void)getAccessTokenForUserAccountIdAsync:(NSString*)accountId
@synchronized(self)
{
// check if access token cache already has a valid token
NSString* accessTokenScope = [scopes componentsJoinedByString:@"+"];
NSString* accessTokenScope = [self _getAuthScopes:scopes];

// clang-format off
[_tokenCache getAccessTokenForScopeAsync:accessTokenScope callback:^void(NSString* accessToken)
Expand Down
2 changes: 2 additions & 0 deletions iOS/samples/iOSSample/AppDataSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@
#import "InboundRequestLogger.h"
#import "MSAAccountProvider.h"
#import "NotificationProvider.h"
#import <ConnectedDevices/Core/MCDPlatform.h>
#import <Foundation/Foundation.h>

@interface AppDataSource : NSObject
+ (AppDataSource*)sharedInstance;
@property(nonatomic) NotificationProvider* notificationProvider;
@property(nonatomic) MSAAccountProvider* accountProvider;
@property(nonatomic) InboundRequestLogger* inboundRequestLogger;
@property(nonatomic) MCDPlatform* platform;
@end
4 changes: 3 additions & 1 deletion iOS/samples/iOSSample/AppDataSource.m
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ - (instancetype)init
// This sample provides the source files that are used to acquired the token under the 'Auth Provider' directory
// The only requirement is to obtain a valid OAuth token
// This sample shows one way it can be done; we are giving you the option to use the sample auth code or use your own
_accountProvider = [[MSAAccountProvider alloc] initWithClientId:CLIENT_ID];
// scopeOverrides allows you to override scopes that are requested by the auth provider. Apps do not normally need to override scopes.
NSDictionary<NSString*, NSArray<NSString*>*>* scopeOverrides = @{};
_accountProvider = [[MSAAccountProvider alloc] initWithClientId:CLIENT_ID scopeOverrides:scopeOverrides];

_inboundRequestLogger = [InboundRequestLogger new];
}
Expand Down
1 change: 0 additions & 1 deletion iOS/samples/iOSSample/AppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ - (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(N
}
else
{

// app run in background and received the push notification, app is launched by user tapping the alert view
[MCDNotificationReceiver receiveNotification:notificationInfo];
}
Expand Down
2 changes: 2 additions & 0 deletions iOS/samples/iOSSample/Auth Provider/AADMSAAccountProvider.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ typedef NS_ENUM(NSInteger, AADMSAAccountProviderSignInState)
// only the first scope in scopes[] passed to for getAccessTokenForUserAccountIdAsync: and onAccessTokenError:, is used
//
// msaClientId is a guid from the app's registration in the msa apps portal
// msaScopeOverrides is a map for the app to specify special scopes to replace the default ones
// aadApplicationId is a guid from the app's registration in the azure portal
// aadRedirectUri is a Uri specified in the azure portal
@interface AADMSAAccountProvider : NSObject <MCDUserAccountProvider>
Expand All @@ -33,6 +34,7 @@ typedef NS_ENUM(NSInteger, AADMSAAccountProviderSignInState)
@property(readonly, nonatomic, copy, nonnull) NSString* aadApplicationId;

- (nullable instancetype)initWithMsaClientId:(nonnull NSString*)msaClientId
msaScopeOverrides:(nullable NSDictionary<NSString*, NSArray<NSString*>*>*) scopes
aadApplicationId:(nonnull NSString*)aadApplicationId
aadRedirectUri:(nonnull NSURL*)aadRedirectUri;
- (void)signInMSAWithCompletionCallback:(nonnull SampleAccountProviderCompletionBlock)callback;
Expand Down
3 changes: 2 additions & 1 deletion iOS/samples/iOSSample/Auth Provider/AADMSAAccountProvider.m
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@ @implementation AADMSAAccountProvider
@synthesize userAccountChanged = _userAccountChanged;

- (instancetype)initWithMsaClientId:(NSString*)msaClientId
msaScopeOverrides:(NSDictionary<NSString*, NSArray<NSString*>*>*)scopes
aadApplicationId:(NSString*)aadApplicationId
aadRedirectUri:(NSURL*)aadRedirectUri
{
if (self = [super init])
{
_userAccountChanged = [MCDUserAccountChangedEvent new];
_msaProvider = [[MSAAccountProvider alloc] initWithClientId:msaClientId];
_msaProvider = [[MSAAccountProvider alloc] initWithClientId:msaClientId scopeOverrides:scopes];
_aadProvider = [[AADAccountProvider alloc] initWithClientId:aadApplicationId redirectUri:aadRedirectUri];

if (_msaProvider.signedIn && _aadProvider.signedIn)
Expand Down
7 changes: 6 additions & 1 deletion iOS/samples/iOSSample/Auth Provider/MSAAccountProvider.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@
* Follows OAuth2.0 protocol, but automatically refreshes tokens when they are close to expiring.
*/
@interface MSAAccountProvider : NSObject <SingleUserAccountProvider>

// @brief clientId is a guid from the app's registration in the msa portal
- (nullable instancetype)initWithClientId:(nonnull NSString*)clientId;
// scopeOverrides is a map for the app to specify special scopes to replace the default ones
- (nullable instancetype)initWithClientId:(nonnull NSString*)clientId
scopeOverrides:(nullable NSDictionary<NSString*, NSArray<NSString*>*>*)scopes;

@property(readonly, nonatomic, copy, nonnull) NSString* clientId;

@end
37 changes: 29 additions & 8 deletions iOS/samples/iOSSample/Auth Provider/MSAAccountProvider.m
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,13 @@
// CDP's SDK currently requires authorization for all features, otherwise platform initialization will fail.
// As such, the user must sign in/consent for the following scopes. This may change to become more modular in the future.
static NSString* const MsaRequiredScopes = //
@"wl.offline_access+" // read and update user info at any time
@"ccs.ReadWrite+" // device commanding scope
@"dds.read+" // device discovery scope (discover other devices)
@"dds.register+" // device discovery scope (allow discovering this device)
@"wns.connect+" // notification scope
@"wl.offline_access+" // read and update user info at any time
@"https://activity.windows.com/UserActivity.ReadWrite.CreatedByApp+" // user activities scope
@"asimovrome.telemetry"; // asimov token scope
@"wns.connect+" // push notification scope
@"asimovrome.telemetry+" // asimov token scope
@"https://activity.windows.com/UserActivity.ReadWrite.CreatedByApp"; // default useractivities scope

// OAuth URLs
static NSString* const MsaRedirectUrl = @"https://login.live.com/oauth20_desktop.srf";
Expand All @@ -88,9 +88,9 @@
@interface MSAAccountProvider () <MSATokenCacheDelegate, UIWebViewDelegate>
{
NSString* _clientId;
NSDictionary<NSString*, NSArray<NSString*>*>* _scopeOverrides;
MCDUserAccount* _account;
MSATokenCache* _tokenCache;

BOOL _signInSignOutInProgress;
SampleAccountProviderCompletionBlock _signInSignOutCallback;
UIWebView* _webView;
Expand All @@ -102,12 +102,14 @@ @implementation MSAAccountProvider
@synthesize userAccountChanged = _userAccountChanged;

- (instancetype)initWithClientId:(NSString*)clientId
scopeOverrides:(NSDictionary<NSString*, NSArray<NSString*>*>*)scopes
{
NSLog(@"MSAAccountProvider initWithClientId");

if (self = [super init])
{
_clientId = clientId;
_clientId = [clientId copy];
_scopeOverrides = [scopes copy];

_tokenCache = [MSATokenCache cacheWithClientId:_clientId delegate:self];

Expand All @@ -130,6 +132,24 @@ - (instancetype)initWithClientId:(NSString*)clientId
}

#pragma mark - Private Helpers
- (NSString*)_getAuthScopes: (NSArray<NSString*>*) incoming
{
NSMutableArray<NSString*>* scopes = [NSMutableArray new];
for (NSString* scope in incoming)
{
NSArray<NSString*>* replacements = [_scopeOverrides objectForKey:scope];
if (replacements)
{
[scopes addObjectsFromArray:replacements];
}
else
{
[scopes addObject:scope];
}
}
return [scopes componentsJoinedByString:@"+"];
}

- (void)_raiseAccountChangedEvent
{
NSLog(@"Raise Account changed event");
Expand Down Expand Up @@ -275,8 +295,9 @@ - (void)signInWithCompletionCallback:(SampleAccountProviderCompletionBlock)signI
_signInSignOutInProgress = YES;

// issue request to sign in
NSArray* scopes = [MsaRequiredScopes componentsSeparatedByString:@"+"];
[self _loadWebRequest:[NSString stringWithFormat:@"%@?redirect_uri=%@&response_type=code&client_id=%@&scope=%@", MsaAuthorizeUrl,
MsaRedirectUrl, _clientId, MsaRequiredScopes]];
MsaRedirectUrl, _clientId, [self _getAuthScopes:scopes]]];
}
}

Expand Down Expand Up @@ -415,7 +436,7 @@ - (void)getAccessTokenForUserAccountIdAsync:(NSString*)accountId
@synchronized(self)
{
// check if access token cache already has a valid token
NSString* accessTokenScope = [scopes componentsJoinedByString:@"+"];
NSString* accessTokenScope = [self _getAuthScopes:scopes];

// clang-format off
[_tokenCache getAccessTokenForScopeAsync:accessTokenScope callback:^void(NSString* accessToken)
Expand Down
2 changes: 1 addition & 1 deletion iOS/samples/iOSSample/IdentityViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#import "AppDataSource.h"
#import "MSAAccountProvider.h"
#import "MainNavigationController.h"
#import <ConnectedDevices/Core/MCDApplicationRegistrationBuilder.h>
#import <ConnectedDevices/Commanding/MCDRemoteSystemApplicationRegistrationBuilder.h>
#import <ConnectedDevices/Core/MCDPlatform.h>
#import <UIKit/UIKit.h>

Expand Down
2 changes: 1 addition & 1 deletion iOS/samples/iOSSample/NotificationProvider.m
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//

#import "NotificationProvider.h"
#import "ConnectedDevices/Core/MCDPlatform.h"
#import <ConnectedDevices/Core/MCDPlatform.h>
#import <UIKit/UIKit.h>

@implementation NotificationProvider
Expand Down
2 changes: 1 addition & 1 deletion iOS/samples/iOSSample/RemoteSystemViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#import "RemoteSystemViewController.h"
#import "IdentityViewController.h"
#import "LaunchAndMessageViewController.h"
#import <ConnectedDevices/Core/MCDApplicationRegistrationBuilder.h>
#import <ConnectedDevices/Commanding/MCDRemoteSystemApplicationRegistrationBuilder.h>
#import <ConnectedDevices/Core/MCDPlatform.h>
#import <ConnectedDevices/Discovery/MCDRemoteSystemApplication.h>
#import <ConnectedDevices/Discovery/MCDRemoteSystemAuthorizationKindFilter.h>
Expand Down
Loading

0 comments on commit f4ee8c4

Please sign in to comment.