Skip to content

Commit

Permalink
Merge pull request #15 from Hexaville/[email protected]
Browse files Browse the repository at this point in the history
Bump HexaviileFramework version to 1.0.0-rc.1
  • Loading branch information
noppoMan committed Dec 27, 2018
2 parents 43e6ee8 + 8056140 commit 544237e
Show file tree
Hide file tree
Showing 14 changed files with 133 additions and 203 deletions.
44 changes: 22 additions & 22 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -2,57 +2,57 @@
"object": {
"pins": [
{
"package": "CHTTPParser",
"repositoryURL": "https://github.com/Zewo/CHTTPParser.git",
"package": "HexavilleFramework",
"repositoryURL": "https://github.com/noppoMan/HexavilleFramework.git",
"state": {
"branch": null,
"revision": "88306ab33bb316b2eedd39c90f4be8f4ebf65a11",
"version": "0.14.0"
"revision": "6edcc3a4e0f4a37e21846b817e27a4f26513d840",
"version": "1.0.0-rc.1"
}
},
{
"package": "CLibreSSL",
"repositoryURL": "https://github.com/vapor/clibressl.git",
"package": "swift-nio",
"repositoryURL": "https://github.com/apple/swift-nio.git",
"state": {
"branch": null,
"revision": "23ddb296981d17a8ee6c7418742a40cad5d2f9d0",
"version": "1.0.0"
"revision": "a20e129c22ad00a51c902dca54a5456f90664780",
"version": "1.12.0"
}
},
{
"package": "HexavilleFramework",
"repositoryURL": "https://github.com/noppoMan/HexavilleFramework.git",
"package": "swift-nio-ssl",
"repositoryURL": "https://github.com/apple/swift-nio-ssl.git",
"state": {
"branch": null,
"revision": "97e9ca73eb28ed2beabb079bf63f43e51360c7e8",
"version": "0.1.16"
"revision": "db16c3a90b101bb53b26a58867a344ad428072e0",
"version": "1.3.2"
}
},
{
"package": "Prorsum",
"repositoryURL": "https://github.com/noppoMan/Prorsum.git",
"package": "swift-nio-ssl-support",
"repositoryURL": "https://github.com/apple/swift-nio-ssl-support.git",
"state": {
"branch": null,
"revision": "b278e88142a3b5a87feabc44b6522dabfcda8f99",
"version": "0.3.3"
"revision": "c02eec4e0e6d351cd092938cf44195a8e669f555",
"version": "1.0.0"
}
},
{
"package": "ProrsumNet",
"repositoryURL": "https://github.com/noppoman/ProrsumNet.git",
"package": "swift-nio-zlib-support",
"repositoryURL": "https://github.com/apple/swift-nio-zlib-support.git",
"state": {
"branch": null,
"revision": "941e0c65df620467130e9eb2496a3c1275c1d307",
"version": "0.1.3"
"revision": "37760e9a52030bb9011972c5213c3350fa9d41fd",
"version": "1.0.0"
}
},
{
"package": "SwiftCLI",
"repositoryURL": "https://github.com/jakeheis/SwiftCLI.git",
"state": {
"branch": null,
"revision": "37f4a7f863f6fe76ce44fc0023f331eea0089beb",
"version": "5.2.0"
"revision": "fb076cba39c679da4e27813518d8860d8815a25b",
"version": "5.2.1"
}
}
]
Expand Down
6 changes: 4 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ let package = Package(
.executable(name: "hexaville-todo-example", targets: ["HexavilleAuthExample"])
],
dependencies: [
.package(url: "https://github.com/noppoMan/HexavilleFramework.git", .upToNextMajor(from: "0.1.16"))
.package(url: "https://github.com/noppoMan/HexavilleFramework.git", .upToNextMajor(from: "1.0.0-rc.1"))
],
targets: [
.target(name: "HexavilleAuth", dependencies: ["HexavilleFramework"]),
.target(name: "HexavilleAuth", dependencies: [
"HexavilleFramework"
]),
.target(name: "HexavilleAuthExample", dependencies: ["HexavilleAuth"])
]
)
1 change: 0 additions & 1 deletion Sources/HexavilleAuth/AuthenticationMiddleware.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import Foundation
import HexavilleFramework


