5 // Created by Dongri Jin on 6/22/14.
6 // Copyright (c) 2014 Dongri Jin. All rights reserved.
11 open class OAuth1Swift: OAuthSwift {
13 /// If your oauth provider doesn't provide `oauth_verifier`
14 /// set this value to true (default: false)
15 open var allowMissingOAuthVerifier: Bool = false
17 /// Optionally add callback URL to authorize Url (default: false)
18 open var addCallbackURLToAuthorizeURL: Bool = false
20 var consumerKey: String
21 var consumerSecret: String
22 var requestTokenUrl: String
23 var authorizeUrl: String
24 var accessTokenUrl: String
27 public init(consumerKey: String, consumerSecret: String, requestTokenUrl: String, authorizeUrl: String, accessTokenUrl: String) {
28 self.consumerKey = consumerKey
29 self.consumerSecret = consumerSecret
30 self.requestTokenUrl = requestTokenUrl
31 self.authorizeUrl = authorizeUrl
32 self.accessTokenUrl = accessTokenUrl
33 super.init(consumerKey: consumerKey, consumerSecret: consumerSecret)
34 self.client.credential.version = .oauth1
37 public convenience override init(consumerKey: String, consumerSecret: String) {
38 self.init(consumerKey: consumerKey, consumerSecret: consumerSecret, requestTokenUrl: "", authorizeUrl: "", accessTokenUrl: "")
41 public convenience init?(parameters: ConfigParameters) {
42 guard let consumerKey = parameters["consumerKey"], let consumerSecret = parameters["consumerSecret"],
43 let requestTokenUrl = parameters["requestTokenUrl"], let authorizeUrl = parameters["authorizeUrl"], let accessTokenUrl = parameters["accessTokenUrl"] else {
46 self.init(consumerKey: consumerKey, consumerSecret: consumerSecret,
47 requestTokenUrl: requestTokenUrl,
48 authorizeUrl: authorizeUrl,
49 accessTokenUrl: accessTokenUrl)
52 open var parameters: ConfigParameters {
54 "consumerKey": consumerKey,
55 "consumerSecret": consumerSecret,
56 "requestTokenUrl": requestTokenUrl,
57 "authorizeUrl": authorizeUrl,
58 "accessTokenUrl": accessTokenUrl
65 open func authorize(withCallbackURL callbackURL: URL, success: @escaping TokenSuccessHandler, failure: FailureHandler?) -> OAuthSwiftRequestHandle? {
67 self.postOAuthRequestToken(callbackURL: callbackURL, success: { [unowned self] credential, _, _ in
69 self.observeCallback { [weak self] url in
70 guard let this = self else { OAuthSwift.retainError(failure); return }
71 var responseParameters = [String: String]()
72 if let query = url.query {
73 responseParameters += query.parametersFromQueryString
75 if let fragment = url.fragment, !fragment.isEmpty {
76 responseParameters += fragment.parametersFromQueryString
78 if let token = responseParameters["token"] {
79 responseParameters["oauth_token"] = token
82 if let token = responseParameters["oauth_token"], !token.isEmpty {
83 this.client.credential.oauthToken = token.safeStringByRemovingPercentEncoding
84 if let oauth_verifier = responseParameters["oauth_verifier"] {
85 this.client.credential.oauthVerifier = oauth_verifier.safeStringByRemovingPercentEncoding
87 if !this.allowMissingOAuthVerifier {
88 failure?(OAuthSwiftError.configurationError(message: "Missing oauth_verifier. Maybe use allowMissingOAuthVerifier=true"))
92 this.postOAuthAccessTokenWithRequestToken(success: success, failure: failure)
94 failure?(OAuthSwiftError.missingToken)
99 if let token = credential.oauthToken.urlQueryEncoded {
100 var urlString = self.authorizeUrl + (self.authorizeUrl.contains("?") ? "&" : "?")
101 urlString += "oauth_token=\(token)"
102 if self.addCallbackURLToAuthorizeURL {
103 urlString += "&oauth_callback=\(callbackURL.absoluteString)"
105 if let queryURL = URL(string: urlString) {
106 self.authorizeURLHandler.handle(queryURL)
108 failure?(OAuthSwiftError.encodingError(urlString: urlString))
111 failure?(OAuthSwiftError.encodingError(urlString: credential.oauthToken)) //TODO specific error
120 open func authorize(withCallbackURL urlString: String, success: @escaping TokenSuccessHandler, failure: FailureHandler?) -> OAuthSwiftRequestHandle? {
121 guard let url = URL(string: urlString) else {
122 failure?(OAuthSwiftError.encodingError(urlString: urlString))
125 return authorize(withCallbackURL: url, success: success, failure: failure)
129 func postOAuthRequestToken(callbackURL: URL, success: @escaping TokenSuccessHandler, failure: FailureHandler?) {
130 var parameters = [String: Any]()
131 parameters["oauth_callback"] = callbackURL.absoluteString
133 if let handle = self.client.post(
134 self.requestTokenUrl, parameters: parameters,
135 success: { [weak self] response in
136 guard let this = self else { OAuthSwift.retainError(failure); return }
137 let parameters = response.string?.parametersFromQueryString ?? [:]
138 if let oauthToken = parameters["oauth_token"] {
139 this.client.credential.oauthToken = oauthToken.safeStringByRemovingPercentEncoding
141 if let oauthTokenSecret=parameters["oauth_token_secret"] {
142 this.client.credential.oauthTokenSecret = oauthTokenSecret.safeStringByRemovingPercentEncoding
144 success(this.client.credential, response, parameters)
147 self.putHandle(handle, withKey: UUID().uuidString)
151 // 3. Get Access token
152 func postOAuthAccessTokenWithRequestToken(success: @escaping TokenSuccessHandler, failure: FailureHandler?) {
153 var parameters = [String: Any]()
154 parameters["oauth_token"] = self.client.credential.oauthToken
155 if !self.allowMissingOAuthVerifier {
156 parameters["oauth_verifier"] = self.client.credential.oauthVerifier
159 if let handle = self.client.post(
160 self.accessTokenUrl, parameters: parameters,
161 success: { [weak self] response in
162 guard let this = self else { OAuthSwift.retainError(failure); return }
163 let parameters = response.string?.parametersFromQueryString ?? [:]
164 if let oauthToken = parameters["oauth_token"] {
165 this.client.credential.oauthToken = oauthToken.safeStringByRemovingPercentEncoding
167 if let oauthTokenSecret = parameters["oauth_token_secret"] {
168 this.client.credential.oauthTokenSecret = oauthTokenSecret.safeStringByRemovingPercentEncoding
170 success(this.client.credential, response, parameters)
173 self.putHandle(handle, withKey: UUID().uuidString)