Rework to store endpoint URL in metadata

Endpoint URL did not belong with credentials. This breaks it out and stores it in the account metadata. Updates validation code to take it as a parameter.
This commit is contained in:
Jeremy Beker 2019-05-29 15:16:09 -04:00
parent 0df86e5761
commit aa6dfe8a08
No known key found for this signature in database
GPG Key ID: CD5EE767A4A34FD0
9 changed files with 60 additions and 29 deletions

View File

@ -121,6 +121,17 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container,
}
}
public var endpointURL: URL? {
get {
return metadata.endpointURL
}
set {
if newValue != metadata.endpointURL {
metadata.endpointURL = newValue
}
}
}
private var fetchingAllUnreadCounts = false
var isUnreadCountsInitialized = false
@ -262,9 +273,9 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container,
switch credentials {
case .basic(let username, _):
self.username = username
case .googleBasicLogin(let username, _, _):
case .googleBasicLogin(let username, _):
self.username = username
case .googleAuthLogin(let username, _, _):
case .googleAuthLogin(let username, _):
self.username = username
}
@ -289,14 +300,14 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container,
self.username = nil
}
public static func validateCredentials(transport: Transport = URLSession.webserviceTransport(), type: AccountType, credentials: Credentials, completion: @escaping (Result<Credentials?, Error>) -> Void) {
public static func validateCredentials(transport: Transport = URLSession.webserviceTransport(), type: AccountType, credentials: Credentials, endpoint: URL? = nil, completion: @escaping (Result<Credentials?, Error>) -> Void) {
switch type {
case .onMyMac:
LocalAccountDelegate.validateCredentials(transport: transport, credentials: credentials, completion: completion)
case .feedbin:
FeedbinAccountDelegate.validateCredentials(transport: transport, credentials: credentials, completion: completion)
case .googleReaderCompatible:
GoogleReaderCompatibleAccountDelegate.validateCredentials(transport: transport, credentials: credentials, completion: completion)
GoogleReaderCompatibleAccountDelegate.validateCredentials(transport: transport, credentials: credentials, endpoint: endpoint, completion: completion)
default:
break
}

View File

@ -46,6 +46,6 @@ protocol AccountDelegate {
// Called at the end of accounts init method.
func accountDidInitialize(_ account: Account)
static func validateCredentials(transport: Transport, credentials: Credentials, completion: @escaping (Result<Credentials?, Error>) -> Void)
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?, completion: @escaping (Result<Credentials?, Error>) -> Void)
}

View File

@ -21,6 +21,7 @@ final class AccountMetadata: Codable {
case username
case conditionalGetInfo
case lastArticleFetch
case endpointURL
}
var name: String? {
@ -63,6 +64,14 @@ final class AccountMetadata: Codable {
}
}
var endpointURL: URL? {
didSet {
if endpointURL != oldValue {
valueDidChange(.endpointURL)
}
}
}
weak var delegate: AccountMetadataDelegate?
func valueDidChange(_ key: CodingKeys) {

View File

@ -485,7 +485,7 @@ final class FeedbinAccountDelegate: AccountDelegate {
accountMetadata = account.metadata
}
static func validateCredentials(transport: Transport, credentials: Credentials, completion: @escaping (Result<Credentials?, Error>) -> Void) {
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL? = nil, completion: @escaping (Result<Credentials?, Error>) -> Void) {
let caller = FeedbinAPICaller(transport: transport)
caller.credentials = credentials

View File

@ -39,18 +39,17 @@ final class GoogleReaderCompatibleAPICaller: NSObject {
var server: String? {
get {
guard let localCredentials = credentials else {
return APIBaseURL?.host
}
}
private var APIBaseURL: URL? {
get {
guard let accountMetadata = accountMetadata else {
return nil
}
switch localCredentials {
case .googleBasicLogin(_, _, let apiUrl):
return apiUrl.host
case .googleAuthLogin(_, _, let apiUrl):
return apiUrl.host
default:
return nil
}
return accountMetadata.endpointURL
}
}
@ -60,18 +59,18 @@ final class GoogleReaderCompatibleAPICaller: NSObject {
self.transport = transport
}
func validateCredentials(completion: @escaping (Result<Credentials?, Error>) -> Void) {
func validateCredentials(endpoint: URL, completion: @escaping (Result<Credentials?, Error>) -> Void) {
guard let credentials = credentials else {
completion(.failure(CredentialsError.incompleteCredentials))
return
}
guard case .googleBasicLogin(let username, _, let apiUrl) = credentials else {
guard case .googleBasicLogin(let username, _) = credentials else {
completion(.failure(CredentialsError.incompleteCredentials))
return
}
let request = URLRequest(url: apiUrl.appendingPathComponent("/accounts/ClientLogin"), credentials: credentials)
let request = URLRequest(url: endpoint.appendingPathComponent("/accounts/ClientLogin"), credentials: credentials)
transport.send(request: request) { result in
switch result {
@ -99,7 +98,7 @@ final class GoogleReaderCompatibleAPICaller: NSObject {
}
// Save Auth Token for later use
self.credentials = .googleAuthLogin(username: username, apiKey: authString, url: apiUrl)
self.credentials = .googleAuthLogin(username: username, apiKey: authString)
completion(.success(self.credentials))
case .failure(let error):
@ -159,10 +158,14 @@ final class GoogleReaderCompatibleAPICaller: NSObject {
}
func retrieveTags(completion: @escaping (Result<[GoogleReaderCompatibleTag]?, Error>) -> Void) {
guard let baseURL = APIBaseURL else {
completion(.failure(CredentialsError.incompleteCredentials))
return
}
let callURL = GoogleReaderCompatibleBaseURL.appendingPathComponent("tags.json")
let conditionalGet = accountMetadata?.conditionalGetInfo[ConditionalGetKeys.tags]
let request = URLRequest(url: callURL, credentials: credentials, conditionalGet: conditionalGet)
let callURL = baseURL.appendingPathComponent("/reader/api/0/tag/list?output=json")
//let conditionalGet = accountMetadata?.conditionalGetInfo[ConditionalGetKeys.tags]
let request = URLRequest(url: callURL, credentials: credentials)
transport.send(request: request, resultType: [GoogleReaderCompatibleTag].self) { result in

View File

@ -490,11 +490,15 @@ final class GoogleReaderCompatibleAccountDelegate: AccountDelegate {
accountMetadata = account.metadata
}
static func validateCredentials(transport: Transport, credentials: Credentials, completion: @escaping (Result<Credentials?, Error>) -> Void) {
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?, completion: @escaping (Result<Credentials?, Error>) -> Void) {
guard let endpoint = endpoint else {
completion(.failure(TransportError.noURL))
return
}
let caller = GoogleReaderCompatibleAPICaller(transport: transport)
caller.credentials = credentials
caller.validateCredentials() { result in
caller.validateCredentials(endpoint: endpoint) { result in
DispatchQueue.main.async {
completion(result)
}

View File

@ -182,7 +182,7 @@ final class LocalAccountDelegate: AccountDelegate {
func accountDidInitialize(_ account: Account) {
}
static func validateCredentials(transport: Transport, credentials: Credentials, completion: (Result<Credentials?, Error>) -> Void) {
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL? = nil, completion: (Result<Credentials?, Error>) -> Void) {
return completion(.success(nil))
}

View File

@ -70,8 +70,8 @@ class AccountsGoogleReaderCompatibleWindowController: NSWindowController {
return
}
let credentials = Credentials.googleBasicLogin(username: usernameTextField.stringValue, password: passwordTextField.stringValue, url: apiURL)
Account.validateCredentials(type: .googleReaderCompatible, credentials: credentials) { [weak self] result in
let credentials = Credentials.googleBasicLogin(username: usernameTextField.stringValue, password: passwordTextField.stringValue)
Account.validateCredentials(type: .googleReaderCompatible, credentials: credentials, endpoint: apiURL) { [weak self] result in
guard let self = self else { return }
@ -94,8 +94,12 @@ class AccountsGoogleReaderCompatibleWindowController: NSWindowController {
}
do {
self.account?.endpointURL = apiURL
try self.account?.removeBasicCredentials()
try self.account?.storeCredentials(validatedCredentials)
if newAccount {
self.account?.refreshAll() { result in
switch result {

@ -1 +1 @@
Subproject commit 07ec7f9179dfdf7e89fc97a4a90c4690fa71581a
Subproject commit f3bcd0312d6797e2722760c1de622e2957114802