64 lines
2.2 KiB
Swift
64 lines
2.2 KiB
Swift
//
|
|
// Copyright Amazon.com Inc. or its affiliates.
|
|
// All Rights Reserved.
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
|
|
import Amplify
|
|
import AppSyncRealTimeClient
|
|
|
|
extension APIError {
|
|
|
|
static let UnauthorizedMessageString: String = "Unauthorized"
|
|
|
|
/// By default, this consolidates unauthorized error scenarios coming from `APIError.httpStatusError` and
|
|
/// `APIError.operationError`. For `.httpStatusError`, this checks if the status code is 401 or 403. For
|
|
/// `.operationError`, this checks if the error description contains "Unauthorized".
|
|
///
|
|
/// **Warning** Customized server responses that indicate unauthorized may not match the internal mapping done
|
|
/// in this API and return `false`. Check APIError enum directly or create your own `UnauthorizedDeterming` rule,
|
|
/// for example:
|
|
/// ```
|
|
/// static let customRule = UnauthorizedDetermining { error in
|
|
/// // Your custom logic to determine if `error` is unauthorized.
|
|
/// // return `true` or `false`.
|
|
/// }
|
|
/// ```
|
|
///
|
|
/// - Parameter rule: Used to determine if the `APIError` is an unauthorized error.
|
|
/// - Returns: `true` if unauthorized error, `false` otherwise
|
|
public func isUnauthorized(rule: UnauthorizedDetermining = .default) -> Bool {
|
|
rule.isUnauthorized(self)
|
|
}
|
|
|
|
public struct UnauthorizedDetermining {
|
|
let isUnauthorized: (APIError) -> Bool
|
|
|
|
public init(isUnauthenticated: @escaping (APIError) -> Bool) {
|
|
self.isUnauthorized = isUnauthenticated
|
|
}
|
|
|
|
public static let `default` = UnauthorizedDetermining { error in
|
|
error.containsUnauthorizedMessageString || error.is401or403
|
|
}
|
|
}
|
|
|
|
private var is401or403: Bool {
|
|
switch self {
|
|
case .httpStatusError(let statusCode, _):
|
|
return statusCode == 401 || statusCode == 403
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
private var containsUnauthorizedMessageString: Bool {
|
|
switch self {
|
|
case .operationError(let errorDescription, _, _):
|
|
return errorDescription.range(of: APIError.UnauthorizedMessageString, options: .caseInsensitive) != nil
|
|
default: return false
|
|
}
|
|
}
|
|
}
|