mirror of
https://github.com/Ranchero-Software/NetNewsWire
synced 2025-08-12 06:26:36 +00:00
Get rid of SecretsProvider protocol. Stop passing secretsProvider around — just use SecretKey.whatever static properties.
This commit is contained in:
@@ -270,7 +270,7 @@ public enum FetchType {
|
||||
return delegate.refreshProgress
|
||||
}
|
||||
|
||||
init(dataFolder: String, type: AccountType, accountID: String, secretsProvider: SecretsProvider, transport: Transport? = nil) {
|
||||
init(dataFolder: String, type: AccountType, accountID: String, transport: Transport? = nil) {
|
||||
switch type {
|
||||
case .onMyMac:
|
||||
self.delegate = LocalAccountDelegate()
|
||||
@@ -279,17 +279,17 @@ public enum FetchType {
|
||||
case .feedbin:
|
||||
self.delegate = FeedbinAccountDelegate(dataFolder: dataFolder, transport: transport)
|
||||
case .feedly:
|
||||
self.delegate = FeedlyAccountDelegate(dataFolder: dataFolder, transport: transport, api: FeedlyAccountDelegate.environment, secretsProvider: secretsProvider)
|
||||
self.delegate = FeedlyAccountDelegate(dataFolder: dataFolder, transport: transport, api: FeedlyAccountDelegate.environment)
|
||||
case .newsBlur:
|
||||
self.delegate = NewsBlurAccountDelegate(dataFolder: dataFolder, transport: transport)
|
||||
case .freshRSS:
|
||||
self.delegate = ReaderAPIAccountDelegate(dataFolder: dataFolder, transport: transport, variant: .freshRSS, secretsProvider: secretsProvider)
|
||||
self.delegate = ReaderAPIAccountDelegate(dataFolder: dataFolder, transport: transport, variant: .freshRSS)
|
||||
case .inoreader:
|
||||
self.delegate = ReaderAPIAccountDelegate(dataFolder: dataFolder, transport: transport, variant: .inoreader, secretsProvider: secretsProvider)
|
||||
self.delegate = ReaderAPIAccountDelegate(dataFolder: dataFolder, transport: transport, variant: .inoreader)
|
||||
case .bazQux:
|
||||
self.delegate = ReaderAPIAccountDelegate(dataFolder: dataFolder, transport: transport, variant: .bazQux, secretsProvider: secretsProvider)
|
||||
self.delegate = ReaderAPIAccountDelegate(dataFolder: dataFolder, transport: transport, variant: .bazQux)
|
||||
case .theOldReader:
|
||||
self.delegate = ReaderAPIAccountDelegate(dataFolder: dataFolder, transport: transport, variant: .theOldReader, secretsProvider: secretsProvider)
|
||||
self.delegate = ReaderAPIAccountDelegate(dataFolder: dataFolder, transport: transport, variant: .theOldReader)
|
||||
}
|
||||
|
||||
self.delegate.accountMetadata = metadata
|
||||
@@ -371,18 +371,18 @@ public enum FetchType {
|
||||
try CredentialsManager.removeCredentials(type: type, server: server, username: username)
|
||||
}
|
||||
|
||||
public static func validateCredentials(transport: Transport = URLSession.webserviceTransport(), type: AccountType, credentials: Credentials, endpoint: URL? = nil, secretsProvider: SecretsProvider) async throws -> Credentials? {
|
||||
public static func validateCredentials(transport: Transport = URLSession.webserviceTransport(), type: AccountType, credentials: Credentials, endpoint: URL? = nil) async throws -> Credentials? {
|
||||
|
||||
switch type {
|
||||
|
||||
case .feedbin:
|
||||
return try await FeedbinAccountDelegate.validateCredentials(transport: transport, credentials: credentials, endpoint: endpoint, secretsProvider: secretsProvider)
|
||||
return try await FeedbinAccountDelegate.validateCredentials(transport: transport, credentials: credentials, endpoint: endpoint)
|
||||
|
||||
case .newsBlur:
|
||||
return try await NewsBlurAccountDelegate.validateCredentials(transport: transport, credentials: credentials, endpoint: endpoint, secretsProvider: secretsProvider)
|
||||
return try await NewsBlurAccountDelegate.validateCredentials(transport: transport, credentials: credentials, endpoint: endpoint)
|
||||
|
||||
case .freshRSS, .inoreader, .bazQux, .theOldReader:
|
||||
return try await ReaderAPIAccountDelegate.validateCredentials(transport: transport, credentials: credentials, endpoint: endpoint, secretsProvider: secretsProvider)
|
||||
return try await ReaderAPIAccountDelegate.validateCredentials(transport: transport, credentials: credentials, endpoint: endpoint)
|
||||
|
||||
default:
|
||||
return nil
|
||||
|
||||
@@ -51,7 +51,7 @@ import Secrets
|
||||
|
||||
func accountWillBeDeleted(_ account: Account)
|
||||
|
||||
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?, secretsProvider: SecretsProvider) async throws -> Credentials?
|
||||
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?) async throws -> Credentials?
|
||||
|
||||
/// Suspend all network activity
|
||||
func suspendNetwork()
|
||||
|
||||
@@ -484,7 +484,7 @@ enum CloudKitAccountDelegateError: LocalizedError {
|
||||
articlesZone.resetChangeToken()
|
||||
}
|
||||
|
||||
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?, secretsProvider: SecretsProvider) async throws -> Credentials? {
|
||||
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?) async throws -> Credentials? {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -395,7 +395,7 @@ public enum FeedbinAccountDelegateError: String, Error {
|
||||
func accountWillBeDeleted(_ account: Account) {
|
||||
}
|
||||
|
||||
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?, secretsProvider: SecretsProvider) async throws -> Credentials? {
|
||||
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?) async throws -> Credentials? {
|
||||
|
||||
let caller = FeedbinAPICaller(transport: transport)
|
||||
caller.credentials = credentials
|
||||
|
||||
@@ -73,14 +73,14 @@ final class FeedlyAccountDelegate: AccountDelegate {
|
||||
private let log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "Feedly")
|
||||
private let syncDatabase: SyncDatabase
|
||||
|
||||
init(dataFolder: String, transport: Transport?, api: FeedlyAPICaller.API, secretsProvider: SecretsProvider) {
|
||||
init(dataFolder: String, transport: Transport?, api: FeedlyAPICaller.API) {
|
||||
// Many operations have their own operation queues, such as the sync all operation.
|
||||
// Making this a serial queue at this higher level of abstraction means we can ensure,
|
||||
// for example, a `FeedlyRefreshAccessTokenOperation` occurs before a `FeedlySyncAllOperation`,
|
||||
// improving our ability to debug, reason about and predict the behaviour of the code.
|
||||
|
||||
if let transport = transport {
|
||||
self.caller = FeedlyAPICaller(transport: transport, api: api, secretsProvider: secretsProvider)
|
||||
self.caller = FeedlyAPICaller(transport: transport, api: api)
|
||||
|
||||
} else {
|
||||
|
||||
@@ -95,12 +95,12 @@ final class FeedlyAccountDelegate: AccountDelegate {
|
||||
sessionConfiguration.httpAdditionalHeaders = UserAgent.headers
|
||||
|
||||
let session = URLSession(configuration: sessionConfiguration)
|
||||
self.caller = FeedlyAPICaller(transport: session, api: api, secretsProvider: secretsProvider)
|
||||
self.caller = FeedlyAPICaller(transport: session, api: api)
|
||||
}
|
||||
|
||||
let databasePath = (dataFolder as NSString).appendingPathComponent("Sync.sqlite3")
|
||||
self.syncDatabase = SyncDatabase(databasePath: databasePath)
|
||||
self.oauthAuthorizationClient = api.oauthAuthorizationClient(secretsProvider: secretsProvider)
|
||||
self.oauthAuthorizationClient = api.oauthAuthorizationClient()
|
||||
|
||||
self.caller.delegate = self
|
||||
}
|
||||
@@ -374,7 +374,7 @@ final class FeedlyAccountDelegate: AccountDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?, secretsProvider: SecretsProvider) async throws -> Credentials? {
|
||||
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?) async throws -> Credentials? {
|
||||
|
||||
assertionFailure("An `account` instance should refresh the access token first instead.")
|
||||
return credentials
|
||||
@@ -999,17 +999,15 @@ public enum FeedlyOAuthAccountAuthorizationOperationError: LocalizedError {
|
||||
|
||||
private let oauthClient: OAuthAuthorizationClient
|
||||
private var session: ASWebAuthenticationSession?
|
||||
private let secretsProvider: SecretsProvider
|
||||
|
||||
public init(secretsProvider: SecretsProvider) {
|
||||
self.secretsProvider = secretsProvider
|
||||
self.oauthClient = FeedlyAPICaller.API.cloud.oauthAuthorizationClient(secretsProvider: secretsProvider)
|
||||
override public init() {
|
||||
self.oauthClient = FeedlyAPICaller.API.cloud.oauthAuthorizationClient()
|
||||
}
|
||||
|
||||
public func run() {
|
||||
assert(presentationAnchor != nil, "\(self) outlived presentation anchor.")
|
||||
|
||||
let request = FeedlyAPICaller.oauthAuthorizationCodeGrantRequest(secretsProvider: secretsProvider)
|
||||
let request = FeedlyAPICaller.oauthAuthorizationCodeGrantRequest()
|
||||
|
||||
guard let url = request.url else {
|
||||
return DispatchQueue.main.async {
|
||||
@@ -1073,7 +1071,7 @@ public enum FeedlyOAuthAccountAuthorizationOperationError: LocalizedError {
|
||||
|
||||
let response = try OAuthAuthorizationResponse(url: url, client: self.oauthClient)
|
||||
|
||||
let tokenResponse = try await FeedlyAPICaller.requestOAuthAccessToken(with: response, transport: URLSession.webserviceTransport(), secretsProvider: secretsProvider)
|
||||
let tokenResponse = try await FeedlyAPICaller.requestOAuthAccessToken(with: response, transport: URLSession.webserviceTransport())
|
||||
saveAccount(for: tokenResponse)
|
||||
|
||||
} catch is ASWebAuthenticationSessionError {
|
||||
|
||||
@@ -158,7 +158,7 @@ final class LocalAccountDelegate: AccountDelegate {
|
||||
func accountWillBeDeleted(_ account: Account) {
|
||||
}
|
||||
|
||||
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?, secretsProvider: SecretsProvider) async throws -> Credentials? {
|
||||
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?) async throws -> Credentials? {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -430,7 +430,7 @@ final class NewsBlurAccountDelegate: AccountDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?, secretsProvider: SecretsProvider) async throws -> Credentials? {
|
||||
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?) async throws -> Credentials? {
|
||||
|
||||
let caller = NewsBlurAPICaller(transport: transport)
|
||||
caller.credentials = credentials
|
||||
|
||||
@@ -54,7 +54,7 @@ final class ReaderAPIAccountDelegate: AccountDelegate {
|
||||
|
||||
var refreshProgress = DownloadProgress(numberOfTasks: 0)
|
||||
|
||||
init(dataFolder: String, transport: Transport?, variant: ReaderAPIVariant, secretsProvider: SecretsProvider) {
|
||||
init(dataFolder: String, transport: Transport?, variant: ReaderAPIVariant) {
|
||||
|
||||
let databasePath = (dataFolder as NSString).appendingPathComponent("Sync.sqlite3")
|
||||
self.database = SyncDatabase(databasePath: databasePath)
|
||||
@@ -62,7 +62,7 @@ final class ReaderAPIAccountDelegate: AccountDelegate {
|
||||
self.variant = variant
|
||||
|
||||
if transport != nil {
|
||||
self.caller = ReaderAPICaller(transport: transport!, secretsProvider: secretsProvider)
|
||||
self.caller = ReaderAPICaller(transport: transport!)
|
||||
} else {
|
||||
let sessionConfiguration = URLSessionConfiguration.default
|
||||
sessionConfiguration.requestCachePolicy = .reloadIgnoringLocalCacheData
|
||||
@@ -74,7 +74,7 @@ final class ReaderAPIAccountDelegate: AccountDelegate {
|
||||
sessionConfiguration.urlCache = nil
|
||||
sessionConfiguration.httpAdditionalHeaders = UserAgent.headers
|
||||
|
||||
self.caller = ReaderAPICaller(transport: URLSession(configuration: sessionConfiguration), secretsProvider: secretsProvider)
|
||||
self.caller = ReaderAPICaller(transport: URLSession(configuration: sessionConfiguration))
|
||||
}
|
||||
|
||||
caller.delegate = self
|
||||
@@ -458,13 +458,13 @@ final class ReaderAPIAccountDelegate: AccountDelegate {
|
||||
func accountWillBeDeleted(_ account: Account) {
|
||||
}
|
||||
|
||||
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?, secretsProvider: SecretsProvider) async throws -> Credentials? {
|
||||
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?) async throws -> Credentials? {
|
||||
|
||||
guard let endpoint else {
|
||||
throw TransportError.noURL
|
||||
}
|
||||
|
||||
let caller = ReaderAPICaller(transport: transport, secretsProvider: secretsProvider)
|
||||
let caller = ReaderAPICaller(transport: transport)
|
||||
caller.credentials = credentials
|
||||
|
||||
return try await caller.validateCredentials(endpoint: endpoint)
|
||||
|
||||
@@ -27,8 +27,6 @@ import Secrets
|
||||
private let defaultAccountFolderName = "OnMyMac"
|
||||
private let defaultAccountIdentifier = "OnMyMac"
|
||||
|
||||
private let secretsProvider: SecretsProvider
|
||||
|
||||
public var isSuspended = false
|
||||
public var isUnreadCountsInitialized: Bool {
|
||||
for account in activeAccounts {
|
||||
@@ -94,10 +92,9 @@ import Secrets
|
||||
return CombinedRefreshProgress(downloadProgressArray: downloadProgressArray)
|
||||
}
|
||||
|
||||
public init(accountsFolder: String, secretsProvider: SecretsProvider) {
|
||||
public init(accountsFolder: String) {
|
||||
|
||||
self.accountsFolder = accountsFolder
|
||||
self.secretsProvider = secretsProvider
|
||||
|
||||
// The local "On My Mac" account must always exist, even if it's empty.
|
||||
let localAccountFolder = (accountsFolder as NSString).appendingPathComponent("OnMyMac")
|
||||
@@ -109,7 +106,7 @@ import Secrets
|
||||
abort()
|
||||
}
|
||||
|
||||
defaultAccount = Account(dataFolder: localAccountFolder, type: .onMyMac, accountID: defaultAccountIdentifier, secretsProvider: secretsProvider)
|
||||
defaultAccount = Account(dataFolder: localAccountFolder, type: .onMyMac, accountID: defaultAccountIdentifier)
|
||||
accountsDictionary[defaultAccount.accountID] = defaultAccount
|
||||
|
||||
readAccountsFromDisk()
|
||||
@@ -136,7 +133,7 @@ import Secrets
|
||||
abort()
|
||||
}
|
||||
|
||||
let account = Account(dataFolder: accountFolder, type: type, accountID: accountID, secretsProvider: secretsProvider)
|
||||
let account = Account(dataFolder: accountFolder, type: type, accountID: accountID)
|
||||
accountsDictionary[accountID] = account
|
||||
|
||||
var userInfo = [String: Any]()
|
||||
@@ -375,7 +372,7 @@ private extension AccountManager {
|
||||
}
|
||||
|
||||
func loadAccount(_ accountSpecifier: AccountSpecifier) -> Account? {
|
||||
return Account(dataFolder: accountSpecifier.folderPath, type: accountSpecifier.type, accountID: accountSpecifier.identifier, secretsProvider: secretsProvider)
|
||||
return Account(dataFolder: accountSpecifier.folderPath, type: accountSpecifier.type, accountID: accountSpecifier.identifier)
|
||||
}
|
||||
|
||||
func loadAccount(_ filename: String) -> Account? {
|
||||
|
||||
@@ -37,12 +37,12 @@ public protocol FeedlyAPICallerDelegate: AnyObject {
|
||||
return components
|
||||
}
|
||||
|
||||
public func oauthAuthorizationClient(secretsProvider: SecretsProvider) -> OAuthAuthorizationClient {
|
||||
public func oauthAuthorizationClient() -> OAuthAuthorizationClient {
|
||||
switch self {
|
||||
case .sandbox:
|
||||
return .feedlySandboxClient
|
||||
case .cloud:
|
||||
return OAuthAuthorizationClient.feedlyCloudClient(secretsProvider: secretsProvider)
|
||||
return OAuthAuthorizationClient.feedlyCloudClient()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,13 +50,11 @@ public protocol FeedlyAPICallerDelegate: AnyObject {
|
||||
private let transport: Transport
|
||||
private let baseURLComponents: URLComponents
|
||||
private let uriComponentAllowed: CharacterSet
|
||||
private let secretsProvider: SecretsProvider
|
||||
private let api: FeedlyAPICaller.API
|
||||
|
||||
public init(transport: Transport, api: API, secretsProvider: SecretsProvider) {
|
||||
public init(transport: Transport, api: API) {
|
||||
self.transport = transport
|
||||
self.baseURLComponents = api.baseUrlComponents
|
||||
self.secretsProvider = secretsProvider
|
||||
self.api = api
|
||||
|
||||
var urlHostAllowed = CharacterSet.urlHostAllowed
|
||||
@@ -556,8 +554,8 @@ extension FeedlyAPICaller {
|
||||
|
||||
private static let oauthAuthorizationGrantScope = "https://cloud.feedly.com/subscriptions"
|
||||
|
||||
public static func oauthAuthorizationCodeGrantRequest(secretsProvider: SecretsProvider) -> URLRequest {
|
||||
let client = API.cloud.oauthAuthorizationClient(secretsProvider: secretsProvider)
|
||||
public static func oauthAuthorizationCodeGrantRequest() -> URLRequest {
|
||||
let client = API.cloud.oauthAuthorizationClient()
|
||||
let authorizationRequest = OAuthAuthorizationRequest(clientID: client.id,
|
||||
redirectURI: client.redirectURI,
|
||||
scope: oauthAuthorizationGrantScope,
|
||||
@@ -566,13 +564,13 @@ extension FeedlyAPICaller {
|
||||
return FeedlyAPICaller.authorizationCodeURLRequest(for: authorizationRequest, baseUrlComponents: baseURLComponents)
|
||||
}
|
||||
|
||||
public static func requestOAuthAccessToken(with response: OAuthAuthorizationResponse, transport: any Web.Transport, secretsProvider: any Secrets.SecretsProvider) async throws -> OAuthAuthorizationGrant {
|
||||
public static func requestOAuthAccessToken(with response: OAuthAuthorizationResponse, transport: any Web.Transport) async throws -> OAuthAuthorizationGrant {
|
||||
|
||||
let client = API.cloud.oauthAuthorizationClient(secretsProvider: secretsProvider)
|
||||
let client = API.cloud.oauthAuthorizationClient()
|
||||
let request = OAuthAccessTokenRequest(authorizationResponse: response,
|
||||
scope: oauthAuthorizationGrantScope,
|
||||
client: client)
|
||||
let caller = FeedlyAPICaller(transport: transport, api: .cloud, secretsProvider: secretsProvider)
|
||||
let caller = FeedlyAPICaller(transport: transport, api: .cloud)
|
||||
let response = try await caller.requestAccessToken(request)
|
||||
|
||||
let accessToken = Credentials(type: .oauthAccessToken, username: response.id, secret: response.accessToken)
|
||||
|
||||
@@ -11,14 +11,14 @@ import Secrets
|
||||
|
||||
public extension OAuthAuthorizationClient {
|
||||
|
||||
static func feedlyCloudClient(secretsProvider: SecretsProvider) -> OAuthAuthorizationClient {
|
||||
static func feedlyCloudClient() -> OAuthAuthorizationClient {
|
||||
/// Models private NetNewsWire client secrets.
|
||||
/// These placeholders are substituted 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: secretsProvider.feedlyClientID,
|
||||
return OAuthAuthorizationClient(id: SecretKey.feedlyClientID,
|
||||
redirectURI: "netnewswire://auth/feedly",
|
||||
state: nil,
|
||||
secret: secretsProvider.feedlyClientSecret)
|
||||
secret: SecretKey.feedlyClientSecret)
|
||||
}
|
||||
|
||||
static var feedlySandboxClient: OAuthAuthorizationClient {
|
||||
|
||||
@@ -69,7 +69,6 @@ public enum CreateReaderAPISubscriptionResult: Sendable {
|
||||
}
|
||||
|
||||
private var transport: Transport!
|
||||
private let secretsProvider: SecretsProvider
|
||||
private let uriComponentAllowed: CharacterSet
|
||||
|
||||
private var accessToken: String?
|
||||
@@ -86,10 +85,9 @@ public enum CreateReaderAPISubscriptionResult: Sendable {
|
||||
}
|
||||
|
||||
/// The delegate should be set in a subsequent call.
|
||||
public init(transport: Transport, secretsProvider: SecretsProvider) {
|
||||
public init(transport: Transport) {
|
||||
|
||||
self.transport = transport
|
||||
self.secretsProvider = secretsProvider
|
||||
|
||||
var urlHostAllowed = CharacterSet.urlHostAllowed
|
||||
urlHostAllowed.remove("+")
|
||||
@@ -543,8 +541,8 @@ private extension ReaderAPICaller {
|
||||
|
||||
func addVariantHeaders(_ request: inout URLRequest) {
|
||||
if variant == .inoreader {
|
||||
request.addValue(secretsProvider.inoreaderAppID, forHTTPHeaderField: "AppId")
|
||||
request.addValue(secretsProvider.inoreaderAppKey, forHTTPHeaderField: "AppKey")
|
||||
request.addValue(SecretKey.inoreaderAppID, forHTTPHeaderField: "AppId")
|
||||
request.addValue(SecretKey.inoreaderAppKey, forHTTPHeaderField: "AppKey")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user