diff --git a/Sources/HexavilleAuth/OAuth/OAuth1.swift b/Sources/HexavilleAuth/OAuth/OAuth1.swift index 38ba670..92d2498 100644 --- a/Sources/HexavilleAuth/OAuth/OAuth1.swift +++ b/Sources/HexavilleAuth/OAuth/OAuth1.swift @@ -23,6 +23,18 @@ public enum OAuth1Error: Error { extension OAuth1Error: CustomStringConvertible { public var description: String { switch self { + case .couldNotGenerateSignature: + return "couldNotGenerateSignature" + + case .invalidAuthrozeURL(let url): + return "invalidAuthrozeURL: \(url)" + + case .missingRequiredParameters(let param): + return "missingRequiredParameter: \(param)" + + case .accessTokenIsMissingInSession: + return "accessTokenIsMissingInSession" + case .verifyFailed(let req, let res): return stringify(code: "verifyFailed", request: req, response: res) @@ -31,9 +43,6 @@ extension OAuth1Error: CustomStringConvertible { case .failedToGetRequestToken(let req, let res): return stringify(code: "failedToGetRequestToken", request: req, response: res) - - default: - return "\(self)" } } @@ -123,22 +132,23 @@ public class OAuth1 { params["oauth_signature"] = sig - var urlRequest = URLRequest(url: URL(string: requestTokenUrl)!) - urlRequest.httpMethod = "POST" - - urlRequest.addValue(OAuth1.oAuthAuthorizationString(fromParameters: params, withAllowedCharacters: withAllowedCharacters), forHTTPHeaderField: "Authorization") - - let (response, data) = try URLSession.shared.resumeSync(with: urlRequest) + let authorizationValue = OAuth1.oAuthAuthorizationString(fromParameters: params, withAllowedCharacters: withAllowedCharacters) - let bodyDictionary = OAuth1.parse(bodyData: data) + let request = Request( + method: .post, + url: URL(string: requestTokenUrl)!, + headers: ["Authorization": authorizationValue] + ) + let client = try HTTPClient(url: request.url) + try client.open() + let response = try client.request(request) guard (200..<300).contains(response.statusCode) else { - throw OAuth1Error.failedToGetRequestToken( - urlRequest.transform(), - response.transform(withBodyData: data) - ) + throw OAuth1Error.failedToGetRequestToken(request, response) } + let bodyDictionary = OAuth1.parse(bodyData: response.body.asData()) + guard let oauthToken = bodyDictionary["oauth_token"] else { throw OAuth1Error.missingRequiredParameters("oauth_token") } @@ -189,21 +199,23 @@ public class OAuth1 { params["oauth_signature"] = sig - var urlRequest = URLRequest(url: URL(string: verifyURL)!) - urlRequest.httpMethod = "GET" + let authrozationString = OAuth1.oAuthAuthorizationString(fromParameters: params, withAllowedCharacters: withAllowedCharacters) - urlRequest.addValue(OAuth1.oAuthAuthorizationString(fromParameters: params, withAllowedCharacters: withAllowedCharacters), forHTTPHeaderField: "Authorization") + let request = Request( + method: .get, + url: URL(string: verifyURL)!, + headers: ["Authorization": authrozationString] + ) - let (response, data) = try URLSession.shared.resumeSync(with: urlRequest) + let client = try HTTPClient(url: request.url) + try client.open() + let response = try client.request(request) guard (200..<300).contains(response.statusCode) else { - throw OAuth1Error.verifyFailed( - urlRequest.transform(), - response.transform(withBodyData: data) - ) + throw OAuth1Error.verifyFailed(request, response) } - return try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] ?? [:] + return try JSONSerialization.jsonObject(with: response.body.asData(), options: []) as? [String: Any] ?? [:] } public func getAccessToken(request: Request, requestToken: RequestToken) throws -> Credential { @@ -239,21 +251,23 @@ public class OAuth1 { params["oauth_signature"] = sig - var urlRequest = URLRequest(url: URL(string: urlString)!) - urlRequest.httpMethod = "POST" + let authrozationString = OAuth1.oAuthAuthorizationString(fromParameters: params, withAllowedCharacters: withAllowedCharacters) - urlRequest.addValue(OAuth1.oAuthAuthorizationString(fromParameters: params, withAllowedCharacters: withAllowedCharacters), forHTTPHeaderField: "Authorization") + let request = Request( + method: .post, + url: URL(string: urlString)!, + headers: ["Authorization": authrozationString] + ) - let (response, data) = try URLSession.shared.resumeSync(with: urlRequest) + let client = try HTTPClient(url: request.url) + try client.open() + let response = try client.request(request) guard (200..<300).contains(response.statusCode) else { - throw OAuth1Error.failedToGetAccessToken( - urlRequest.transform(), - response.transform(withBodyData: data) - ) + throw OAuth1Error.failedToGetAccessToken(request, response) } - return try Credential(withDictionary: OAuth1.parse(bodyData: data)) + return try Credential(withDictionary: OAuth1.parse(bodyData: response.body.asData())) } } diff --git a/Sources/HexavilleAuth/OAuth/OAuth2.swift b/Sources/HexavilleAuth/OAuth/OAuth2.swift index f8ebdd9..d893fe4 100644 --- a/Sources/HexavilleAuth/OAuth/OAuth2.swift +++ b/Sources/HexavilleAuth/OAuth/OAuth2.swift @@ -68,20 +68,26 @@ public class OAuth2 { "redirect_uri=\(self.callbackURL.absoluteURL()!.absoluteString)" ] - var request = URLRequest(url: url) - request.httpMethod = "POST" - request.addValue("application/json", forHTTPHeaderField: "Accept") - request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") - request.httpBody = body.joined(separator: "&").data + let request = Request( + method: .post, + url: url, + headers: [ + "Accept": "application/json", + "Content-Type": "application/x-www-form-urlencoded" + ], + body: body.joined(separator: "&").data + ) - let (response, bodyData) = try URLSession.shared.resumeSync(with: request) + let client = try HTTPClient(url: request.url) + try client.open() + let response = try client.request(request) guard (200..<300).contains(response.statusCode) else { - throw HexavilleAuthError.responseError(response.transform(withBodyData: bodyData)) + throw HexavilleAuthError.responseError(response) } do { - let bodyDictionary = try JSONSerialization.jsonObject(with: bodyData, options: []) as! [String: Any] + let bodyDictionary = try JSONSerialization.jsonObject(with: response.body.asData(), options: []) as! [String: Any] return try Credential(withDictionary: bodyDictionary) } catch { throw error diff --git a/Sources/HexavilleAuth/Providers/OAuth2/FacebookAuthorizationProvider.swift b/Sources/HexavilleAuth/Providers/OAuth2/FacebookAuthorizationProvider.swift index bd38b4c..ea33c85 100644 --- a/Sources/HexavilleAuth/Providers/OAuth2/FacebookAuthorizationProvider.swift +++ b/Sources/HexavilleAuth/Providers/OAuth2/FacebookAuthorizationProvider.swift @@ -38,14 +38,21 @@ public struct FacebookAuthorizationProvider: OAuth2AuthorizationProvidable { public func authorize(request: Request) throws -> (Credential, LoginUser) { let credential = try self.getAccessToken(request: request) - let url = URL(string: "https://graph.facebook.com/me?fields=id,name,email,picture,gender&access_token=\(credential.accessToken)")! - let (response, data) = try URLSession.shared.resumeSync(with: URLRequest(url: url)) + + let request = Request( + method: .get, + url: URL(string: "https://graph.facebook.com/me?fields=id,name,email,picture,gender&access_token=\(credential.accessToken)")! + ) + + let client = try HTTPClient(url: request.url) + try client.open() + let response = try client.request(request) guard (200..<300).contains(response.statusCode) else { - throw HexavilleAuthError.responseError(response.transform(withBodyData: data)) + throw HexavilleAuthError.responseError(response) } - guard let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] else { + guard let json = try JSONSerialization.jsonObject(with: response.body.asData(), options: []) as? [String: Any] else { throw FacebookAuthorizationProviderError.bodyShouldBeAJSON } diff --git a/Sources/HexavilleAuth/Providers/OAuth2/GithubAuthorizationProvider.swift b/Sources/HexavilleAuth/Providers/OAuth2/GithubAuthorizationProvider.swift index e01f159..840e550 100644 --- a/Sources/HexavilleAuth/Providers/OAuth2/GithubAuthorizationProvider.swift +++ b/Sources/HexavilleAuth/Providers/OAuth2/GithubAuthorizationProvider.swift @@ -38,14 +38,21 @@ public struct GithubAuthorizationProvider: OAuth2AuthorizationProvidable { public func authorize(request: Request) throws -> (Credential, LoginUser) { let credential = try self.getAccessToken(request: request) - let url = URL(string: "https://api.github.com/user?access_token=\(credential.accessToken)")! - let (response, data) = try URLSession.shared.resumeSync(with: URLRequest(url: url)) + + let request = Request( + method: .get, + url: URL(string: "https://api.github.com/user?access_token=\(credential.accessToken)")! + ) + + let client = try HTTPClient(url: request.url) + try client.open() + let response = try client.request(request) guard (200..<300).contains(response.statusCode) else { - throw HexavilleAuthError.responseError(response.transform(withBodyData: data)) + throw HexavilleAuthError.responseError(response) } - guard let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] else { + guard let json = try JSONSerialization.jsonObject(with: response.body.asData(), options: []) as? [String: Any] else { throw GithubAuthorizationProviderError.bodyShouldBeAJSON } diff --git a/Sources/HexavilleAuth/URLSession.swift b/Sources/HexavilleAuth/URLSession.swift deleted file mode 100644 index b578dd0..0000000 --- a/Sources/HexavilleAuth/URLSession.swift +++ /dev/null @@ -1,41 +0,0 @@ -// -// URLSession.swift -// HexavilleAuth -// -// Created by Yuki Takei on 2017/05/31. -// -// - -import Prorsum -import Foundation - -#if os(Linux) -let _urlSessionShared = URLSession(configuration: URLSessionConfiguration(), delegate: nil, delegateQueue: nil) - extension URLSession { - static var shared: URLSession { - return _urlSessionShared - } - } -#endif - -extension URLSession { - func resumeSync(with request: URLRequest) throws -> (HTTPURLResponse, Data) { - let chan = Channel<(Error?, (HTTPURLResponse, Data)?)>.make(capacity: 1) - - let task = self.dataTask(with: request) { data, response, error in - if let error = error { - try! chan.send((error, nil)) - return - } - try! chan.send((nil, (response as! HTTPURLResponse, data!))) - } - - task.resume() - - let (err, tupple) = try chan.receive() - if let error = err { - throw error - } - return (tupple!.0, tupple!.1) - } -}