From 0a110a59d8a1cdb9c739d21f0b628f86196293d3 Mon Sep 17 00:00:00 2001 From: meiron03 Date: Sat, 14 Oct 2023 15:01:19 -0400 Subject: [PATCH] Fix getAccessToken() race condition. --- .../pennapps/labs/pennmobile/MainActivity.kt | 3 ++ .../pennmobile/api/OAuth2NetworkManager.kt | 43 +++++++++++++------ 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/PennMobile/src/main/java/com/pennapps/labs/pennmobile/MainActivity.kt b/PennMobile/src/main/java/com/pennapps/labs/pennmobile/MainActivity.kt index defd14e2..7736004d 100644 --- a/PennMobile/src/main/java/com/pennapps/labs/pennmobile/MainActivity.kt +++ b/PennMobile/src/main/java/com/pennapps/labs/pennmobile/MainActivity.kt @@ -48,6 +48,7 @@ import eightbitlab.com.blurview.RenderScriptBlur import kotlinx.android.synthetic.main.custom_sneaker_view.view.* import kotlinx.android.synthetic.main.fragment_dining_holder.* import kotlinx.android.synthetic.main.include_main.* +import kotlinx.coroutines.sync.Mutex import retrofit.RestAdapter import retrofit.android.AndroidLog import retrofit.client.OkClient @@ -60,6 +61,8 @@ class MainActivity : AppCompatActivity() { private lateinit var fragmentManager: FragmentManager private lateinit var mSharedPrefs: SharedPreferences + val tokenMutex = Mutex() + override fun onCreate(savedInstanceState: Bundle?) { setTheme(R.style.AppTheme) if (Build.VERSION.SDK_INT > 28) { diff --git a/PennMobile/src/main/java/com/pennapps/labs/pennmobile/api/OAuth2NetworkManager.kt b/PennMobile/src/main/java/com/pennapps/labs/pennmobile/api/OAuth2NetworkManager.kt index ce3cb51d..55cca64e 100644 --- a/PennMobile/src/main/java/com/pennapps/labs/pennmobile/api/OAuth2NetworkManager.kt +++ b/PennMobile/src/main/java/com/pennapps/labs/pennmobile/api/OAuth2NetworkManager.kt @@ -3,10 +3,16 @@ package com.pennapps.labs.pennmobile.api import android.preference.PreferenceManager import android.provider.Settings import android.util.Log +import androidx.lifecycle.lifecycleScope import com.pennapps.labs.pennmobile.BuildConfig import com.pennapps.labs.pennmobile.MainActivity import com.pennapps.labs.pennmobile.R import com.pennapps.labs.pennmobile.classes.AccessTokenResponse +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.sync.withLock import retrofit.Callback import retrofit.RetrofitError import retrofit.client.Response @@ -25,24 +31,33 @@ class OAuth2NetworkManager(private var mActivity: MainActivity) { @Synchronized fun getAccessToken(function: () -> Unit) { - val expiresIn = sp.getString(mActivity.getString(R.string.expires_in), "") - if (expiresIn != "") { - val expiresAt = sp.getLong(mActivity.getString(R.string.token_expires_at), 0) - val currentTime = Calendar.getInstance().timeInMillis - if (currentTime >= expiresAt) { // if it has expired, refresh access token - Log.i("Accounts", "Expired") - refreshAccessToken(function) + mActivity.lifecycleScope.launch { + val tokenMutex = mActivity.tokenMutex + tokenMutex.lock() + val expiresIn = sp.getString(mActivity.getString(R.string.expires_in), "") + if (expiresIn != "") { + val expiresAt = sp.getLong(mActivity.getString(R.string.token_expires_at), 0) + val currentTime = Calendar.getInstance().timeInMillis + if (currentTime >= expiresAt) { // if it has expired, refresh access token + Log.i("Accounts", "Expired") + refreshAccessToken (function) { + tokenMutex.unlock() + } + } else { + Log.i("Accounts", "Not Expired") + tokenMutex.unlock() + function.invoke() + } } else { - Log.i("Accounts", "Not Expired") - function.invoke() + refreshAccessToken (function) { + tokenMutex.unlock() + } } - } else { - refreshAccessToken(function) } } @Synchronized - private fun refreshAccessToken(function: () -> Unit) { + private fun refreshAccessToken(function: () -> Unit, unlockMutex: () -> Unit) { val refreshToken = sp.getString(mActivity.getString(R.string.refresh_token), "") val clientID = BuildConfig.PLATFORM_CLIENT_ID @@ -61,6 +76,7 @@ class OAuth2NetworkManager(private var mActivity: MainActivity) { val currentTime = Calendar.getInstance().timeInMillis editor.putLong(mActivity.getString(R.string.token_expires_at), currentTime + expiresInInt) editor.apply() + unlockMutex.invoke() function.invoke() Log.i("Accounts", "Reloaded Homepage") } @@ -72,9 +88,8 @@ class OAuth2NetworkManager(private var mActivity: MainActivity) { if (error.response != null && error.response.status == 400) { mActivity.startLoginFragment() + unlockMutex.invoke() } - - function.invoke() } }) }