From 5f58b3b906177fe9292a3292249253b5fc848d81 Mon Sep 17 00:00:00 2001 From: Sabari Date: Wed, 27 Mar 2019 03:53:13 +0530 Subject: [PATCH 01/13] implementing oauth with stackexchange api --- app/src/main/AndroidManifest.xml | 21 ++++- .../com/nathansdev/stack/AppConstants.java | 6 ++ .../com/nathansdev/stack/AppPreferences.java | 18 +++++ .../nathansdev/stack/auth/LoginActivity.kt | 80 +++++++++++++++++++ .../stack/di/ActivityBuilderModule.java | 5 ++ .../com/nathansdev/stack/di/AppModule.java | 2 - .../nathansdev/stack/splash/SplashActivity.kt | 21 ++++- app/src/main/res/layout/activity_login.xml | 21 +++++ app/src/main/res/values/strings.xml | 2 + app/src/main/res/values/styles.xml | 1 + 10 files changed, 169 insertions(+), 8 deletions(-) create mode 100644 app/src/main/java/com/nathansdev/stack/auth/LoginActivity.kt create mode 100644 app/src/main/res/layout/activity_login.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f0f0ecf..0540639 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,6 +2,10 @@ + + + + + android:theme="@style/AppTheme" /> @@ -24,6 +28,19 @@ - + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/nathansdev/stack/AppConstants.java b/app/src/main/java/com/nathansdev/stack/AppConstants.java index fe1b877..8c79efb 100644 --- a/app/src/main/java/com/nathansdev/stack/AppConstants.java +++ b/app/src/main/java/com/nathansdev/stack/AppConstants.java @@ -4,6 +4,7 @@ * App Constants data. */ public final class AppConstants { + public static final String AUTH_URL = "https://stackoverflow.com/oauth/dialog"; public static final String VOTES = "votes"; public static final String ACTIVITY = "activity"; public static final String HOT = "hot"; @@ -12,4 +13,9 @@ public final class AppConstants { public static final String DESC = "desc"; public static final String SITE = "stackoverflow"; public static final String ARG_FILTER_TYPE = "filterType"; + public static final String CLIENT_ID = "client_id"; + public static final String REDIRECT_URI = "redirect_uri"; + public static final String ACCESS_TOKEN = "access_token"; + public static final String EXPIRES = "expires"; + public static final String ERROR = "error"; } diff --git a/app/src/main/java/com/nathansdev/stack/AppPreferences.java b/app/src/main/java/com/nathansdev/stack/AppPreferences.java index 19658bd..4eb5de2 100644 --- a/app/src/main/java/com/nathansdev/stack/AppPreferences.java +++ b/app/src/main/java/com/nathansdev/stack/AppPreferences.java @@ -9,9 +9,27 @@ */ public class AppPreferences { private static final String PREFS_NAME = "app-prefs"; + private static final String IS_LOGGEDIN = "isLoggedIn"; + private static final String ACCESS_TOKEN = "accessToken"; private final SharedPreferences prefs; public AppPreferences(Application app) { this.prefs = app.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE); } + + public boolean isLoggedIn() { + return prefs.getBoolean(IS_LOGGEDIN, Boolean.FALSE); + } + + public void setIsLoggedin(boolean isLoggedin) { + prefs.edit().putBoolean(IS_LOGGEDIN, isLoggedin).apply(); + } + + public String getAccessToken() { + return prefs.getString(ACCESS_TOKEN, ""); + } + + public void setAccessToken(String token) { + prefs.edit().putString(ACCESS_TOKEN, token).apply(); + } } diff --git a/app/src/main/java/com/nathansdev/stack/auth/LoginActivity.kt b/app/src/main/java/com/nathansdev/stack/auth/LoginActivity.kt new file mode 100644 index 0000000..164d50b --- /dev/null +++ b/app/src/main/java/com/nathansdev/stack/auth/LoginActivity.kt @@ -0,0 +1,80 @@ +package com.nathansdev.stack.auth + +import android.content.Intent +import android.net.Uri +import android.os.Bundle +import android.view.View +import android.widget.Button +import android.widget.ProgressBar +import com.nathansdev.stack.AppConstants +import com.nathansdev.stack.AppPreferences +import com.nathansdev.stack.base.BaseActivity +import timber.log.Timber +import javax.inject.Inject + + +/** + * A login screen that offers login via email/password. + */ +class LoginActivity : BaseActivity() { + + @Inject + lateinit var appPreferences: AppPreferences + + private val clientId = "14730" + private val redirectUri = "https://stack-query.herokuapp.com" + private var progressBar: ProgressBar? = null + private var button: Button? = null + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(com.nathansdev.stack.R.layout.activity_login) + button = findViewById(com.nathansdev.stack.R.id.button_auth) + progressBar = findViewById(com.nathansdev.stack.R.id.progress_loading) + progressBar?.visibility = View.GONE + button?.setOnClickListener { + val intent = Intent(Intent.ACTION_VIEW, + Uri.parse(AppConstants.AUTH_URL + "?" + AppConstants.CLIENT_ID + "=" + clientId + + "&" + AppConstants.REDIRECT_URI + "=" + redirectUri)) + startActivity(intent) + progressBar?.visibility = View.VISIBLE + button?.visibility = View.GONE + } + Timber.d("onCreate") + } + + override fun onResume() { + super.onResume() + Timber.d("onResume %s", intent) + handleIntent() + } + + private fun handleIntent() { + progressBar?.visibility = View.GONE + button?.visibility = View.VISIBLE + // the intent filter defined in AndroidManifest will handle the return from ACTION_VIEW intent + val uri = intent.data + Timber.d("uri %s", uri) + if (uri != null && uri.toString().startsWith(redirectUri)) { + val extra = uri.fragment + Timber.d("extra %s", extra) + val accessToken = extra?.split("&")?.get(0)?.split("=")?.get(1) + Timber.d("token %s", accessToken) + if (accessToken != null) { + appPreferences.setIsLoggedin(true) + appPreferences.accessToken = accessToken + // get access token + // we'll do that in a minute + } else if (uri.getQueryParameter(AppConstants.ERROR) != null) { + val error = uri.getQueryParameter(AppConstants.ERROR) + Timber.d(error) + // show an error message here + } + } + } + + override fun onNewIntent(intent: Intent?) { + super.onNewIntent(intent) + Timber.d("onNewIntent %s", intent) + } +} diff --git a/app/src/main/java/com/nathansdev/stack/di/ActivityBuilderModule.java b/app/src/main/java/com/nathansdev/stack/di/ActivityBuilderModule.java index e845837..ef459ae 100644 --- a/app/src/main/java/com/nathansdev/stack/di/ActivityBuilderModule.java +++ b/app/src/main/java/com/nathansdev/stack/di/ActivityBuilderModule.java @@ -1,5 +1,6 @@ package com.nathansdev.stack.di; +import com.nathansdev.stack.auth.LoginActivity; import com.nathansdev.stack.home.HomeActivity; import com.nathansdev.stack.home.HomeActivityModule; import com.nathansdev.stack.splash.SplashActivity; @@ -19,4 +20,8 @@ abstract class ActivityBuilderModule { @PerActivity @ContributesAndroidInjector abstract SplashActivity bindSplashActivity(); + + @PerActivity + @ContributesAndroidInjector + abstract LoginActivity bindLoginActivity(); } diff --git a/app/src/main/java/com/nathansdev/stack/di/AppModule.java b/app/src/main/java/com/nathansdev/stack/di/AppModule.java index 623a68a..8c9dd7a 100755 --- a/app/src/main/java/com/nathansdev/stack/di/AppModule.java +++ b/app/src/main/java/com/nathansdev/stack/di/AppModule.java @@ -4,9 +4,7 @@ import android.content.Context; import com.nathansdev.stack.AppPreferences; -import com.nathansdev.stack.data.model.MyAdapterFactory; import com.nathansdev.stack.rxevent.RxEventBus; -import com.squareup.moshi.Moshi; import javax.inject.Singleton; diff --git a/app/src/main/java/com/nathansdev/stack/splash/SplashActivity.kt b/app/src/main/java/com/nathansdev/stack/splash/SplashActivity.kt index 07eeff6..d6435df 100644 --- a/app/src/main/java/com/nathansdev/stack/splash/SplashActivity.kt +++ b/app/src/main/java/com/nathansdev/stack/splash/SplashActivity.kt @@ -3,12 +3,18 @@ package com.nathansdev.stack.splash import android.content.Intent import android.os.Bundle import android.os.Handler +import com.nathansdev.stack.AppPreferences import com.nathansdev.stack.R +import com.nathansdev.stack.auth.LoginActivity import com.nathansdev.stack.base.BaseActivity import com.nathansdev.stack.home.HomeActivity +import javax.inject.Inject class SplashActivity : BaseActivity() { + @Inject + lateinit var appPreferences: AppPreferences + override fun onCreate(savedInstanceState: Bundle?) { setTheme(R.style.AppTheme_Launcher) super.onCreate(savedInstanceState) @@ -16,13 +22,20 @@ class SplashActivity : BaseActivity() { override fun onResume() { super.onResume() - routeToHome() + routeTo() } - private fun routeToHome() { + private fun routeTo() { Handler().postDelayed({ - val intent = Intent(this, HomeActivity::class.java) - startActivity(intent) + if (appPreferences.isLoggedIn) { + val intent = Intent(this, HomeActivity::class.java) + startActivity(intent) + finish() + } else { + val intent = Intent(this, LoginActivity::class.java) + startActivity(intent) + finish() + } }, 1000) } } \ No newline at end of file diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..2c637b5 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,21 @@ + + + +