2020-03-05 19:02:22 +01:00
|
|
|
package com.h.pixeldroid
|
|
|
|
|
2020-03-05 22:46:40 +01:00
|
|
|
import android.content.ActivityNotFoundException
|
|
|
|
import android.content.Context
|
2020-03-06 18:24:20 +01:00
|
|
|
import android.content.Intent
|
2020-03-05 22:46:40 +01:00
|
|
|
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
|
2020-03-05 22:46:40 +01:00
|
|
|
import android.util.Log
|
2020-03-05 20:36:23 +01:00
|
|
|
import androidx.appcompat.app.AppCompatActivity
|
2020-03-05 22:46:40 +01:00
|
|
|
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
|
2020-03-05 22:46:40 +01:00
|
|
|
import kotlinx.android.synthetic.main.activity_login.*
|
2020-03-06 18:24:20 +01:00
|
|
|
import okhttp3.HttpUrl
|
2020-03-05 22:46:40 +01:00
|
|
|
import retrofit2.Call
|
|
|
|
import retrofit2.Callback
|
|
|
|
import retrofit2.Response
|
2020-03-05 19:02:22 +01:00
|
|
|
|
2020-03-06 08:49:26 +01:00
|
|
|
class LoginActivity : AppCompatActivity() {
|
2020-03-05 22:46:40 +01:00
|
|
|
|
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
|
2020-03-05 22:46:40 +01:00
|
|
|
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
|
|
|
|
|
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
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
private fun onClickConnect() {
|
|
|
|
|
|
|
|
connect_instance_button.isEnabled = false
|
|
|
|
|
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:13:26 +01:00
|
|
|
failedRegistration(getString(R.string.invalid_domain))
|
2020-03-06 18:24:20 +01:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
preferences.edit()
|
|
|
|
.putString("domain", normalizedDomain)
|
|
|
|
.apply()
|
2020-03-07 18:13:26 +01:00
|
|
|
registerAppToServer(normalizedDomain)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun normalizeDomain(domain: String): String {
|
|
|
|
var d = domain.replace("http://", "")
|
|
|
|
d = d.replace("https://", "")
|
|
|
|
return d.trim(Char::isWhitespace)
|
|
|
|
}
|
2020-03-05 22:46:40 +01:00
|
|
|
|
2020-03-07 18:13:26 +01:00
|
|
|
private fun registerAppToServer(normalizedDomain: String) {
|
2020-03-05 22:46:40 +01:00
|
|
|
val callback = object : Callback<Application> {
|
|
|
|
override fun onResponse(call: Call<Application>, response: Response<Application>) {
|
|
|
|
if (!response.isSuccessful) {
|
2020-03-06 18:24:20 +01:00
|
|
|
failedRegistration()
|
|
|
|
return
|
2020-03-05 22:46:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
val credentials = response.body()
|
2020-03-06 18:24:20 +01:00
|
|
|
val clientId = credentials?.client_id ?: return failedRegistration()
|
2020-03-05 22:46:40 +01:00
|
|
|
val clientSecret = credentials.client_secret
|
|
|
|
|
2020-03-06 18:24:20 +01:00
|
|
|
preferences.edit()
|
|
|
|
.putString("clientID", clientId)
|
2020-03-05 22:46:40 +01:00
|
|
|
.putString("clientSecret", clientSecret)
|
|
|
|
.apply()
|
|
|
|
|
2020-03-07 18:13:26 +01:00
|
|
|
promptOAuth(normalizedDomain, clientId)
|
2020-03-05 22:46:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
override fun onFailure(call: Call<Application>, t: Throwable) {
|
2020-03-06 18:24:20 +01:00
|
|
|
failedRegistration()
|
|
|
|
return
|
2020-03-05 22:46:40 +01:00
|
|
|
}
|
|
|
|
}
|
2020-03-07 18:13:26 +01:00
|
|
|
PixelfedAPI.create("https://$normalizedDomain").registerApplication(
|
|
|
|
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 = "https://$normalizedDomain/oauth/authorize?" +
|
2020-03-05 22:46:40 +01:00
|
|
|
"client_id" + "=" + client_id + "&" +
|
2020-03-06 18:24:20 +01:00
|
|
|
"redirect_uri" + "=" + "$OAUTH_SCHEME://$PACKAGE_ID" + "&" +
|
2020-03-05 22:46:40 +01:00
|
|
|
"response_type=code" + "&" +
|
2020-03-06 18:24:20 +01:00
|
|
|
"scope=$SCOPE"
|
2020-03-05 22:46:40 +01:00
|
|
|
|
|
|
|
val intent = CustomTabsIntent.Builder().build()
|
|
|
|
|
|
|
|
try {
|
2020-03-07 18:13:26 +01:00
|
|
|
intent.launchUrl(this, Uri.parse(url))
|
2020-03-05 22:46:40 +01:00
|
|
|
} 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:13:26 +01:00
|
|
|
failedRegistration(getString(R.string.browser_launch_failed))
|
2020-03-06 18:24:20 +01:00
|
|
|
return
|
|
|
|
}
|
2020-03-05 22:46:40 +01:00
|
|
|
}
|
2020-03-06 18:24:20 +01:00
|
|
|
connect_instance_button.isEnabled = true
|
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()) {
|
|
|
|
failedRegistration(getString(R.string.auth_failed))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
//Successful authorization
|
|
|
|
val callback = object : Callback<Token> {
|
|
|
|
override fun onResponse(call: Call<Token>, response: Response<Token>) {
|
|
|
|
if (!response.isSuccessful || response.body() == null) {
|
|
|
|
failedRegistration(getString(R.string.token_error))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
authenticationSuccessful(domain, response.body()!!.access_token)
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onFailure(call: Call<Token>, t: Throwable) {
|
|
|
|
failedRegistration(getString(R.string.token_error))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
val pixelfedAPI = PixelfedAPI.create("https://$domain")
|
|
|
|
pixelfedAPI.obtainToken(
|
|
|
|
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)){
|
|
|
|
connect_instance_button.isEnabled = true
|
|
|
|
editText.error = message
|
|
|
|
}
|
|
|
|
|
2020-03-05 19:02:22 +01:00
|
|
|
}
|