Skip to content

Commit

Permalink
Add enum to enabl/disable XPC service
Browse files Browse the repository at this point in the history
  • Loading branch information
Kai Song authored and Kai Song committed Feb 26, 2025
1 parent 019d5d3 commit 9bd5556
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 8 deletions.
7 changes: 7 additions & 0 deletions IdentityCore/src/MSIDConstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,13 @@ typedef NS_ENUM(NSInteger, MSIDHeaderType)
MSIDHeaderTypeDeviceRegistration
};

typedef NS_ENUM(NSUInteger, MSIDXpcMode)
{
MSIDXpcModeDisable = 0,
MSIDXpcModeBackup,
MSIDXpcModeFull
};

typedef void (^MSIDRequestCompletionBlock)(MSIDTokenResult * _Nullable result, NSError * _Nullable error);
typedef void (^MSIDSignoutRequestCompletionBlock)(BOOL success, NSError * _Nullable error);
typedef void (^MSIDGetAccountsRequestCompletionBlock)(NSArray<MSIDAccount *> * _Nullable accounts, BOOL returnBrokerAccountsOnly, NSError * _Nullable error);
Expand Down
13 changes: 10 additions & 3 deletions IdentityCore/src/controllers/MSIDRequestControllerFactory.m
Original file line number Diff line number Diff line change
Expand Up @@ -162,14 +162,21 @@ @implementation MSIDRequestControllerFactory
fallbackController.isLocalFallbackMode = YES;
}

MSIDSilentController *xpcController = nil;
#if TARGET_OS_OSX
if (parameters.enableXpcFlow && [MSIDXpcSilentTokenRequestController canPerformRequest])
if (parameters.xpcMode != MSIDXpcModeDisable && [MSIDXpcSilentTokenRequestController canPerformRequest])
{
fallbackController = [[MSIDXpcSilentTokenRequestController alloc] initWithRequestParameters:parameters
xpcController = [[MSIDXpcSilentTokenRequestController alloc] initWithRequestParameters:parameters
forceRefresh:forceRefresh
tokenRequestProvider:tokenRequestProvider
fallbackInteractiveController:fallbackController
error:error];
if (parameters.xpcMode == MSIDXpcModeFull)
{
// If in Xpc full mode, the XPCController will work as a isolated controller when SsoExtension cannotPerformRequest
fallbackController = xpcController;
xpcController = nil;
}
}
#endif

Expand All @@ -178,7 +185,7 @@ @implementation MSIDRequestControllerFactory
fallbackController = [[MSIDSSOExtensionSilentTokenRequestController alloc] initWithRequestParameters:parameters
forceRefresh:forceRefresh
tokenRequestProvider:tokenRequestProvider
fallbackInteractiveController:fallbackController
fallbackInteractiveController:xpcController?:fallbackController
error:error];
}
}
Expand Down
4 changes: 3 additions & 1 deletion IdentityCore/src/parameters/MSIDRequestParameters.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@
@property (nonatomic) NSUInteger tokenExpirationBuffer;
@property (nonatomic) BOOL extendedLifetimeEnabled;
@property (nonatomic) BOOL instanceAware;
@property (nonatomic) BOOL enableXpcFlow;
@property (nonatomic) BOOL allowUsingLocalCachedRtWhenSsoExtFailed;
@property (nonatomic) BOOL clientBrokerKeyCapabilityNotSupported;
@property (nonatomic) NSString *intuneApplicationIdentifier;
Expand Down Expand Up @@ -109,6 +108,9 @@
#pragma mark - SSO context
@property (nonatomic) MSIDExternalSSOContext *ssoContext;

#pragma mark - Xpc Mode
@property (nonatomic) MSIDXpcMode xpcMode;

- (NSURL *)tokenEndpoint;

#pragma mark Methods
Expand Down
2 changes: 1 addition & 1 deletion IdentityCore/src/util/MSIDXpcSingleSignOnProvider.m
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ - (void)handleRequestParam:(NSDictionary *)requestParam

+ (BOOL)canPerformRequest
{
// This will be upgraded in item: xxx
// TODO: The full implementation will be done in 3166516
// Synchronously entering this class method
@synchronized (self) {
dispatch_group_t group = dispatch_group_create();
Expand Down
136 changes: 133 additions & 3 deletions IdentityCore/tests/MSIDRequestControllerFactoryTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -198,14 +198,76 @@ - (void)testWhenUseLocalRt_isUnDefined_shouldSkip_whenFallBackController_isValid
XCTAssertTrue([(MSIDSilentController *)controller skipLocalRt]);
}


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

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

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;

// 2. When SsoExtension controller disabled, use local signin controller to refresh. XPC is ignore as it is in XPC backup mode
if (![baseController.fallbackController isMemberOfClass:MSIDSilentController.class])
{
XCTFail();
}

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

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

NSError *error;
Expand Down Expand Up @@ -272,9 +334,77 @@ - (void)testWhenSsoExtensionIsEnabled_andXPCIsEnabled_controllersOrder_areCorrec
XCTAssertTrue([(MSIDSilentController *)baseController forceRefresh]);
XCTAssertTrue([(MSIDSilentController *)baseController isLocalFallbackMode]);
}

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

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

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]);

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

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

// 3. 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
- (void)testWhenSsoExtensionIsEnabled_andXpcIsDisabled_controllersOrder_areCorrect
{
MSIDTestTokenRequestProvider *provider = [[MSIDTestTokenRequestProvider alloc] initWithTestResponse:nil
testError:nil
Expand Down

0 comments on commit 9bd5556

Please sign in to comment.