Skip to content

Commit e2cb149

Browse files
committed
Merge branch 'dev' into veena/PasskeyBiometric
2 parents 67f7022 + 2b3b0a7 commit e2cb149

File tree

10 files changed

+257
-2
lines changed

10 files changed

+257
-2
lines changed

IdentityCore/src/MSIDError.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ typedef NS_ENUM(NSInteger, MSIDErrorCode)
171171
*/
172172

173173
MSIDErrorServerUnhandledResponse = -51500,
174+
// http status Code 403 or 404
175+
MSIDErrorUnexpectedHttpResponse = -51501,
174176

175177
/*!
176178
=========================================================

IdentityCore/src/MSIDError.m

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,8 @@ MSIDErrorCode MSIDErrorCodeForOAuthErrorWithSubErrorCode(NSString *oauthError, M
227227
@(MSIDErrorServerError),
228228
],
229229
MSIDHttpErrorCodeDomain : @[
230-
@(MSIDErrorServerUnhandledResponse)
230+
@(MSIDErrorServerUnhandledResponse),
231+
@(MSIDErrorUnexpectedHttpResponse)
231232
]
232233

233234
// TODO: add new codes here
@@ -304,6 +305,8 @@ void MSIDFillAndLogError(NSError **error, MSIDErrorCode errorCode, NSString *err
304305
// HTTP errors
305306
case MSIDErrorServerUnhandledResponse:
306307
return @"MSIDErrorServerUnhandledResponse";
308+
case MSIDErrorUnexpectedHttpResponse:
309+
return @"MSIDErrorUnexpectedHttpResponse";
307310
// Authority validation errors
308311
case MSIDErrorAuthorityValidation:
309312
return @"MSIDErrorAuthorityValidation";

IdentityCore/src/network/error_handler/MSIDAADRequestErrorHandler.m

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,13 @@ - (void)handleError:(NSError *)error
150150
}
151151
}
152152

153-
NSError *httpError = MSIDCreateError(MSIDHttpErrorCodeDomain, MSIDErrorServerUnhandledResponse, errorDescription, nil, nil, nil, context.correlationId, additionalInfo, YES);
153+
NSError *httpUnderlyingError = nil;
154+
if (httpResponse.statusCode == 403 || httpResponse.statusCode == 404)
155+
{
156+
httpUnderlyingError = MSIDCreateError(MSIDHttpErrorCodeDomain, MSIDErrorUnexpectedHttpResponse, errorDescription, nil, nil, nil, context.correlationId, nil, YES);
157+
}
158+
159+
NSError *httpError = MSIDCreateError(MSIDHttpErrorCodeDomain, MSIDErrorServerUnhandledResponse, errorDescription, nil, nil, httpUnderlyingError, context.correlationId, additionalInfo, YES);
154160

155161
if (completionBlock) completionBlock(nil, httpError);
156162
}

IdentityCore/tests/MSIDAADRequestErrorHandlerTests.m

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,8 @@ - (void)testHandleError_whenItIsNotServerError_shouldReturnStatusCodeAndHeaders
191191

192192
XCTAssertEqualObjects(returnError.domain, MSIDHttpErrorCodeDomain);
193193
XCTAssertEqual(returnError.code, MSIDErrorServerUnhandledResponse);
194+
NSError *underlyingError = returnError.userInfo[NSUnderlyingErrorKey];
195+
XCTAssertEqual(underlyingError.code, MSIDErrorUnexpectedHttpResponse);
194196
XCTAssertEqualObjects(returnError.userInfo[MSIDHTTPHeadersKey], @{@"headerKey":@"headerValue"});
195197

196198
XCTAssertNil(errorResponse);
@@ -275,6 +277,8 @@ - (void)testHandleError_whenItIsServerError_shouldReturnResponseCodeInError
275277

276278
XCTAssertEqualObjects(returnError.domain, MSIDHttpErrorCodeDomain);
277279
XCTAssertEqual(returnError.code, MSIDErrorServerUnhandledResponse);
280+
NSError *underlyingError = returnError.userInfo[NSUnderlyingErrorKey];
281+
XCTAssertEqual(underlyingError.code, MSIDErrorUnexpectedHttpResponse);
278282
XCTAssertEqualObjects(returnError.userInfo[MSIDHTTPResponseCodeKey], @"404");
279283
}
280284

IdentityCore/tests/automation/shared/MSIDAutomationTestRequest.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ typedef NS_ENUM(NSUInteger, MSIDAutomationWPJRegistrationAPIMode)
3333
MSIDAutomationWPJRegistrationAPIModeCompanyPortal = 2 //Company Portal
3434
};
3535

36+
typedef NS_ENUM(NSInteger, MSIDAutomationWPJSSOExtensionSecureStorage)
37+
{
38+
MSIDAutomationWPJSSOExtensionNoValueFound = 0,
39+
MSIDAutomationWPJSSOExtensionValueNo = 1,
40+
MSIDAutomationWPJSSOExtensionValueYes = 2
41+
};
42+
3643
@interface MSIDAutomationTestRequest : NSObject <MSIDJsonSerializable>
3744

3845
@property (nonatomic, strong) NSString *clientId;
@@ -86,6 +93,8 @@ typedef NS_ENUM(NSUInteger, MSIDAutomationWPJRegistrationAPIMode)
8693
@property (nonatomic) NSString *wpjRegistrationUpn;
8794
@property (nonatomic) BOOL operateOnPrimaryWPJ;
8895
@property (nonatomic) BOOL useMostSecureStorageForWpj;
96+
@property (nonatomic) BOOL isSecureEnclaveSupportedForWpj;
97+
@property (nonatomic) MSIDAutomationWPJSSOExtensionSecureStorage ssoExtensionSecureStorageEnabled;
8998
@property (nonatomic) BOOL shouldExpirePRT;
9099
@property (nonatomic) BOOL isSsoSeedingCompleted;
91100
@property (nonatomic) BOOL shouldOnlyDeleteSeedingPrt;

IdentityCore/tests/automation/shared/MSIDAutomationTestRequest.m

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ - (instancetype)initWithJSONDictionary:(NSDictionary *)json
103103
_wpjRegistrationUpn = json[@"wpj_registration_upn"];
104104
_operateOnPrimaryWPJ = [json[@"wpj_operate_on_primary_reg"] boolValue];
105105
_useMostSecureStorageForWpj = [json[@"use_most_secure_storage"] boolValue];
106+
_isSecureEnclaveSupportedForWpj = [json[@"wpj_secure_enclave_supported"] boolValue];
107+
_ssoExtensionSecureStorageEnabled = (MSIDAutomationWPJSSOExtensionSecureStorage)[json[@"wpj_sso_extension_secure_storage_enabled"] integerValue];
106108
_shouldExpirePRT = [json[@"should_expire_prt"] boolValue];
107109
_isSsoSeedingCompleted = [json[@"is_sso_seeding_completed"] boolValue];
108110
_shouldOnlyDeleteSeedingPrt = [json[@"should_only_delete_seeding_prt"] boolValue];
@@ -184,6 +186,8 @@ - (NSDictionary *)jsonDictionary
184186
json[@"wpj_registration_upn"] = _wpjRegistrationUpn;
185187
json[@"wpj_operate_on_primary_reg"] = @(_operateOnPrimaryWPJ);
186188
json[@"use_most_secure_storage"] = @(_useMostSecureStorageForWpj);
189+
json[@"wpj_secure_enclave_supported"] = @(_isSecureEnclaveSupportedForWpj);
190+
json[@"wpj_sso_extension_secure_storage_enabled"] = @(_ssoExtensionSecureStorageEnabled);
187191
json[@"should_expire_prt"] = @(_shouldExpirePRT);
188192
json[@"is_sso_seeding_completed"] = @(_isSsoSeedingCompleted);
189193
json[@"should_only_delete_seeding_prt"] = @(_shouldOnlyDeleteSeedingPrt);

IdentityCore/tests/automation/ui_tests_lib/lab_api/MSIDTestAutomationAccountConfigurationRequest.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ extern MSIDTestAccountProtectionPolicyType MSIDTestAccountProtectionPolicyTypeMA
4848
extern MSIDTestAccountProtectionPolicyType MSIDTestAccountProtectionPolicyTypeMAMCASPO;
4949
extern MSIDTestAccountProtectionPolicyType MSIDTestAccountProtectionPolicyTypeTrueMAMCA;
5050
extern MSIDTestAccountProtectionPolicyType MSIDTestAccountProtectionPolicyTypeMDMCA;
51+
extern MSIDTestAccountProtectionPolicyType MSIDTestAccountProtectionPolicyTypeTB;
5152

5253
typedef NSString *MSIDTestAccountB2CProviderType;
5354
extern MSIDTestAccountB2CProviderType MSIDTestAccountB2CProviderTypeNone;

IdentityCore/tests/automation/ui_tests_lib/lab_api/MSIDTestAutomationAccountConfigurationRequest.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
MSIDTestAccountProtectionPolicyType MSIDTestAccountProtectionPolicyTypeMAMCASPO = @"mamspo";
4747
MSIDTestAccountProtectionPolicyType MSIDTestAccountProtectionPolicyTypeTrueMAMCA = @"truemamca";
4848
MSIDTestAccountProtectionPolicyType MSIDTestAccountProtectionPolicyTypeMDMCA = @"mdmca";
49+
MSIDTestAccountProtectionPolicyType MSIDTestAccountProtectionPolicyTypeTB = @"tokenbinding";
4950

5051
#pragma mark - MSIDTestAccountB2CProviderType;
5152
MSIDTestAccountB2CProviderType MSIDTestAccountB2CProviderTypeNone = @"none";

IdentityCore/tests/integration/ios/MSIDDefaultSilentTokenRequestTests.m

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1336,6 +1336,68 @@ - (void)testAcquireTokenSilent_when429ThrottledErrorReturned_shouldReturnAllHead
13361336
[self waitForExpectationsWithTimeout:1.0 handler:nil];
13371337
}
13381338

1339+
1340+
- (void)testAcquireTokenSilent_when403HttpCodeReturned_shouldReturnMSIDErrorUnexpectedHttpResponseInUnderlyingError
1341+
{
1342+
MSIDRequestParameters *silentParameters = [self silentRequestParameters];
1343+
MSIDDefaultTokenCacheAccessor *tokenCache = self.tokenCache;
1344+
1345+
[self saveExpiredTokensInCache:tokenCache configuration:silentParameters.msidConfiguration];
1346+
silentParameters.accountIdentifier = [[MSIDAccountIdentifier alloc] initWithDisplayableId:DEFAULT_TEST_ID_TOKEN_USERNAME homeAccountId:DEFAULT_TEST_HOME_ACCOUNT_ID];
1347+
1348+
NSString *authority = DEFAULT_TEST_AUTHORITY_GUID;
1349+
MSIDTestURLResponse *discoveryResponse = [MSIDTestURLResponse discoveryResponseForAuthority:authority];
1350+
[MSIDTestURLSession addResponse:discoveryResponse];
1351+
1352+
MSIDTestURLResponse *oidcResponse = [MSIDTestURLResponse oidcResponseForAuthority:authority];
1353+
[MSIDTestURLSession addResponse:oidcResponse];
1354+
1355+
NSMutableDictionary *reqHeaders = [[MSIDTestURLResponse msidDefaultRequestHeaders] mutableCopy];
1356+
[reqHeaders setObject:@"application/x-www-form-urlencoded" forKey:@"Content-Type"];
1357+
1358+
MSIDTestURLResponse *errorTokenResponse =
1359+
[MSIDTestURLResponse requestURLString:DEFAULT_TEST_TOKEN_ENDPOINT_GUID
1360+
requestHeaders:reqHeaders
1361+
requestParamsBody:@{ @"client_id" : @"my_client_id",
1362+
@"scope" : @"user.read tasks.read openid profile offline_access",
1363+
@"grant_type" : @"refresh_token",
1364+
@"refresh_token" : DEFAULT_TEST_REFRESH_TOKEN,
1365+
MSID_OAUTH2_REDIRECT_URI : [[self silentRequestParameters] redirectUri],
1366+
@"client_info" : @"1"}
1367+
responseURLString:DEFAULT_TEST_TOKEN_ENDPOINT_GUID
1368+
responseCode:403
1369+
httpHeaderFields:@{@"Retry-After": @"256",
1370+
@"Other-Header-Field": @"Other header field"
1371+
}
1372+
dictionaryAsJSON:nil];
1373+
1374+
[errorTokenResponse->_requestHeaders removeObjectForKey:@"Content-Length"];
1375+
1376+
[MSIDTestURLSession addResponse:errorTokenResponse];
1377+
1378+
MSIDDefaultSilentTokenRequest *silentRequest = [[MSIDDefaultSilentTokenRequest alloc] initWithRequestParameters:silentParameters
1379+
forceRefresh:NO
1380+
oauthFactory:[MSIDAADV2Oauth2Factory new]
1381+
tokenResponseValidator:[MSIDDefaultTokenResponseValidator new]
1382+
tokenCache:tokenCache
1383+
accountMetadataCache:self.accountMetadataCache];
1384+
1385+
XCTestExpectation *expectation = [self expectationWithDescription:@"silent request"];
1386+
1387+
[silentRequest executeRequestWithCompletion:^(MSIDTokenResult * _Nullable result, NSError * _Nullable error) {
1388+
1389+
XCTAssertNotNil(error);
1390+
XCTAssertNil(result);
1391+
XCTAssertEqual(error.code, MSIDErrorServerUnhandledResponse);
1392+
NSError *underlyingError = error.userInfo[NSUnderlyingErrorKey];
1393+
XCTAssertEqual(underlyingError.code, MSIDErrorUnexpectedHttpResponse);
1394+
XCTAssertEqualObjects(error.domain, MSIDHttpErrorCodeDomain);
1395+
XCTAssertEqualObjects(error.userInfo[MSIDHTTPResponseCodeKey], @"403");
1396+
[expectation fulfill];
1397+
}];
1398+
1399+
[self waitForExpectationsWithTimeout:1.0 handler:nil];
1400+
}
13391401
- (void)testAcquireTokenSilent_whenTokenEndpointInDifferentCloud_shouldReturnInteractionRequired
13401402
{
13411403
// Prepare RT in cache
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
# Xcode
2+
# Build, test, and archive an Xcode workspace on macOS.
3+
# Add steps that install certificates, test, sign, and distribute an app, save build artifacts, and more:
4+
# https://docs.microsoft.com/azure/devops/pipelines/languages/xcode
5+
6+
trigger:
7+
branches:
8+
include:
9+
- dev
10+
11+
pr:
12+
autoCancel: true
13+
branches:
14+
include:
15+
- '*'
16+
drafts: true
17+
18+
pool:
19+
name: 'Azure Pipelines'
20+
21+
resources:
22+
repositories:
23+
- repository: azure-activedirectory-tokenbroker-for-objc
24+
type: github
25+
endpoint: 'MSAL ObjC Service Connection'
26+
name: AzureAD/azure-activedirectory-tokenbroker-for-objc
27+
28+
- repository: WorkplaceJoin-for-iOS
29+
type: github
30+
endpoint: 'MSAL ObjC Service Connection'
31+
name: AzureAD/WorkplaceJoin-for-iOS
32+
33+
jobs:
34+
- job: 'Validate_Pull_Request'
35+
displayName: Validate Pull Request
36+
pool:
37+
vmImage: 'macOS-14'
38+
timeOutInMinutes: 30
39+
40+
steps:
41+
- checkout: azure-activedirectory-tokenbroker-for-objc
42+
displayName: 'Checkout Broker'
43+
clean: false
44+
submodules: false
45+
fetchTags: true
46+
persistCredentials: true
47+
48+
- task: Bash@3
49+
displayName: 'Checkout MSAL, ADAL, and submodules'
50+
inputs:
51+
workingDirectory: $(Pipeline.Workspace)/s
52+
targetType: 'inline'
53+
script: |
54+
cd azure-activedirectory-tokenbroker-for-objc
55+
git submodule update --init --recursive ADAuthenticationBroker/Frameworks/adal
56+
git submodule update --init ADAuthenticationBroker/Frameworks/microsoft-authentication-library-for-objc
57+
58+
- checkout: self
59+
displayName: 'Checkout IdentityCore'
60+
clean: false
61+
submodules: false
62+
fetchTags: true
63+
path: 's/azure-activedirectory-tokenbroker-for-objc/ADAuthenticationBroker/Frameworks/microsoft-authentication-library-for-objc/MSAL/IdentityCore'
64+
persistCredentials: true
65+
66+
- checkout: WorkplaceJoin-for-iOS
67+
displayName: 'Checkout WPJ'
68+
clean: false
69+
submodules: false
70+
fetchTags: true
71+
path: 's/azure-activedirectory-tokenbroker-for-objc/ADAuthenticationBroker/Frameworks/WorkplaceJoin-for-iOS'
72+
persistCredentials: true
73+
74+
- task: AzureCLI@2
75+
inputs:
76+
azureSubscription: 'AuthSdkResourceManager'
77+
scriptType: 'pscore'
78+
scriptLocation: 'inlineScript'
79+
inlineScript: |
80+
# if this fails, check out this bash script that includes diagnostics:
81+
# https://gist.github.com/johnterickson/19f80a3e969e39f1000d118739176e62
82+
# uncomment these for more debugging spew
83+
# GIT_TRACE=1
84+
# GIT_CURL_VERBOSE=1
85+
86+
# Note that the resoruce is specified to limit the token to Azure DevOps
87+
$token = az account get-access-token --query accessToken --resource 499b84ac-1321-427f-aa17-267ca6975798 -o tsv
88+
Write-Host "##vso[task.setvariable variable=aadToken;issecret=true]$token"
89+
- task: Bash@3
90+
displayName: 'Checkout NGC Submodules'
91+
env:
92+
AccessToken: $(MSAzureToken_encoded)
93+
inputs:
94+
workingDirectory: $(Pipeline.Workspace)/s
95+
targetType: 'inline'
96+
script: |
97+
cd azure-activedirectory-tokenbroker-for-objc/ADAuthenticationBroker/Frameworks
98+
git -c http.https://msazure.visualstudio.com/DefaultCollection/One/_git/AD-MFA-NGCAuthentication.extraheader="AUTHORIZATION: bearer $(aadToken)" submodule update --init AD-MFA-NGCAuthentication
99+
cd AD-MFA-NGCAuthentication
100+
git -c http.https://msazure.visualstudio.com/DefaultCollection/One/_git/AD-MFA-NGCKeyProvider-ios.extraheader="AUTHORIZATION: bearer $(aadToken)" submodule update --init NGCKeyProvider
101+
git -c http.https://msazure.visualstudio.com/DefaultCollection/One/_git/AD-MFA-MSAuthNetworking.extraheader="AUTHORIZATION: bearer $(aadToken)" submodule update --init MSAuthNetworking
102+
103+
- task: Bash@3
104+
displayName: 'Checkout WPJ openssl-msft submodule'
105+
inputs:
106+
workingDirectory: $(Pipeline.Workspace)/s
107+
targetType: 'inline'
108+
script: |
109+
cd azure-activedirectory-tokenbroker-for-objc/ADAuthenticationBroker/Frameworks/WorkplaceJoin-for-iOS
110+
git -c http.https://msazure.visualstudio.com/DefaultCollection/PlatformCrypto/_git/openssl-msft.extraheader="AUTHORIZATION: bearer $(aadToken)" submodule update --init Frameworks/openssl-msft
111+
112+
- task: Bash@3
113+
displayName: 'Update WPJ submodules'
114+
inputs:
115+
workingDirectory: $(Pipeline.Workspace)/s
116+
targetType: 'inline'
117+
script: |
118+
cd azure-activedirectory-tokenbroker-for-objc/ADAuthenticationBroker/Frameworks/WorkplaceJoin-for-iOS
119+
git submodule update --init --recursive Frameworks/microsoft-authentication-library-for-objc
120+
121+
- script: 'gem uninstall xcpretty -I --version 0.4.0'
122+
displayName: 'Uninstall xcpretty v0.4.0'
123+
124+
- script: 'gem install xcpretty -N -v 0.3.0'
125+
displayName: 'Install xcpretty v0.3.0'
126+
127+
- script: 'gem install slather -N'
128+
displayName: 'Install slather'
129+
130+
- task: UsePythonVersion@0
131+
displayName: 'Use Python 3.x'
132+
133+
- task: Bash@3
134+
displayName: 'Select Xcode version'
135+
inputs:
136+
targetType: 'inline'
137+
script: '/bin/bash -c "sudo xcode-select -s /Applications/Xcode_15.4.app"'
138+
139+
# The following is needed to install the visionOS SDK on macos-14 vm image which
140+
# doesn't have visionOS installed by default.
141+
# TODO: Remove when macos-14-arm64 is supported on ADO.
142+
- task: Bash@3
143+
displayName: download visionOS SDK
144+
inputs:
145+
targetType: 'inline'
146+
script: |
147+
echo "Downloading simulator for visionOS"
148+
sudo xcode-select -s /Applications/Xcode_15.4.app/Contents/Developer
149+
defaults write com.apple.dt.Xcode AllowUnsupportedVisionOSHost -bool YES
150+
defaults write com.apple.CoreSimulator AllowUnsupportedVisionOSHost -bool YES
151+
xcodebuild -downloadPlatform visionOS
152+
failOnStderr: false
153+
154+
155+
- task: Bash@3
156+
displayName: 'Run a python script for Broker'
157+
inputs:
158+
targetType: 'inline'
159+
script: |
160+
cd azure-activedirectory-tokenbroker-for-objc
161+
echo "executing build:./build.py"
162+
python3 ./build.py
163+

0 commit comments

Comments
 (0)