2021-07-12 10:14:26 +02:00
|
|
|
package audio.funkwhale.ffa.activities
|
2019-08-19 16:50:33 +02:00
|
|
|
|
|
|
|
import android.content.Intent
|
2020-06-26 20:03:48 +02:00
|
|
|
import android.content.res.Configuration
|
2019-08-19 16:50:33 +02:00
|
|
|
import android.net.Uri
|
2019-10-23 20:21:18 +02:00
|
|
|
import android.os.Bundle
|
2020-06-26 20:03:48 +02:00
|
|
|
import android.view.ViewGroup
|
2019-08-19 16:50:33 +02:00
|
|
|
import androidx.appcompat.app.AppCompatActivity
|
2020-06-26 20:03:48 +02:00
|
|
|
import androidx.core.view.doOnLayout
|
2020-06-25 01:26:15 +02:00
|
|
|
import androidx.lifecycle.lifecycleScope
|
2021-07-12 10:14:26 +02:00
|
|
|
import audio.funkwhale.ffa.R
|
2021-07-16 10:03:52 +02:00
|
|
|
import audio.funkwhale.ffa.databinding.ActivityLoginBinding
|
2021-07-12 10:14:26 +02:00
|
|
|
import audio.funkwhale.ffa.fragments.LoginDialog
|
2021-09-09 09:56:15 +02:00
|
|
|
import audio.funkwhale.ffa.utils.AppContext
|
|
|
|
import audio.funkwhale.ffa.utils.FuelResult
|
|
|
|
import audio.funkwhale.ffa.utils.OAuth
|
|
|
|
import audio.funkwhale.ffa.utils.Userinfo
|
2019-08-19 16:50:33 +02:00
|
|
|
import com.github.kittinunf.fuel.Fuel
|
2019-11-22 00:13:22 +01:00
|
|
|
import com.github.kittinunf.fuel.coroutines.awaitObjectResponseResult
|
2019-08-19 16:50:33 +02:00
|
|
|
import com.github.kittinunf.fuel.gson.gsonDeserializerOf
|
2019-11-22 00:13:22 +01:00
|
|
|
import com.github.kittinunf.result.Result
|
2019-08-19 16:50:33 +02:00
|
|
|
import com.preference.PowerPreference
|
|
|
|
import kotlinx.coroutines.Dispatchers.Main
|
|
|
|
import kotlinx.coroutines.launch
|
2021-08-10 14:54:37 +02:00
|
|
|
import kotlinx.coroutines.runBlocking
|
2021-08-09 06:50:46 +02:00
|
|
|
import org.koin.java.KoinJavaComponent.inject
|
2019-08-19 16:50:33 +02:00
|
|
|
|
2020-05-29 01:10:12 +02:00
|
|
|
data class FwCredentials(val token: String, val non_field_errors: List<String>?)
|
2019-08-19 16:50:33 +02:00
|
|
|
|
|
|
|
class LoginActivity : AppCompatActivity() {
|
2021-07-16 10:03:52 +02:00
|
|
|
|
|
|
|
private lateinit var binding: ActivityLoginBinding
|
2021-08-09 06:50:46 +02:00
|
|
|
private val oAuth: OAuth by inject(OAuth::class.java)
|
2021-07-23 14:10:13 +02:00
|
|
|
|
2019-10-23 20:21:18 +02:00
|
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
|
|
super.onCreate(savedInstanceState)
|
2019-08-19 16:50:33 +02:00
|
|
|
|
2021-07-16 10:03:52 +02:00
|
|
|
binding = ActivityLoginBinding.inflate(layoutInflater)
|
|
|
|
setContentView(binding.root)
|
2020-06-26 20:03:48 +02:00
|
|
|
limitContainerWidth()
|
2019-10-23 20:21:18 +02:00
|
|
|
}
|
2019-08-19 16:50:33 +02:00
|
|
|
|
2021-07-23 14:10:13 +02:00
|
|
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
|
|
|
super.onActivityResult(requestCode, resultCode, data)
|
|
|
|
|
|
|
|
data?.let {
|
|
|
|
when (requestCode) {
|
|
|
|
0 -> {
|
2021-08-13 10:55:26 +02:00
|
|
|
oAuth.exchange(this, data) {
|
|
|
|
PowerPreference
|
|
|
|
.getFileByName(AppContext.PREFS_CREDENTIALS)
|
|
|
|
.setBoolean("anonymous", false)
|
2021-07-23 14:10:13 +02:00
|
|
|
|
2021-08-13 10:55:26 +02:00
|
|
|
lifecycleScope.launch(Main) {
|
|
|
|
Userinfo.get(this@LoginActivity, oAuth)?.let {
|
|
|
|
startActivity(Intent(this@LoginActivity, MainActivity::class.java))
|
2021-07-23 14:10:13 +02:00
|
|
|
|
2021-08-13 10:55:26 +02:00
|
|
|
return@launch finish()
|
2021-07-23 14:10:13 +02:00
|
|
|
}
|
2021-08-13 10:55:26 +02:00
|
|
|
throw Exception(getString(R.string.login_error_userinfo))
|
|
|
|
}
|
|
|
|
}
|
2021-07-23 14:10:13 +02:00
|
|
|
}
|
2019-11-25 23:14:16 +01:00
|
|
|
}
|
|
|
|
}
|
2021-07-23 14:10:13 +02:00
|
|
|
}
|
2019-11-25 23:14:16 +01:00
|
|
|
|
2021-07-23 14:10:13 +02:00
|
|
|
override fun onResume() {
|
|
|
|
super.onResume()
|
|
|
|
with(binding) {
|
|
|
|
login.setOnClickListener {
|
2021-09-10 09:23:35 +02:00
|
|
|
var hostname = hostname.text.toString().trim().trim('/')
|
2019-08-19 16:50:33 +02:00
|
|
|
|
2021-07-23 14:10:13 +02:00
|
|
|
try {
|
2021-08-10 14:54:37 +02:00
|
|
|
validateHostname(hostname, cleartext.isChecked)?.let {
|
|
|
|
hostnameField.error = it
|
|
|
|
return@setOnClickListener
|
|
|
|
}
|
2019-08-19 16:50:33 +02:00
|
|
|
|
2021-08-10 14:54:37 +02:00
|
|
|
val uri = Uri.parse(hostname)
|
|
|
|
if (uri.scheme == null) {
|
|
|
|
hostname = when (cleartext.isChecked) {
|
|
|
|
true -> "http://$hostname"
|
|
|
|
false -> "https://$hostname"
|
2020-06-20 16:52:41 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-23 14:10:13 +02:00
|
|
|
hostnameField.error = ""
|
2020-06-20 16:52:41 +02:00
|
|
|
|
2021-08-10 14:54:37 +02:00
|
|
|
val fuelResult = when (anonymous.isChecked) {
|
2021-07-23 14:10:13 +02:00
|
|
|
false -> authedLogin(hostname)
|
|
|
|
true -> anonymousLogin(hostname)
|
|
|
|
}
|
2021-08-10 14:54:37 +02:00
|
|
|
|
|
|
|
hostnameField.error = mapFuelResultToError(fuelResult)
|
2021-07-23 14:10:13 +02:00
|
|
|
} catch (e: Exception) {
|
|
|
|
val message =
|
|
|
|
if (e.message?.isEmpty() == true) getString(R.string.login_error_hostname)
|
|
|
|
else e.message
|
2019-08-19 16:50:33 +02:00
|
|
|
|
2021-07-23 14:10:13 +02:00
|
|
|
hostnameField.error = message
|
|
|
|
}
|
2019-08-19 16:50:33 +02:00
|
|
|
}
|
2019-11-25 23:14:16 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-10 14:54:37 +02:00
|
|
|
private fun mapFuelResultToError(fuelResult: FuelResult) = when {
|
|
|
|
fuelResult.httpStatus == 404 ->
|
|
|
|
getString(R.string.login_error_funkwhale_not_found)
|
|
|
|
|
|
|
|
!fuelResult.success ->
|
|
|
|
getString(R.string.login_error, fuelResult.message)
|
|
|
|
|
|
|
|
else -> ""
|
|
|
|
}
|
|
|
|
|
2020-06-26 20:03:48 +02:00
|
|
|
override fun onConfigurationChanged(newConfig: Configuration) {
|
|
|
|
super.onConfigurationChanged(newConfig)
|
|
|
|
|
|
|
|
limitContainerWidth()
|
|
|
|
}
|
|
|
|
|
2021-08-10 14:54:37 +02:00
|
|
|
private fun validateHostname(hostname: String, cleartext: Boolean): String? {
|
|
|
|
if (hostname.isEmpty()) {
|
|
|
|
return getString(R.string.login_error_hostname)
|
|
|
|
}
|
2021-09-03 11:12:23 +02:00
|
|
|
if (!cleartext && hostname.startsWith("http://")) {
|
2021-08-10 14:54:37 +02:00
|
|
|
return getString(R.string.login_error_hostname_https)
|
|
|
|
}
|
|
|
|
return null
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun authedLogin(hostname: String): FuelResult {
|
2021-07-30 10:57:49 +02:00
|
|
|
oAuth.init(hostname)
|
2021-08-10 14:54:37 +02:00
|
|
|
return oAuth.register {
|
|
|
|
PowerPreference.getFileByName(AppContext.PREFS_CREDENTIALS).setString("hostname", hostname)
|
2021-07-30 10:57:49 +02:00
|
|
|
oAuth.authorize(this)
|
2019-11-25 23:14:16 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-10 14:54:37 +02:00
|
|
|
private fun anonymousLogin(hostname: String): FuelResult {
|
2019-11-25 23:14:16 +01:00
|
|
|
val dialog = LoginDialog().apply {
|
|
|
|
show(supportFragmentManager, "LoginDialog")
|
|
|
|
}
|
|
|
|
|
2021-08-10 14:54:37 +02:00
|
|
|
val uri = "$hostname/api/v1/tracks/"
|
|
|
|
val (_, _, result) = runBlocking {
|
|
|
|
Fuel.get(uri).awaitObjectResponseResult(gsonDeserializerOf(FwCredentials::class.java))
|
|
|
|
}
|
2019-11-25 23:14:16 +01:00
|
|
|
|
2021-08-10 14:54:37 +02:00
|
|
|
when (result) {
|
|
|
|
is Result.Success -> {
|
|
|
|
PowerPreference.getFileByName(AppContext.PREFS_CREDENTIALS).apply {
|
|
|
|
setString("hostname", hostname)
|
|
|
|
setBoolean("anonymous", true)
|
2019-10-23 22:05:56 +02:00
|
|
|
}
|
2019-11-25 23:14:16 +01:00
|
|
|
|
2021-08-10 14:54:37 +02:00
|
|
|
dialog.dismiss()
|
|
|
|
startActivity(Intent(this@LoginActivity, MainActivity::class.java))
|
|
|
|
finish()
|
|
|
|
return FuelResult.ok()
|
|
|
|
}
|
2019-11-25 23:14:16 +01:00
|
|
|
|
2021-08-10 14:54:37 +02:00
|
|
|
is Result.Failure -> {
|
|
|
|
dialog.dismiss()
|
|
|
|
return FuelResult.from(result)
|
2019-08-19 16:50:33 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-06-26 20:03:48 +02:00
|
|
|
|
|
|
|
private fun limitContainerWidth() {
|
2021-07-16 10:03:52 +02:00
|
|
|
binding.container.doOnLayout {
|
|
|
|
if (resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE && binding.container.width >= 1440) {
|
|
|
|
binding.container.layoutParams.width = 1440
|
2020-06-26 20:03:48 +02:00
|
|
|
} else {
|
2021-07-16 10:03:52 +02:00
|
|
|
binding.container.layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT
|
2020-06-26 20:03:48 +02:00
|
|
|
}
|
|
|
|
|
2021-07-16 10:03:52 +02:00
|
|
|
binding.container.requestLayout()
|
2020-06-26 20:03:48 +02:00
|
|
|
}
|
|
|
|
}
|
2021-07-02 13:55:49 +02:00
|
|
|
}
|