check if talk is available at server selection and if version is valid

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
This commit is contained in:
Marcel Hibbe 2023-06-09 17:50:29 +02:00
parent deb512af91
commit cc391d889a
No known key found for this signature in database
GPG Key ID: C793F8B59F43CE7B
5 changed files with 90 additions and 23 deletions

View File

@ -44,11 +44,11 @@ import com.nextcloud.talk.models.json.search.ContactsByNumberOverall;
import com.nextcloud.talk.models.json.signaling.SignalingOverall; import com.nextcloud.talk.models.json.signaling.SignalingOverall;
import com.nextcloud.talk.models.json.signaling.settings.SignalingSettingsOverall; import com.nextcloud.talk.models.json.signaling.settings.SignalingSettingsOverall;
import com.nextcloud.talk.models.json.status.StatusOverall; import com.nextcloud.talk.models.json.status.StatusOverall;
import com.nextcloud.talk.translate.repositories.model.TranslationsOverall;
import com.nextcloud.talk.models.json.unifiedsearch.UnifiedSearchOverall; import com.nextcloud.talk.models.json.unifiedsearch.UnifiedSearchOverall;
import com.nextcloud.talk.models.json.userprofile.UserProfileFieldsOverall; import com.nextcloud.talk.models.json.userprofile.UserProfileFieldsOverall;
import com.nextcloud.talk.models.json.userprofile.UserProfileOverall; import com.nextcloud.talk.models.json.userprofile.UserProfileOverall;
import com.nextcloud.talk.polls.repositories.model.PollOverall; import com.nextcloud.talk.polls.repositories.model.PollOverall;
import com.nextcloud.talk.translate.repositories.model.TranslationsOverall;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -358,6 +358,9 @@ public interface NcApi {
@GET @GET
Observable<CapabilitiesOverall> getCapabilities(@Header("Authorization") String authorization, @Url String url); Observable<CapabilitiesOverall> getCapabilities(@Header("Authorization") String authorization, @Url String url);
@GET
Observable<CapabilitiesOverall> getCapabilities(@Url String url);
/* /*
QueryMap items are as follows: QueryMap items are as follows:
- "lookIntoFuture": int (0 or 1), - "lookIntoFuture": int (0 or 1),

View File

@ -29,6 +29,7 @@ import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.security.KeyChain import android.security.KeyChain
import android.text.TextUtils import android.text.TextUtils
import android.util.Log
import android.view.KeyEvent import android.view.KeyEvent
import android.view.View import android.view.View
import android.view.inputmethod.EditorInfo import android.view.inputmethod.EditorInfo
@ -44,6 +45,7 @@ import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedA
import com.nextcloud.talk.controllers.base.BaseController import com.nextcloud.talk.controllers.base.BaseController
import com.nextcloud.talk.controllers.util.viewBinding import com.nextcloud.talk.controllers.util.viewBinding
import com.nextcloud.talk.databinding.ControllerServerSelectionBinding import com.nextcloud.talk.databinding.ControllerServerSelectionBinding
import com.nextcloud.talk.models.json.capabilities.CapabilitiesOverall
import com.nextcloud.talk.models.json.generic.Status import com.nextcloud.talk.models.json.generic.Status
import com.nextcloud.talk.users.UserManager import com.nextcloud.talk.users.UserManager
import com.nextcloud.talk.utils.AccountUtils import com.nextcloud.talk.utils.AccountUtils
@ -51,7 +53,9 @@ import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.DisplayUtils import com.nextcloud.talk.utils.DisplayUtils
import com.nextcloud.talk.utils.UriUtils import com.nextcloud.talk.utils.UriUtils
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_IS_ACCOUNT_IMPORT import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_IS_ACCOUNT_IMPORT
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
import com.nextcloud.talk.utils.singletons.ApplicationWideMessageHolder import com.nextcloud.talk.utils.singletons.ApplicationWideMessageHolder
import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
@ -211,33 +215,27 @@ class ServerSelectionController :
if (url.endsWith("/")) { if (url.endsWith("/")) {
url = url.substring(0, url.length - 1) url = url.substring(0, url.length - 1)
} }
val queryUrl = url + ApiUtils.getUrlPostfixForStatus()
if (UriUtils.hasHttpProtocollPrefixed(url)) { if (UriUtils.hasHttpProtocollPrefixed(url)) {
checkServer(queryUrl, false) checkServer(url, false)
} else { } else {
checkServer("https://$queryUrl", true) checkServer("https://$url", true)
} }
} }
private fun checkServer(queryUrl: String, checkForcedHttps: Boolean) { private fun checkServer(url: String, checkForcedHttps: Boolean) {
statusQueryDisposable = ncApi.getServerStatus(queryUrl) val queryStatusUrl = url + ApiUtils.getUrlPostfixForStatus()
statusQueryDisposable = ncApi.getServerStatus(queryStatusUrl)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe({ status: Status -> .subscribe({ status: Status ->
val productName = resources!!.getString(R.string.nc_server_product_name) val productName = resources!!.getString(R.string.nc_server_product_name)
val versionString: String = status.version!!.substring(0, status.version!!.indexOf(".")) val versionString: String = status.version!!.substring(0, status.version!!.indexOf("."))
val version: Int = versionString.toInt() val version: Int = versionString.toInt()
if (isServerStatusQueryable(status) && version >= MIN_SERVER_MAJOR_VERSION) { if (isServerStatusQueryable(status) && version >= MIN_SERVER_MAJOR_VERSION) {
router.pushController( findServerTalkApp(url)
RouterTransaction.with(
WebViewLoginController(
queryUrl.replace("/status.php", ""),
false
)
)
.pushChangeHandler(HorizontalChangeHandler())
.popChangeHandler(HorizontalChangeHandler())
)
} else if (!status.installed) { } else if (!status.installed) {
setErrorText( setErrorText(
String.format( String.format(
@ -270,7 +268,7 @@ class ServerSelectionController :
} }
}, { throwable: Throwable -> }, { throwable: Throwable ->
if (checkForcedHttps) { if (checkForcedHttps) {
checkServer(queryUrl.replace("https://", "http://"), false) checkServer(queryStatusUrl.replace("https://", "http://"), false)
} else { } else {
if (throwable.localizedMessage != null) { if (throwable.localizedMessage != null) {
setErrorText(throwable.localizedMessage) setErrorText(throwable.localizedMessage)
@ -296,6 +294,66 @@ class ServerSelectionController :
} }
} }
private fun findServerTalkApp(queryUrl: String) {
ncApi.getCapabilities(ApiUtils.getUrlForCapabilities(queryUrl))
.subscribeOn(Schedulers.io())
.subscribe(object : Observer<CapabilitiesOverall> {
override fun onSubscribe(d: Disposable) {
}
override fun onNext(capabilitiesOverall: CapabilitiesOverall) {
val capabilities = capabilitiesOverall.ocs?.data?.capabilities
val hasTalk =
capabilities?.spreedCapability != null &&
capabilities.spreedCapability?.features != null &&
capabilities.spreedCapability?.features?.isNotEmpty() == true
if (hasTalk) {
activity?.runOnUiThread {
if (CapabilitiesUtilNew.isServerEOL(capabilities)) {
if (resources != null) {
activity!!.runOnUiThread {
setErrorText(resources!!.getString(R.string.nc_settings_server_eol))
}
}
} else {
router.pushController(
RouterTransaction.with(
WebViewLoginController(
queryUrl.replace("/status.php", ""),
false
)
)
.pushChangeHandler(HorizontalChangeHandler())
.popChangeHandler(HorizontalChangeHandler())
)
}
}
} else {
if (activity != null && resources != null) {
activity!!.runOnUiThread {
setErrorText(resources!!.getString(R.string.nc_server_unsupported))
}
}
}
}
override fun onError(e: Throwable) {
Log.e(TAG, "Error while checking capabilities", e)
if (activity != null && resources != null) {
activity!!.runOnUiThread {
setErrorText(resources!!.getString(R.string.nc_common_error_sorry))
}
}
}
override fun onComplete() {
// unused atm
}
})
}
private fun isServerStatusQueryable(status: Status): Boolean { private fun isServerStatusQueryable(status: Status): Boolean {
return status.installed && !status.maintenance && !status.needsUpgrade return status.installed && !status.maintenance && !status.needsUpgrade
} }

View File

@ -233,7 +233,7 @@ class ConversationsListActivity :
} }
currentUser = userManager.currentUser.blockingGet() currentUser = userManager.currentUser.blockingGet()
if (currentUser != null) { if (currentUser != null) {
if (isServerEOL(currentUser!!)) { if (isServerEOL(currentUser!!.capabilities)) {
showServerEOLDialog() showServerEOLDialog()
return return
} }

View File

@ -621,7 +621,7 @@ class SettingsActivity : BaseActivity() {
private fun setupServerAgeWarning() { private fun setupServerAgeWarning() {
when { when {
CapabilitiesUtilNew.isServerEOL(currentUser!!) -> { CapabilitiesUtilNew.isServerEOL(currentUser!!.capabilities) -> {
binding.serverAgeWarningText.setTextColor(ContextCompat.getColor((context), R.color.nc_darkRed)) binding.serverAgeWarningText.setTextColor(ContextCompat.getColor((context), R.color.nc_darkRed))
binding.serverAgeWarningText.setText(R.string.nc_settings_server_eol) binding.serverAgeWarningText.setText(R.string.nc_settings_server_eol)
binding.serverAgeWarningIcon.setColorFilter( binding.serverAgeWarningIcon.setColorFilter(

View File

@ -22,6 +22,7 @@
package com.nextcloud.talk.utils.database.user package com.nextcloud.talk.utils.database.user
import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.models.json.capabilities.Capabilities
@Suppress("TooManyFunctions") @Suppress("TooManyFunctions")
object CapabilitiesUtilNew { object CapabilitiesUtilNew {
@ -37,9 +38,9 @@ object CapabilitiesUtilNew {
} }
@JvmStatic @JvmStatic
fun isServerEOL(user: User): Boolean { fun isServerEOL(capabilities: Capabilities?): Boolean {
// Capability is available since Talk 4 => Nextcloud 14 => Autmn 2018 // Capability is available since Talk 4 => Nextcloud 14 => Autmn 2018
return !hasSpreedFeatureCapability(user, "no-ping") return !hasSpreedFeatureCapability(capabilities, "no-ping")
} }
fun isServerAlmostEOL(user: User): Boolean { fun isServerAlmostEOL(user: User): Boolean {
@ -57,8 +58,13 @@ object CapabilitiesUtilNew {
@JvmStatic @JvmStatic
fun hasSpreedFeatureCapability(user: User?, capabilityName: String): Boolean { fun hasSpreedFeatureCapability(user: User?, capabilityName: String): Boolean {
if (user?.capabilities?.spreedCapability?.features != null) { return hasSpreedFeatureCapability(user?.capabilities, capabilityName)
return user.capabilities!!.spreedCapability!!.features!!.contains(capabilityName) }
@JvmStatic
fun hasSpreedFeatureCapability(capabilities: Capabilities?, capabilityName: String): Boolean {
if (capabilities?.spreedCapability?.features != null) {
return capabilities.spreedCapability!!.features!!.contains(capabilityName)
} }
return false return false
} }