mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2026-07-31 07:44:24 +02:00
Endurain: Improve token refresh logic
This commit is contained in:
+16
-12
@@ -25,6 +25,8 @@ import nodomain.freeyourgadget.gadgetbridge.GBApplication
|
||||
import nodomain.freeyourgadget.gadgetbridge.R
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.AbstractPreferenceFragment
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.AbstractSettingsActivityV2
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB
|
||||
|
||||
class EndurainPreferencesActivity : AbstractSettingsActivityV2() {
|
||||
|
||||
@@ -45,14 +47,16 @@ class EndurainPreferencesActivity : AbstractSettingsActivityV2() {
|
||||
updateLogoutPreferenceVisibility()
|
||||
setupLoginResultListener()
|
||||
|
||||
// Refresh auth token
|
||||
// Refresh tokens
|
||||
val vm: EndurainSetupViewModel by viewModels()
|
||||
val server = GBApplication.getPrefs().preferences.getString("endurain_server", null)
|
||||
if (server != null) {
|
||||
vm.performTokenRefresh(server) {
|
||||
activity?.runOnUiThread {
|
||||
updateStatus()
|
||||
updateLogoutPreferenceVisibility()
|
||||
if (vm.tokenManager.isAccessTokenExpired()) {
|
||||
vm.performTokenRefresh(server) {
|
||||
activity?.runOnUiThread {
|
||||
updateStatus()
|
||||
updateLogoutPreferenceVisibility()
|
||||
}
|
||||
}
|
||||
}
|
||||
vm.fetchServerVersion(server) {
|
||||
@@ -106,29 +110,29 @@ class EndurainPreferencesActivity : AbstractSettingsActivityV2() {
|
||||
vm.logout { success ->
|
||||
activity?.runOnUiThread {
|
||||
if (success) {
|
||||
Toast.makeText(requireContext(), "Logged out successfully", Toast.LENGTH_SHORT).show()
|
||||
GB.toast("Logged out successfully", Toast.LENGTH_SHORT, GB.INFO)
|
||||
updateStatus()
|
||||
updateLogoutPreferenceVisibility()
|
||||
} else {
|
||||
Toast.makeText(requireContext(), "Logout failed", Toast.LENGTH_SHORT).show()
|
||||
GB.toast("Logout failed", Toast.LENGTH_SHORT, GB.WARN)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateLogoutPreferenceVisibility() {
|
||||
findPreference<Preference>("pref_key_log_out")?.isVisible = vm.isLoggedIn()
|
||||
findPreference<Preference>("pref_key_log_in")?.isVisible = !vm.isLoggedIn()
|
||||
findPreference<Preference>("pref_key_log_out")?.isVisible = vm.tokenManager.isLoggedIn()
|
||||
findPreference<Preference>("pref_key_log_in")?.isVisible = !vm.tokenManager.isLoggedIn()
|
||||
}
|
||||
|
||||
private fun updateStatus() {
|
||||
val statusPref = findPreference<Preference>("pref_key_status")
|
||||
val server = GBApplication.getPrefs().preferences.getString("endurain_server", null)
|
||||
val tokenExpiresAt = vm.getTokenExpiresAt()
|
||||
val tokenExpiresAt = DateTimeUtils.parseTimeStamp(vm.tokenManager.getRefreshTokenExpiresAt())
|
||||
|
||||
var summaryText = "Not logged in, integration is disabled"
|
||||
if (vm.isLoggedIn() && server != null) {
|
||||
summaryText = "Logged in to $server\nAuth token expires: $tokenExpiresAt"
|
||||
if (vm.tokenManager.isLoggedIn() && server != null) {
|
||||
summaryText = "Logged in to $server\nRefresh token expires: $tokenExpiresAt"
|
||||
}
|
||||
if (vm.serverVersion != null) {
|
||||
summaryText += "\nServer version: ${vm.serverVersion}"
|
||||
|
||||
+3
-17
@@ -27,7 +27,6 @@ import java.util.Date
|
||||
class EndurainSetupViewModel(application: Application) : AndroidViewModel(application) {
|
||||
|
||||
private val LOG = LoggerFactory.getLogger(EndurainSetupViewModel::class.java)
|
||||
private val tokenManager = EndurainTokenManager(application)
|
||||
private lateinit var apiClient: EndurainApiClient
|
||||
|
||||
enum class Step {
|
||||
@@ -38,6 +37,7 @@ class EndurainSetupViewModel(application: Application) : AndroidViewModel(applic
|
||||
SSO_LOGIN
|
||||
}
|
||||
|
||||
val tokenManager = EndurainTokenManager(application)
|
||||
var step = Step.SERVER
|
||||
var server = ""
|
||||
var localLoginEnabled = false
|
||||
@@ -45,7 +45,6 @@ class EndurainSetupViewModel(application: Application) : AndroidViewModel(applic
|
||||
var pendingMfaUsername: String? = null
|
||||
var serverVersion: String? = null
|
||||
|
||||
|
||||
/**
|
||||
* Fetch server version
|
||||
*/
|
||||
@@ -57,9 +56,10 @@ class EndurainSetupViewModel(application: Application) : AndroidViewModel(applic
|
||||
try {
|
||||
apiClient = EndurainApiClient(serverUrl, tokenManager)
|
||||
serverVersion = apiClient.fetchVersion()
|
||||
callback(true)
|
||||
} catch (e: Exception) {
|
||||
LOG.error("Fetching server version error", e)
|
||||
callback(true)
|
||||
callback(false)
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
@@ -224,20 +224,6 @@ class EndurainSetupViewModel(application: Application) : AndroidViewModel(applic
|
||||
}.start()
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if user is currently logged in
|
||||
*/
|
||||
fun isLoggedIn(): Boolean {
|
||||
return tokenManager.getAccessToken() != null && !tokenManager.isTokenExpired()
|
||||
}
|
||||
|
||||
/**
|
||||
* Get token expiry date
|
||||
*/
|
||||
fun getTokenExpiresAt(): Date {
|
||||
return DateTimeUtils.parseTimeStamp(tokenManager.getAccessTokenExpiresAt())
|
||||
}
|
||||
|
||||
/**
|
||||
* Logout and clear tokens
|
||||
*/
|
||||
|
||||
+20
-8
@@ -38,18 +38,30 @@ class EndurainTokenManager(context: Context) {
|
||||
sharedPreferences.edit {
|
||||
putString("access_token", accessToken)
|
||||
.putString("refresh_token", refreshToken)
|
||||
.putInt("expires_at", accessTokenExpiresAt)
|
||||
.putInt("access_token_expires_at", accessTokenExpiresAt)
|
||||
.putInt("refresh_token_expires_at",
|
||||
((System.currentTimeMillis() / 1000) + (7 * 24 * 60 * 60)).toInt()
|
||||
) // FIXME: 7 days is the Endurain default for refresh token expiry
|
||||
// https://github.com/endurain-project/endurain/issues/514
|
||||
}
|
||||
}
|
||||
|
||||
fun getAccessToken(): String? = sharedPreferences.getString("access_token", null)
|
||||
fun getRefreshToken(): String? = sharedPreferences.getString("refresh_token", null)
|
||||
fun getAccessTokenExpiresAt(): Int = sharedPreferences.getInt("expires_at", 0)
|
||||
fun isTokenExpired(): Boolean {
|
||||
return (System.currentTimeMillis() / 1000) >= getAccessTokenExpiresAt()
|
||||
}
|
||||
|
||||
fun clearTokens() {
|
||||
sharedPreferences.edit { clear() }
|
||||
}
|
||||
|
||||
fun getAccessToken(): String? = sharedPreferences.getString("access_token", null)
|
||||
fun getAccessTokenExpiresAt(): Int = sharedPreferences.getInt("access_token_expires_at", 0)
|
||||
fun getRefreshToken(): String? = sharedPreferences.getString("refresh_token", null)
|
||||
fun getRefreshTokenExpiresAt(): Int = sharedPreferences.getInt("refresh_token_expires_at", 0)
|
||||
|
||||
fun isLoggedIn(): Boolean {
|
||||
return getRefreshToken() != null && !isRefreshTokenExpired()
|
||||
}
|
||||
fun isAccessTokenExpired(): Boolean {
|
||||
return (System.currentTimeMillis() / 1000) >= getAccessTokenExpiresAt()
|
||||
}
|
||||
fun isRefreshTokenExpired(): Boolean {
|
||||
return (System.currentTimeMillis() / 1000) >= getRefreshTokenExpiresAt()
|
||||
}
|
||||
}
|
||||
+20
-15
@@ -61,7 +61,6 @@ import nodomain.freeyourgadget.gadgetbridge.activities.ActivitySummariesChartFra
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.charts.DurationXLabelFormatter
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.endurain.EndurainApiClient
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.endurain.EndurainSetupViewModel
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.endurain.EndurainTokenManager
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.fit.FitViewerActivity
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.workouts.charts.ChartDataRepository
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.workouts.charts.DefaultWorkoutCharts
|
||||
@@ -639,13 +638,7 @@ class WorkoutDetailsFragment : Fragment(), MenuProvider {
|
||||
|
||||
val endurainVm: EndurainSetupViewModel by viewModels()
|
||||
val server = GBApplication.getPrefs().preferences.getString("endurain_server", null)
|
||||
if (server != null) {
|
||||
endurainVm.performTokenRefresh(server) {
|
||||
activity?.runOnUiThread {
|
||||
overflowMenu?.findItem(R.id.activity_action_upload_to_endurain)?.isVisible = hasGpx && endurainVm.isLoggedIn()
|
||||
}
|
||||
}
|
||||
}
|
||||
overflowMenu?.findItem(R.id.activity_action_upload_to_endurain)?.isVisible = hasGpx && server != null && endurainVm.tokenManager.isLoggedIn()
|
||||
}
|
||||
|
||||
private fun takeSharedScreenshot() {
|
||||
@@ -761,14 +754,26 @@ class WorkoutDetailsFragment : Fragment(), MenuProvider {
|
||||
}
|
||||
|
||||
try {
|
||||
val tokenManager = EndurainTokenManager(requireContext())
|
||||
val endurainVm: EndurainSetupViewModel by viewModels()
|
||||
val serverUrl = GBApplication.getPrefs().preferences.getString("endurain_server", null)
|
||||
val apiClient = EndurainApiClient(serverUrl!!, tokenManager)
|
||||
apiClient.uploadActivity(gpxFile) { success ->
|
||||
if (success)
|
||||
GB.toast("Successfully uploaded to Endurain", Toast.LENGTH_SHORT, GB.INFO)
|
||||
else
|
||||
GB.toast("Error while uploading to Endurain", Toast.LENGTH_SHORT, GB.INFO)
|
||||
val apiClient = EndurainApiClient(serverUrl!!, endurainVm.tokenManager)
|
||||
endurainVm.performTokenRefresh(serverUrl) {
|
||||
apiClient.uploadActivity(gpxFile) { success ->
|
||||
activity?.runOnUiThread {
|
||||
if (success)
|
||||
GB.toast(
|
||||
"Successfully uploaded to Endurain",
|
||||
Toast.LENGTH_SHORT,
|
||||
GB.INFO
|
||||
)
|
||||
else
|
||||
GB.toast(
|
||||
"Error while uploading to Endurain",
|
||||
Toast.LENGTH_SHORT,
|
||||
GB.INFO
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
GB.toast(
|
||||
|
||||
Reference in New Issue
Block a user