extension HexavilleAuth {
public struct AuthenticationMiddleware: Middleware {

Expand Down
2 changes: 1 addition & 1 deletion Sources/HexavilleAuth/HMAC.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//

import Foundation
import CLibreSSL
import CNIOOpenSSL

func hmacsha1(string: String, key: [UInt8]) -> [UInt8] {
var context = HMAC_CTX()
Expand Down
40 changes: 40 additions & 0 deletions Sources/HexavilleAuth/HTTPClient.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//
// HTTPClient.swift
// CNIOAtomics
//
// Created by Yuki Takei on 2018/12/12.
//

import Foundation
import Dispatch

struct HTTPClient {
func send(request: URLRequest) throws -> (HTTPURLResponse, Data) {
var _error: Error?
var _data: Data?
var _response: HTTPURLResponse?
let semaphore = DispatchSemaphore(value: 0)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
_error = error
_data = data
_response = response as? HTTPURLResponse
semaphore.signal()
}

task.resume()

semaphore.wait()

if let error = _error {
throw error
}

return (_response!, _data ?? Data())
}

func send(url: URL) throws -> (HTTPURLResponse, Data) {
return try self.send(request: URLRequest(url: url))
}
}


6 changes: 3 additions & 3 deletions Sources/HexavilleAuth/HexaviileAuth.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@ import HexavilleFramework
public enum HexavilleAuthError: Error {
case unsupportedPlaform
case codeIsMissingInResponseParameters
case responseError(Response)
case responseError(HTTPURLResponse, Data)
}

extension HexavilleAuthError: CustomStringConvertible {
public var description: String {
switch self {
case .responseError(let response):
case .responseError(let response, let body):
var str = ""
str += "\(response)"
str += "\n"
str += "\n"
str += String(data: response.body.asData(), encoding: .utf8) ?? "Unknown Error"
str += String(data: body, encoding: .utf8) ?? "Unknown Error"
return str

default:
Expand Down
10 changes: 5 additions & 5 deletions Sources/HexavilleAuth/HexavilleAuth+Router.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,18 @@ extension HexavilleAuth {
for type in providers {
switch type {
case .oauth1(let provider):
router.use(.get, provider.path) { request, context in
router.use(.GET, provider.path) { request, context in
let requestToken = try provider.getRequestToken(for: request)
context.session?["hexaville.oauth_token_secret"] = requestToken.oauthTokenSecret
context.session?["hexaville.oauth_token"] = requestToken.oauthToken
let location = try provider.createAuthorizeURL(requestToken: requestToken).absoluteString

var headers = context.responseHeaders
headers["Location"] = location
headers.add(name: "Location", value: location)
return Response(status: .found, headers: headers)
}

router.use(.get, provider.oauth.callbackURL.path) { request, context in
router.use(.GET, provider.oauth.callbackURL.path) { request, context in
guard let secret = context.session?["hexaville.oauth_token_secret"] as? String else {
throw OAuth1Error.accessTokenIsMissingInSession
}
Expand All @@ -48,7 +48,7 @@ extension HexavilleAuth {


case .oauth2(let provider):
router.use(.get, provider.path) { request, context in
router.use(.GET, provider.path) { request, context in
return Response(
status: .found,
headers: [
Expand All @@ -57,7 +57,7 @@ extension HexavilleAuth {
)
}

router.use(.get, provider.oauth.callbackURL.path) { request, context in
router.use(.GET, provider.oauth.callbackURL.path) { request, context in
let (cred, user) = try provider.authorize(for: request)
context.session?[AuthenticationMiddleware.sessionKey] = user.serialize()
return try provider.callback(cred, user, request, context)
Expand Down
91 changes: 40 additions & 51 deletions Sources/HexavilleAuth/OAuth/OAuth1.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,15 @@

import Foundation
import HexavilleFramework
import CLibreSSL

public enum OAuth1Error: Error {
case couldNotGenerateSignature
case invalidAuthrozeURL(String)
case missingRequiredParameters(String)
case accessTokenIsMissingInSession
case verifyFailed(Request, Response)
case failedToGetAccessToken(Request, Response)
case failedToGetRequestToken(Request, Response)
case verifyFailed(URLRequest, HTTPURLResponse, Data)
case failedToGetAccessToken(URLRequest, HTTPURLResponse, Data)
case failedToGetRequestToken(URLRequest, HTTPURLResponse, Data)
}

extension OAuth1Error: CustomStringConvertible {
Expand All @@ -35,39 +34,41 @@ extension OAuth1Error: CustomStringConvertible {
case .accessTokenIsMissingInSession:
return "accessTokenIsMissingInSession"

case .verifyFailed(let req, let res):
return stringify(code: "verifyFailed", request: req, response: res)
case .verifyFailed(let req, let res, let body):
return stringify(code: "verifyFailed", request: req, response: res, body: body)

case .failedToGetAccessToken(let req, let res):
return stringify(code: "failedToGetAccessToken", request: req, response: res)
case .failedToGetAccessToken(let req, let res, let body):
return stringify(code: "failedToGetAccessToken", request: req, response: res, body: body)

case .failedToGetRequestToken(let req, let res):
return stringify(code: "failedToGetRequestToken", request: req, response: res)
case .failedToGetRequestToken(let req, let res, let body):
return stringify(code: "failedToGetRequestToken", request: req, response: res, body: body)
}
}

private func stringify(code: String, request: Request, response: Response) -> String {
private func stringify(code: String, request: URLRequest, response: HTTPURLResponse, body: Data) -> String {
var requestHeaders: [String: String] = [:]
for (key, value) in request.headers {
for (key, value) in request.allHTTPHeaderFields ?? [:] {
requestHeaders[key.description] = value
}

var responseHeaders: [String: String] = [:]
for (key, value) in response.headers {
responseHeaders[key.description] = value
for (key, value) in response.allHeaderFields {
if let value = value as? String {
responseHeaders[key.description] = value
}
}

let requestDict: [String: Any] = [
"method": request.method.rawValue,
"url": request.url.absoluteString,
"method": request.httpMethod ?? "GET",
"url": request.url!.absoluteString,
"headers": requestHeaders,
"body": String(data: request.body.asData(), encoding: .utf8) ?? ""
"body": String(data: body, encoding: .utf8) ?? ""
]

let responseDict: [String: Any] = [
"statusCode": response.statusCode,
"headers": responseHeaders,
"body": String(data: response.body.asData(), encoding: .utf8) ?? ""
"body": String(data: body, encoding: .utf8) ?? ""
]

do {
Expand Down Expand Up @@ -137,20 +138,17 @@ public class OAuth1 {

let authorizationValue = OAuth1.oAuthAuthorizationString(fromParameters: params, withAllowedCharacters: withAllowedCharacters)

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)
var request = URLRequest(url: URL(string: requestTokenUrl)!)
request.addValue(authorizationValue, forHTTPHeaderField: "Authorization")
request.httpMethod = "POST"

let (response, body) = try HTTPClient().send(request: request)

guard (200..<300).contains(response.statusCode) else {
throw OAuth1Error.failedToGetRequestToken(request, response)
throw OAuth1Error.failedToGetRequestToken(request, response, body)
}

let bodyDictionary = OAuth1.parse(bodyData: response.body.asData())
let bodyDictionary = OAuth1.parse(bodyData: body)

guard let oauthToken = bodyDictionary["oauth_token"] else {
throw OAuth1Error.missingRequiredParameters("oauth_token")
Expand Down Expand Up @@ -203,22 +201,16 @@ public class OAuth1 {
params["oauth_signature"] = sig

let authrozationString = OAuth1.oAuthAuthorizationString(fromParameters: params, withAllowedCharacters: withAllowedCharacters)

let request = Request(
method: .get,
url: URL(string: verifyURL)!,
headers: ["Authorization": authrozationString]
)

let client = try HTTPClient(url: request.url)
try client.open()
let response = try client.request(request)
var request = URLRequest(url: URL(string: verifyURL)!)
request.addValue(authrozationString, forHTTPHeaderField: "Authorization")

let (response, body) = try HTTPClient().send(request: request)

guard (200..<300).contains(response.statusCode) else {
throw OAuth1Error.verifyFailed(request, response)
throw OAuth1Error.verifyFailed(request, response, body)
}

return try JSONSerialization.jsonObject(with: response.body.asData(), options: []) as? [String: Any] ?? [:]
return try JSONSerialization.jsonObject(with: body, options: []) as? [String: Any] ?? [:]
}

public func getAccessToken(request: Request, requestToken: RequestToken) throws -> Credential {
Expand Down Expand Up @@ -256,21 +248,17 @@ public class OAuth1 {

let authrozationString = OAuth1.oAuthAuthorizationString(fromParameters: params, withAllowedCharacters: withAllowedCharacters)

let request = Request(
method: .post,
url: URL(string: urlString)!,
headers: ["Authorization": authrozationString]
)
var request = URLRequest(url: URL(string: requestTokenUrl)!)
request.addValue(authrozationString, forHTTPHeaderField: "Authorization")
request.httpMethod = "POST"

let client = try HTTPClient(url: request.url)
try client.open()
let response = try client.request(request)
let (response, body) = try HTTPClient().send(request: request)

guard (200..<300).contains(response.statusCode) else {
throw OAuth1Error.failedToGetAccessToken(request, response)
throw OAuth1Error.failedToGetAccessToken(request, response, body)
}

return try Credential(withDictionary: OAuth1.parse(bodyData: response.body.asData()))
return try Credential(withDictionary: OAuth1.parse(bodyData: body))
}
}

Expand Down Expand Up @@ -324,7 +312,8 @@ extension OAuth1 {
}

let rawString = [method, percentEncodedUrl, percentEncodedJoinedParameters].joined(separator: "&")
let encodedRawBytes = hmacsha1(string: rawString, key: (percentEncodedConsumerSecret + "&" + (oauthToken ?? "")).bytes)
let bytes = Array((percentEncodedConsumerSecret + "&" + (oauthToken ?? "")).utf8)
let encodedRawBytes = hmacsha1(string: rawString, key: bytes)

let encodedString = String(bytes: Base64Encoder.shared.encode(encodedRawBytes), encoding: .utf8) ?? ""

Expand Down
Loading

0 comments on commit 544237e

Please sign in to comment.