Skip to content

Commit

Permalink
Merge pull request #5 from Hexaville/specific-error-messages
Browse files Browse the repository at this point in the history
show more specific error messages for OAuth1
  • Loading branch information
noppoMan committed Jul 12, 2017
2 parents fbf3000 + b61b751 commit 9dbb01b
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 11 deletions.
79 changes: 74 additions & 5 deletions Sources/HexavilleAuth/OAuth/OAuth1.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,66 @@ public enum OAuth1Error: Error {
case invalidAuthrozeURL(String)
case missingRequiredParameters(String)
case accessTokenIsMissingInSession
case verifyFailed(Request, Response)
case failedToGetAccessToken(Request, Response)
case failedToGetRequestToken(Request, Response)
}

extension OAuth1Error: CustomStringConvertible {
public var description: String {
switch self {
case .verifyFailed(let req, let res):
return stringify(code: "verifyFailed", request: req, response: res)

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

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

default:
return "\(self)"
}
}

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

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

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

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

do {
let json = try JSONSerialization.data(
withJSONObject: [
"errorCode": code,
"request": requestDict,
"response": responseDict
],
options: [.prettyPrinted]
)
return String(data: json, encoding: .utf8) ?? ""
} catch {
return "\(error)"
}
}
}

public struct RequestToken {
Expand Down Expand Up @@ -73,7 +133,10 @@ public class OAuth1 {
let bodyDictionary = OAuth1.parse(bodyData: data)

guard (200..<300).contains(response.statusCode) else {
throw HexavilleAuthError.responseError(response.transform(withBodyData: data))
throw OAuth1Error.failedToGetRequestToken(
urlRequest.transform(),
response.transform(withBodyData: data)
)
}

guard let oauthToken = bodyDictionary["oauth_token"] else {
Expand Down Expand Up @@ -134,7 +197,10 @@ public class OAuth1 {
let (response, data) = try URLSession.shared.resumeSync(with: urlRequest)

guard (200..<300).contains(response.statusCode) else {
throw HexavilleAuthError.responseError(response.transform(withBodyData: data))
throw OAuth1Error.verifyFailed(
urlRequest.transform(),
response.transform(withBodyData: data)
)
}

return try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] ?? [:]
Expand Down Expand Up @@ -167,8 +233,8 @@ public class OAuth1 {
parameters: params,
oauthToken: requestToken.oauthTokenSecret,
withAllowedCharacters: withAllowedCharacters
) else {
throw OAuth1Error.couldNotGenerateSignature
) else {
throw OAuth1Error.couldNotGenerateSignature
}

params["oauth_signature"] = sig
Expand All @@ -181,7 +247,10 @@ public class OAuth1 {
let (response, data) = try URLSession.shared.resumeSync(with: urlRequest)

guard (200..<300).contains(response.statusCode) else {
throw HexavilleAuthError.responseError(response.transform(withBodyData: data))
throw OAuth1Error.failedToGetAccessToken(
urlRequest.transform(),
response.transform(withBodyData: data)
)
}

return try Credential(withDictionary: OAuth1.parse(bodyData: data))
Expand Down
57 changes: 57 additions & 0 deletions Sources/HexavilleAuth/URLRequest.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//
// URLRequest.swift
// HexavilleAuth
//
// Created by Yuki Takei on 2017/07/12.
//
//

import Foundation
import Prorsum

extension Request.Method {
init(rawValue: String) {
switch rawValue.lowercased() {
case "get":
self = .get
case "post":
self = .post
case "put":
self = .put
case "patch":
self = .patch
case "delete":
self = .delete
case "head":
self = .head
default:
self = .other(method: rawValue)
}
}

var rawValue: String {
switch self {
case .other(method: let method):
return method.uppercased()
default:
return "\(self)".uppercased()
}
}
}

extension URLRequest {
func transform() -> Request {
var headers: Headers = [:]
for (key, value) in self.allHTTPHeaderFields ?? [:] {
headers[key] = value
}
let method = Request.Method(rawValue: self.httpMethod ?? "get")
return Request(
method: method,
url: self.url!,
headers: headers,
body: self.httpBody ?? Data()
)
}
}

8 changes: 2 additions & 6 deletions Sources/HexavilleAuthExample/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,8 @@ router.use(.get, "/") { req, context in
app.use(router)

app.catch { error in
switch error {
case HexavilleAuthError.responseError(let response):
return Response(status: .badRequest, body: response.body.asData())
default:
return Response(body: "\(error)")
}
print(error)
return Response(status: .badRequest, body: "\(error)")
}

try app.run()

0 comments on commit 9dbb01b

Please sign in to comment.