From 4349be98c59d6f6496c9acb15389f9ff3d53f576 Mon Sep 17 00:00:00 2001 From: meiron03 Date: Wed, 22 Jan 2025 18:07:10 -0500 Subject: [PATCH 1/2] Remove StudentLife from login logic. --- .../pennmobile/api/OAuth2NetworkManager.kt | 66 ++++++++--------- .../labs/pennmobile/api/StudentLife.java | 18 ----- .../labs/pennmobile/api/StudentLifeRf2.kt | 21 ++++++ .../api/fragments/LoginWebviewFragment.kt | 73 ++++++++++--------- 4 files changed, 89 insertions(+), 89 deletions(-) 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 9d8428be0..585ca108a 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 @@ -18,7 +18,7 @@ import java.util.Calendar class OAuth2NetworkManager( private var mActivity: MainActivity, ) { - private var mStudentLife = MainActivity.studentLifeInstance + private var mStudentLifeRf2 = MainActivity.studentLifeInstanceRf2 private val sp = PreferenceManager.getDefaultSharedPreferences(mActivity) val editor = sp?.edit() @@ -62,49 +62,45 @@ class OAuth2NetworkManager( } } - @Synchronized - private fun refreshAccessToken( + private suspend fun refreshAccessToken( function: () -> Unit, unlockMutex: () -> Unit, ) { - val refreshToken = sp.getString(mActivity.getString(R.string.refresh_token), "") + val refreshToken = sp.getString(mActivity.getString(R.string.refresh_token), "") ?: "" val clientID = BuildConfig.PLATFORM_CLIENT_ID - mStudentLife.refreshAccessToken( + val response = mStudentLifeRf2.refreshAccessToken( refreshToken, "refresh_token", clientID, - object : Callback { - override fun success( - t: AccessTokenResponse?, - response: Response?, - ) { - if (response?.status == 200) { - val editor = sp.edit() - editor.putString(mActivity.getString(R.string.access_token), t?.accessToken) - editor.putString(mActivity.getString(R.string.refresh_token), t?.refreshToken) - editor.putString(mActivity.getString(R.string.expires_in), t?.expiresIn) - val expiresIn = t?.expiresIn - val expiresInInt = (expiresIn!!.toInt() * 1000) - 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") - } - } + ) - override fun failure(error: RetrofitError) { - FirebaseCrashlytics.getInstance().recordException(error) - Log.e("Accounts", "Error refreshing access token $error") + if (response.isSuccessful) { + val t = response.body()!! - if (error.response != null && error.response.status == 400) { - mActivity.startLoginFragment() - unlockMutex.invoke() - } - } - }, - ) + val editor = sp.edit() + editor.putString(mActivity.getString(R.string.access_token), t.accessToken) + editor.putString(mActivity.getString(R.string.refresh_token), t.refreshToken) + editor.putString(mActivity.getString(R.string.expires_in), t.expiresIn) + val expiresIn = t.expiresIn + val expiresInInt = (expiresIn!!.toInt() * 1000) + val currentTime = Calendar.getInstance().timeInMillis + editor.putLong(mActivity.getString(R.string.token_expires_at), currentTime + expiresInInt) + editor.apply() + Log.i("Accounts", "Refreshed access token") + + unlockMutex.invoke() + function.invoke() + } else { + val error = response.errorBody()!! + + FirebaseCrashlytics.getInstance().recordException(Exception(error.toString())) + Log.e("Accounts", "Error refreshing access token $error") + + if (response.code() == 400) { + mActivity.startLoginFragment() + unlockMutex.invoke() + } + } } } diff --git a/PennMobile/src/main/java/com/pennapps/labs/pennmobile/api/StudentLife.java b/PennMobile/src/main/java/com/pennapps/labs/pennmobile/api/StudentLife.java index aa4380b48..a0cb53764 100644 --- a/PennMobile/src/main/java/com/pennapps/labs/pennmobile/api/StudentLife.java +++ b/PennMobile/src/main/java/com/pennapps/labs/pennmobile/api/StudentLife.java @@ -44,24 +44,6 @@ */ public interface StudentLife { - @FormUrlEncoded - @POST("/accounts/token/") - void getAccessToken( - @Field("code") String authCode, - @Field("grant_type") String grantType, - @Field("client_id") String clientID, - @Field("redirect_uri") String redirectURI, - @Field("code_verifier") String codeVerifier, - Callback callback); - - @FormUrlEncoded - @POST("/accounts/token/") - void refreshAccessToken( - @Field("refresh_token") String refreshToken, - @Field("grant_type") String grantType, - @Field("client_id") String clientID, - Callback callback); - @GET("/dining/venues") Observable> venues(); diff --git a/PennMobile/src/main/java/com/pennapps/labs/pennmobile/api/StudentLifeRf2.kt b/PennMobile/src/main/java/com/pennapps/labs/pennmobile/api/StudentLifeRf2.kt index c3168effa..a57bdd997 100644 --- a/PennMobile/src/main/java/com/pennapps/labs/pennmobile/api/StudentLifeRf2.kt +++ b/PennMobile/src/main/java/com/pennapps/labs/pennmobile/api/StudentLifeRf2.kt @@ -1,3 +1,4 @@ +import com.pennapps.labs.pennmobile.api.classes.AccessTokenResponse import com.pennapps.labs.pennmobile.laundry.classes.LaundryPreferences import com.pennapps.labs.pennmobile.laundry.classes.LaundryRequest import com.pennapps.labs.pennmobile.laundry.classes.LaundryRoom @@ -6,12 +7,32 @@ import com.pennapps.labs.pennmobile.laundry.classes.LaundryUsage import okhttp3.ResponseBody import retrofit2.Response import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded import retrofit2.http.GET import retrofit2.http.Header import retrofit2.http.POST import retrofit2.http.Path interface StudentLifeRf2 { + @FormUrlEncoded + @POST("accounts/token/") + suspend fun getAccessToken( + @Field("code") authCode: String, + @Field("grant_type") grantType: String, + @Field("client_id") clientID: String, + @Field("redirect_uri") redirectURI: String, + @Field("code_verifier") codeVerifier: String, + ): Response + + @FormUrlEncoded + @POST("accounts/token/") + suspend fun refreshAccessToken( + @Field("refresh_token") refreshToken: String, + @Field("grant_type") grantType: String, + @Field("client_id") clientID: String, + ): Response + @GET("laundry/halls/ids") suspend fun laundryRooms(): Response> diff --git a/PennMobile/src/main/java/com/pennapps/labs/pennmobile/api/fragments/LoginWebviewFragment.kt b/PennMobile/src/main/java/com/pennapps/labs/pennmobile/api/fragments/LoginWebviewFragment.kt index 904c49cb3..40ab77b22 100644 --- a/PennMobile/src/main/java/com/pennapps/labs/pennmobile/api/fragments/LoginWebviewFragment.kt +++ b/PennMobile/src/main/java/com/pennapps/labs/pennmobile/api/fragments/LoginWebviewFragment.kt @@ -1,5 +1,6 @@ package com.pennapps.labs.pennmobile.api.fragments +import StudentLifeRf2 import android.content.SharedPreferences import android.os.Bundle import android.security.keystore.KeyGenParameterSpec @@ -17,6 +18,7 @@ import android.widget.Button import android.widget.LinearLayout import android.widget.Toast import androidx.fragment.app.Fragment +import androidx.lifecycle.lifecycleScope import androidx.preference.PreferenceManager import com.google.firebase.analytics.FirebaseAnalytics import com.google.firebase.crashlytics.FirebaseCrashlytics @@ -29,6 +31,7 @@ import com.pennapps.labs.pennmobile.api.StudentLife import com.pennapps.labs.pennmobile.api.classes.AccessTokenResponse import com.pennapps.labs.pennmobile.api.classes.Account import com.pennapps.labs.pennmobile.api.classes.GetUserResponse +import kotlinx.coroutines.launch import org.apache.commons.lang3.RandomStringUtils import retrofit.Callback import retrofit.RetrofitError @@ -46,7 +49,7 @@ class LoginWebviewFragment : Fragment() { lateinit var headerLayout: LinearLayout lateinit var cancelButton: Button lateinit var user: Account - private lateinit var mStudentLife: StudentLife + private lateinit var mStudentLifeRf2: StudentLifeRf2 private var mPlatform: Platform? = null private lateinit var mActivity: MainActivity lateinit var sp: SharedPreferences @@ -64,7 +67,7 @@ class LoginWebviewFragment : Fragment() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - mStudentLife = MainActivity.studentLifeInstance + mStudentLifeRf2 = MainActivity.studentLifeInstanceRf2 mPlatform = MainActivity.platformInstance arguments?.let { user = arguments?.getSerializable("user") as Account @@ -180,43 +183,41 @@ class LoginWebviewFragment : Fragment() { } private fun initiateAuthentication(authCode: String) { - mStudentLife.getAccessToken( - authCode, - "authorization_code", - clientID, - redirectUri, - codeVerifier, - object : Callback { - override fun success( - t: AccessTokenResponse?, - response: Response?, - ) { - if (response?.status == 200) { - FirebaseAnalytics.getInstance(mActivity).logEvent("LoginEvent", null) + mActivity.lifecycleScope.launch { + val response = mStudentLifeRf2.getAccessToken( + authCode, + "authorization_code", + clientID, + redirectUri, + codeVerifier, + ) - val accessToken = t?.accessToken - val editor = sp.edit() - editor.putString(getString(R.string.access_token), accessToken) - editor.putString(getString(R.string.refresh_token), t?.refreshToken) - editor.putString(getString(R.string.expires_in), t?.expiresIn) + if (response.isSuccessful) { + val t : AccessTokenResponse? = response.body() + FirebaseAnalytics.getInstance(mActivity).logEvent("LoginEvent", null) - val expiresInInt = t?.expiresIn!!.toInt() * 1000 - Log.i("LoginWebview", "Expires In: $expiresInInt") - val currentTime = Calendar.getInstance().timeInMillis - editor.putLong(getString(R.string.token_expires_at), currentTime + expiresInInt) - editor.apply() - getUser(accessToken) - } - } + val accessToken = t?.accessToken + val editor = sp.edit() + editor.putString(getString(R.string.access_token), accessToken) + editor.putString(getString(R.string.refresh_token), t?.refreshToken) + editor.putString(getString(R.string.expires_in), t?.expiresIn) - override fun failure(error: RetrofitError) { - FirebaseCrashlytics.getInstance().recordException(error) - Log.e("Accounts", "Error fetching access token $error", error) - Toast.makeText(mActivity, "Error logging in", Toast.LENGTH_SHORT).show() - mActivity.startLoginFragment() - } - }, - ) + val expiresInInt = t?.expiresIn!!.toInt() * 1000 + Log.i("LoginWebview", "Expires In: $expiresInInt") + val currentTime = Calendar.getInstance().timeInMillis + editor.putLong(getString(R.string.token_expires_at), currentTime + expiresInInt) + editor.apply() + getUser(accessToken) + } else { + val error = response.errorBody() + val exception = Exception(error.toString()) + + FirebaseCrashlytics.getInstance().recordException(exception) + Log.e("Accounts", "Error fetching access token $error", exception) + Toast.makeText(mActivity, "Error logging in", Toast.LENGTH_SHORT).show() + mActivity.startLoginFragment() + } + } } private fun getUser(accessToken: String?) { From 00ed683505a983c3fea7466af535ba698914ff9f Mon Sep 17 00:00:00 2001 From: meiron03 Date: Wed, 22 Jan 2025 18:07:10 -0500 Subject: [PATCH 2/2] Remove StudentLife from login logic. --- .../pennmobile/api/OAuth2NetworkManager.kt | 66 ++++++++--------- .../labs/pennmobile/api/StudentLife.java | 18 ----- .../labs/pennmobile/api/StudentLifeRf2.kt | 21 ++++++ .../api/fragments/LoginWebviewFragment.kt | 74 +++++++++---------- 4 files changed, 89 insertions(+), 90 deletions(-) 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 9d8428be0..585ca108a 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 @@ -18,7 +18,7 @@ import java.util.Calendar class OAuth2NetworkManager( private var mActivity: MainActivity, ) { - private var mStudentLife = MainActivity.studentLifeInstance + private var mStudentLifeRf2 = MainActivity.studentLifeInstanceRf2 private val sp = PreferenceManager.getDefaultSharedPreferences(mActivity) val editor = sp?.edit() @@ -62,49 +62,45 @@ class OAuth2NetworkManager( } } - @Synchronized - private fun refreshAccessToken( + private suspend fun refreshAccessToken( function: () -> Unit, unlockMutex: () -> Unit, ) { - val refreshToken = sp.getString(mActivity.getString(R.string.refresh_token), "") + val refreshToken = sp.getString(mActivity.getString(R.string.refresh_token), "") ?: "" val clientID = BuildConfig.PLATFORM_CLIENT_ID - mStudentLife.refreshAccessToken( + val response = mStudentLifeRf2.refreshAccessToken( refreshToken, "refresh_token", clientID, - object : Callback { - override fun success( - t: AccessTokenResponse?, - response: Response?, - ) { - if (response?.status == 200) { - val editor = sp.edit() - editor.putString(mActivity.getString(R.string.access_token), t?.accessToken) - editor.putString(mActivity.getString(R.string.refresh_token), t?.refreshToken) - editor.putString(mActivity.getString(R.string.expires_in), t?.expiresIn) - val expiresIn = t?.expiresIn - val expiresInInt = (expiresIn!!.toInt() * 1000) - 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") - } - } + ) - override fun failure(error: RetrofitError) { - FirebaseCrashlytics.getInstance().recordException(error) - Log.e("Accounts", "Error refreshing access token $error") + if (response.isSuccessful) { + val t = response.body()!! - if (error.response != null && error.response.status == 400) { - mActivity.startLoginFragment() - unlockMutex.invoke() - } - } - }, - ) + val editor = sp.edit() + editor.putString(mActivity.getString(R.string.access_token), t.accessToken) + editor.putString(mActivity.getString(R.string.refresh_token), t.refreshToken) + editor.putString(mActivity.getString(R.string.expires_in), t.expiresIn) + val expiresIn = t.expiresIn + val expiresInInt = (expiresIn!!.toInt() * 1000) + val currentTime = Calendar.getInstance().timeInMillis + editor.putLong(mActivity.getString(R.string.token_expires_at), currentTime + expiresInInt) + editor.apply() + Log.i("Accounts", "Refreshed access token") + + unlockMutex.invoke() + function.invoke() + } else { + val error = response.errorBody()!! + + FirebaseCrashlytics.getInstance().recordException(Exception(error.toString())) + Log.e("Accounts", "Error refreshing access token $error") + + if (response.code() == 400) { + mActivity.startLoginFragment() + unlockMutex.invoke() + } + } } } diff --git a/PennMobile/src/main/java/com/pennapps/labs/pennmobile/api/StudentLife.java b/PennMobile/src/main/java/com/pennapps/labs/pennmobile/api/StudentLife.java index aa4380b48..a0cb53764 100644 --- a/PennMobile/src/main/java/com/pennapps/labs/pennmobile/api/StudentLife.java +++ b/PennMobile/src/main/java/com/pennapps/labs/pennmobile/api/StudentLife.java @@ -44,24 +44,6 @@ */ public interface StudentLife { - @FormUrlEncoded - @POST("/accounts/token/") - void getAccessToken( - @Field("code") String authCode, - @Field("grant_type") String grantType, - @Field("client_id") String clientID, - @Field("redirect_uri") String redirectURI, - @Field("code_verifier") String codeVerifier, - Callback callback); - - @FormUrlEncoded - @POST("/accounts/token/") - void refreshAccessToken( - @Field("refresh_token") String refreshToken, - @Field("grant_type") String grantType, - @Field("client_id") String clientID, - Callback callback); - @GET("/dining/venues") Observable> venues(); diff --git a/PennMobile/src/main/java/com/pennapps/labs/pennmobile/api/StudentLifeRf2.kt b/PennMobile/src/main/java/com/pennapps/labs/pennmobile/api/StudentLifeRf2.kt index c3168effa..a57bdd997 100644 --- a/PennMobile/src/main/java/com/pennapps/labs/pennmobile/api/StudentLifeRf2.kt +++ b/PennMobile/src/main/java/com/pennapps/labs/pennmobile/api/StudentLifeRf2.kt @@ -1,3 +1,4 @@ +import com.pennapps.labs.pennmobile.api.classes.AccessTokenResponse import com.pennapps.labs.pennmobile.laundry.classes.LaundryPreferences import com.pennapps.labs.pennmobile.laundry.classes.LaundryRequest import com.pennapps.labs.pennmobile.laundry.classes.LaundryRoom @@ -6,12 +7,32 @@ import com.pennapps.labs.pennmobile.laundry.classes.LaundryUsage import okhttp3.ResponseBody import retrofit2.Response import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded import retrofit2.http.GET import retrofit2.http.Header import retrofit2.http.POST import retrofit2.http.Path interface StudentLifeRf2 { + @FormUrlEncoded + @POST("accounts/token/") + suspend fun getAccessToken( + @Field("code") authCode: String, + @Field("grant_type") grantType: String, + @Field("client_id") clientID: String, + @Field("redirect_uri") redirectURI: String, + @Field("code_verifier") codeVerifier: String, + ): Response + + @FormUrlEncoded + @POST("accounts/token/") + suspend fun refreshAccessToken( + @Field("refresh_token") refreshToken: String, + @Field("grant_type") grantType: String, + @Field("client_id") clientID: String, + ): Response + @GET("laundry/halls/ids") suspend fun laundryRooms(): Response> diff --git a/PennMobile/src/main/java/com/pennapps/labs/pennmobile/api/fragments/LoginWebviewFragment.kt b/PennMobile/src/main/java/com/pennapps/labs/pennmobile/api/fragments/LoginWebviewFragment.kt index 904c49cb3..e3c9121a3 100644 --- a/PennMobile/src/main/java/com/pennapps/labs/pennmobile/api/fragments/LoginWebviewFragment.kt +++ b/PennMobile/src/main/java/com/pennapps/labs/pennmobile/api/fragments/LoginWebviewFragment.kt @@ -1,5 +1,6 @@ package com.pennapps.labs.pennmobile.api.fragments +import StudentLifeRf2 import android.content.SharedPreferences import android.os.Bundle import android.security.keystore.KeyGenParameterSpec @@ -17,6 +18,7 @@ import android.widget.Button import android.widget.LinearLayout import android.widget.Toast import androidx.fragment.app.Fragment +import androidx.lifecycle.lifecycleScope import androidx.preference.PreferenceManager import com.google.firebase.analytics.FirebaseAnalytics import com.google.firebase.crashlytics.FirebaseCrashlytics @@ -25,10 +27,10 @@ import com.pennapps.labs.pennmobile.MainActivity import com.pennapps.labs.pennmobile.R import com.pennapps.labs.pennmobile.api.Platform import com.pennapps.labs.pennmobile.api.Platform.platformBaseUrl -import com.pennapps.labs.pennmobile.api.StudentLife import com.pennapps.labs.pennmobile.api.classes.AccessTokenResponse import com.pennapps.labs.pennmobile.api.classes.Account import com.pennapps.labs.pennmobile.api.classes.GetUserResponse +import kotlinx.coroutines.launch import org.apache.commons.lang3.RandomStringUtils import retrofit.Callback import retrofit.RetrofitError @@ -46,7 +48,7 @@ class LoginWebviewFragment : Fragment() { lateinit var headerLayout: LinearLayout lateinit var cancelButton: Button lateinit var user: Account - private lateinit var mStudentLife: StudentLife + private lateinit var mStudentLifeRf2: StudentLifeRf2 private var mPlatform: Platform? = null private lateinit var mActivity: MainActivity lateinit var sp: SharedPreferences @@ -64,7 +66,7 @@ class LoginWebviewFragment : Fragment() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - mStudentLife = MainActivity.studentLifeInstance + mStudentLifeRf2 = MainActivity.studentLifeInstanceRf2 mPlatform = MainActivity.platformInstance arguments?.let { user = arguments?.getSerializable("user") as Account @@ -180,43 +182,41 @@ class LoginWebviewFragment : Fragment() { } private fun initiateAuthentication(authCode: String) { - mStudentLife.getAccessToken( - authCode, - "authorization_code", - clientID, - redirectUri, - codeVerifier, - object : Callback { - override fun success( - t: AccessTokenResponse?, - response: Response?, - ) { - if (response?.status == 200) { - FirebaseAnalytics.getInstance(mActivity).logEvent("LoginEvent", null) + mActivity.lifecycleScope.launch { + val response = mStudentLifeRf2.getAccessToken( + authCode, + "authorization_code", + clientID, + redirectUri, + codeVerifier, + ) - val accessToken = t?.accessToken - val editor = sp.edit() - editor.putString(getString(R.string.access_token), accessToken) - editor.putString(getString(R.string.refresh_token), t?.refreshToken) - editor.putString(getString(R.string.expires_in), t?.expiresIn) + if (response.isSuccessful) { + val t : AccessTokenResponse? = response.body() + FirebaseAnalytics.getInstance(mActivity).logEvent("LoginEvent", null) - val expiresInInt = t?.expiresIn!!.toInt() * 1000 - Log.i("LoginWebview", "Expires In: $expiresInInt") - val currentTime = Calendar.getInstance().timeInMillis - editor.putLong(getString(R.string.token_expires_at), currentTime + expiresInInt) - editor.apply() - getUser(accessToken) - } - } + val accessToken = t?.accessToken + val editor = sp.edit() + editor.putString(getString(R.string.access_token), accessToken) + editor.putString(getString(R.string.refresh_token), t?.refreshToken) + editor.putString(getString(R.string.expires_in), t?.expiresIn) - override fun failure(error: RetrofitError) { - FirebaseCrashlytics.getInstance().recordException(error) - Log.e("Accounts", "Error fetching access token $error", error) - Toast.makeText(mActivity, "Error logging in", Toast.LENGTH_SHORT).show() - mActivity.startLoginFragment() - } - }, - ) + val expiresInInt = t?.expiresIn!!.toInt() * 1000 + Log.i("LoginWebview", "Expires In: $expiresInInt") + val currentTime = Calendar.getInstance().timeInMillis + editor.putLong(getString(R.string.token_expires_at), currentTime + expiresInInt) + editor.apply() + getUser(accessToken) + } else { + val error = response.errorBody() + val exception = Exception(error.toString()) + + FirebaseCrashlytics.getInstance().recordException(exception) + Log.e("Accounts", "Error fetching access token $error", exception) + Toast.makeText(mActivity, "Error logging in", Toast.LENGTH_SHORT).show() + mActivity.startLoginFragment() + } + } } private fun getUser(accessToken: String?) {