From b72465852877e06b1b323b46e2aa12e42cabda3d Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Thu, 30 Jul 2020 17:40:45 -0500 Subject: [PATCH] Refactor how we do Secrets to work with the new Swift Package structure --- .../Reddit/RedditFeedProvider.swift | 4 ++-- .../Twitter/TwitterFeedProvider.swift | 12 ++++++------ .../FeedWrangler/FeedWranglerConfig.swift | 1 - .../OAuthAuthorizationClient+Feedly.swift | 4 ++-- .../Sources/Account/URLRequest+RSWeb.swift | 2 +- Mac/AppDelegate.swift | 2 ++ Multiplatform/iOS/AppDelegate.swift | 2 ++ Multiplatform/macOS/AppDelegate.swift | 2 ++ NetNewsWire.xcodeproj/project.pbxproj | 19 +++++++++++++++++++ .../xcschemes/NetNewsWire-iOS.xcscheme | 2 +- Secrets/Package.swift | 3 +-- Secrets/Sources/Secrets/SecretsManager.swift | 12 ++++++++++++ Secrets/Sources/Secrets/SecretsProvider.swift | 19 +++++++++++++++++++ .../Article Extractor/ArticleExtractor.swift | 4 ++-- .../Secrets => Shared}/Secrets.swift.gyb | 13 ++++++------- iOS/AppDelegate.swift | 2 ++ 16 files changed, 79 insertions(+), 24 deletions(-) create mode 100644 Secrets/Sources/Secrets/SecretsManager.swift create mode 100644 Secrets/Sources/Secrets/SecretsProvider.swift rename {Secrets/Sources/Secrets => Shared}/Secrets.swift.gyb (85%) diff --git a/Account/Sources/Account/FeedProvider/Reddit/RedditFeedProvider.swift b/Account/Sources/Account/FeedProvider/Reddit/RedditFeedProvider.swift index 1ba8397a7..e244df51c 100644 --- a/Account/Sources/Account/FeedProvider/Reddit/RedditFeedProvider.swift +++ b/Account/Sources/Account/FeedProvider/Reddit/RedditFeedProvider.swift @@ -266,7 +266,7 @@ public final class RedditFeedProvider: FeedProvider { extension RedditFeedProvider: OAuth2SwiftProvider { public static var oauth2Swift: OAuth2Swift { - let oauth2 = OAuth2Swift(consumerKey: Secrets.redditConsumerKey, + let oauth2 = OAuth2Swift(consumerKey: SecretsManager.provider.redditConsumerKey, consumerSecret: "", authorizeUrl: "https://www.reddit.com/api/v1/authorize.compact?", accessTokenUrl: "https://www.reddit.com/api/v1/access_token", @@ -283,7 +283,7 @@ extension RedditFeedProvider: OAuth2SwiftProvider { let state = generateState(withLength: 20) let scope = "identity mysubreddits read" let params = [ - "client_id" : Secrets.redditConsumerKey, + "client_id" : SecretsManager.provider.redditConsumerKey, "response_type" : "code", "state" : state, "redirect_uri" : "netnewswire://success", diff --git a/Account/Sources/Account/FeedProvider/Twitter/TwitterFeedProvider.swift b/Account/Sources/Account/FeedProvider/Twitter/TwitterFeedProvider.swift index 5df94b4ac..7ab04827b 100644 --- a/Account/Sources/Account/FeedProvider/Twitter/TwitterFeedProvider.swift +++ b/Account/Sources/Account/FeedProvider/Twitter/TwitterFeedProvider.swift @@ -74,8 +74,8 @@ public final class TwitterFeedProvider: FeedProvider { let tokenSecretCredentials = Credentials(type: .oauthAccessTokenSecret, username: screenName, secret: oauthTokenSecret) try? CredentialsManager.storeCredentials(tokenSecretCredentials, server: Self.server) - client = OAuthSwiftClient(consumerKey: Secrets.twitterConsumerKey, - consumerSecret: Secrets.twitterConsumerSecret, + client = OAuthSwiftClient(consumerKey: SecretsManager.provider.twitterConsumerKey, + consumerSecret: SecretsManager.provider.twitterConsumerSecret, oauthToken: oauthToken, oauthTokenSecret: oauthTokenSecret, version: .oauth1) @@ -92,8 +92,8 @@ public final class TwitterFeedProvider: FeedProvider { self.oauthToken = tokenCredentials.secret self.oauthTokenSecret = tokenSecretCredentials.secret - client = OAuthSwiftClient(consumerKey: Secrets.twitterConsumerKey, - consumerSecret: Secrets.twitterConsumerSecret, + client = OAuthSwiftClient(consumerKey: SecretsManager.provider.twitterConsumerKey, + consumerSecret: SecretsManager.provider.twitterConsumerSecret, oauthToken: oauthToken, oauthTokenSecret: oauthTokenSecret, version: .oauth1) @@ -286,8 +286,8 @@ extension TwitterFeedProvider: OAuth1SwiftProvider { public static var oauth1Swift: OAuth1Swift { return OAuth1Swift( - consumerKey: Secrets.twitterConsumerKey, - consumerSecret: Secrets.twitterConsumerSecret, + consumerKey: SecretsManager.provider.twitterConsumerKey, + consumerSecret: SecretsManager.provider.twitterConsumerSecret, requestTokenUrl: "https://api.twitter.com/oauth/request_token", authorizeUrl: "https://api.twitter.com/oauth/authorize", accessTokenUrl: "https://api.twitter.com/oauth/access_token" diff --git a/Account/Sources/Account/FeedWrangler/FeedWranglerConfig.swift b/Account/Sources/Account/FeedWrangler/FeedWranglerConfig.swift index 508dfedc4..5d41fba17 100644 --- a/Account/Sources/Account/FeedWrangler/FeedWranglerConfig.swift +++ b/Account/Sources/Account/FeedWrangler/FeedWranglerConfig.swift @@ -11,7 +11,6 @@ import Secrets enum FeedWranglerConfig { static let pageSize = 100 - static let clientKey = Secrets.feedWranglerKey // Add FEED_WRANGLER_KEY = XYZ to SharedXcodeSettings/DeveloperSettings.xcconfig static let clientPath = "https://feedwrangler.net/api/v2/" static let clientURL = { URL(string: FeedWranglerConfig.clientPath)! diff --git a/Account/Sources/Account/Feedly/OAuthAuthorizationClient+Feedly.swift b/Account/Sources/Account/Feedly/OAuthAuthorizationClient+Feedly.swift index 7802ef29b..ea8174807 100644 --- a/Account/Sources/Account/Feedly/OAuthAuthorizationClient+Feedly.swift +++ b/Account/Sources/Account/Feedly/OAuthAuthorizationClient+Feedly.swift @@ -15,10 +15,10 @@ extension OAuthAuthorizationClient { /// Models private NetNewsWire client secrets. /// These placeholders are substitued at build time using a Run Script phase with build settings. /// https://developer.feedly.com/v3/auth/#authenticating-a-user-and-obtaining-an-auth-code - return OAuthAuthorizationClient(id: Secrets.feedlyClientId, + return OAuthAuthorizationClient(id: SecretsManager.provider.feedlyClientId, redirectUri: "netnewswire://auth/feedly", state: nil, - secret: Secrets.feedlyClientSecret) + secret: SecretsManager.provider.feedlyClientSecret) } static var feedlySandboxClient: OAuthAuthorizationClient { diff --git a/Account/Sources/Account/URLRequest+RSWeb.swift b/Account/Sources/Account/URLRequest+RSWeb.swift index 2f47785a8..be43ea00f 100755 --- a/Account/Sources/Account/URLRequest+RSWeb.swift +++ b/Account/Sources/Account/URLRequest+RSWeb.swift @@ -30,7 +30,7 @@ public extension URLRequest { self.url = url.appendingQueryItems([ URLQueryItem(name: "email", value: credentials.username), URLQueryItem(name: "password", value: credentials.secret), - URLQueryItem(name: "client_key", value: FeedWranglerConfig.clientKey) + URLQueryItem(name: "client_key", value: SecretsManager.provider.feedWranglerKey) ]) case .feedWranglerToken: self.url = url.appendingQueryItem(URLQueryItem(name: "access_token", value: credentials.secret)) diff --git a/Mac/AppDelegate.swift b/Mac/AppDelegate.swift index 51ac9368b..1a927e5b2 100644 --- a/Mac/AppDelegate.swift +++ b/Mac/AppDelegate.swift @@ -14,6 +14,7 @@ import RSWeb import Account import RSCore import RSCoreResources +import Secrets // If we're not going to import Sparkle, provide dummy protocols to make it easy // for AppDelegate to comply @@ -104,6 +105,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations, NSWindow.allowsAutomaticWindowTabbing = false super.init() + SecretsManager.provider = Secrets() AccountManager.shared = AccountManager(accountsFolder: Platform.dataSubfolder(forApplication: nil, folderName: "Accounts")!) FeedProviderManager.shared.delegate = ExtensionPointManager.shared diff --git a/Multiplatform/iOS/AppDelegate.swift b/Multiplatform/iOS/AppDelegate.swift index f97bef0c6..afc25d7d0 100644 --- a/Multiplatform/iOS/AppDelegate.swift +++ b/Multiplatform/iOS/AppDelegate.swift @@ -12,6 +12,7 @@ import RSWeb import Account import BackgroundTasks import os.log +import Secrets var appDelegate: AppDelegate! @@ -60,6 +61,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD super.init() appDelegate = self + SecretsManager.provider = Secrets() let documentAccountURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! let documentAccountsFolder = documentAccountURL.appendingPathComponent("Accounts").absoluteString let documentAccountsFolderPath = String(documentAccountsFolder.suffix(from: documentAccountsFolder.index(documentAccountsFolder.startIndex, offsetBy: 7))) diff --git a/Multiplatform/macOS/AppDelegate.swift b/Multiplatform/macOS/AppDelegate.swift index 4be1eb37c..0f6f0d23d 100644 --- a/Multiplatform/macOS/AppDelegate.swift +++ b/Multiplatform/macOS/AppDelegate.swift @@ -13,6 +13,7 @@ import Articles import RSWeb import Account import RSCore +import Secrets // If we're not going to import Sparkle, provide dummy protocols to make it easy // for AppDelegate to comply @@ -70,6 +71,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele override init() { super.init() + SecretsManager.provider = Secrets() AccountManager.shared = AccountManager(accountsFolder: Platform.dataSubfolder(forApplication: nil, folderName: "Accounts")!) FeedProviderManager.shared.delegate = ExtensionPointManager.shared diff --git a/NetNewsWire.xcodeproj/project.pbxproj b/NetNewsWire.xcodeproj/project.pbxproj index 13311b89e..d82338d49 100644 --- a/NetNewsWire.xcodeproj/project.pbxproj +++ b/NetNewsWire.xcodeproj/project.pbxproj @@ -444,6 +444,12 @@ 51C452AF2265108300C03939 /* ArticleArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F204DF1FAACBB30076E152 /* ArticleArray.swift */; }; 51C452B42265141B00C03939 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51C452B32265141B00C03939 /* WebKit.framework */; }; 51C452B82265178500C03939 /* styleSheet.css in Resources */ = {isa = PBXBuildFile; fileRef = 51C452B72265178500C03939 /* styleSheet.css */; }; + 51C4CFF024D37D1F00AF9874 /* Secrets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C4CFEF24D37D1F00AF9874 /* Secrets.swift */; }; + 51C4CFF124D37D1F00AF9874 /* Secrets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C4CFEF24D37D1F00AF9874 /* Secrets.swift */; }; + 51C4CFF224D37D1F00AF9874 /* Secrets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C4CFEF24D37D1F00AF9874 /* Secrets.swift */; }; + 51C4CFF324D37D1F00AF9874 /* Secrets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C4CFEF24D37D1F00AF9874 /* Secrets.swift */; }; + 51C4CFF424D37D1F00AF9874 /* Secrets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C4CFEF24D37D1F00AF9874 /* Secrets.swift */; }; + 51C4CFF624D37DD500AF9874 /* Secrets in Frameworks */ = {isa = PBXBuildFile; productRef = 51C4CFF524D37DD500AF9874 /* Secrets */; }; 51C65AFC24CCB2C9008EB3BD /* TimelineItems.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C65AFB24CCB2C9008EB3BD /* TimelineItems.swift */; }; 51C65AFD24CCB2C9008EB3BD /* TimelineItems.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C65AFB24CCB2C9008EB3BD /* TimelineItems.swift */; }; 51C9DE5823EA2EF4003D5A6D /* WrapperScriptMessageHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C9DE5723EA2EF4003D5A6D /* WrapperScriptMessageHandler.swift */; }; @@ -1661,6 +1667,7 @@ 51C4528B2265095F00C03939 /* AddFolderViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddFolderViewController.swift; sourceTree = ""; }; 51C452B32265141B00C03939 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.2.sdk/System/Library/Frameworks/WebKit.framework; sourceTree = DEVELOPER_DIR; }; 51C452B72265178500C03939 /* styleSheet.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; path = styleSheet.css; sourceTree = ""; }; + 51C4CFEF24D37D1F00AF9874 /* Secrets.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Secrets.swift; sourceTree = ""; }; 51C65AFB24CCB2C9008EB3BD /* TimelineItems.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItems.swift; sourceTree = ""; }; 51C9DE5723EA2EF4003D5A6D /* WrapperScriptMessageHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WrapperScriptMessageHandler.swift; sourceTree = ""; }; 51CD32A824D2CB25009ABAEF /* SyncDatabase */ = {isa = PBXFileReference; lastKnownFileType = folder; path = SyncDatabase; sourceTree = ""; }; @@ -2043,6 +2050,7 @@ 514C16DE24D2EF15009A3AFA /* RSTree in Frameworks */, 65ED42DE235E74230081F399 /* Sparkle.framework in Frameworks */, 65ED42D9235E740D0081F399 /* Sparkle.framework in Frameworks */, + 51C4CFF624D37DD500AF9874 /* Secrets in Frameworks */, 51E4DAED2425F6940091EB5B /* CloudKit.framework in Frameworks */, 514C16E124D2EF38009A3AFA /* RSCoreResources in Frameworks */, 514C16CE24D2E63F009A3AFA /* Account in Frameworks */, @@ -3190,6 +3198,7 @@ isa = PBXGroup; children = ( 842E45CD1ED8C308000A8B52 /* AppNotifications.swift */, + 51C4CFEF24D37D1F00AF9874 /* Secrets.swift */, 511B9805237DCAC90028BCAA /* UserInfoKey.swift */, 51C452AD2265102800C03939 /* Timeline */, 84702AB31FA27AE8006B8943 /* Commands */, @@ -3702,6 +3711,7 @@ 514C16CD24D2E63F009A3AFA /* Account */, 514C16DD24D2EF15009A3AFA /* RSTree */, 514C16E024D2EF38009A3AFA /* RSCoreResources */, + 51C4CFF524D37DD500AF9874 /* Secrets */, ); productName = NetNewsWire; productReference = 849C64601ED37A5D003D8FC0 /* NetNewsWire.app */; @@ -4420,6 +4430,7 @@ 51B80EB824BD1F8B00C6C32D /* ActivityViewController.swift in Sources */, 51E4994224A8713C00B667CB /* ArticleStatusSyncTimer.swift in Sources */, 51E498F624A8085D00B667CB /* SearchFeedDelegate.swift in Sources */, + 51C4CFF324D37D1F00AF9874 /* Secrets.swift in Sources */, 51B80EE124BD3E9600C6C32D /* FindInArticleActivity.swift in Sources */, 6586A5F724B632F8002BCF4F /* SettingsDetailAccountModel.swift in Sources */, 51E498F224A8085D00B667CB /* SmartFeedsController.swift in Sources */, @@ -4625,6 +4636,7 @@ 51B54A4324B5499B0014348B /* WebViewProvider.swift in Sources */, 1799E6CE24C320D600511E91 /* InspectorModel.swift in Sources */, 514E6C0024AD255D00AC6F6E /* PreviewArticles.swift in Sources */, + 51C4CFF424D37D1F00AF9874 /* Secrets.swift in Sources */, 1729529524AA1CAA00D65E66 /* GeneralPreferencesView.swift in Sources */, 1769E32724BC5B6C000E1E8E /* AddAccountModel.swift in Sources */, 1729529424AA1CAA00D65E66 /* AdvancedPreferencesView.swift in Sources */, @@ -4803,6 +4815,7 @@ 65ED403C235DEF6C0081F399 /* SingleLineTextFieldSizer.swift in Sources */, 65ED403D235DEF6C0081F399 /* TimelineTableCellView.swift in Sources */, 65ED403E235DEF6C0081F399 /* TimelineCellAppearance.swift in Sources */, + 51C4CFF124D37D1F00AF9874 /* Secrets.swift in Sources */, 510C43F4243C11FE009F70C3 /* ExtensionPointAddTableCellView.swift in Sources */, 65ED403F235DEF6C0081F399 /* ArticleRenderer.swift in Sources */, 65ED4040235DEF6C0081F399 /* GeneralPrefencesViewController.swift in Sources */, @@ -4888,6 +4901,7 @@ 5F323809231DF9F000706F6B /* VibrantTableViewCell.swift in Sources */, 51FE10042345529D0056195D /* UserNotificationManager.swift in Sources */, 519ED47C24488C6F007F8E94 /* ExtensionInspectorViewController.swift in Sources */, + 51C4CFF224D37D1F00AF9874 /* Secrets.swift in Sources */, 51C452A022650A1900C03939 /* WebFeedIconDownloader.swift in Sources */, 51C4529E22650A1900C03939 /* ImageDownloader.swift in Sources */, 51A66685238075AE00CB272D /* AddWebFeedDefaultContainer.swift in Sources */, @@ -5140,6 +5154,7 @@ 84B99C9D1FAE83C600ECDEDB /* DeleteCommand.swift in Sources */, 849A97541ED9EAC0007D329B /* AddWebFeedWindowController.swift in Sources */, 5144EA40227A37EC00D19003 /* ImportOPMLWindowController.swift in Sources */, + 51C4CFF024D37D1F00AF9874 /* Secrets.swift in Sources */, 849A976D1ED9EBC8007D329B /* TimelineTableView.swift in Sources */, 51333D1624685D2E00EB5C91 /* AddRedditFeedWindowController.swift in Sources */, 84D52E951FE588BB00D14F5B /* DetailStatusBarView.swift in Sources */, @@ -5782,6 +5797,10 @@ package = 510ECA4024D1DCD0001C31A6 /* XCRemoteSwiftPackageReference "RSTree" */; productName = RSTree; }; + 51C4CFF524D37DD500AF9874 /* Secrets */ = { + isa = XCSwiftPackageProductDependency; + productName = Secrets; + }; /* End XCSwiftPackageProductDependency section */ }; rootObject = 849C64581ED37A5D003D8FC0 /* Project object */; diff --git a/NetNewsWire.xcodeproj/xcshareddata/xcschemes/NetNewsWire-iOS.xcscheme b/NetNewsWire.xcodeproj/xcshareddata/xcschemes/NetNewsWire-iOS.xcscheme index 4195245b2..6a87af624 100644 --- a/NetNewsWire.xcodeproj/xcshareddata/xcschemes/NetNewsWire-iOS.xcscheme +++ b/NetNewsWire.xcodeproj/xcshareddata/xcschemes/NetNewsWire-iOS.xcscheme @@ -10,7 +10,7 @@ ActionType = "Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.ShellScriptAction"> + scriptText = ""${PROJECT_DIR}/buildscripts/updateSecrets.sh" 2>&1 "> String { + private func decode(_ encoded: [UInt8], salt: [UInt8]) -> String { String(decoding: encoded.enumerated().map { (offset, element) in element ^ salt[offset % salt.count] }, as: UTF8.self) diff --git a/iOS/AppDelegate.swift b/iOS/AppDelegate.swift index 6d99165ff..b1045d328 100644 --- a/iOS/AppDelegate.swift +++ b/iOS/AppDelegate.swift @@ -12,6 +12,7 @@ import RSWeb import Account import BackgroundTasks import os.log +import Secrets var appDelegate: AppDelegate! @@ -60,6 +61,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD super.init() appDelegate = self + SecretsManager.provider = Secrets() let documentAccountURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! let documentAccountsFolder = documentAccountURL.appendingPathComponent("Accounts").absoluteString let documentAccountsFolderPath = String(documentAccountsFolder.suffix(from: documentAccountsFolder.index(documentAccountsFolder.startIndex, offsetBy: 7)))