Skip to content

Commit 9357b57

Browse files
author
Swasti Gupta
committed
Ensuing valid parantViewController is required for MSAL Interactive APIs
1 parent d23a6f1 commit 9357b57

File tree

3 files changed

+153
-9
lines changed

3 files changed

+153
-9
lines changed

MSAL/src/MSIDInteractiveRequestParameters+MSALRequest.m

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,18 @@ - (BOOL)fillWithWebViewParameters:(MSALWebviewParameters *)webParameters
3737
customWebView:(WKWebView *)customWebView
3838
error:(NSError **)error
3939
{
40+
if (webParameters == nil)
41+
{
42+
NSError *msidError = MSIDCreateError(MSIDErrorDomain, MSIDErrorInvalidDeveloperParameter, @"webviewParameters is a required parameter.", nil, nil, nil, nil, nil, YES);
43+
if (error) *error = msidError;
44+
return NO;
45+
}
46+
4047
__typeof__(webParameters.parentViewController) parentViewController = webParameters.parentViewController;
4148

42-
#if TARGET_OS_IPHONE
4349
if (parentViewController == nil)
4450
{
45-
NSError *msidError = MSIDCreateError(MSIDErrorDomain, MSIDErrorInvalidDeveloperParameter, @"parentViewController is a required parameter on iOS.", nil, nil, nil, nil, nil, YES);
51+
NSError *msidError = MSIDCreateError(MSIDErrorDomain, MSIDErrorInvalidDeveloperParameter, @"parentViewController is a required parameter.", nil, nil, nil, nil, nil, YES);
4652
if (error) *error = msidError;
4753
return NO;
4854
}
@@ -54,9 +60,10 @@ - (BOOL)fillWithWebViewParameters:(MSALWebviewParameters *)webParameters
5460
return NO;
5561
}
5662

63+
#if TARGET_OS_IPHONE
5764
self.presentationType = webParameters.presentationStyle;
5865
#endif
59-
66+
6067
self.parentViewController = parentViewController;
6168

6269
self.prefersEphemeralWebBrowserSession = webParameters.prefersEphemeralWebBrowserSession;

MSAL/src/public/MSALWebviewParameters.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ NS_ASSUME_NONNULL_BEGIN
4444
#pragma mark - Configuration options
4545

4646
/**
47-
The view controller to present from. If nil, MSAL will attempt to still proceed with the authentication, but the results will be unexpected.
48-
It is strongly recommended to provide a non-null parentViewController to avoid unexpected results.
47+
The view controller to present from. This property must be valid. If nil is provided, or if the view controller is not attached to a window (i.e., parentViewController.view.window is nil), MSAL will return an error and will not proceed with authentication.
48+
It is required to provide a valid parentViewController with a window to proceed with authentication.
4949
*/
50-
@property (nullable, weak, nonatomic) MSALViewController *parentViewController;
50+
@property (nonatomic, strong, nonnull) MSALViewController *parentViewController;
5151

5252
#if TARGET_OS_IPHONE
5353

@@ -83,10 +83,10 @@ NS_ASSUME_NONNULL_BEGIN
8383

8484
/**
8585
Creates an instance of MSALWebviewParameters with a provided parentViewController.
86-
@param parentViewController The view controller to present authorization UI from.
87-
@note parentViewController is mandatory on iOS 13+ and macOS 10.15+. Your app will experience unexpected results if parentViewController is not provided.
86+
@param parentViewController The view controller to present authorization UI from. This property must be valid
87+
@note parentViewController is mandatory on iOS 13+ and macOS 10.15+. If nil is provided, or if the view controller is not attached to a window (i.e., parentViewController.view.window is nil), MSAL will return an error and authentication will not proceed. It is required to provide a valid parentViewController with a window to proceed with authentication.
8888
*/
89-
- (nonnull instancetype)initWithAuthPresentationViewController:(MSALViewController *)parentViewController;
89+
- (nonnull instancetype)initWithAuthPresentationViewController:(nonnull MSALViewController *)parentViewController;
9090

9191

