--- /dev/null
+//
+// OAuth1Swift.swift
+// OAuthSwift
+//
+// Created by Dongri Jin on 6/22/14.
+// Copyright (c) 2014 Dongri Jin. All rights reserved.
+//
+
+import Foundation
+
+open class OAuth1Swift: OAuthSwift {
+
+ /// If your oauth provider doesn't provide `oauth_verifier`
+ /// set this value to true (default: false)
+ open var allowMissingOAuthVerifier: Bool = false
+
+ /// Optionally add callback URL to authorize Url (default: false)
+ open var addCallbackURLToAuthorizeURL: Bool = false
+
+ var consumerKey: String
+ var consumerSecret: String
+ var requestTokenUrl: String
+ var authorizeUrl: String
+ var accessTokenUrl: String
+
+ // MARK: init
+ public init(consumerKey: String, consumerSecret: String, requestTokenUrl: String, authorizeUrl: String, accessTokenUrl: String) {
+ self.consumerKey = consumerKey
+ self.consumerSecret = consumerSecret
+ self.requestTokenUrl = requestTokenUrl
+ self.authorizeUrl = authorizeUrl
+ self.accessTokenUrl = accessTokenUrl
+ super.init(consumerKey: consumerKey, consumerSecret: consumerSecret)
+ self.client.credential.version = .oauth1
+ }
+
+ public convenience override init(consumerKey: String, consumerSecret: String) {
+ self.init(consumerKey: consumerKey, consumerSecret: consumerSecret, requestTokenUrl: "", authorizeUrl: "", accessTokenUrl: "")
+ }
+
+ public convenience init?(parameters: ConfigParameters) {
+ guard let consumerKey = parameters["consumerKey"], let consumerSecret = parameters["consumerSecret"],
+ let requestTokenUrl = parameters["requestTokenUrl"], let authorizeUrl = parameters["authorizeUrl"], let accessTokenUrl = parameters["accessTokenUrl"] else {
+ return nil
+ }
+ self.init(consumerKey: consumerKey, consumerSecret: consumerSecret,
+ requestTokenUrl: requestTokenUrl,
+ authorizeUrl: authorizeUrl,
+ accessTokenUrl: accessTokenUrl)
+ }
+
+ open var parameters: ConfigParameters {
+ return [
+ "consumerKey": consumerKey,
+ "consumerSecret": consumerSecret,
+ "requestTokenUrl": requestTokenUrl,
+ "authorizeUrl": authorizeUrl,
+ "accessTokenUrl": accessTokenUrl
+ ]
+ }
+
+ // MARK: functions
+ // 0. Start
+ @discardableResult
+ open func authorize(withCallbackURL callbackURL: URL, success: @escaping TokenSuccessHandler, failure: FailureHandler?) -> OAuthSwiftRequestHandle? {
+
+ self.postOAuthRequestToken(callbackURL: callbackURL, success: { [unowned self] credential, _, _ in
+
+ self.observeCallback { [weak self] url in
+ guard let this = self else { OAuthSwift.retainError(failure); return }
+ var responseParameters = [String: String]()
+ if let query = url.query {
+ responseParameters += query.parametersFromQueryString
+ }
+ if let fragment = url.fragment, !fragment.isEmpty {
+ responseParameters += fragment.parametersFromQueryString
+ }
+ if let token = responseParameters["token"] {
+ responseParameters["oauth_token"] = token
+ }
+
+ if let token = responseParameters["oauth_token"], !token.isEmpty {
+ this.client.credential.oauthToken = token.safeStringByRemovingPercentEncoding
+ if let oauth_verifier = responseParameters["oauth_verifier"] {
+ this.client.credential.oauthVerifier = oauth_verifier.safeStringByRemovingPercentEncoding
+ } else {
+ if !this.allowMissingOAuthVerifier {
+ failure?(OAuthSwiftError.configurationError(message: "Missing oauth_verifier. Maybe use allowMissingOAuthVerifier=true"))
+ return
+ }
+ }
+ this.postOAuthAccessTokenWithRequestToken(success: success, failure: failure)
+ } else {
+ failure?(OAuthSwiftError.missingToken)
+ return
+ }
+ }
+ // 2. Authorize
+ if let token = credential.oauthToken.urlQueryEncoded {
+ var urlString = self.authorizeUrl + (self.authorizeUrl.contains("?") ? "&" : "?")
+ urlString += "oauth_token=\(token)"
+ if self.addCallbackURLToAuthorizeURL {
+ urlString += "&oauth_callback=\(callbackURL.absoluteString)"
+ }
+ if let queryURL = URL(string: urlString) {
+ self.authorizeURLHandler.handle(queryURL)
+ } else {
+ failure?(OAuthSwiftError.encodingError(urlString: urlString))
+ }
+ } else {
+ failure?(OAuthSwiftError.encodingError(urlString: credential.oauthToken)) //TODO specific error
+ }
+
+ }, failure: failure)
+
+ return self
+ }
+
+ @discardableResult
+ open func authorize(withCallbackURL urlString: String, success: @escaping TokenSuccessHandler, failure: FailureHandler?) -> OAuthSwiftRequestHandle? {
+ guard let url = URL(string: urlString) else {
+ failure?(OAuthSwiftError.encodingError(urlString: urlString))
+ return nil
+ }
+ return authorize(withCallbackURL: url, success: success, failure: failure)
+ }
+
+ // 1. Request token
+ func postOAuthRequestToken(callbackURL: URL, success: @escaping TokenSuccessHandler, failure: FailureHandler?) {
+ var parameters = [String: Any]()
+ parameters["oauth_callback"] = callbackURL.absoluteString
+
+ if let handle = self.client.post(
+ self.requestTokenUrl, parameters: parameters,
+ success: { [weak self] response in
+ guard let this = self else { OAuthSwift.retainError(failure); return }
+ let parameters = response.string?.parametersFromQueryString ?? [:]
+ if let oauthToken = parameters["oauth_token"] {
+ this.client.credential.oauthToken = oauthToken.safeStringByRemovingPercentEncoding
+ }
+ if let oauthTokenSecret=parameters["oauth_token_secret"] {
+ this.client.credential.oauthTokenSecret = oauthTokenSecret.safeStringByRemovingPercentEncoding
+ }
+ success(this.client.credential, response, parameters)
+ }, failure: failure
+ ) {
+ self.putHandle(handle, withKey: UUID().uuidString)
+ }
+ }
+
+ // 3. Get Access token
+ func postOAuthAccessTokenWithRequestToken(success: @escaping TokenSuccessHandler, failure: FailureHandler?) {
+ var parameters = [String: Any]()
+ parameters["oauth_token"] = self.client.credential.oauthToken
+ if !self.allowMissingOAuthVerifier {
+ parameters["oauth_verifier"] = self.client.credential.oauthVerifier
+ }
+
+ if let handle = self.client.post(
+ self.accessTokenUrl, parameters: parameters,
+ success: { [weak self] response in
+ guard let this = self else { OAuthSwift.retainError(failure); return }
+ let parameters = response.string?.parametersFromQueryString ?? [:]
+ if let oauthToken = parameters["oauth_token"] {
+ this.client.credential.oauthToken = oauthToken.safeStringByRemovingPercentEncoding
+ }
+ if let oauthTokenSecret = parameters["oauth_token_secret"] {
+ this.client.credential.oauthTokenSecret = oauthTokenSecret.safeStringByRemovingPercentEncoding
+ }
+ success(this.client.credential, response, parameters)
+ }, failure: failure
+ ) {
+ self.putHandle(handle, withKey: UUID().uuidString)
+ }
+ }
+
+}