Skip to content

Commit

Permalink
add UTs to check fallback controlers' order
Browse files Browse the repository at this point in the history
  • Loading branch information
Kai Song authored and Kai Song committed Feb 22, 2025
1 parent 7721a7c commit 019d5d3
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 19 deletions.
12 changes: 6 additions & 6 deletions IdentityCore/src/controllers/MSIDRequestControllerFactory.m
Original file line number Diff line number Diff line change
Expand Up @@ -183,28 +183,28 @@ @implementation MSIDRequestControllerFactory
}
}

MSIDSilentController *localController = [[MSIDSilentController alloc] initWithRequestParameters:parameters
MSIDSilentController *silentController = [[MSIDSilentController alloc] initWithRequestParameters:parameters
forceRefresh:forceRefresh
tokenRequestProvider:tokenRequestProvider
fallbackInteractiveController:fallbackController
error:error];
if (!localController) return nil;
if (!silentController) return nil;

switch (skipLocalRt) {
case MSIDSilentControllerForceSkippingLocalRt:
localController.skipLocalRt = YES;
silentController.skipLocalRt = YES;
break;
case MSIDSilentControllerForceUsingLocalRt:
localController.skipLocalRt = NO;
silentController.skipLocalRt = NO;
break;
case MSIDSilentControllerUndefinedLocalRtUsage:
if (fallbackController) localController.skipLocalRt = YES;
if (fallbackController) silentController.skipLocalRt = YES;
break;
default:
break;
}

return localController;
return silentController;

}

Expand Down
16 changes: 3 additions & 13 deletions IdentityCore/src/util/MSIDXpcSingleSignOnProvider.m
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,7 @@ - (void)canPerformAuthorization:(NSURL *)url

@protocol MSIDXpcBrokerDispatcherProtocol <NSObject>

- (void)getBrokerInstanceEndpointWithRequestInfo:(NSDictionary <NSString *, id> * _Nullable)requestInfo
reply:(void (^)(NSXPCListenerEndpoint * _Nullable listenerEndpoint, NSDictionary * _Nullable params, NSError * _Nullable error))reply;
- (void)getBrokerInstanceEndpointWithReply:(void (^)(NSXPCListenerEndpoint * _Nullable listenerEndpoint, NSDictionary * _Nullable params, NSError * _Nullable error))reply;
@end

typedef void (^NSXPCListenerEndpointCompletionBlock)(id<MSIDXpcBrokerInstanceProtocol> _Nullable xpcService, NSXPCConnection * _Nullable directConnection, NSError *error);
Expand Down Expand Up @@ -114,16 +113,6 @@ - (void)handleRequestParam:(NSDictionary *)requestParam
[directConnection suspend];
[directConnection invalidate];

// MSIDBrokerCryptoProvider *cryptoProvider = [[MSIDBrokerCryptoProvider alloc] initWithEncryptionKey:[NSData msidDataFromBase64UrlEncodedString:brokerKey]];
// NSError *jsonResponseError = nil;
// NSDictionary *jsonResponse = [cryptoProvider decryptBrokerResponse:replyParam correlationId:context.correlationId error:&jsonResponseError];
// if (jsonResponseError)
// {
// MSID_LOG_WITH_CTX_PII(MSIDLogLevelError, nil, @"[Entra broker] CLIENT received operationResponse but failed to decrypt it with error: %@", jsonResponseError);
// if (continueBlock) continueBlock(nil, callbackError);
// return;
// }

