From 5f05e945a8f34b26e114dbdd2181dbffd84453b7 Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Sun, 3 May 2020 14:10:21 -0500 Subject: [PATCH] Added Reddit extension point enablement --- .../Reddit/RedditFeedProvider.swift | 23 ++++++++-- .../Twitter/TwitterFeedProvider.swift | 4 ++ Frameworks/Secrets/OAuth1SwiftProvider.swift | 1 + Frameworks/Secrets/OAuth2SwiftProvider.swift | 2 + ...ExtensionPointEnableWindowController.swift | 43 ++++++++++++++++--- 5 files changed, 65 insertions(+), 8 deletions(-) diff --git a/Frameworks/Account/FeedProvider/Reddit/RedditFeedProvider.swift b/Frameworks/Account/FeedProvider/Reddit/RedditFeedProvider.swift index 0c3da6dd0..e29356715 100644 --- a/Frameworks/Account/FeedProvider/Reddit/RedditFeedProvider.swift +++ b/Frameworks/Account/FeedProvider/Reddit/RedditFeedProvider.swift @@ -24,9 +24,8 @@ public enum RedditFeedProviderError: LocalizedError { public struct RedditFeedProvider: FeedProvider { - private static let server = "api.twitter.com" - private static let apiBase = "https://api.twitter.com/1.1/" - private static let dateFormat = "EEE MMM dd HH:mm:ss Z yyyy" + private static let server = "www.reddit.com" + private static let apiBase = "https://oauth.reddit.com" private static let userPaths = ["/home", "/notifications"] private static let reservedPaths = ["/search", "/explore", "/messages", "/i", "/compose"] @@ -150,6 +149,24 @@ extension RedditFeedProvider: OAuth2SwiftProvider { return oauth2 } + public static var callbackURL: URL { + return URL(string: "netnewswire://success")! + } + + public static var oauth2Vars: (state: String, scope: String, params: [String : String]) { + let state = generateState(withLength: 20) + let scope = "identity mysubreddits" + let params = [ + "client_id" : Secrets.redditConsumerKey, + "response_type" : "code", + "state" : state, + "redirect_uri" : "netnewswire://success", + "duration" : "permanent", + "scope" : scope + ] + return (state: state, scope: scope, params: params) + } + } private extension RedditFeedProvider { diff --git a/Frameworks/Account/FeedProvider/Twitter/TwitterFeedProvider.swift b/Frameworks/Account/FeedProvider/Twitter/TwitterFeedProvider.swift index 6ae33b226..1d27cb8d0 100644 --- a/Frameworks/Account/FeedProvider/Twitter/TwitterFeedProvider.swift +++ b/Frameworks/Account/FeedProvider/Twitter/TwitterFeedProvider.swift @@ -263,6 +263,10 @@ public struct TwitterFeedProvider: FeedProvider { extension TwitterFeedProvider: OAuth1SwiftProvider { + public static var callbackURL: URL { + return URL(string: "netnewswire://")! + } + public static var oauth1Swift: OAuth1Swift { return OAuth1Swift( consumerKey: Secrets.twitterConsumerKey, diff --git a/Frameworks/Secrets/OAuth1SwiftProvider.swift b/Frameworks/Secrets/OAuth1SwiftProvider.swift index 327aa34d7..468061796 100644 --- a/Frameworks/Secrets/OAuth1SwiftProvider.swift +++ b/Frameworks/Secrets/OAuth1SwiftProvider.swift @@ -12,5 +12,6 @@ import OAuthSwift public protocol OAuth1SwiftProvider { static var oauth1Swift: OAuth1Swift { get } + static var callbackURL: URL { get } } diff --git a/Frameworks/Secrets/OAuth2SwiftProvider.swift b/Frameworks/Secrets/OAuth2SwiftProvider.swift index 5509dfeea..13f5de5ca 100644 --- a/Frameworks/Secrets/OAuth2SwiftProvider.swift +++ b/Frameworks/Secrets/OAuth2SwiftProvider.swift @@ -13,5 +13,7 @@ import OAuthSwift public protocol OAuth2SwiftProvider { static var oauth2Swift: OAuth2Swift { get } + static var callbackURL: URL { get } + static var oauth2Vars: (state: String, scope: String, params: [String: String]) { get } } diff --git a/Mac/Preferences/ExtensionPoints/ExtensionPointEnableWindowController.swift b/Mac/Preferences/ExtensionPoints/ExtensionPointEnableWindowController.swift index feccecc73..f68d57370 100644 --- a/Mac/Preferences/ExtensionPoints/ExtensionPointEnableWindowController.swift +++ b/Mac/Preferences/ExtensionPoints/ExtensionPointEnableWindowController.swift @@ -20,7 +20,7 @@ class ExtensionPointEnableWindowController: NSWindowController { private weak var hostWindow: NSWindow? - private let callbackURL = URL(string: "netnewswire://")! + private var callbackURL: URL? = nil private var oauth: OAuthSwift? var extensionPointType: ExtensionPoint.Type? @@ -58,6 +58,8 @@ class ExtensionPointEnableWindowController: NSWindowController { if let oauth1 = extensionPointType as? OAuth1SwiftProvider.Type { enableOauth1(oauth1) + } else if let oauth2 = extensionPointType as? OAuth2SwiftProvider.Type { + enableOauth2(oauth2) } else { ExtensionPointManager.shared.activateExtensionPoint(extensionPointType) { result in if case .failure(let error) = result { @@ -74,7 +76,7 @@ class ExtensionPointEnableWindowController: NSWindowController { extension ExtensionPointEnableWindowController: OAuthSwiftURLHandlerType { public func handle(_ url: URL) { - let session = ASWebAuthenticationSession(url: url, callbackURLScheme: callbackURL.scheme, completionHandler: { (url, error) in + let session = ASWebAuthenticationSession(url: url, callbackURLScheme: callbackURL!.scheme, completionHandler: { (url, error) in if let callbackedURL = url { OAuth1Swift.handle(url: callbackedURL) } @@ -114,12 +116,13 @@ extension ExtensionPointEnableWindowController: ASWebAuthenticationPresentationC private extension ExtensionPointEnableWindowController { func enableOauth1(_ provider: OAuth1SwiftProvider.Type) { - + callbackURL = provider.callbackURL + let oauth1 = provider.oauth1Swift self.oauth = oauth1 oauth1.authorizeURLHandler = self - oauth1.authorize(withCallbackURL: callbackURL) { [weak self] result in + oauth1.authorize(withCallbackURL: callbackURL!) { [weak self] result in guard let self = self, let extensionPointType = self.extensionPointType else { return } switch result { @@ -131,7 +134,37 @@ private extension ExtensionPointEnableWindowController { self.hostWindow!.endSheet(self.window!, returnCode: NSApplication.ModalResponse.OK) } case .failure(let oauthSwiftError): - NSApplication.shared.presentError(oauthSwiftError) + self.presentError(oauthSwiftError) + } + + self.oauth?.cancel() + self.oauth = nil + } + + } + + func enableOauth2(_ provider: OAuth2SwiftProvider.Type) { + callbackURL = provider.callbackURL + + let oauth2 = provider.oauth2Swift + self.oauth = oauth2 + oauth2.authorizeURLHandler = self + + let oauth2Vars = provider.oauth2Vars + + oauth2.authorize(withCallbackURL: callbackURL!, scope: oauth2Vars.scope, state: oauth2Vars.state, parameters: oauth2Vars.params) { [weak self] result in + guard let self = self, let extensionPointType = self.extensionPointType else { return } + + switch result { + case .success(let tokenSuccess): + ExtensionPointManager.shared.activateExtensionPoint(extensionPointType, tokenSuccess: tokenSuccess) { result in + if case .failure(let error) = result { + self.presentError(error) + } + self.hostWindow!.endSheet(self.window!, returnCode: NSApplication.ModalResponse.OK) + } + case .failure(let oauthSwiftError): + self.presentError(oauthSwiftError) } self.oauth?.cancel()