added iOS source code
[wl-app.git] / iOS / Pods / OAuthSwift / Sources / OAuth1Swift.swift
1 //
2 //  OAuth1Swift.swift
3 //  OAuthSwift
4 //
5 //  Created by Dongri Jin on 6/22/14.
6 //  Copyright (c) 2014 Dongri Jin. All rights reserved.
7 //
8
9 import Foundation
10
11 open class OAuth1Swift: OAuthSwift {
12
13     /// If your oauth provider doesn't provide `oauth_verifier`
14     /// set this value to true (default: false)
15     open var allowMissingOAuthVerifier: Bool = false
16
17     /// Optionally add callback URL to authorize Url (default: false)
18     open var addCallbackURLToAuthorizeURL: Bool = false
19
20     var consumerKey: String
21     var consumerSecret: String
22     var requestTokenUrl: String
23     var authorizeUrl: String
24     var accessTokenUrl: String
25
26     // MARK: init
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
35     }
36
37     public convenience override init(consumerKey: String, consumerSecret: String) {
38         self.init(consumerKey: consumerKey, consumerSecret: consumerSecret, requestTokenUrl: "", authorizeUrl: "", accessTokenUrl: "")
39     }
40
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 {
44             return nil
45         }
46         self.init(consumerKey: consumerKey, consumerSecret: consumerSecret,
47           requestTokenUrl: requestTokenUrl,
48           authorizeUrl: authorizeUrl,
49           accessTokenUrl: accessTokenUrl)
50     }
51
52     open var parameters: ConfigParameters {
53         return [
54             "consumerKey": consumerKey,
55             "consumerSecret": consumerSecret,
56             "requestTokenUrl": requestTokenUrl,
57             "authorizeUrl": authorizeUrl,
58             "accessTokenUrl": accessTokenUrl
59         ]
60     }
61
62     // MARK: functions
63     // 0. Start
64     @discardableResult
65     open func authorize(withCallbackURL callbackURL: URL, success: @escaping TokenSuccessHandler, failure: FailureHandler?) -> OAuthSwiftRequestHandle? {
66
67         self.postOAuthRequestToken(callbackURL: callbackURL, success: { [unowned self] credential, _, _ in
68
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
74                 }
75                 if let fragment = url.fragment, !fragment.isEmpty {
76                     responseParameters += fragment.parametersFromQueryString
77                 }
78                 if let token = responseParameters["token"] {
79                     responseParameters["oauth_token"] = token
80                 }
81
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
86                     } else {
87                         if !this.allowMissingOAuthVerifier {
88                             failure?(OAuthSwiftError.configurationError(message: "Missing oauth_verifier. Maybe use allowMissingOAuthVerifier=true"))
89                             return
90                         }
91                     }
92                     this.postOAuthAccessTokenWithRequestToken(success: success, failure: failure)
93                 } else {
94                     failure?(OAuthSwiftError.missingToken)
95                     return
96                 }
97             }
98             // 2. Authorize
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)"
104                 }
105                 if let queryURL = URL(string: urlString) {
106                     self.authorizeURLHandler.handle(queryURL)
107                 } else {
108                     failure?(OAuthSwiftError.encodingError(urlString: urlString))
109                 }
110             } else {
111                 failure?(OAuthSwiftError.encodingError(urlString: credential.oauthToken)) //TODO specific error
112             }
113
114         }, failure: failure)
115
116         return self
117     }
118
119     @discardableResult
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))
123             return nil
124         }
125         return authorize(withCallbackURL: url, success: success, failure: failure)
126     }
127
128     // 1. Request token
129     func postOAuthRequestToken(callbackURL: URL, success: @escaping TokenSuccessHandler, failure: FailureHandler?) {
130         var parameters = [String: Any]()
131         parameters["oauth_callback"] = callbackURL.absoluteString
132
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
140                 }
141                 if let oauthTokenSecret=parameters["oauth_token_secret"] {
142                     this.client.credential.oauthTokenSecret = oauthTokenSecret.safeStringByRemovingPercentEncoding
143                 }
144                 success(this.client.credential, response, parameters)
145             }, failure: failure
146             ) {
147             self.putHandle(handle, withKey: UUID().uuidString)
148         }
149     }
150
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
157         }
158
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
166                 }
167                 if let oauthTokenSecret = parameters["oauth_token_secret"] {
168                     this.client.credential.oauthTokenSecret = oauthTokenSecret.safeStringByRemovingPercentEncoding
169                 }
170                 success(this.client.credential, response, parameters)
171             }, failure: failure
172             ) {
173             self.putHandle(handle, withKey: UUID().uuidString)
174         }
175     }
176
177 }