소스 검색

Added authorization functionality

sirekanyan 8 년 전
부모
커밋
ee72bdcb5e
2개의 변경된 파일121개의 추가작업 그리고 3개의 파일을 삭제
  1. 57 3
      app/src/main/java/me/vadik/knigopis/MainActivity.kt
  2. 64 0
      app/src/main/java/me/vadik/knigopis/auth/KAuth.kt

+ 57 - 3
app/src/main/java/me/vadik/knigopis/MainActivity.kt

@@ -1,23 +1,32 @@
 package me.vadik.knigopis
 
+import android.content.Intent
 import android.os.Bundle
 import android.support.design.widget.BottomNavigationView
 import android.support.v7.app.AppCompatActivity
 import android.support.v7.widget.LinearLayoutManager
 import android.support.v7.widget.RecyclerView
 import android.support.v7.widget.Toolbar
-import me.vadik.knigopis.CurrentTab.*
+import android.view.MenuItem
+import me.vadik.knigopis.CurrentTab.DONE_TAB
+import me.vadik.knigopis.CurrentTab.HOME_TAB
+import me.vadik.knigopis.auth.KAuth
+import me.vadik.knigopis.auth.KAuthImpl
 import me.vadik.knigopis.model.Book
 import me.vadik.knigopis.model.User
 import retrofit2.Call
 import retrofit2.Callback
 import retrofit2.Response
 
+private const val ULOGIN_REQUEST_CODE = 0
+
 class MainActivity : AppCompatActivity() {
 
   private val api by lazy { app().retrofit.create(Endpoint::class.java) }
+  private val auth by lazy { KAuthImpl(applicationContext, api) as KAuth }
   private val users = mutableListOf<User>()
   private val adapter = UsersAdapter(users)
+  private lateinit var loginOption: MenuItem
   private lateinit var currentTab: CurrentTab
 
   override fun onCreate(savedInstanceState: Bundle?) {
@@ -52,8 +61,27 @@ class MainActivity : AppCompatActivity() {
     })
   }
 
+  override fun onStart() {
+    super.onStart()
+    refreshOptionsMenu()
+    auth.requestAccessToken {
+      refreshOptionsMenu()
+    }
+  }
+
+  override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+    when (requestCode) {
+      ULOGIN_REQUEST_CODE -> {
+        if (resultCode == RESULT_OK && data != null) {
+          auth.saveTokenResponse(data)
+        }
+      }
+    }
+  }
+
   private fun initNavigationView(navigation: BottomNavigationView) {
-    currentTab = HOME_TAB
+    currentTab = if (auth.isAuthorized()) DONE_TAB else HOME_TAB
+    navigation.selectedItemId = currentTab.itemId
     navigation.setOnNavigationItemSelectedListener { item ->
       currentTab = CurrentTab.getByItemId(item.itemId)
       true
@@ -62,10 +90,36 @@ class MainActivity : AppCompatActivity() {
 
   private fun initRecyclerView(recyclerView: RecyclerView) {
     recyclerView.adapter = adapter
-    recyclerView.layoutManager = LinearLayoutManager(this@MainActivity)
+    recyclerView.layoutManager = LinearLayoutManager(this)
   }
 
   private fun initToolbar(toolbar: Toolbar) {
     toolbar.inflateMenu(R.menu.options)
+    toolbar.setOnMenuItemClickListener { item ->
+      when (item.itemId) {
+        R.id.option_login -> {
+          if (auth.isAuthorized()) {
+            auth.logout()
+          } else {
+            startActivityForResult(auth.getTokenRequest(), ULOGIN_REQUEST_CODE)
+          }
+          refreshOptionsMenu()
+          true
+        }
+        else -> false
+      }
+    }
+    loginOption = toolbar.menu.findItem(R.id.option_login)
+  }
+
+  private fun refreshOptionsMenu() {
+    loginOption.isVisible = true
+    if (auth.isAuthorized()) {
+      loginOption.setTitle(R.string.option_logout)
+      loginOption.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER)
+    } else {
+      loginOption.setTitle(R.string.option_login)
+      loginOption.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS)
+    }
   }
 }

+ 64 - 0
app/src/main/java/me/vadik/knigopis/auth/KAuth.kt

@@ -0,0 +1,64 @@
+package me.vadik.knigopis.auth
+
+import android.content.Context
+import android.content.Intent
+import me.vadik.knigopis.Endpoint
+import me.vadik.knigopis.log
+import me.vadik.knigopis.model.Credentials
+import retrofit2.Call
+import retrofit2.Callback
+import retrofit2.Response
+import ru.ulogin.sdk.UloginAuthActivity
+import java.util.HashMap
+
+private const val PREFS_NAME = "knigopis"
+private const val TOKEN_KEY = "token"
+private const val ACCESS_TOKEN_KEY = "access_token"
+
+interface KAuth {
+  fun isAuthorized(): Boolean
+  fun getTokenRequest(): Intent
+  fun saveTokenResponse(data: Intent)
+  fun requestAccessToken(onSuccess: () -> Unit)
+  fun logout()
+}
+
+class KAuthImpl(
+    private val context: Context,
+    private val api: Endpoint
+) : KAuth {
+
+  private val preferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
+
+  override fun isAuthorized() = preferences.contains(ACCESS_TOKEN_KEY)
+
+  override fun getTokenRequest(): Intent {
+    return Intent(context, UloginAuthActivity::class.java)
+        .putExtra(UloginAuthActivity.FIELDS, arrayOf(TOKEN_KEY))
+  }
+
+  override fun saveTokenResponse(data: Intent) {
+    val userData = data.getSerializableExtra(UloginAuthActivity.USERDATA) as HashMap<*, *>
+    preferences.edit().putString(TOKEN_KEY, userData[TOKEN_KEY].toString()).apply()
+  }
+
+  override fun requestAccessToken(onSuccess: () -> Unit) {
+    val token = preferences.getString(TOKEN_KEY, null)
+    if (token != null && !isAuthorized()) {
+      api.getCredentials(token).enqueue(object : Callback<Credentials> {
+        override fun onResponse(call: Call<Credentials>?, response: Response<Credentials>?) {
+          preferences.edit().putString(ACCESS_TOKEN_KEY, response?.body()?.accessToken).apply()
+          onSuccess()
+        }
+
+        override fun onFailure(call: Call<Credentials>?, t: Throwable?) {
+          log("cannot get credentials", t)
+        }
+      })
+    }
+  }
+
+  override fun logout() {
+    preferences.edit().remove(TOKEN_KEY).remove(ACCESS_TOKEN_KEY).apply()
+  }
+}