-
Notifications
You must be signed in to change notification settings - Fork 34
Update Xpc silent controler error handling as fallback #1516
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
base: dev
Are you sure you want to change the base?
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,6 +31,7 @@ NS_ASSUME_NONNULL_BEGIN | |
| @protocol MSIDRequestControlling <NSObject> | ||
|
|
||
| - (void)acquireToken:(nonnull MSIDRequestCompletionBlock)completionBlock; | ||
| - (void)shouldSkipAcquireTokenBasedOn:(nonnull NSError *)error; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1, methods with 'should' prefix usually indicate return type as BOOL but this does not seem to be the case here. |
||
|
|
||
| @end | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -111,7 +111,7 @@ - (void)acquireTokenWithRequest:(MSIDSilentTokenRequest *)request | |
| MSID_LOG_WITH_CTX(MSIDLogLevelError, nil, @"Passed nil completionBlock"); | ||
| return; | ||
| } | ||
|
|
||
| CONDITIONAL_START_EVENT(CONDITIONAL_SHARED_INSTANCE, self.requestParameters.telemetryRequestId, MSID_TELEMETRY_EVENT_API_EVENT); | ||
| self.currentRequest = request; | ||
| [request executeRequestWithCompletion:^(MSIDTokenResult *result, NSError *error) | ||
|
|
@@ -143,19 +143,26 @@ - (void)acquireTokenWithRequest:(MSIDSilentTokenRequest *)request | |
| self.currentRequest = nil; | ||
| MSIDRequestCompletionBlock completionBlockWrapper = ^(MSIDTokenResult *fallResult, NSError *fallError) | ||
| { | ||
| // We don't have any meaningful information from fallback controller (edge case of SSO error) so we use the local controller result earlier | ||
| if (!fallResult && (fallError.code == MSIDErrorSSOExtensionUnexpectedError)) | ||
| // Only return fallback when there is a valid result, otherwise, return error from main controller | ||
| // (!result && !error) is a special case when using local silent controller and to skip local refreh token (broker first flow). In this case, the main controller is the 1st fallback controller, and should return the error | ||
| if (fallResult || (!result && !error)) | ||
|
||
| { | ||
| completionBlock(result, error); | ||
| completionBlock(fallResult, fallError); | ||
| } | ||
| else | ||
| { | ||
| completionBlock(fallResult, fallError); | ||
| completionBlock(result, error); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why do we call fallback if we already have result?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In this case, the result is nil, the valid part is error only. I can send |
||
| } | ||
| }; | ||
|
|
||
|
|
||
| [self.fallbackController shouldSkipAcquireTokenBasedOn:error]; | ||
| [self.fallbackController acquireToken:completionBlockWrapper]; | ||
| }]; | ||
| } | ||
|
|
||
| - (void)shouldSkipAcquireTokenBasedOn:(NSError *)error | ||
| { | ||
| // This method is not used in this class. | ||
| } | ||
|
|
||
| @end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -118,4 +118,5 @@ - (BOOL)shouldFallback:(NSError *)error | |
| } | ||
|
|
||
| @end | ||
|
|
||
| #endif | ||
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -28,20 +28,44 @@ | |||||||||
| #import "MSIDLogger+Internal.h" | ||||||||||
| #import "MSIDXpcProviderCache.h" | ||||||||||
|
|
||||||||||
| @interface MSIDXpcSilentTokenRequestController () | ||||||||||
|
|
||||||||||
| // shouldSkipXpcRequest is used when the fallback is not needed for non ASAuthorizationErrorDomain or MSIDErrorSSOExtensionUnexpectedError | ||||||||||
| @property (nonatomic) BOOL shouldSkipAcquireToken; | ||||||||||
|
Comment on lines
+33
to
+34
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The comment says shouldSkipXpcRequest but property is named shouldSkipAcquireToken. Can you rename property to shouldSkipCallingXpc? shouldSkipAcquireToken is confusing
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since this boolean would be initialized to NO by default, I would suggest naming property to 'shouldUseXpcToAcquireToken' instead of 'shouldSkip..' |
||||||||||
|
|
||||||||||
| @end | ||||||||||
|
|
||||||||||
| @implementation MSIDXpcSilentTokenRequestController | ||||||||||
|
|
||||||||||
| - (void)acquireToken:(MSIDRequestCompletionBlock)completionBlock | ||||||||||
| { | ||||||||||
| MSID_LOG_WITH_CTX(MSIDLogLevelInfo, self.requestParameters, @"Beginning silent broker xpc flow."); | ||||||||||
| MSIDRequestCompletionBlock completionBlockWrapper = ^(MSIDTokenResult *result, NSError *error) | ||||||||||
| MSID_LOG_WITH_CTX(MSIDLogLevelInfo, self.requestParameters, @"Beginning silent broker xpc flow, should use Xpc flow to acquire token: %@", @(!self.shouldSkipAcquireToken)); | ||||||||||
| if (!self.shouldSkipAcquireToken) | ||||||||||
| { | ||||||||||
| MSID_LOG_WITH_CTX(MSIDLogLevelInfo, self.requestParameters, @"Silent broker xpc flow finished. Result %@, error: %ld error domain: %@, shouldFallBack: %@", _PII_NULLIFY(result), (long)error.code, error.domain, @(self.fallbackController != nil)); | ||||||||||
| completionBlock(result, error); | ||||||||||
| }; | ||||||||||
|
|
||||||||||
| __auto_type request = [self.tokenRequestProvider silentXpcTokenRequestWithParameters:self.requestParameters | ||||||||||
| forceRefresh:self.forceRefresh]; | ||||||||||
| [self acquireTokenWithRequest:request completionBlock:completionBlockWrapper]; | ||||||||||
| MSIDRequestCompletionBlock completionBlockWrapper = ^(MSIDTokenResult *result, NSError *error) | ||||||||||
| { | ||||||||||
| MSID_LOG_WITH_CTX(MSIDLogLevelInfo, self.requestParameters, @"Silent broker xpc flow finished. Result %@, error: %ld error domain: %@, shouldFallBack: %@", _PII_NULLIFY(result), (long)error.code, error.domain, @(self.fallbackController != nil)); | ||||||||||
| completionBlock(result, error); | ||||||||||
| }; | ||||||||||
|
|
||||||||||
| __auto_type request = [self.tokenRequestProvider silentXpcTokenRequestWithParameters:self.requestParameters | ||||||||||
| forceRefresh:self.forceRefresh]; | ||||||||||
| [self acquireTokenWithRequest:request completionBlock:completionBlockWrapper]; | ||||||||||
| } | ||||||||||
| else | ||||||||||
| { | ||||||||||
| // self.fallbackController cannot be nil here as it has been validated from caller | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this comment inaccurate? If we know fallbackController cannot be nil here, why do a nil check and log in the code? Please remove the comment as it isn't accurate according to the code following it |
||||||||||
| if (self.fallbackController) | ||||||||||
| { | ||||||||||
| [self.fallbackController acquireToken:completionBlock]; | ||||||||||
| } | ||||||||||
| else | ||||||||||
| { | ||||||||||
| // Add handler in case | ||||||||||
| NSError *error = MSIDCreateError(MSIDErrorDomain, MSIDErrorInternal, @"Fallback controller is nil", nil, nil, nil, nil, nil, YES); | ||||||||||
| if (completionBlock) completionBlock(nil, error); | ||||||||||
| } | ||||||||||
| } | ||||||||||
| } | ||||||||||
|
|
||||||||||
| + (BOOL)canPerformRequest | ||||||||||
|
|
@@ -55,4 +79,24 @@ + (BOOL)canPerformRequest | |||||||||
| } | ||||||||||
| } | ||||||||||
|
|
||||||||||
| - (void)shouldSkipAcquireTokenBasedOn:(NSError *)error | ||||||||||
| { | ||||||||||
| self.shouldSkipAcquireToken = YES; | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if error is nil? This method will log incorrect info which might confuse in case of issue debugging |
||||||||||
| MSID_LOG_WITH_CTX(MSIDLogLevelInfo, self.requestParameters, @"Looking if we should fallback to Xpc controller, error: %ld error domain: %@.", (long)error.code, error.domain); | ||||||||||
| // If it is MSIDErrorDomain and Sso Extension returns unexpected error, we should fall back to local controler and unblock user | ||||||||||
| if (![error.domain isEqualToString:ASAuthorizationErrorDomain] && ![error.domain isEqualToString:MSIDErrorDomain]) { | ||||||||||
|
||||||||||
| if (![error.domain isEqualToString:ASAuthorizationErrorDomain] && ![error.domain isEqualToString:MSIDErrorDomain]) { | |
| if (![error.domain isEqualToString:ASAuthorizationErrorDomain] && ![error.domain isEqualToString:MSIDErrorDomain]) { | |
| // No action is required for error domains other than ASAuthorizationErrorDomain or MSIDErrorDomain. | |
| // This block is intentionally left empty. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this supposed to do? Did you miss something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can the controller be reused for multiple requests? If it is, controller's shouldSkipAcquireToken might get set to NO in 1st request and remain NO for second request
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This pull request does not update changelog.txt.
Please consider if this change would be noticeable to a partner or user and either update changelog.txt or resolve this conversation.