Add lastCredentialRenewTime and honour it in FeedlyRefreshAccessTokenOperation

This commit is contained in:
Kiel Gillard 🤪 2020-04-19 08:31:20 +10:00
parent a4c672bb46
commit 8973adbdbd
2 changed files with 31 additions and 1 deletions

View File

@ -23,6 +23,7 @@ final class AccountMetadata: Codable {
case lastArticleFetchStartTime = "lastArticleFetch"
case lastArticleFetchEndTime
case endpointURL
case lastCredentialRenewTime = "lastCredentialRenewTime"
}
var name: String? {
@ -80,6 +81,16 @@ final class AccountMetadata: Codable {
}
}
}
/// The last moment an account successfully renewed its credentials, or `nil` if no such moment exists.
/// An account delegate can use this value to decide when to next ask the service provider to renew credentials.
var lastCredentialRenewTime: Date? {
didSet {
if lastCredentialRenewTime != oldValue {
valueDidChange(.lastCredentialRenewTime)
}
}
}
weak var delegate: AccountMetadataDelegate?

View File

@ -17,14 +17,31 @@ final class FeedlyRefreshAccessTokenOperation: FeedlyOperation {
let account: Account
let log: OSLog
init(account: Account, service: OAuthAccessTokenRefreshing, oauthClient: OAuthAuthorizationClient, log: OSLog) {
/// The moment the refresh is being requested. The token will refresh only if the account's `lastCredentialRenewTime` is not on the same day as this moment. When nil, the operation will always refresh the token.
let refreshDate: Date?
init(account: Account, service: OAuthAccessTokenRefreshing, oauthClient: OAuthAuthorizationClient, refreshDate: Date?, log: OSLog) {
self.oauthClient = oauthClient
self.service = service
self.account = account
self.refreshDate = refreshDate
self.log = log
}
override func run() {
// Only refresh the token if these dates are not on the same day.
let shouldRefresh: Bool = {
guard let date = refreshDate, let lastRenewDate = account.metadata.lastCredentialRenewTime else {
return true
}
return !Calendar.current.isDate(lastRenewDate, equalTo: date, toGranularity: .day)
}()
guard shouldRefresh else {
didFinish()
return
}
let refreshToken: Credentials
do {
@ -64,6 +81,8 @@ final class FeedlyRefreshAccessTokenOperation: FeedlyOperation {
// Now store the access token because we want the account delegate to use it.
try account.storeCredentials(grant.accessToken)
account.metadata.lastCredentialRenewTime = Date()
didFinish()
} catch {
didFinish(with: error)