BOOL forceRunOnBackgroundQueue = [[replyParam objectForKey:MSID_BROKER_OPERATION_KEY] isEqualToString:@"refresh"];
[self forceRunOnBackgroundQueue:forceRunOnBackgroundQueue dispatchBlock:^{
if (callbackError)
Expand Down Expand Up @@ -153,6 +142,7 @@ - (void)handleRequestParam:(NSDictionary *)requestParam

+ (BOOL)canPerformRequest
{
// This will be upgraded in item: xxx
// Synchronously entering this class method
@synchronized (self) {
dispatch_group_t group = dispatch_group_create();
Expand Down Expand Up @@ -301,7 +291,7 @@ - (void)getXpcService:(NSXPCListenerEndpointCompletionBlock)continueBlock
if (continueBlock) continueBlock(nil, nil, xpcUnexpectedError);
}];

[parentXpcService getBrokerInstanceEndpointWithRequestInfo:@{} reply:^(NSXPCListenerEndpoint * _Nullable listenerEndpoint, NSDictionary<NSString *, id> * _Nullable __unused params, NSError * _Nullable error) {
[parentXpcService getBrokerInstanceEndpointWithReply:^(NSXPCListenerEndpoint * _Nullable listenerEndpoint, NSDictionary<NSString *, id> * _Nullable __unused params, NSError * _Nullable error) {
[connection suspend];
[connection invalidate];
if (error)
Expand Down
144 changes: 144 additions & 0 deletions IdentityCore/tests/MSIDRequestControllerFactoryTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@
#import "MSIDSSOExtensionSilentTokenRequestController.h"
#import "MSIDTestSwizzle.h"
#import "MSIDRequestParameters+Broker.h"
#if TARGET_OS_OSX
#import "MSIDXpcSilentTokenRequestController.h"
#endif

@interface MSIDBaseRequestController (Testing)

@property (nonatomic, readwrite) id<MSIDRequestControlling> fallbackController;

@end

@interface MSIDRequestControllerFactoryTests : XCTestCase

Expand Down Expand Up @@ -189,6 +198,141 @@ - (void)testWhenUseLocalRt_isUnDefined_shouldSkip_whenFallBackController_isValid
XCTAssertTrue([(MSIDSilentController *)controller skipLocalRt]);
}

#if TARGET_OS_OSX
- (void)testWhenSsoExtensionIsEnabled_andXPCIsEnabled_controllersOrder_areCorrect
{
MSIDTestTokenRequestProvider *provider = [[MSIDTestTokenRequestProvider alloc] initWithTestResponse:nil
testError:nil
testWebMSAuthResponse:nil];
MSIDRequestParameters *parameters = [self requestParameters];
parameters.enableXpcFlow = YES;
parameters.allowUsingLocalCachedRtWhenSsoExtFailed = YES;

NSError *error;
SEL selectorForMSIDSSOExtensionSilentTokenRequestController = NSSelectorFromString(@"canPerformRequest");
[MSIDTestSwizzle classMethod:selectorForMSIDSSOExtensionSilentTokenRequestController
class:[MSIDSSOExtensionSilentTokenRequestController class]
block:(id)^(void)
{
return YES;
}];

SEL selectorForMSIDXpcSilentTokenRequestController = NSSelectorFromString(@"canPerformRequest");
[MSIDTestSwizzle classMethod:selectorForMSIDXpcSilentTokenRequestController
class:[MSIDXpcSilentTokenRequestController class]
block:(id)^(void)
{
return YES;
}];

SEL selectorForMSIDRequestParameters = NSSelectorFromString(@"shouldUseBroker");
[MSIDTestSwizzle instanceMethod:selectorForMSIDRequestParameters
class:[MSIDRequestParameters class]
block:(id)^(void)
{
return YES;
}];

id<MSIDRequestControlling> controller = [MSIDRequestControllerFactory silentControllerForParameters:parameters
forceRefresh:NO
skipLocalRt:MSIDSilentControllerForceSkippingLocalRt
tokenRequestProvider:provider
error:&error];
// 1. Start with local signin controller to read cached tokens
if (![controller isMemberOfClass:MSIDSilentController.class])
{
XCTFail();
}

XCTAssertTrue([(MSIDSilentController *)controller skipLocalRt]);
XCTAssertFalse([(MSIDSilentController *)controller forceRefresh]);

MSIDBaseRequestController *baseController = (MSIDBaseRequestController *)controller;
if (![baseController.fallbackController isMemberOfClass:MSIDSSOExtensionSilentTokenRequestController.class])
{
XCTFail();
}

// 2. When local signin controller failed, use SsoExtension controller
baseController = (MSIDSSOExtensionSilentTokenRequestController *)baseController.fallbackController;
if (![baseController.fallbackController isMemberOfClass:MSIDXpcSilentTokenRequestController.class])
{
XCTFail();
}

// 3. When SsoExtension controller failed, use Xpc Controller
baseController = (MSIDXpcSilentTokenRequestController *)baseController.fallbackController;
if (![baseController.fallbackController isMemberOfClass:MSIDSilentController.class])
{
XCTFail();
}

// 4. When Xpc controller failed, use local signin controller to refresh
baseController = (MSIDSilentController *)baseController.fallbackController;
XCTAssertTrue([(MSIDSilentController *)baseController forceRefresh]);
XCTAssertTrue([(MSIDSilentController *)baseController isLocalFallbackMode]);
}
#endif

- (void)testWhenSsoExtensionIsEnabled_andXPCIsDisabled_controllersOrder_areCorrect
{
MSIDTestTokenRequestProvider *provider = [[MSIDTestTokenRequestProvider alloc] initWithTestResponse:nil
testError:nil
testWebMSAuthResponse:nil];
MSIDRequestParameters *parameters = [self requestParameters];
parameters.allowUsingLocalCachedRtWhenSsoExtFailed = YES;

NSError *error;
SEL selectorForMSIDSSOExtensionSilentTokenRequestController = NSSelectorFromString(@"canPerformRequest");
[MSIDTestSwizzle classMethod:selectorForMSIDSSOExtensionSilentTokenRequestController
class:[MSIDSSOExtensionSilentTokenRequestController class]
block:(id)^(void)
{
return YES;
}];

SEL selectorForMSIDRequestParameters = NSSelectorFromString(@"shouldUseBroker");
[MSIDTestSwizzle instanceMethod:selectorForMSIDRequestParameters
class:[MSIDRequestParameters class]
block:(id)^(void)
{
return YES;
}];


id<MSIDRequestControlling> controller = [MSIDRequestControllerFactory silentControllerForParameters:parameters
forceRefresh:NO
skipLocalRt:MSIDSilentControllerForceSkippingLocalRt
tokenRequestProvider:provider
error:&error];
// 1. Start with local signin controller to read cached tokens
if (![controller isMemberOfClass:MSIDSilentController.class])
{
XCTFail();
}

XCTAssertTrue([(MSIDSilentController *)controller skipLocalRt]);
XCTAssertFalse([(MSIDSilentController *)controller forceRefresh]);

// 2. When local signin controller failed, use SsoExtension controller
MSIDBaseRequestController *baseController = (MSIDBaseRequestController *)controller;
if (![baseController.fallbackController isMemberOfClass:MSIDSSOExtensionSilentTokenRequestController.class])
{
XCTFail();
}

// 3. When SsoExtension controller failed, use local signin controller to refresh
baseController = (MSIDSSOExtensionSilentTokenRequestController *)baseController.fallbackController;
if (![baseController.fallbackController isMemberOfClass:MSIDSilentController.class])
{
XCTFail();
}

baseController = (MSIDSilentController *)baseController.fallbackController;
XCTAssertTrue([(MSIDSilentController *)baseController forceRefresh]);
XCTAssertTrue([(MSIDSilentController *)baseController isLocalFallbackMode]);
}

- (void)testWhenUseLocalRt_isUnDefined_shouldNotSkip_whenFallBackController_isNotValid
{
MSIDTestTokenRequestProvider *provider = [[MSIDTestTokenRequestProvider alloc] initWithTestResponse:nil
Expand Down

0 comments on commit 019d5d3

Please sign in to comment.