Remove initAccount from Account interface

This commit is contained in:
sim 2024-11-04 12:31:28 +00:00
parent 0373d0eb63
commit 4c65a1d40f
9 changed files with 73 additions and 85 deletions

View File

@ -4,12 +4,29 @@ import android.app.Activity
import android.content.Context
import android.content.Intent
interface Account {
var name: String?
var url: String?
fun initAccount(context: Context): Boolean
interface Account<T> {
/** Nextcloud username. */
val name: String?
/** Nextcloud instance url. */
val url: String?
/** Are we connected to nextcloud ? */
var connected: Boolean
/** Connect to nextcloud. */
fun connect(activity: Activity)
/**
* Invoked after [connect].
*
* Used to import nextcloud account after linking to Nextcloud app
*/
fun onActivityResult(activity: Activity, requestCode: Int, resultCode: Int, data: Intent?, block: (success: Boolean) -> Unit)
fun getAccount(context: Context): Any?
/** Get client used to request the server. */
fun getClient(context: Context): T?
/** Logout. */
fun logout(context: Context)
}

View File

@ -2,9 +2,6 @@ package org.unifiedpush.distributor.nextpush.account
import android.content.Context
import android.util.Log
import android.widget.Toast
import com.nextcloud.android.sso.exceptions.NextcloudFilesAppAccountNotFoundException
import com.nextcloud.android.sso.exceptions.NoCurrentAccountSelectedException
import org.unifiedpush.distributor.nextpush.utils.TAG
internal const val PREF_NAME = "NextPush"
@ -24,7 +21,7 @@ private fun Int.toAccountType(): AccountType {
}
object AccountFactory {
private var account: Account? = null
private var account: Account<out Any>? = null
var Context.accountType: AccountType
get() = this.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
@ -48,39 +45,15 @@ object AccountFactory {
}.apply()
}
fun getAccount(context: Context, uninitialized: Boolean = false): Account? {
fun getAccount(context: Context, connected: Boolean = true): Account<out Any>? {
return account
?: run {
Log.d(TAG, "New account, type=${context.accountType}")
when (context.accountType) {
AccountType.SSO -> {
try {
SSOAccount().apply {
initAccount(context)
account = this
}
} catch (e: NextcloudFilesAppAccountNotFoundException) {
Toast.makeText(
context,
"Nextcloud application not found",
Toast.LENGTH_SHORT
).show()
Log.w(TAG, "Nextcloud application not found")
null
} catch (e: NoCurrentAccountSelectedException) {
if (uninitialized) {
SSOAccount()
} else {
null
}
}
}
AccountType.Direct -> {
DirectAccount().apply {
initAccount(context)
account = this
}
}
AccountType.SSO -> SSOAccount(context)
AccountType.Direct -> DirectAccount(context)
}.takeIf { !connected || it.connected }.also {
account = it
}
}
}
@ -101,8 +74,4 @@ object AccountFactory {
accountType = AccountType.Direct
DirectAccount.setCredentials(this, url, username, password)
}
fun isConnected(context: Context): Boolean {
return getAccount(context)?.initAccount(context) == true
}
}

View File

@ -16,27 +16,20 @@ private const val PREF_URL = "direct_account::url"
private const val PREF_USERNAME = "direct_account::username"
private const val PREF_PASSWORD = "direct_account::password"
class DirectAccount : Account {
override var name: String? = null
override var url: String? = null
class DirectAccount(context: Context) : Account<OkHttpClient> {
private var Context.connected: Boolean
get() = this.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
.getBoolean(PREF_CONNECTED, false)
set(value) = this.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
.edit().putBoolean(PREF_CONNECTED, value)
.apply()
override val name: String? = context.username
override val url: String? = context.url
override var connected = context.connected
override fun initAccount(context: Context): Boolean {
url = context.url
name = context.username
return context.connected
private fun setConnected(context: Context, value: Boolean) {
connected = value
context.connected = value
}
override fun connect(activity: Activity) {
activity.connected = false
val client = getAccount(activity) as OkHttpClient? ?: return retActivity(activity)
setConnected(activity, false)
val client = getClient(activity) ?: return retActivity(activity)
val url = activity.url ?: return retActivity(activity)
val request = try {
@ -57,8 +50,8 @@ class DirectAccount : Account {
}
override fun onResponse(call: Call, response: Response) {
Log.e(TAG, "Status: ${response.code}")
activity.connected = response.code == 200
Log.d(TAG, "Status: ${response.code}")
setConnected(activity, response.code == 200)
response.close()
retActivity(activity)
}
@ -72,10 +65,10 @@ class DirectAccount : Account {
data: Intent?,
block: (success: Boolean) -> Unit
) {
block(activity.connected)
block(connected)
}
override fun getAccount(context: Context): Any? {
override fun getClient(context: Context): OkHttpClient? {
val username = context.username ?: return null
val password = context.password ?: return null
return OkHttpClient.Builder()
@ -86,7 +79,7 @@ class DirectAccount : Account {
}
override fun logout(context: Context) {
context.connected = false
setConnected(context, false)
setCredentials(context, null, null, null)
}
@ -158,6 +151,13 @@ class DirectAccount : Account {
.apply()
}
private var Context.connected: Boolean
get() = this.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
.getBoolean(PREF_CONNECTED, false)
set(value) = this.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
.edit().putBoolean(PREF_CONNECTED, value)
.apply()
fun setCredentials(context: Context, url: String?, username: String?, password: String?) {
context.url = url
context.username = username

View File

@ -14,27 +14,30 @@ import androidx.appcompat.app.AlertDialog
import com.nextcloud.android.sso.AccountImporter
import com.nextcloud.android.sso.exceptions.* // ktlint-disable no-wildcard-imports
import com.nextcloud.android.sso.helper.SingleAccountHelper
import com.nextcloud.android.sso.model.SingleSignOnAccount
import com.nextcloud.android.sso.ui.UiExceptionManager
import org.unifiedpush.distributor.nextpush.R
import org.unifiedpush.distributor.nextpush.utils.TAG
class SSOAccount : Account {
class SSOAccount(val context: Context) : Account<SingleSignOnAccount> {
override var name: String? = null
override var url: String? = null
override var connected = false
override fun initAccount(context: Context): Boolean {
init {
try {
SingleAccountHelper.getCurrentSingleSignOnAccount(context).let {
name = it.name
url = it.url
}
connected = true
} catch (e: NextcloudFilesAppAccountNotFoundException) {
return false
Log.d(TAG, "Nextcloud application not found")
connected = false
} catch (e: NoCurrentAccountSelectedException) {
Log.d(TAG, "Device is not connected")
return false
connected = false
}
return true
}
override fun connect(activity: Activity) {
@ -70,7 +73,7 @@ class SSOAccount : Account {
}
}
override fun getAccount(context: Context): Any? {
override fun getClient(context: Context): SingleSignOnAccount? {
return try {
SingleAccountHelper.getCurrentSingleSignOnAccount(context)
} catch (e: NextcloudFilesAppAccountNotFoundException) {

View File

@ -30,8 +30,6 @@ import org.unifiedpush.distributor.nextpush.Database.Companion.getDb
import org.unifiedpush.distributor.nextpush.LocalNotification
import org.unifiedpush.distributor.nextpush.R
import org.unifiedpush.distributor.nextpush.account.AccountFactory
import org.unifiedpush.distributor.nextpush.account.AccountFactory.getAccount
import org.unifiedpush.distributor.nextpush.account.AccountFactory.isConnected
import org.unifiedpush.distributor.nextpush.activities.PermissionsRequest.requestAppPermissions
import org.unifiedpush.distributor.nextpush.activities.StartActivity.Companion.goToStartActivity
import org.unifiedpush.distributor.nextpush.distributor.Distributor
@ -58,13 +56,14 @@ class MainActivity : AppCompatActivity() {
setContentView(R.layout.activity_main)
setSupportActionBar(findViewById(R.id.toolbar))
this.requestAppPermissions()
if (!isConnected(this)) {
if (AccountFactory.getAccount(this)?.connected != true) {
Log.d(TAG, "Not connected: going to StartActivity.")
goToStartActivity(this)
finish()
}
findViewById<TextView>(R.id.main_account_desc).text =
format(getString(R.string.main_account_desc), getAccount(this)?.name)
format(getString(R.string.main_account_desc), AccountFactory.getAccount(this)?.name)
invalidateOptionsMenu()
RestartWorker.startPeriodic(this)
setDebugInformationListener()

View File

@ -29,7 +29,7 @@ class StartActivity : AppCompatActivity() {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_start)
this.requestAppPermissions()
if (AccountFactory.isConnected(this)) {
if (AccountFactory.getAccount(this)?.connected == true) {
goToMainActivity(this)
finish()
}
@ -74,7 +74,7 @@ class StartActivity : AppCompatActivity() {
}
private fun login() {
AccountFactory.getAccount(this, uninitialized = true)?.let {
AccountFactory.getAccount(this, connected = false)?.let {
onResult = { activity: Activity, i: Int, i1: Int, intent: Intent?, block: (success: Boolean) -> Unit ->
it.onActivityResult(activity, i, i1, intent, block)
}

View File

@ -1,8 +1,8 @@
package org.unifiedpush.distributor.nextpush.api.provider
import android.content.Context
import okhttp3.* // ktlint-disable no-wildcard-imports
import org.unifiedpush.distributor.nextpush.account.AccountFactory.getAccount
import org.unifiedpush.distributor.nextpush.account.AccountFactory
import org.unifiedpush.distributor.nextpush.account.DirectAccount
import org.unifiedpush.distributor.nextpush.api.provider.ApiProvider.Companion.mApiEndpoint
import retrofit2.Retrofit
import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory
@ -10,13 +10,13 @@ import retrofit2.converter.gson.GsonConverterFactory
class ApiDirectFactory(val context: Context) : ApiProviderFactory {
override fun getProviderAndExecute(block: (ApiProvider, then: () -> Unit) -> Unit) {
val account = getAccount(context) ?: run {
val account = AccountFactory.getAccount(context) ?: run {
throw NoProviderException("No account found")
}
val url = account.url ?: run {
throw NoProviderException("No url found")
}
val client = account.getAccount(context) as OkHttpClient? ?: run {
val client = (account as DirectAccount).getClient(context) ?: run {
throw NoProviderException("No client found")
}
Retrofit.Builder()

View File

@ -4,8 +4,8 @@ import android.content.Context
import android.util.Log
import com.google.gson.GsonBuilder
import com.nextcloud.android.sso.api.NextcloudAPI
import com.nextcloud.android.sso.model.SingleSignOnAccount
import org.unifiedpush.distributor.nextpush.account.AccountFactory.getAccount
import org.unifiedpush.distributor.nextpush.account.AccountFactory
import org.unifiedpush.distributor.nextpush.account.SSOAccount
import retrofit2.NextcloudRetrofitApiBuilder
class ApiSSOFactory(val context: Context) : ApiProviderFactory {
@ -14,10 +14,10 @@ class ApiSSOFactory(val context: Context) : ApiProviderFactory {
override fun getProviderAndExecute(block: (ApiProvider, then: () -> Unit) -> Unit) {
var nextcloudAPI: NextcloudAPI? = null
val account = getAccount(context) ?: run {
val account = AccountFactory.getAccount(context) ?: run {
throw NoProviderException("No account found")
}
val client = account.getAccount(context) as SingleSignOnAccount? ?: run {
val client = (account as SSOAccount).getClient(context) ?: run {
throw NoProviderException("No client found")
}
val ssoApiCallback = object : NextcloudAPI.ApiConnectedListener {

View File

@ -11,7 +11,7 @@ import androidx.annotation.RequiresApi
import org.unifiedpush.distributor.nextpush.AppCompanion
import org.unifiedpush.distributor.nextpush.Database.Companion.getDb
import org.unifiedpush.distributor.nextpush.WakeLock
import org.unifiedpush.distributor.nextpush.account.AccountFactory.isConnected
import org.unifiedpush.distributor.nextpush.account.AccountFactory
import org.unifiedpush.distributor.nextpush.distributor.* // ktlint-disable no-wildcard-imports
import org.unifiedpush.distributor.nextpush.distributor.Distributor.checkToken
import org.unifiedpush.distributor.nextpush.distributor.Distributor.createApp
@ -167,7 +167,7 @@ class RegisterBroadcastReceiver : BroadcastReceiver() {
private fun onRegisterNewToken(context: Context, connectorToken: String, application: String) {
val appName = context.getApplicationName(application) ?: application
when {
!isConnected(context) -> registrationFailedWithToast(
AccountFactory.getAccount(context)?.connected != true -> registrationFailedWithToast(
context,
connectorToken,
application,