Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ let package = Package(
name: "OAuth2"),
],
dependencies: [
.Package(url: "https://github.com/PerfectlySoft/PerfectLib.git", majorVersion: 2),
.Package(url: "https://github.com/PerfectlySoft/Perfect-HTTP.git", majorVersion: 2),
.Package(url: "https://github.com/PerfectlySoft/Perfect-Logger.git", majorVersion: 1),
.Package(url: "https://github.com/iamjono/SwiftString.git", majorVersion: 1),
.Package(url: "https://github.com/PerfectlySoft/Perfect-Session.git", majorVersion: 1),
.Package(url: "https://github.com/PerfectlySoft/PerfectLib.git", majorVersion: 3),
.Package(url: "https://github.com/PerfectlySoft/Perfect-HTTP.git", majorVersion: 3),
.Package(url: "https://github.com/PerfectlySoft/Perfect-Logger.git", majorVersion: 3),
.Package(url: "https://github.com/iamjono/SwiftString.git", majorVersion: 2),
.Package(url: "https://github.com/PerfectlySoft/Perfect-Session.git", majorVersion: 3),
]

)
42 changes: 41 additions & 1 deletion Sources/OAuth2/OAuth2.swift
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,47 @@ open class OAuth2 {
return try exchange(authorizationCode: AuthorizationCode(code: code, redirectURL: redirectURL))
}

// TODO: add refresh token support

/// Renew Access token by using the previously fetched refresh token
/// - Parameters:
/// - refreshToken: the refresh token used to renew the access token
/// - needSecret: Some providers do not need a client secret (i.e. Microsoft)
/// - scopes: the scopes used with the original access token (optional)
/// - Throws:
/// - InvalidAPIResponse(): if the server does not respond in a way we expect
/// - OAuth2Error() if the oauth server calls back with an error

func refresh(refreshToken: String, needSecret: Bool = false, scopes: [String] = []) throws -> OAuth2Token {

var postBody = ["grant_type": "refresh_token",
"client_id": clientID,
"refresh_token": refreshToken]

if !scopes.isEmpty {
postBody["scope"] = scopes.joined(separator: " ")
}

if needSecret {
postBody["client_secret"] = clientSecret
}

var httpBody = URLComponents()
httpBody.queryItems = postBody.map { key, value in
return URLQueryItem(name: key, value: value)
}

let data = makeRequest(.post, tokenURL, body: httpBody.percentEncodedQuery!, encoding: "form")
guard let token = OAuth2Token(json: data) else {
if let error = OAuth2Error(json: data) {
throw error
} else {
throw InvalidAPIResponse()
}
}
return token

}

}

extension URLComponents {
Expand Down
2 changes: 1 addition & 1 deletion Sources/OAuth2/OAuth2Error.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public struct OAuth2Error: Error {
}

/// Convenience initializer from JSON
init?(json: [String: Any]) {
public init?(json: [String: Any]) {
guard let errorCode = json["error"] as? String,
let code = OAuth2ErrorCode(rawValue: errorCode) else {
return nil
Expand Down
2 changes: 1 addition & 1 deletion Sources/OAuth2/makeRequest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ extension OAuth2 {
/// - body: The JSON formatted sring to sent to the server
/// Response:
/// (HTTPResponseStatus, "data" - [String:Any], "raw response" - [String:Any], HTTPHeaderParser)
func makeRequest(
open func makeRequest(
_ method: HTTPMethod,
_ url: String,
body: String = "",
Expand Down
2 changes: 1 addition & 1 deletion Tests/AuthTests/AuthProvidersTests.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import XCTest
@testable import AuthProviders
@testable import OAuth2

class AuthProvidersTests: XCTestCase {

Expand Down