Skip to content

Commit 5f5979c

Browse files
nilo-msborgesmb
andauthored
Native authentication email OTP MFA (#2341)
* Email OTP MFA Network layer implementation (#2275) * add introspect request, response and error classes * make authentication method fields mandatory, add validator code for introspect responses * update signIN challenge request and response * handle mfa required using suberror and not error code * fix unit tests after new changes * rename validate function and add new test for introspect required error result * add new unit tests for introspect validation * add new unit tests for token response validation - mfa required * fix integration tests compilation error * add new integration tests for introspect api * - Adjustments in integration tests to align with mock API changes * Address comments on PR --------- Co-authored-by: Marcos Borges <[email protected]> Co-authored-by: Marcos Borges <[email protected]> * first public interface draft * add missing method in signINPasswordRequiredDelegate * add dummy logic * Add dedicated errors for MFA sub flow * add optional new state to error callbacks * Make channel type extensible * Update and add new public comments * fix compilation errors in E2E tests * Fix typo and swiftlint warnings * add base mfa states, return awaiting mfa on password required state * add implementation for mfa required response after submitting a code * handle remaning strongAuthRequired response * handle introspect required and update todo comment * add send challenge MFA business logic * reuse code for send challenge method * Email OTP MFA - public interface changes (#2296) * first public interface draft * add missing method in signINPasswordRequiredDelegate * add dummy logic * Add dedicated errors for MFA sub flow * add optional new state to error callbacks * Make channel type extensible * Update and add new public comments * fix compilation errors in E2E tests * Fix typo and swiftlint warnings * Address PR comments * use same name for awaitingMFA method, add more details to the comment * merge two mfa error and handle get auth methods request * complete implementation of get auth methods method * implement submit challenge reusing submit code function * remove telemetry check in controller test. Delegate dispatcher should trigger telemetry * Add unit tests for SendChallenge delegate dispatcher * Add remaining tests for mfa delegate dispatchers * add new unit tests for MFA error classes * Writing tests for awaitingMFAState * add unit tests for mfaRequiredState * add new unit tests to existing signIn Controller * add new test for sendChallengeState, add new class for MFA controller tests * move mfa tests to dedicated class * add new tests for mfa controller. Fix some bugs too * add new tests for send challenge * add new tests for get auth methods * add new tests for submit Challenge, stop telemetry on successful result * fix compilation error on integration tests * rename sendChallenge to requestChallenge * Address PR comments * address PR comments. Fix bug around SSPR telemetry id * address PR comments * Email OTP MFA business logic (#2302) * first public interface draft * add missing method in signINPasswordRequiredDelegate * add dummy logic * Add dedicated errors for MFA sub flow * add optional new state to error callbacks * Make channel type extensible * Update and add new public comments * fix compilation errors in E2E tests * Fix typo and swiftlint warnings * add base mfa states, return awaiting mfa on password required state * add implementation for mfa required response after submitting a code * handle remaning strongAuthRequired response * handle introspect required and update todo comment * add send challenge MFA business logic * reuse code for send challenge method * merge two mfa error and handle get auth methods request * complete implementation of get auth methods method * implement submit challenge reusing submit code function * remove telemetry check in controller test. Delegate dispatcher should trigger telemetry * Add unit tests for SendChallenge delegate dispatcher * Add remaining tests for mfa delegate dispatchers * add new unit tests for MFA error classes * Writing tests for awaitingMFAState * add unit tests for mfaRequiredState * add new unit tests to existing signIn Controller * add new test for sendChallengeState, add new class for MFA controller tests * move mfa tests to dedicated class * add new tests for mfa controller. Fix some bugs too * add new tests for send challenge * add new tests for get auth methods * add new tests for submit Challenge, stop telemetry on successful result * fix compilation error on integration tests * rename sendChallenge to requestChallenge * Address PR comments * address PR comments. Fix bug around SSPR telemetry id * address PR comments * Log a warning message and add warning on code documentation (#2306) * add email otp mfa files to mac targets. Remove not used files * Add E2E tests for email OTP MFA feature (#2331) * add new e2e test for signIn with username and password and MFA * add new end to end tests for mfa * add missing E2E tests for email OTP MFA * throw xctskip error to skip error * refactor E2E tests * rename internal test function * send wrong code as string * Refresh token, customise MFA required error description (#2322) * add new error codes key and parse msid error codes * add new error converter tests * update changelog file * add custom error message if error code is mfaRequired * Add new unit tests for error codes handling * add file to mac os target * revert change for project file * Add new MFARequestChallengeError and MFAGetAuthMethodsError (#2340) * add period at the end of the sentence * remove null pointer in project file * remove trailing space and enable all mfa e2e tests --------- Co-authored-by: Marcos Borges <[email protected]> Co-authored-by: Marcos Borges <[email protected]>
1 parent 51ea00f commit 5f5979c

File tree

105 files changed

+4216
-409
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

105 files changed

+4216
-409
lines changed

MSAL/.swiftlint.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ function_parameter_count:
1313

1414
disabled_rules:
1515
- todo
16+
- empty_enum_arguments

MSAL/MSAL.xcodeproj/project.pbxproj

Lines changed: 216 additions & 22 deletions
Large diffs are not rendered by default.

MSAL/src/native_auth/network/MSALNativeAuthInternalChannelType.swift renamed to MSAL/src/native_auth/MSALNativeAuthLogMessage.swift

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,11 @@
2020
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2121
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2222
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23-
// THE SOFTWARE.
23+
// THE SOFTWARE.
2424

25-
enum MSALNativeAuthInternalChannelType: String, Decodable {
26-
case phone
27-
case email
25+
import Foundation
2826

29-
func toPublicChannelType() -> MSALNativeAuthChannelType {
30-
switch self {
31-
case .phone:
32-
return .phone
33-
case .email:
34-
return .email
35-
}
36-
}
27+
enum MSALNativeAuthLogMessage {
28+
static let privatePreviewLog =
29+
"Warning ⚠️: this API is experimental. It may be changed in the future without notice. Do not use in production applications."
3730
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//
2+
// Copyright (c) Microsoft Corporation.
3+
// All rights reserved.
4+
//
5+
// This code is licensed under the MIT License.
6+
//
7+
// Permission is hereby granted, free of charge, to any person obtaining a copy
8+
// of this software and associated documentation files(the "Software"), to deal
9+
// in the Software without restriction, including without limitation the rights
10+
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
11+
// copies of the Software, and to permit persons to whom the Software is
12+
// furnished to do so, subject to the following conditions :
13+
//
14+
// The above copyright notice and this permission notice shall be included in
15+
// all copies or substantial portions of the Software.
16+
//
17+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
// THE SOFTWARE.
24+
25+
import Foundation
26+
27+
enum MFARequestChallengeResult {
28+
case verificationRequired(sentTo: String, channelTargetType: MSALNativeAuthChannelType, codeLength: Int, newState: MFARequiredState)
29+
case selectionRequired(authMethods: [MSALAuthMethod], newState: MFARequiredState)
30+
case error(error: MFARequestChallengeError, newState: MFARequiredState?)
31+
}
32+
33+
enum MFAGetAuthMethodsResult {
34+
case selectionRequired(authMethods: [MSALAuthMethod], newState: MFARequiredState)
35+
case error(error: MFAGetAuthMethodsError, newState: MFARequiredState?)
36+
}
37+
38+
enum MFASubmitChallengeResult {
39+
case completed(MSALNativeAuthUserAccountResult)
40+
case error(error: MFASubmitChallengeError, newState: MFARequiredState?)
41+
}

MSAL/src/native_auth/controllers/responses/SignInResults.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,15 @@ enum SignInStartResult {
2828
case completed(MSALNativeAuthUserAccountResult)
2929
case codeRequired(newState: SignInCodeRequiredState, sentTo: String, channelTargetType: MSALNativeAuthChannelType, codeLength: Int)
3030
case passwordRequired(newState: SignInPasswordRequiredState)
31+
case awaitingMFA(newState: AwaitingMFAState)
3132
case error(SignInStartError)
3233
}
3334

3435
typealias SignInResendCodeResult = CodeRequiredGenericResult<SignInCodeRequiredState, ResendCodeError>
3536

3637
enum SignInPasswordRequiredResult {
3738
case completed(MSALNativeAuthUserAccountResult)
39+
case awaitingMFA(newState: AwaitingMFAState)
3840
case error(error: PasswordRequiredError, newState: SignInPasswordRequiredState?)
3941
}
4042

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//
2+
// Copyright (c) Microsoft Corporation.
3+
// All rights reserved.
4+
//
5+
// This code is licensed under the MIT License.
6+
//
7+
// Permission is hereby granted, free of charge, to any person obtaining a copy
8+
// of this software and associated documentation files(the "Software"), to deal
9+
// in the Software without restriction, including without limitation the rights
10+
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
11+
// copies of the Software, and to permit persons to whom the Software is
12+
// furnished to do so, subject to the following conditions :
13+
//
14+
// The above copyright notice and this permission notice shall be included in
15+
// all copies or substantial portions of the Software.
16+
//
17+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
// THE SOFTWARE.
24+
25+
import Foundation
26+
27+
protocol MSALNativeAuthMFAControlling {
28+
29+
typealias MFARequestChallengeControllerResponse = MSALNativeAuthControllerTelemetryWrapper<MFARequestChallengeResult>
30+
typealias MFAGetAuthMethodsControllerResponse = MSALNativeAuthControllerTelemetryWrapper<MFAGetAuthMethodsResult>
31+
typealias MFASubmitChallengeControllerResponse = MSALNativeAuthControllerTelemetryWrapper<MFASubmitChallengeResult>
32+
33+
func requestChallenge(
34+
continuationToken: String,
35+
authMethod: MSALAuthMethod?,
36+
context: MSALNativeAuthRequestContext,
37+
scopes: [String]
38+
) async -> MFARequestChallengeControllerResponse
39+
40+
func getAuthMethods(
41+
continuationToken: String,
42+
context: MSALNativeAuthRequestContext,
43+
scopes: [String]
44+
) async -> MFAGetAuthMethodsControllerResponse
45+
46+
func submitChallenge(
47+
challenge: String,
48+
continuationToken: String,
49+
context: MSALNativeAuthRequestContext,
50+
scopes: [String]) async -> MFASubmitChallengeControllerResponse
51+
}

0 commit comments

Comments
 (0)