Skip to content

Commit

Permalink
Report any errors that occur during interactions with Credential.default
Browse files Browse the repository at this point in the history
  • Loading branch information
mikenachbaur-okta committed Sep 26, 2024
1 parent 3ca3e3b commit bbc0be1
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 18 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ on:
- 'Tests/**/*.swift'

env:
DEVELOPER_DIR: /Applications/Xcode_15.4.app/Contents/Developer
DEVELOPER_DIR: /Applications/Xcode_16.app/Contents/Developer
NSUnbufferedIO: YES

jobs:
Expand Down Expand Up @@ -71,6 +71,7 @@ jobs:
destination:
- "platform=iOS Simulator,OS=16.4,name=iPhone 14 Pro Max"
- "platform=iOS Simulator,OS=17.5,name=iPhone 15 Pro Max"
- "platform=iOS Simulator,OS=18.0,name=iPhone 16 Pro Max"
- "platform=tvOS Simulator,OS=17.5,name=Apple TV"
- "platform=visionOS Simulator,OS=1.2,name=Apple Vision Pro"
- "platform=watchOS Simulator,OS=10.5,name=Apple Watch Series 7 (45mm)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,21 @@ final class KeychainTokenStorage: TokenStorage {
weak var delegate: TokenStorageDelegate?

private(set) lazy var defaultTokenID: String? = {
guard let defaultResult = try? Keychain
do {
let defaultResult = try Keychain
.Search(account: KeychainTokenStorage.defaultTokenName)
.get(),
let id = String(data: defaultResult.value, encoding: .utf8)
else {
.get()
guard let id = String(data: defaultResult.value, encoding: .utf8)
else {
return nil
}

return id
} catch {
NSLog("Unexpected error while loading the default token ID from the keychain: %@", error.localizedDescription)
NotificationCenter.default.post(name: .credentialDefaultError, object: error)
return nil
}

return id
}()

func setDefaultTokenID(_ id: String?) throws {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ extension Notification.Name {

/// Notification broadcast when a credential fails to refresh.
public static let credentialRefreshFailed = Notification.Name("com.okta.credential.refresh.failed")

/// Notification broadcast when an internal error occurs with the default credential static member.
public static let credentialDefaultError = Notification.Name("com.okta.credential.default.error")
}

@available(iOS 13.0, tvOS 13.0, macOS 10.15, watchOS 6, *)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,15 @@ final class CredentialCoordinatorImpl: CredentialCoordinator {
didSet {
tokenStorage.delegate = self

_default = try? CredentialCoordinatorImpl.defaultCredential(
tokenStorage: tokenStorage,
credentialDataSource: credentialDataSource,
coordinator: self)
do {
_default = try CredentialCoordinatorImpl.defaultCredential(
tokenStorage: tokenStorage,
credentialDataSource: credentialDataSource,
coordinator: self)
} catch {
NSLog("Unexpected error when initializing the initial default credential during TokenStorage assignment: %@", error.localizedDescription)
NotificationCenter.default.post(name: .credentialDefaultError, object: error)
}
}
}

Expand All @@ -41,19 +46,27 @@ final class CredentialCoordinatorImpl: CredentialCoordinator {
credentialDataSource: credentialDataSource,
coordinator: self)
} catch {
// Placeholder for when logging is added in a future release
NSLog("Unexpected error when initializing the initial value for the default credential: %@", error.localizedDescription)
NotificationCenter.default.post(name: .credentialDefaultError, object: error)
return nil
}
}()
var `default`: Credential? {
get { _default }
set {
if let token = newValue?.token {
try? tokenStorage.add(token: token,
metadata: Token.Metadata(id: token.id),
security: Credential.Security.standard)
do {
if let token = newValue?.token,
!tokenStorage.allIDs.contains(token.id)
{
try tokenStorage.add(token: token,
metadata: Token.Metadata(id: token.id),
security: Credential.Security.standard)
}
try tokenStorage.setDefaultTokenID(newValue?.id)
} catch {
NSLog("Unexpected error while assigning a default credential: %@", error.localizedDescription)
NotificationCenter.default.post(name: .credentialDefaultError, object: error)
}
try? tokenStorage.setDefaultTokenID(newValue?.id)
}
}

Expand Down
13 changes: 12 additions & 1 deletion Tests/AuthFoundationTests/CredentialCoordinatorTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,26 @@ final class UserCoordinatorTests: XCTestCase {
XCTAssertEqual(try coordinator.with(id: token.id, prompt: nil, authenticationContext: nil), credential)
}

func testDirectAssignmentToCredentialDefault() throws {
XCTAssertNil(coordinator.default)
let token = Token.simpleMockToken
coordinator.default = try coordinator.store(token: token, tags: [:], security: Credential.Security.standard)
XCTAssertNotNil(coordinator.default)
XCTAssertEqual(coordinator.default?.id, token.id)
}

func testImplicitCredentialForToken() throws {
XCTAssertTrue(storage.allIDs.isEmpty)
XCTAssertNil(coordinator.default)

let credential = try coordinator.store(token: token, tags: [:], security: [])

XCTAssertEqual(storage.allIDs, [token.id])
XCTAssertEqual(storage.defaultTokenID, token.id)
XCTAssertEqual(coordinator.default, credential)
}

func testNotifications() throws {
func testCredentialChangedNotification() throws {
let oldCredential = coordinator.default

let recorder = NotificationRecorder(observing: [.defaultCredentialChanged])
Expand Down

0 comments on commit bbc0be1

Please sign in to comment.