9292
/**

MSAL/test/unit/MSALPublicClientApplicationTests.m

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,143 @@ - (void)testAcquireTokenScopes
508508
application = nil;
509509
}
510510

511+
- (void)testAcquireTokenScopes_WithNilParentViewController_shouldReturnError
512+
{
513+
__auto_type authority = [@"https://login.microsoftonline.com/common" msalAuthority];
514+
515+
MSALPublicClientApplicationConfig *config = [[MSALPublicClientApplicationConfig alloc] initWithClientId:UNIT_TEST_CLIENT_ID redirectUri:nil authority:authority];
516+
config.sliceConfig = [MSALSliceConfig configWithSlice:@"slice" dc:@"dc"];
517+
518+
NSError *error = nil;
519+
__auto_type application = [[MSALPublicClientApplication alloc] initWithConfiguration:config
520+
error:&error];
521+
XCTAssertNotNil(application);
522+
XCTAssertNil(error);
523+
524+
__block dispatch_semaphore_t dsem = dispatch_semaphore_create(0);
525+
526+
[MSIDTestSwizzle instanceMethod:@selector(acquireToken:)
527+
class:[MSIDLocalInteractiveController class]
528+
block:(id)^(MSIDLocalInteractiveController *obj, MSIDRequestCompletionBlock completionBlock)
529+
{
530+
XCTAssertTrue([obj isKindOfClass:[MSIDLocalInteractiveController class]]);
531+
completionBlock(nil, nil);
532+
}];
533+
534+
MSALGlobalConfig.brokerAvailability = MSALBrokeredAvailabilityNone;
535+
536+
MSALViewController *parentViewController = nil;
537+
MSALWebviewParameters *webParameters = [[MSALWebviewParameters alloc] initWithAuthPresentationViewController:parentViewController];
538+
MSALInteractiveTokenParameters *parameters = [[MSALInteractiveTokenParameters alloc] initWithScopes:@[@"fakescope"]
539+
webviewParameters:webParameters];
540+
541+
[application acquireTokenWithParameters:parameters
542+
completionBlock:^(MSALResult *result, NSError *error)
543+
{
544+
XCTAssertNil(result);
545+
XCTAssertNotNil(error);
546+
547+
dispatch_semaphore_signal(dsem);
548+
}];
549+
550+
dispatch_semaphore_wait(dsem, DISPATCH_TIME_NOW);
551+
application = nil;
552+
}
553+
554+
- (void)testAcquireTokenScopes_WithInvalidParentViewController_shouldReturnError
555+
{
556+
__auto_type authority = [@"https://login.microsoftonline.com/common" msalAuthority];
557+
558+
MSALPublicClientApplicationConfig *config = [[MSALPublicClientApplicationConfig alloc] initWithClientId:UNIT_TEST_CLIENT_ID redirectUri:nil authority:authority];
559+
config.sliceConfig = [MSALSliceConfig configWithSlice:@"slice" dc:@"dc"];
560+
561+
NSError *error = nil;
562+
__auto_type application = [[MSALPublicClientApplication alloc] initWithConfiguration:config
563+
error:&error];
564+
XCTAssertNotNil(application);
565+
XCTAssertNil(error);
566+
567+
__block dispatch_semaphore_t dsem = dispatch_semaphore_create(0);
568+
569+
[MSIDTestSwizzle instanceMethod:@selector(acquireToken:)
570+
class:[MSIDLocalInteractiveController class]
571+
block:(id)^(MSIDLocalInteractiveController *obj, MSIDRequestCompletionBlock completionBlock)
572+
{
573+
XCTAssertTrue([obj isKindOfClass:[MSIDLocalInteractiveController class]]);
574+
completionBlock(nil, nil);
575+
}];
576+
577+
static dispatch_once_t once;
578+
static MSALViewController *controller;
579+
580+
#if TARGET_OS_IPHONE
581+
MSALGlobalConfig.brokerAvailability = MSALBrokeredAvailabilityNone;
582+
dispatch_once(&once, ^{
583+
controller = [UIViewController new];
584+
});
585+
#else
586+
dispatch_once(&once, ^{
587+
controller = [NSViewController new];
588+
});
589+
#endif
590+
591+
MSALWebviewParameters *webParameters = [[MSALWebviewParameters alloc] initWithAuthPresentationViewController:controller];
592+
MSALInteractiveTokenParameters *parameters = [[MSALInteractiveTokenParameters alloc] initWithScopes:@[@"fakescope"]
593+
webviewParameters:webParameters];
594+
595+
[application acquireTokenWithParameters:parameters
596+
completionBlock:^(MSALResult *result, NSError *error)
597+
{
598+
XCTAssertNil(result);
599+
XCTAssertNotNil(error);
600+
601+
dispatch_semaphore_signal(dsem);
602+
}];
603+
604+
dispatch_semaphore_wait(dsem, DISPATCH_TIME_NOW);
605+
application = nil;
606+
}
607+
608+
- (void)testAcquireTokenScopes_WithNilWebviewParameters_shouldReturnError
609+
{
610+
__auto_type authority = [@"https://login.microsoftonline.com/common" msalAuthority];
611+
612+
MSALPublicClientApplicationConfig *config = [[MSALPublicClientApplicationConfig alloc] initWithClientId:UNIT_TEST_CLIENT_ID redirectUri:nil authority:authority];
613+
config.sliceConfig = [MSALSliceConfig configWithSlice:@"slice" dc:@"dc"];
614+
615+
NSError *error = nil;
616+
__auto_type application = [[MSALPublicClientApplication alloc] initWithConfiguration:config
617+
error:&error];
618+
XCTAssertNotNil(application);
619+
XCTAssertNil(error);
620+
621+
__block dispatch_semaphore_t dsem = dispatch_semaphore_create(0);
622+
623+
[MSIDTestSwizzle instanceMethod:@selector(acquireToken:)
624+
class:[MSIDLocalInteractiveController class]
625+
block:(id)^(MSIDLocalInteractiveController *obj, MSIDRequestCompletionBlock completionBlock)
626+
{
627+
XCTAssertTrue([obj isKindOfClass:[MSIDLocalInteractiveController class]]);
628+
completionBlock(nil, nil);
629+
}];
630+
631+
MSALGlobalConfig.brokerAvailability = MSALBrokeredAvailabilityNone;
632+
MSALWebviewParameters *webParameters = nil;
633+
MSALInteractiveTokenParameters *parameters = [[MSALInteractiveTokenParameters alloc] initWithScopes:@[@"fakescope"]
634+
webviewParameters:webParameters];
635+
636+
[application acquireTokenWithParameters:parameters
637+
completionBlock:^(MSALResult *result, NSError *error)
638+
{
639+
XCTAssertNil(result);
640+
XCTAssertNotNil(error);
641+
642+
dispatch_semaphore_signal(dsem);
643+
}];
644+
645+
dispatch_semaphore_wait(dsem, DISPATCH_TIME_NOW);
646+
application = nil;
647+
}
511648
#pragma mark - Known authorities
512649

513650
- (void)testAcquireToken_whenKnownAADAuthority_shouldNotForceValidation

0 commit comments

Comments
 (0)