Skip to content

Commit ad9c2dd

Browse files
Merge pull request #72 from okta/iabdullin/success_state_fix
Unlock account flow: Success status creation failure
2 parents 6dd0e75 + 552532c commit ad9c2dd

File tree

8 files changed

+169
-5
lines changed

8 files changed

+169
-5
lines changed

OktaAuthNative.xcodeproj/project.pbxproj

+12
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,9 @@
122122
A1E7469F2283819700C48A28 /* MFA_ENROLL_ACTIVATE_CALL in Resources */ = {isa = PBXBuildFile; fileRef = A1E7469E2283819700C48A28 /* MFA_ENROLL_ACTIVATE_CALL */; };
123123
A1E746A0228381D400C48A28 /* MFA_ENROLL_ACTIVATE_CALL in Resources */ = {isa = PBXBuildFile; fileRef = A1E7469E2283819700C48A28 /* MFA_ENROLL_ACTIVATE_CALL */; };
124124
A1E746A22283830F00C48A28 /* OktaFactorOtherTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1E746A12283830F00C48A28 /* OktaFactorOtherTests.swift */; };
125+
A1F9E5922298729100924F7A /* MFA_ENROLL_ACTIVATE_TOTP in Resources */ = {isa = PBXBuildFile; fileRef = A1F9E5912298729100924F7A /* MFA_ENROLL_ACTIVATE_TOTP */; };
126+
A1F9E594229888BC00924F7A /* SUCCESS_UNLOCK in Resources */ = {isa = PBXBuildFile; fileRef = A1F9E593229888BC00924F7A /* SUCCESS_UNLOCK */; };
127+
A1F9E5962298895600924F7A /* OktaAuthStatusSuccessTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1F9E5952298895500924F7A /* OktaAuthStatusSuccessTests.swift */; };
125128
A1FCB12F220A458F0026F522 /* OktaAPIMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1FCB12E220A458F0026F522 /* OktaAPIMock.swift */; };
126129
FA4ED9A021C1499200A065A1 /* OktaAuth_iOS.h in Headers */ = {isa = PBXBuildFile; fileRef = FA4ED99E21C1499200A065A1 /* OktaAuth_iOS.h */; settings = {ATTRIBUTES = (Public, ); }; };
127130
FA4ED9AA21C2895B00A065A1 /* OktaError.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA4ED9A921C2895B00A065A1 /* OktaError.swift */; };
@@ -222,6 +225,9 @@
222225
A1E7469C22837E7400C48A28 /* OktaFactorCallTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OktaFactorCallTests.swift; sourceTree = "<group>"; };
223226
A1E7469E2283819700C48A28 /* MFA_ENROLL_ACTIVATE_CALL */ = {isa = PBXFileReference; lastKnownFileType = text; path = MFA_ENROLL_ACTIVATE_CALL; sourceTree = "<group>"; };
224227
A1E746A12283830F00C48A28 /* OktaFactorOtherTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OktaFactorOtherTests.swift; sourceTree = "<group>"; };
228+
A1F9E5912298729100924F7A /* MFA_ENROLL_ACTIVATE_TOTP */ = {isa = PBXFileReference; lastKnownFileType = text; path = MFA_ENROLL_ACTIVATE_TOTP; sourceTree = "<group>"; };
229+
A1F9E593229888BC00924F7A /* SUCCESS_UNLOCK */ = {isa = PBXFileReference; lastKnownFileType = text; path = SUCCESS_UNLOCK; sourceTree = "<group>"; };
230+
A1F9E5952298895500924F7A /* OktaAuthStatusSuccessTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OktaAuthStatusSuccessTests.swift; sourceTree = "<group>"; };
225231
A1FCB12E220A458F0026F522 /* OktaAPIMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OktaAPIMock.swift; sourceTree = "<group>"; };
226232
FA4ED99B21C1499200A065A1 /* OktaAuthNative.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = OktaAuthNative.framework; sourceTree = BUILT_PRODUCTS_DIR; };
227233
FA4ED99E21C1499200A065A1 /* OktaAuth_iOS.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OktaAuth_iOS.h; sourceTree = "<group>"; };
@@ -298,6 +304,7 @@
298304
A151096B2281FD3F009AF8EB /* OktaAuthStatusPasswordWarningTests.swift */,
299305
A1E746432282050F00C48A28 /* OktaAuthStatusRecoveryChallengeTests.swift */,
300306
A1E746472282359B00C48A28 /* OktaAuthStatusRecoveryTests.swift */,
307+
A1F9E5952298895500924F7A /* OktaAuthStatusSuccessTests.swift */,
301308
);
302309
path = Statuses;
303310
sourceTree = "<group>";
@@ -336,6 +343,8 @@
336343
A1E74645228207A800C48A28 /* RECOVERY_CHALLENGE_EMAIL */,
337344
A1E7465522834B9800C48A28 /* Questions */,
338345
A1E7469E2283819700C48A28 /* MFA_ENROLL_ACTIVATE_CALL */,
346+
A1F9E5912298729100924F7A /* MFA_ENROLL_ACTIVATE_TOTP */,
347+
A1F9E593229888BC00924F7A /* SUCCESS_UNLOCK */,
339348
);
340349
path = Resources;
341350
sourceTree = "<group>";
@@ -584,12 +593,14 @@
584593
2F8155932270B740009FA6C5 /* LOCKED_OUT in Resources */,
585594
2F7C3BBF226DED2300A62FD4 /* MFA_ENROLL_NotEnrolled in Resources */,
586595
2FF5C85921D3A9E700EECA75 /* OperationNotAllowedError in Resources */,
596+
A1F9E594229888BC00924F7A /* SUCCESS_UNLOCK in Resources */,
587597
A1671554227BA90700E7801D /* Unknown_State_And_FactorResult in Resources */,
588598
2F7C3BC0226DED2300A62FD4 /* MFA_ENROLL_PartiallyEnrolled in Resources */,
589599
2F7C3BC1226DED2300A62FD4 /* MFA_ENROLL_ACTIVATE_SMS in Resources */,
590600
2F7C3BC5226DED2300A62FD4 /* MFA_CHALLENGE_TOTP in Resources */,
591601
2F7C3BBE226DED1E00A62FD4 /* MFA_CHALLENGE_WAITING_PUSH in Resources */,
592602
2FF5C85221D1078E00EECA75 /* PrimaryAuthResponse in Resources */,
603+
A1F9E5922298729100924F7A /* MFA_ENROLL_ACTIVATE_TOTP in Resources */,
593604
A1E74646228207A800C48A28 /* RECOVERY_CHALLENGE_EMAIL in Resources */,
594605
2F7C3BBD226DED1B00A62FD4 /* SUCCESS in Resources */,
595606
);
@@ -662,6 +673,7 @@
662673
A1E746A22283830F00C48A28 /* OktaFactorOtherTests.swift in Sources */,
663674
A1920FC122615A97007D50D2 /* OktaAuthStatusPasswordWarning.swift in Sources */,
664675
A1920FA622615A97007D50D2 /* OktaAuthStatusRecoveryChallenge.swift in Sources */,
676+
A1F9E5962298895600924F7A /* OktaAuthStatusSuccessTests.swift in Sources */,
665677
2F7C3B7E2268B83400A62FD4 /* OktaFactorPushTests.swift in Sources */,
666678
A1E746482282359B00C48A28 /* OktaAuthStatusRecoveryTests.swift in Sources */,
667679
2F7C3B7A2268AF2800A62FD4 /* OktaAPIRequestTests.swift in Sources */,

