Last active
March 8, 2021 16:56
-
-
Save markvanwijnen/4b66de2f924527d5e4b338b85f01873e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func oAuthRequestTokenPublisher() -> AnyPublisher<TemporaryCredentials, OAuthError> { | |
// 1 | |
let request = (baseURLString: "https://api.twitter.com/oauth/request_token", | |
httpMethod: "POST", | |
consumerKey: ClientCredentials.APIKey, | |
consumerSecret: ClientCredentials.APIKeySecret, | |
callbackURLString: "\(ClientCredentials.CallbackURLScheme)://") | |
// 2 | |
guard let baseURL = URL(string: request.baseURLString) else { | |
return Fail(error: OAuthError.urlError(URLError(.badURL))) | |
.eraseToAnyPublisher() | |
} | |
// 3 | |
var parameters = [ | |
URLQueryItem(name: "oauth_callback", value: request.callbackURLString), | |
URLQueryItem(name: "oauth_consumer_key", value: request.consumerKey), | |
URLQueryItem(name: "oauth_nonce", value: UUID().uuidString), | |
URLQueryItem(name: "oauth_signature_method", value: "HMAC-SHA1"), | |
URLQueryItem(name: "oauth_timestamp", value: String(Int(Date().timeIntervalSince1970))), | |
URLQueryItem(name: "oauth_version", value: "1.0") | |
] | |
// 4 | |
let signature = oAuthSignature(httpMethod: request.httpMethod, | |
baseURLString: request.baseURLString, | |
parameters: parameters, | |
consumerSecret: request.consumerSecret) | |
// 5 | |
parameters.append(URLQueryItem(name: "oauth_signature", value: signature)) | |
// 6 | |
var urlRequest = URLRequest(url: baseURL) | |
urlRequest.httpMethod = request.httpMethod | |
urlRequest.setValue(oAuthAuthorizationHeader(parameters: parameters), | |
forHTTPHeaderField: "Authorization") | |
return | |
//7 | |
URLSession.shared.dataTaskPublisher(for: urlRequest) | |
// 8 | |
.tryMap { data, response -> TemporaryCredentials in | |
// 9 | |
guard let response = response as? HTTPURLResponse | |
else { throw OAuthError.unknown } | |
// 10 | |
guard response.statusCode == 200 | |
else { throw OAuthError.httpURLResponse(response.statusCode) } | |
// 11 | |
guard let parameterString = String(data: data, encoding: .utf8) | |
else { throw OAuthError.cannotDecodeRawData } | |
// 12 | |
if let parameters = parameterString.urlQueryItems { | |
// 13 | |
guard let oAuthToken = parameters["oauth_token"], | |
let oAuthTokenSecret = parameters["oauth_token_secret"], | |
let oAuthCallbackConfirmed = parameters["oauth_callback_confirmed"] | |
else { | |
throw OAuthError.unexpectedResponse | |
} | |
// 14 | |
if oAuthCallbackConfirmed != "true" { | |
throw OAuthError.failedToConfirmCallback | |
} | |
// 15 | |
return TemporaryCredentials(requestToken: oAuthToken, | |
requestTokenSecret: oAuthTokenSecret) | |
} else { | |
throw OAuthError.cannotParseResponse | |
} | |
} | |
// 16 | |
.mapError { error -> OAuthError in | |
switch (error) { | |
case let oAuthError as OAuthError: | |
return oAuthError | |
default: | |
return OAuthError.unknown | |
} | |
} | |
// 17 | |
.eraseToAnyPublisher() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment