Skip to content

Commit

Permalink
ran through Swift3 converter
Browse files Browse the repository at this point in the history
  • Loading branch information
edjiang committed Aug 6, 2016
1 parent 29969c6 commit 922857a
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 84 deletions.
3 changes: 3 additions & 0 deletions Simplicity.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@
TargetAttributes = {
DF74EC2F1CE2A8BB008F16BF = {
CreatedOnToolsVersion = 7.3.1;
LastSwiftMigration = 0800;
};
};
};
Expand Down Expand Up @@ -315,6 +316,7 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
};
name = Debug;
};
Expand All @@ -333,6 +335,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.stormpath.Simplicity;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0;
};
name = Release;
};
Expand Down
20 changes: 10 additions & 10 deletions Simplicity/Helpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ class Helpers {
Scheme matches the filter
- returns: A list of URL Schemes that match the filter closure.
*/
static func registeredURLSchemes(filter closure: String -> Bool) -> [String] {
guard let urlTypes = NSBundle.mainBundle().infoDictionary?["CFBundleURLTypes"] as? [[String: AnyObject]] else {
static func registeredURLSchemes(filter closure: (String) -> Bool) -> [String] {
guard let urlTypes = Bundle.main.infoDictionary?["CFBundleURLTypes"] as? [[String: AnyObject]] else {
return [String]()
}

Expand All @@ -35,18 +35,18 @@ class Helpers {
- parts: A dictionary of parameters to put in a query string.
- returns: A query string
*/
static func queryString(parts: [String: String?]) -> String? {
static func queryString(_ parts: [String: String?]) -> String? {
return parts.flatMap { key, value -> String? in
if let value = value {
return key + "=" + value
} else {
return nil
}
}.joinWithSeparator("&").stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())
}.joined(separator: "&").addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)
}
}

extension NSURL {
extension URL {
/// Dictionary with key/value pairs from the URL fragment
var fragmentDictionary: [String: String] {
return dictionaryFromFormEncodedString(fragment)
Expand All @@ -65,22 +65,22 @@ extension NSURL {
return result
}

private func dictionaryFromFormEncodedString(input: String?) -> [String: String] {
private func dictionaryFromFormEncodedString(_ input: String?) -> [String: String] {
var result = [String: String]()

guard let input = input else {
return result
}
let inputPairs = input.componentsSeparatedByString("&")
let inputPairs = input.components(separatedBy: "&")

for pair in inputPairs {
let split = pair.componentsSeparatedByString("=")
let split = pair.components(separatedBy: "=")
if split.count == 2 {
if let key = split[0].stringByRemovingPercentEncoding, value = split[1].stringByRemovingPercentEncoding {
if let key = split[0].removingPercentEncoding, let value = split[1].removingPercentEncoding {
result[key] = value
}
}
}
return result
}
}
}
8 changes: 4 additions & 4 deletions Simplicity/LoginProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import Foundation
*/
public protocol LoginProvider {
/// The URL to redirect to when beginning the login process
var authorizationURL: NSURL { get }
var authorizationURL: URL { get }

/// The URL Scheme that this LoginProvider is bound to.
var urlScheme: String { get }
Expand All @@ -26,11 +26,11 @@ public protocol LoginProvider {
- url: The URL that triggered that AppDelegate's link handler
- callback: A callback that returns with an access token or NSError.
*/
func linkHandler(url: NSURL, callback: ExternalLoginCallback)
func linkHandler(_ url: URL, callback: ExternalLoginCallback)
}

public extension LoginProvider {
func login(callback: ExternalLoginCallback) {
func login(_ callback: ExternalLoginCallback) {
Simplicity.login(self, callback: callback)
}
}
}
10 changes: 5 additions & 5 deletions Simplicity/LoginProviders/Facebook.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,12 @@ public class Facebook: OAuth2 {
// Search for URL Scheme, error if not there

guard let urlScheme = Helpers.registeredURLSchemes(filter: {$0.hasPrefix("fb")}).first,
range = urlScheme.rangeOfString("\\d+", options: .RegularExpressionSearch) else {
let range = urlScheme.range(of: "\\d+", options: .regularExpression) else {
preconditionFailure("You must configure your Facebook URL Scheme to use Facebook login.")
}
let clientId = urlScheme.substringWithRange(range)
let authorizationEndpoint = NSURL(string: "https://www.facebook.com/dialog/oauth")!
let redirectEndpoint = NSURL(string: urlScheme + "://authorize")!
let clientId = urlScheme.substring(with: range)
let authorizationEndpoint = URL(string: "https://www.facebook.com/dialog/oauth")!
let redirectEndpoint = URL(string: urlScheme + "://authorize")!

super.init(clientId: clientId, authorizationEndpoint: authorizationEndpoint, redirectEndpoint: redirectEndpoint, grantType: .Implicit)
}
Expand All @@ -77,4 +77,4 @@ public enum FacebookAuthType: String {

/// None
None = ""
}
}
26 changes: 13 additions & 13 deletions Simplicity/LoginProviders/Google.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ public class Google: OAuth2 {
preconditionFailure("You must configure your Google URL Scheme to use Google login.")
}

let appId = urlScheme.componentsSeparatedByString(".").reverse().joinWithSeparator(".")
let authorizationEndpoint = NSURL(string: "https://accounts.google.com/o/oauth2/auth")!
let redirectionEndpoint = NSURL(string: "\(urlScheme):/oauth2callback")!
let appId = urlScheme.components(separatedBy: ".").reversed().joined(separator: ".")
let authorizationEndpoint = URL(string: "https://accounts.google.com/o/oauth2/auth")!
let redirectionEndpoint = URL(string: "\(urlScheme):/oauth2callback")!

super.init(clientId: appId, authorizationEndpoint: authorizationEndpoint, redirectEndpoint: redirectionEndpoint, grantType: .AuthorizationCode)
self.scopes = ["email", "profile"]
Expand All @@ -57,8 +57,8 @@ public class Google: OAuth2 {
- url: The OAuth redirect URL
- callback: A callback that returns with an access token or NSError.
*/
override public func linkHandler(url: NSURL, callback: ExternalLoginCallback) {
guard let authorizationCode = url.queryDictionary["code"] where url.queryDictionary["state"] == state else {
override public func linkHandler(_ url: URL, callback: ExternalLoginCallback) {
guard let authorizationCode = url.queryDictionary["code"], url.queryDictionary["state"] == state else {
if let error = OAuth2Error.error(url.queryDictionary) ?? OAuth2Error.error(url.queryDictionary) {
callback(accessToken: nil, error: error)
} else {
Expand All @@ -69,21 +69,21 @@ public class Google: OAuth2 {
exchangeCodeForAccessToken(authorizationCode, callback: callback)
}

private func exchangeCodeForAccessToken(authorizationCode: String, callback: ExternalLoginCallback) {
let session = NSURLSession(configuration: NSURLSessionConfiguration.ephemeralSessionConfiguration())
let url = NSURL(string: "https://www.googleapis.com/oauth2/v4/token")!
private func exchangeCodeForAccessToken(_ authorizationCode: String, callback: ExternalLoginCallback) {
let session = URLSession(configuration: URLSessionConfiguration.ephemeral)
let url = URL(string: "https://www.googleapis.com/oauth2/v4/token")!

let requestParams: [String: String?] = ["client_id": clientId,
"code": authorizationCode,
"grant_type": "authorization_code",
"redirect_uri": authorizationURLParameters["redirect_uri"] ?? nil]

let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.HTTPBody = Helpers.queryString(requestParams)?.dataUsingEncoding(NSUTF8StringEncoding)
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = Helpers.queryString(requestParams)?.data(using: String.Encoding.utf8)

let task = session.dataTaskWithRequest(request) { (data, response, error) -> Void in
guard let data = data, json = try? NSJSONSerialization.JSONObjectWithData(data, options: []), accessToken = json["access_token"] as? String else {
let task = session.dataTask(with: request) { (data, response, error) -> Void in
guard let data = data, let json = try? JSONSerialization.jsonObject(with: data, options: []), let accessToken = json["access_token"] as? String else {
callback(accessToken: nil, error: LoginError.InternalSDKError) // This request should not fail.
return
}
Expand Down
8 changes: 4 additions & 4 deletions Simplicity/LoginProviders/VKontakte.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ public class VKontakte: OAuth2 {

public init() {
guard let urlScheme = Helpers.registeredURLSchemes(filter: {$0.hasPrefix("vk")}).first,
range = urlScheme.rangeOfString("\\d+", options: .RegularExpressionSearch) else {
let range = urlScheme.range(of: "\\d+", options: .regularExpression) else {
preconditionFailure("You must configure your VK URL Scheme to use VK login.")
}
let clientId = urlScheme.substringWithRange(range)
let authorizationEndpoint = NSURL(string: "https://oauth.vk.com/authorize")!
let redirectEndpoint = NSURL(string: urlScheme + "://authorize")!
let clientId = urlScheme.substring(with: range)
let authorizationEndpoint = URL(string: "https://oauth.vk.com/authorize")!
let redirectEndpoint = URL(string: urlScheme + "://authorize")!

super.init(clientId: clientId, authorizationEndpoint: authorizationEndpoint, redirectEndpoint: redirectEndpoint, grantType: .Implicit)
}
Expand Down
26 changes: 13 additions & 13 deletions Simplicity/OAuth2.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public class OAuth2: LoginProvider {

/// The URL Scheme registered by the app.
public final var urlScheme: String {
return redirectEndpoint.scheme
return redirectEndpoint.scheme!
}

/// The state used to prevent CSRF attacks with bad access tokens.
Expand All @@ -36,10 +36,10 @@ public class OAuth2: LoginProvider {
public final let grantType: OAuth2GrantType

/// The OAuth 2 authorization endpoint
public final let authorizationEndpoint: NSURL
public final let authorizationEndpoint: URL

/// The OAuth 2 redirection endpoint
public final let redirectEndpoint: NSURL
public final let redirectEndpoint: URL

/**
An array with query string parameters for the authorization URL.
Expand All @@ -52,23 +52,23 @@ public class OAuth2: LoginProvider {
return ["client_id": clientId,
"redirect_uri": redirectEndpoint.absoluteString,
"response_type": grantType.rawValue,
"scope": scopes.joinWithSeparator(" "),
"scope": scopes.joined(separator: " "),
"state": state]
}

/// The authorization URL to start the OAuth flow.
public var authorizationURL: NSURL {
public var authorizationURL: URL {
guard grantType != .Custom else {
preconditionFailure("Custom Grant Type Not Supported")
}

let url = NSURLComponents(URL: authorizationEndpoint, resolvingAgainstBaseURL: false)!
var url = URLComponents(url: authorizationEndpoint, resolvingAgainstBaseURL: false)!

url.queryItems = authorizationURLParameters.flatMap({key, value -> NSURLQueryItem? in
return value != nil ? NSURLQueryItem(name: key, value: value) : nil
url.queryItems = authorizationURLParameters.flatMap({key, value -> URLQueryItem? in
return value != nil ? URLQueryItem(name: key, value: value) : nil
})

return url.URL!
return url.url!
}

/**
Expand All @@ -78,13 +78,13 @@ public class OAuth2: LoginProvider {
- url: The OAuth redirect URL
- callback: A callback that returns with an access token or NSError.
*/
public func linkHandler(url: NSURL, callback: ExternalLoginCallback) {
public func linkHandler(_ url: URL, callback: ExternalLoginCallback) {
switch grantType {
case .AuthorizationCode:
preconditionFailure("Authorization Code Grant Type Not Supported")
case .Implicit:
// Get the access token, and check that the state is the same
guard let accessToken = url.fragmentDictionary["access_token"] where url.fragmentAndQueryDictionary["state"] == state else {
guard let accessToken = url.fragmentDictionary["access_token"], url.fragmentAndQueryDictionary["state"] == state else {
/**
Facebook's mobile implicit grant type returns errors as
query. Don't think it's a huge issue to be liberal in looking
Expand Down Expand Up @@ -114,7 +114,7 @@ public class OAuth2: LoginProvider {
- redirectEndpoint: The redirect URI passed to the provider.
- grantType: The OAuth 2 Grant Type
*/
public init(clientId: String, authorizationEndpoint: NSURL, redirectEndpoint: NSURL, grantType: OAuth2GrantType) {
public init(clientId: String, authorizationEndpoint: URL, redirectEndpoint: URL, grantType: OAuth2GrantType) {
self.grantType = grantType
self.clientId = clientId
self.authorizationEndpoint = authorizationEndpoint
Expand All @@ -136,4 +136,4 @@ public enum OAuth2GrantType: String {

/// Custom Grant Type
Custom = ""
}
}
48 changes: 24 additions & 24 deletions Simplicity/OAuth2Error.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ import Foundation
*/
public class OAuth2Error: LoginError {
/// A mapping of OAuth 2 Error strings to OAuth2ErrorCode enum.
public static let mapping: [String: OAuth2ErrorCode] = [ "invalid_request": .InvalidRequest,
"unauthorized_client": .UnauthorizedClient,
"access_denied": .AccessDenied,
"unsupported_response_type": .UnsupportedResponseType,
"invalid_scope": .InvalidScope,
"server_error": .ServerError,
"temporarily_unavailable": .TemporarilyUnavailable ]
public static let mapping: [String: OAuth2ErrorCode] = [ "invalid_request": .invalidRequest,
"unauthorized_client": .unauthorizedClient,
"access_denied": .accessDenied,
"unsupported_response_type": .unsupportedResponseType,
"invalid_scope": .invalidScope,
"server_error": .serverError,
"temporarily_unavailable": .temporarilyUnavailable ]

/**
Constructs a OAuth 2 error object from an OAuth response.
Expand All @@ -30,11 +30,11 @@ public class OAuth2Error: LoginError {
- callbackParameters: A dictionary of OAuth 2 Error response parameters.
- returns: OAuth2Error object.
*/
public class func error(callbackParameters: [String: String]) -> LoginError? {
public class func error(_ callbackParameters: [String: String]) -> LoginError? {
let errorCode = mapping[callbackParameters["error"] ?? ""]

if let errorCode = errorCode {
let errorDescription = callbackParameters["error_description"]?.stringByRemovingPercentEncoding?.stringByReplacingOccurrencesOfString("+", withString: " ") ?? errorCode.description
let errorDescription = callbackParameters["error_description"]?.removingPercentEncoding?.replacingOccurrences(of: "+", with: " ") ?? errorCode.description

return OAuth2Error(code: errorCode.rawValue, description: errorDescription)
} else {
Expand All @@ -49,43 +49,43 @@ public enum OAuth2ErrorCode: Int, CustomStringConvertible {
The request is missing a required parameter. This is usually programmer
error, and should be filed as a GitHub issue.
*/
case InvalidRequest = 100,
case invalidRequest = 100,

/// The client ID is not authorized to make this request.
UnauthorizedClient,
unauthorizedClient,

/// The user or OAuth server denied this request.
AccessDenied,
accessDenied,

/// The grant type requested is not supported. This is programmer error.
UnsupportedResponseType,
unsupportedResponseType,

/// A scope requested is invalid.
InvalidScope,
invalidScope,

/// The authorization server is currently experiencing an error.
ServerError,
serverError,

/// The authorization server is currently unavailable.
TemporarilyUnavailable
temporarilyUnavailable

/// User readable default error message
public var description: String {
switch self {
case .InvalidRequest:
case .invalidRequest:
return "The OAuth request is missing a required parameter"
case .UnauthorizedClient:
case .unauthorizedClient:
return "The client ID is not authorized to make this request"
case .AccessDenied:
case .accessDenied:
return "You denied the login request"
case .UnsupportedResponseType:
case .unsupportedResponseType:
return "The grant type requested is not supported"
case .InvalidScope:
case .invalidScope:
return "A scope requested is invalid"
case .ServerError:
case .serverError:
return "The login server experienced an internal error"
case .TemporarilyUnavailable:
case .temporarilyUnavailable:
return "The login server is temporarily unavailable. Please try again later. "
}
}
}
}
Loading

0 comments on commit 922857a

Please sign in to comment.