PixelDroid-App-Android/app/src/main/java/com/h/pixeldroid/LoginActivity.kt

196 lines
6.4 KiB
Kotlin
Raw Normal View History

2020-03-05 19:02:22 +01:00
package com.h.pixeldroid
import android.content.ActivityNotFoundException
import android.content.Context
2020-03-06 18:24:20 +01:00
import android.content.Intent
import android.content.SharedPreferences
2020-03-05 20:36:23 +01:00
import android.net.Uri
2020-03-05 19:02:22 +01:00
import android.os.Bundle
import android.view.View
2020-03-05 20:36:23 +01:00
import androidx.appcompat.app.AppCompatActivity
import androidx.browser.customtabs.CustomTabsIntent
2020-03-05 20:36:23 +01:00
import com.h.pixeldroid.api.PixelfedAPI
2020-03-06 08:37:59 +01:00
import com.h.pixeldroid.objects.Application
2020-03-06 18:24:20 +01:00
import com.h.pixeldroid.objects.Token
import kotlinx.android.synthetic.main.activity_login.*
2020-03-06 18:24:20 +01:00
import okhttp3.HttpUrl
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
2020-03-05 19:02:22 +01:00
class LoginActivity : AppCompatActivity() {
2020-03-07 18:13:26 +01:00
private lateinit var OAUTH_SCHEME: String
private val PACKAGE_ID = BuildConfig.APPLICATION_ID
2020-03-06 18:24:20 +01:00
private val SCOPE = "read write follow"
2020-03-07 18:13:26 +01:00
private lateinit var APP_NAME: String
private lateinit var preferences: SharedPreferences
2020-03-05 19:02:22 +01:00
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)
2020-03-05 20:36:23 +01:00
2020-03-06 18:24:20 +01:00
connect_instance_button.setOnClickListener { onClickConnect() }
2020-03-07 18:13:26 +01:00
APP_NAME = getString(R.string.app_name)
OAUTH_SCHEME = getString(R.string.auth_scheme)
2020-03-06 18:24:20 +01:00
preferences = getSharedPreferences(
"$PACKAGE_ID.pref", Context.MODE_PRIVATE
)
}
override fun onStart(){
super.onStart()
val url = intent.data
//Check if the activity was started after the authentication
2020-03-07 18:13:26 +01:00
if (url == null || !url.toString().startsWith("$OAUTH_SCHEME://$PACKAGE_ID")) return
2020-03-06 18:24:20 +01:00
loadingAnimation(true)
2020-03-07 18:13:26 +01:00
val code = url.getQueryParameter("code")
authenticate(code)
2020-03-05 19:02:22 +01:00
2020-03-06 18:24:20 +01:00
}
override fun onStop() {
super.onStop()
loadingAnimation(false)
}
override fun onBackPressed() {
}
2020-03-06 18:24:20 +01:00
private fun onClickConnect() {
2020-03-07 18:13:26 +01:00
val normalizedDomain = normalizeDomain(editText.text.toString())
2020-03-06 18:24:20 +01:00
try{
2020-03-07 18:13:26 +01:00
HttpUrl.Builder().host(normalizedDomain).scheme("https").build()
2020-03-06 18:24:20 +01:00
} catch (e: IllegalArgumentException) {
2020-03-07 18:31:58 +01:00
return failedRegistration(getString(R.string.invalid_domain))
2020-03-06 18:24:20 +01:00
}
loadingAnimation(true)
2020-03-06 18:24:20 +01:00
preferences.edit()
.putString("domain", "https://$normalizedDomain")
2020-03-06 18:24:20 +01:00
.apply()
registerAppToServer("https://$normalizedDomain")
2020-03-07 18:13:26 +01:00
}
private fun normalizeDomain(domain: String): String {
var d = domain.replace("http://", "")
d = d.replace("https://", "")
return d.trim(Char::isWhitespace)
}
2020-03-07 18:13:26 +01:00
private fun registerAppToServer(normalizedDomain: String) {
val callback = object : Callback<Application> {
override fun onResponse(call: Call<Application>, response: Response<Application>) {
if (!response.isSuccessful) {
2020-03-07 18:31:58 +01:00
return failedRegistration()
}
val credentials = response.body()
2020-03-06 18:24:20 +01:00
val clientId = credentials?.client_id ?: return failedRegistration()
val clientSecret = credentials.client_secret
2020-03-06 18:24:20 +01:00
preferences.edit()
.putString("clientID", clientId)
.putString("clientSecret", clientSecret)
.apply()
2020-03-07 18:13:26 +01:00
promptOAuth(normalizedDomain, clientId)
}
override fun onFailure(call: Call<Application>, t: Throwable) {
2020-03-07 18:31:58 +01:00
return failedRegistration()
}
}
PixelfedAPI.create(normalizedDomain).registerApplication(
2020-03-07 18:13:26 +01:00
APP_NAME,"$OAUTH_SCHEME://$PACKAGE_ID", SCOPE
).enqueue(callback)
2020-03-06 18:24:20 +01:00
}
2020-03-05 20:36:23 +01:00
2020-03-07 18:13:26 +01:00
private fun promptOAuth(normalizedDomain: String, client_id: String) {
2020-03-06 18:24:20 +01:00
val url = "$normalizedDomain/oauth/authorize?" +
"client_id" + "=" + client_id + "&" +
2020-03-06 18:24:20 +01:00
"redirect_uri" + "=" + "$OAUTH_SCHEME://$PACKAGE_ID" + "&" +
"response_type=code" + "&" +
2020-03-06 18:24:20 +01:00
"scope=$SCOPE"
val intent = CustomTabsIntent.Builder().build()
try {
2020-03-07 18:13:26 +01:00
intent.launchUrl(this, Uri.parse(url))
} catch (e: ActivityNotFoundException) {
2020-03-06 18:24:20 +01:00
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
if (browserIntent.resolveActivity(packageManager) != null) {
startActivity(browserIntent)
} else {
2020-03-07 18:31:58 +01:00
return failedRegistration(getString(R.string.browser_launch_failed))
2020-03-06 18:24:20 +01:00
}
}
2020-03-05 19:02:22 +01:00
}
2020-03-07 18:13:26 +01:00
private fun authenticate(code: String?) {
// Get previous values from preferences
val domain = preferences.getString("domain", "")
val clientId = preferences.getString("clientID", "")
val clientSecret = preferences.getString("clientSecret", "")
if (code == null || domain.isNullOrEmpty() || clientId.isNullOrEmpty() || clientSecret.isNullOrEmpty()) {
2020-03-07 18:31:58 +01:00
return failedRegistration(getString(R.string.auth_failed))
2020-03-07 18:13:26 +01:00
}
//Successful authorization
val callback = object : Callback<Token> {
override fun onResponse(call: Call<Token>, response: Response<Token>) {
if (!response.isSuccessful || response.body() == null) {
2020-03-07 18:31:58 +01:00
return failedRegistration(getString(R.string.token_error))
2020-03-07 18:13:26 +01:00
}
authenticationSuccessful(domain, response.body()!!.access_token)
}
override fun onFailure(call: Call<Token>, t: Throwable) {
2020-03-07 18:31:58 +01:00
return failedRegistration(getString(R.string.token_error))
2020-03-07 18:13:26 +01:00
}
}
PixelfedAPI.create("$domain")
2020-03-07 18:31:58 +01:00
.obtainToken(
2020-03-07 18:13:26 +01:00
clientId, clientSecret, "$OAUTH_SCHEME://$PACKAGE_ID", SCOPE, code,
"authorization_code"
).enqueue(callback)
}
private fun authenticationSuccessful(domain: String, accessToken: String) {
preferences.edit().putString("accessToken", accessToken).apply()
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
finish()
}
private fun failedRegistration(message: String =
getString(R.string.registration_failed)){
loadingAnimation(false)
2020-03-07 18:13:26 +01:00
editText.error = message
}
private fun loadingAnimation(on: Boolean){
if(on) {
domainTextInputLayout.visibility = View.GONE
progressLayout.visibility = View.VISIBLE
}
else {
domainTextInputLayout.visibility = View.VISIBLE
progressLayout.visibility = View.GONE
}
}
2020-03-05 19:02:22 +01:00
}