Source/Factors/OktaFactorTotp.swift

+18
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,24 @@ import Foundation
1414

1515
open class OktaFactorTotp : OktaFactor {
1616

17+
public var activation: EmbeddedResponse.Factor.Embedded.Activation? {
18+
get {
19+
return factor.embedded?.activation
20+
}
21+
}
22+
23+
public var activationLinks: LinksResponse? {
24+
get {
25+
return factor.embedded?.activation?.links
26+
}
27+
}
28+
29+
public var qrCodeLink: LinksResponse.QRCode? {
30+
get {
31+
return factor.embedded?.activation?.links?.qrcode
32+
}
33+
}
34+
1735
public func enroll(onStatusChange: @escaping (_ newStatus: OktaAuthStatus) -> Void,
1836
onError: @escaping (_ error: OktaError) -> Void) {
1937
self.enroll(questionId: nil,

Source/Statuses/OktaAuthStatusSuccess.swift

+8-5
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,16 @@ import Foundation
1414

1515
open class OktaAuthStatusSuccess : OktaAuthStatus {
1616

17-
public var sessionToken: String
17+
open var recoveryType: OktaAPISuccessResponse.RecoveryType? {
18+
get {
19+
return model.recoveryType
20+
}
21+
}
22+
23+
public var sessionToken: String?
1824

1925
public override init(currentState: OktaAuthStatus, model: OktaAPISuccessResponse) throws {
20-
guard let sessionToken = model.sessionToken else {
21-
throw OktaError.invalidResponse
22-
}
23-
self.sessionToken = sessionToken
26+
self.sessionToken = model.sessionToken
2427
try super.init(currentState: currentState, model: model)
2528
statusType = .success
2629
}

Tests/Factors/OktaFactorTotpTests.swift

+15
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,21 @@ import XCTest
1414
@testable import OktaAuthNative
1515

1616
class OktaFactorTotpTests: OktaFactorTestCase {
17+
18+
func testActivation() {
19+
guard let factor: OktaFactorTotp = createFactor(from: .MFA_ENROLL_ACTIVATE_TOTP, type: .TOTP) else {
20+
XCTFail()
21+
return
22+
}
23+
24+
XCTAssertNotNil(factor.activation)
25+
XCTAssertNotNil(factor.activationLinks)
26+
XCTAssertNotNil(factor.activationLinks?.qrcode)
27+
XCTAssertEqual(
28+
"https://test.domain.com.com/api/v1/users/factors/qr/cQYp5xpm",
29+
factor.qrCodeLink?.href.absoluteString
30+
)
31+
}
1732

1833
// MARK: - verify
1934

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
{
2+
"stateToken":"00_id3fUof3vX9Fy1H3qejz7izKh1gou0rOWkwJesi",
3+
"expiresAt":"2019-04-18T15:43:41.000Z",
4+
"status":"MFA_ENROLL_ACTIVATE",
5+
"_embedded":{
6+
"user":{
7+
"id":"00ujbyedtoxuuXn9l0h7",
8+
"passwordChanged":"2019-02-11T14:09:22.000Z",
9+
"profile":{
10+
"login":"ayurok",
11+
"firstName":"ayurok",
12+
"lastName":"ayurok",
13+
"locale":"en",
14+
"timeZone":"America/Los_Angeles"
15+
}
16+
},
17+
"factor":{
18+
"id":"opfkdh40kws5XarDb0h7",
19+
"factorType":"token:software:totp",
20+
"provider":"OKTA",
21+
"vendorName":"OKTA",
22+
"_embedded":{
23+
"activation":{
24+
"expiresAt":"2019-04-18T15:48:41.000Z",
25+
"_links":{
26+
"qrcode":{
27+
"href":"https://test.domain.com.com/api/v1/users/factors/qr/cQYp5xpm",
28+
"type":"image/png"
29+
}
30+
}
31+
}
32+
}
33+
}
34+
},
35+
"_links":{
36+
"next":{
37+
"name":"activate",
38+
"href":"https://test.domain.com/api/v1/authn/factors/mbljbyz1nyglPZm000h7/lifecycle/activate",
39+
"hints":{
40+
"allow":[
41+
"POST"
42+
]
43+
}
44+
},
45+
"cancel":{
46+
"href":"https://test.domain.com/api/v1/authn/cancel",
47+
"hints":{
48+
"allow":[
49+
"POST"
50+
]
51+
}
52+
},
53+
"prev":{
54+
"href":"https://test.domain.com/api/v1/authn/previous",
55+
"hints":{
56+
"allow":[
57+
"POST"
58+
]
59+
}
60+
}
61+
}
62+
}

Tests/Resources/SUCCESS_UNLOCK

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"status":"SUCCESS","recoveryType":"UNLOCK","_embedded":{"user":{"id":"00u2rejxahomC7fZP0g7","passwordChanged":"2019-05-23T20:17:50.000Z","profile":{"login":"ildar.abdullin@okta.com","firstName":"Ildar","lastName":"Abdullin","locale":"en","timeZone":"America/Los_Angeles"}}}}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright (c) 2019, Okta, Inc. and/or its affiliates. All rights reserved.
3+
* The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")
4+
*
5+
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
6+
* Unless required by applicable law or agreed to in writing, software
7+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
8+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9+
*
10+
* See the License for the specific language governing permissions and limitations under the License.
11+
*/
12+
13+
import XCTest
14+
15+
class OktaAuthStatusSuccessTests: XCTestCase {
16+
17+
func testSuccessSignIn() {
18+
guard let status = createStatus() else {
19+
XCTFail()
20+
return
21+
}
22+
23+
XCTAssertNotNil(status.sessionToken)
24+
XCTAssertNil(status.recoveryType)
25+
}
26+
27+
func testSuccessUnlock() {
28+
guard let status = createStatus(from: OktaAuthStatusUnauthenticated(oktaDomain: URL(string: "http://test.com")!),
29+
withResponse: .SUCCESS_UNLOCK) else {
30+
XCTFail()
31+
return
32+
}
33+
34+
XCTAssertNil(status.sessionToken)
35+
XCTAssertNotNil(status.recoveryType)
36+
}
37+
38+
// MARK: - Utils
39+
40+
func createStatus(
41+
from currentStatus: OktaAuthStatus = OktaAuthStatusUnauthenticated(oktaDomain: URL(string: "http://test.com")!),
42+
withResponse response: TestResponse = .SUCCESS)
43+
-> OktaAuthStatusSuccess? {
44+
45+
guard let response = response.parse() else {
46+
return nil
47+
}
48+
49+
return try? OktaAuthStatusSuccess(currentState: currentStatus, model: response)
50+
}
51+
}

Tests/Utils/TestResponse.swift

+2
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@ enum TestResponse: String {
2020
case MFA_ENROLL_ACTIVATE_SMS = "MFA_ENROLL_ACTIVATE_SMS"
2121
case MFA_ENROLL_ACTIVATE_CALL = "MFA_ENROLL_ACTIVATE_CALL"
2222
case MFA_ENROLL_ACTIVATE_Push = "MFA_ENROLL_ACTIVATE_Push"
23+
case MFA_ENROLL_ACTIVATE_TOTP = "MFA_ENROLL_ACTIVATE_TOTP"
2324
case MFA_REQUIRED = "MFA_REQUIRED"
2425
case MFA_CHALLENGE_SMS = "MFA_CHALLENGE_SMS"
2526
case MFA_CHALLENGE_TOTP = "MFA_CHALLENGE_TOTP"
2627
case MFA_CHALLENGE_WAITING_PUSH = "MFA_CHALLENGE_WAITING_PUSH"
2728
case SUCCESS = "SUCCESS"
29+
case SUCCESS_UNLOCK = "SUCCESS_UNLOCK"
2830
case PASSWORD_WARNING = "PASSWORD_WARN"
2931
case PASSWORD_EXPIRED = "PASSWORD_EXPIRED"
3032
case PASSWORD_RESET = "PASSWORD_RESET"

0 commit comments

Comments
 (0)