|
|
|
@ -47,7 +47,7 @@ public class RequestMaker: NSObject {
|
|
|
|
|
private let udAuthFailureBlock: UDAuthFailureBlock
|
|
|
|
|
private let websocketFailureBlock: WebsocketFailureBlock
|
|
|
|
|
private let recipientId: String
|
|
|
|
|
private let udAccessKey: SMKUDAccessKey?
|
|
|
|
|
private let udAccess: OWSUDAccess?
|
|
|
|
|
private let canFailoverUDAuth: Bool
|
|
|
|
|
|
|
|
|
|
@objc
|
|
|
|
@ -56,14 +56,14 @@ public class RequestMaker: NSObject {
|
|
|
|
|
udAuthFailureBlock : @escaping UDAuthFailureBlock,
|
|
|
|
|
websocketFailureBlock : @escaping WebsocketFailureBlock,
|
|
|
|
|
recipientId: String,
|
|
|
|
|
udAccessKey: SMKUDAccessKey?,
|
|
|
|
|
udAccess: OWSUDAccess?,
|
|
|
|
|
canFailoverUDAuth: Bool) {
|
|
|
|
|
self.label = label
|
|
|
|
|
self.requestFactoryBlock = requestFactoryBlock
|
|
|
|
|
self.udAuthFailureBlock = udAuthFailureBlock
|
|
|
|
|
self.websocketFailureBlock = websocketFailureBlock
|
|
|
|
|
self.recipientId = recipientId
|
|
|
|
|
self.udAccessKey = udAccessKey
|
|
|
|
|
self.udAccess = udAccess
|
|
|
|
|
self.canFailoverUDAuth = canFailoverUDAuth
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -81,6 +81,10 @@ public class RequestMaker: NSObject {
|
|
|
|
|
return SSKEnvironment.shared.udManager
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private var profileManager: ProfileManagerProtocol {
|
|
|
|
|
return SSKEnvironment.shared.profileManager
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// MARK: -
|
|
|
|
|
|
|
|
|
|
@objc
|
|
|
|
@ -104,37 +108,41 @@ public class RequestMaker: NSObject {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private func makeRequestInternal(skipUD: Bool, skipWebsocket: Bool) -> Promise<RequestMakerResult> {
|
|
|
|
|
var udAccessKeyForRequest: SMKUDAccessKey?
|
|
|
|
|
var udAccessForRequest: OWSUDAccess?
|
|
|
|
|
if !skipUD {
|
|
|
|
|
udAccessKeyForRequest = udAccessKey
|
|
|
|
|
udAccessForRequest = udAccess
|
|
|
|
|
}
|
|
|
|
|
let isUDSend = udAccessKeyForRequest != nil
|
|
|
|
|
let request = requestFactoryBlock(udAccessKeyForRequest)
|
|
|
|
|
let webSocketType: OWSWebSocketType = (isUDSend ? .UD : .default)
|
|
|
|
|
let isUDRequest = udAccessForRequest != nil
|
|
|
|
|
let request = requestFactoryBlock(udAccessForRequest?.udAccessKey)
|
|
|
|
|
let webSocketType: OWSWebSocketType = (isUDRequest ? .UD : .default)
|
|
|
|
|
let canMakeWebsocketRequests = (socketManager.canMakeRequests(of: webSocketType) && !skipWebsocket)
|
|
|
|
|
|
|
|
|
|
if canMakeWebsocketRequests {
|
|
|
|
|
return Promise { resolver in
|
|
|
|
|
socketManager.make(request, webSocketType: webSocketType, success: { (responseObject: Any?) in
|
|
|
|
|
if self.udManager.isUDVerboseLoggingEnabled() {
|
|
|
|
|
if isUDSend {
|
|
|
|
|
if isUDRequest {
|
|
|
|
|
Logger.debug("UD websocket request '\(self.label)' succeeded.")
|
|
|
|
|
} else {
|
|
|
|
|
Logger.debug("Non-UD websocket request '\(self.label)' succeeded.")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resolver.fulfill(RequestMakerResult(responseObject: responseObject, wasSentByUD: isUDSend))
|
|
|
|
|
self.requestSucceeded(udAccess: udAccessForRequest)
|
|
|
|
|
|
|
|
|
|
resolver.fulfill(RequestMakerResult(responseObject: responseObject, wasSentByUD: isUDRequest))
|
|
|
|
|
}) { (statusCode: Int, responseData: Data?, error: Error) in
|
|
|
|
|
resolver.reject(RequestMakerError.websocketRequestError(statusCode: statusCode, responseData: responseData, underlyingError: error))
|
|
|
|
|
}
|
|
|
|
|
}.recover { (error: Error) -> Promise<RequestMakerResult> in
|
|
|
|
|
switch error {
|
|
|
|
|
case RequestMakerError.websocketRequestError(let statusCode, _, _):
|
|
|
|
|
if isUDSend && (statusCode == 401 || statusCode == 403) {
|
|
|
|
|
// If a UD send fails due to service response (as opposed to network
|
|
|
|
|
if isUDRequest && (statusCode == 401 || statusCode == 403) {
|
|
|
|
|
// If a UD request fails due to service response (as opposed to network
|
|
|
|
|
// failure), mark recipient as _not_ in UD mode, then retry.
|
|
|
|
|
self.udManager.setUnidentifiedAccessMode(.disabled, recipientId: self.recipientId)
|
|
|
|
|
self.profileManager.fetchProfile(forRecipientId: self.recipientId)
|
|
|
|
|
|
|
|
|
|
self.udAuthFailureBlock()
|
|
|
|
|
if self.canFailoverUDAuth {
|
|
|
|
|
Logger.info("UD websocket request '\(self.label)' auth failed; failing over to non-UD websocket request.")
|
|
|
|
@ -157,23 +165,27 @@ public class RequestMaker: NSObject {
|
|
|
|
|
return self.networkManager.makePromise(request: request)
|
|
|
|
|
.map { (networkManagerResult: TSNetworkManager.NetworkManagerResult) -> RequestMakerResult in
|
|
|
|
|
if self.udManager.isUDVerboseLoggingEnabled() {
|
|
|
|
|
if isUDSend {
|
|
|
|
|
if isUDRequest {
|
|
|
|
|
Logger.debug("UD REST request '\(self.label)' succeeded.")
|
|
|
|
|
} else {
|
|
|
|
|
Logger.debug("Non-UD REST request '\(self.label)' succeeded.")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
self.requestSucceeded(udAccess: udAccessForRequest)
|
|
|
|
|
|
|
|
|
|
// Unwrap the network manager promise into a request maker promise.
|
|
|
|
|
return RequestMakerResult(responseObject: networkManagerResult.responseObject, wasSentByUD: isUDSend)
|
|
|
|
|
return RequestMakerResult(responseObject: networkManagerResult.responseObject, wasSentByUD: isUDRequest)
|
|
|
|
|
}.recover { (error: Error) -> Promise<RequestMakerResult> in
|
|
|
|
|
switch error {
|
|
|
|
|
case NetworkManagerError.taskError(let task, _):
|
|
|
|
|
let statusCode = task.statusCode()
|
|
|
|
|
if isUDSend && (statusCode == 401 || statusCode == 403) {
|
|
|
|
|
// If a UD send fails due to service response (as opposed to network
|
|
|
|
|
if isUDRequest && (statusCode == 401 || statusCode == 403) {
|
|
|
|
|
// If a UD request fails due to service response (as opposed to network
|
|
|
|
|
// failure), mark recipient as _not_ in UD mode, then retry.
|
|
|
|
|
self.udManager.setUnidentifiedAccessMode(.disabled, recipientId: self.recipientId)
|
|
|
|
|
self.profileManager.fetchProfile(forRecipientId: self.recipientId)
|
|
|
|
|
|
|
|
|
|
self.udAuthFailureBlock()
|
|
|
|
|
if self.canFailoverUDAuth {
|
|
|
|
|
Logger.info("UD REST request '\(self.label)' auth failed; failing over to non-UD REST request.")
|
|
|
|
@ -193,4 +205,24 @@ public class RequestMaker: NSObject {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private func requestSucceeded(udAccess: OWSUDAccess?) {
|
|
|
|
|
guard let udAccess = udAccess else {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
guard udAccess.udAccessMode == .unknown else {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if udAccess.isRandomKey {
|
|
|
|
|
// If a UD request succeeds for an unknown user with a random key,
|
|
|
|
|
// mark recipient as .unrestricted.
|
|
|
|
|
self.udManager.setUnidentifiedAccessMode(.unrestricted, recipientId: self.recipientId)
|
|
|
|
|
} else {
|
|
|
|
|
// If a UD request succeeds for an unknown user with a non-random key,
|
|
|
|
|
// mark recipient as .enabled.
|
|
|
|
|
self.udManager.setUnidentifiedAccessMode(.enabled, recipientId: self.recipientId)
|
|
|
|
|
}
|
|
|
|
|
self.profileManager.fetchProfile(forRecipientId: self.recipientId)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|