Commit 6eb48680 authored by Filipe de Lima Brito's avatar Filipe de Lima Brito

Finishes the delete own account feature.

parent dc75f75e
......@@ -23,10 +23,17 @@ class OnBoardingPresenter @Inject constructor(
private val getAccountsInteractor: GetAccountsInteractor,
val settingsInteractor: GetSettingsInteractor,
val factory: RocketChatClientFactory
) : CheckServerPresenter(strategy, factory, settingsInteractor) {
) : CheckServerPresenter(
strategy = strategy,
factory = factory,
settingsInteractor = settingsInteractor,
refreshSettingsInteractor = refreshSettingsInteractor
) {
fun toSignInToYourServer() = navigator.toSignInToYourServer()
fun toCreateANewServer(createServerUrl: String) = navigator.toWebPage(createServerUrl)
fun connectToCommunityServer(communityServerUrl: String) {
connectToServer(communityServerUrl) {
if (totalSocialAccountsEnabled == 0 && !isNewAccountCreationEnabled) {
......@@ -63,8 +70,6 @@ class OnBoardingPresenter @Inject constructor(
}
}
fun toCreateANewServer(createServerUrl: String) = navigator.toWebPage(createServerUrl)
private fun connectToServer(serverUrl: String, block: () -> Unit) {
launchUI(strategy) {
// Check if we already have an account for this server...
......@@ -77,9 +82,9 @@ class OnBoardingPresenter @Inject constructor(
try {
withContext(DefaultDispatcher) {
setupConnectionInfo(serverUrl)
refreshSettingsInteractor.refresh(serverUrl)
// preparing next fragment before showing it
refreshServerAccounts()
checkEnabledAccounts(serverUrl)
checkIfLoginFormIsEnabled()
checkIfCreateNewAccountIsEnabled()
......
......@@ -25,7 +25,13 @@ class ServerPresenter @Inject constructor(
private val getAccountsInteractor: GetAccountsInteractor,
val settingsInteractor: GetSettingsInteractor,
val factory: RocketChatClientFactory
) : CheckServerPresenter(strategy, factory, settingsInteractor, view) {
) : CheckServerPresenter(
strategy = strategy,
factory = factory,
settingsInteractor = settingsInteractor,
versionCheckView = view,
refreshSettingsInteractor = refreshSettingsInteractor
) {
fun checkServer(server: String) {
if (!server.isValidUrl()) {
......@@ -93,9 +99,8 @@ class ServerPresenter @Inject constructor(
view.showLoading()
try {
withContext(DefaultDispatcher) {
refreshSettingsInteractor.refresh(serverUrl)
// preparing next fragment before showing it
refreshServerAccounts()
checkEnabledAccounts(serverUrl)
checkIfLoginFormIsEnabled()
checkIfCreateNewAccountIsEnabled()
......@@ -112,5 +117,4 @@ class ServerPresenter @Inject constructor(
}
}
}
}
\ No newline at end of file
package chat.rocket.android.main.presentation
import android.content.Context
import chat.rocket.android.R
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.db.DatabaseManagerFactory
import chat.rocket.android.emoji.Emoji
......@@ -36,13 +35,9 @@ import chat.rocket.common.model.UserStatus
import chat.rocket.common.util.ifNull
import chat.rocket.core.RocketChatClient
import chat.rocket.core.internal.rest.getCustomEmojis
import chat.rocket.core.internal.rest.logout
import chat.rocket.core.internal.rest.me
import chat.rocket.core.internal.rest.unregisterPushToken
import chat.rocket.core.model.Myself
import kotlinx.coroutines.experimental.CommonPool
import kotlinx.coroutines.experimental.channels.Channel
import kotlinx.coroutines.experimental.withContext
import timber.log.Timber
import javax.inject.Inject
......@@ -51,23 +46,33 @@ class MainPresenter @Inject constructor(
private val strategy: CancelStrategy,
private val navigator: MainNavigator,
private val tokenRepository: TokenRepository,
private val serverInteractor: GetCurrentServerInteractor,
private val refreshSettingsInteractor: RefreshSettingsInteractor,
private val refreshPermissionsInteractor: RefreshPermissionsInteractor,
private val localRepository: LocalRepository,
private val navHeaderMapper: NavHeaderUiModelMapper,
private val saveAccountInteractor: SaveAccountInteractor,
private val getAccountsInteractor: GetAccountsInteractor,
private val removeAccountInteractor: RemoveAccountInteractor,
factory: RocketChatClientFactory,
private val groupedPush: GroupedPush,
serverInteractor: GetCurrentServerInteractor,
localRepository: LocalRepository,
removeAccountInteractor: RemoveAccountInteractor,
factory: RocketChatClientFactory,
dbManagerFactory: DatabaseManagerFactory,
getSettingsInteractor: GetSettingsInteractor,
managerFactory: ConnectionManagerFactory
) : CheckServerPresenter(strategy, factory, view = view) {
) : CheckServerPresenter(
strategy = strategy,
factory = factory,
serverInteractor = serverInteractor,
localRepository = localRepository,
removeAccountInteractor = removeAccountInteractor,
tokenRepository = tokenRepository,
managerFactory = managerFactory,
dbManagerFactory = dbManagerFactory,
tokenView = view,
navigator = navigator
) {
private val currentServer = serverInteractor.get()!!
private val manager = managerFactory.create(currentServer)
private val dbManager = dbManagerFactory.create(currentServer)
private val client: RocketChatClient = factory.create(currentServer)
private var settings: PublicSettings = getSettingsInteractor.get(serverInteractor.get()!!)
private val userDataChannel = Channel<Myself>()
......@@ -114,9 +119,7 @@ class MainPresenter @Inject constructor(
view.setupUserAccountInfo(model)
} catch (ex: Exception) {
when (ex) {
is RocketChatAuthException -> {
logout()
}
is RocketChatAuthException -> logout()
else -> {
Timber.d(ex, "Error loading my information for navheader")
ex.message?.let {
......@@ -163,36 +166,9 @@ class MainPresenter @Inject constructor(
}
}
/**
* Logout from current server.
*/
fun logout() {
launchUI(strategy) {
view.showProgress()
try {
clearTokens()
retryIO("logout") { client.logout() }
} catch (exception: RocketChatException) {
Timber.d(exception, "Error calling logout")
exception.message?.let {
view.showMessage(it)
}.ifNull {
view.showGenericErrorMessage()
}
}
try {
disconnect()
removeAccountInteractor.remove(currentServer)
tokenRepository.remove(currentServer)
withContext(CommonPool) { dbManager.logout() }
navigator.switchOrAddNewServer()
} catch (ex: Exception) {
Timber.d(ex, "Error cleaning up the session...")
}
view.hideProgress()
}
setupConnectionInfo(currentServer)
super.logout(userDataChannel)
}
fun connect() {
......@@ -202,8 +178,8 @@ class MainPresenter @Inject constructor(
}
fun disconnect() {
manager.removeUserDataChannel(userDataChannel)
manager.disconnect()
setupConnectionInfo(currentServer)
super.disconnect(userDataChannel)
}
fun changeServer(serverUrl: String) {
......@@ -247,20 +223,6 @@ class MainPresenter @Inject constructor(
saveAccountInteractor.save(account)
}
private suspend fun clearTokens() {
serverInteractor.clear()
val pushToken = localRepository.get(LocalRepository.KEY_PUSH_TOKEN)
if (pushToken != null) {
try {
retryIO("unregisterPushToken") { client.unregisterPushToken(pushToken) }
view.invalidateToken(pushToken)
} catch (ex: Exception) {
Timber.d(ex, "Error unregistering push token")
}
}
localRepository.clearAllFromServer(currentServer)
}
private suspend fun subscribeMyselfUpdates() {
manager.addUserDataChannel(userDataChannel)
for (myself in userDataChannel) {
......
......@@ -4,9 +4,10 @@ import chat.rocket.android.authentication.server.presentation.VersionCheckView
import chat.rocket.android.core.behaviours.MessageView
import chat.rocket.android.main.uimodel.NavHeaderUiModel
import chat.rocket.android.server.domain.model.Account
import chat.rocket.android.server.presentation.TokenView
import chat.rocket.common.model.UserStatus
interface MainView : MessageView, VersionCheckView {
interface MainView : MessageView, VersionCheckView, TokenView {
/**
* Shows the current user status.
......@@ -31,8 +32,6 @@ interface MainView : MessageView, VersionCheckView {
fun closeServerSelection()
fun invalidateToken(token: String)
fun showProgress()
fun hideProgress()
......
......@@ -202,8 +202,7 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector,
.show()
}
override fun invalidateToken(token: String) =
invalidateFirebaseToken(token)
override fun invalidateToken(token: String) = invalidateFirebaseToken(token)
override fun showMessage(resId: Int) = showToast(resId)
......
......@@ -5,9 +5,15 @@ import android.net.Uri
import chat.rocket.android.chatroom.domain.UriInteractor
import chat.rocket.android.core.behaviours.showMessage
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.db.DatabaseManagerFactory
import chat.rocket.android.helper.UserHelper
import chat.rocket.android.main.presentation.MainNavigator
import chat.rocket.android.server.domain.GetCurrentServerInteractor
import chat.rocket.android.server.domain.RemoveAccountInteractor
import chat.rocket.android.server.domain.TokenRepository
import chat.rocket.android.server.infraestructure.ConnectionManagerFactory
import chat.rocket.android.server.infraestructure.RocketChatClientFactory
import chat.rocket.android.server.presentation.CheckServerPresenter
import chat.rocket.android.util.extension.compressImageAndGetByteArray
import chat.rocket.android.util.extension.gethash
import chat.rocket.android.util.extension.launchUI
......@@ -21,6 +27,8 @@ import chat.rocket.core.internal.rest.deleteOwnAccount
import chat.rocket.core.internal.rest.resetAvatar
import chat.rocket.core.internal.rest.setAvatar
import chat.rocket.core.internal.rest.updateProfile
import kotlinx.coroutines.experimental.DefaultDispatcher
import kotlinx.coroutines.experimental.withContext
import java.lang.Exception
import java.util.*
import javax.inject.Inject
......@@ -30,8 +38,23 @@ class ProfilePresenter @Inject constructor(
private val strategy: CancelStrategy,
private val uriInteractor: UriInteractor,
val userHelper: UserHelper,
navigator: MainNavigator,
serverInteractor: GetCurrentServerInteractor,
factory: RocketChatClientFactory
factory: RocketChatClientFactory,
removeAccountInteractor: RemoveAccountInteractor,
tokenRepository: TokenRepository,
dbManagerFactory: DatabaseManagerFactory,
managerFactory: ConnectionManagerFactory
) : CheckServerPresenter(
strategy = strategy,
factory = factory,
serverInteractor = serverInteractor,
removeAccountInteractor = removeAccountInteractor,
tokenRepository = tokenRepository,
dbManagerFactory = dbManagerFactory,
managerFactory = managerFactory,
tokenView = view,
navigator = navigator
) {
private val serverUrl = serverInteractor.get()!!
private val client: RocketChatClient = factory.create(serverUrl)
......@@ -156,7 +179,13 @@ class ProfilePresenter @Inject constructor(
launchUI(strategy) {
view.showLoading()
try {
retryIO { client.deleteOwnAccount(password.gethash().toHex()) }
withContext(DefaultDispatcher) {
// REMARK: Backend API is only working with a lowercase hash.
// https://github.com/RocketChat/Rocket.Chat/issues/12573
retryIO { client.deleteOwnAccount(password.gethash().toHex().toLowerCase()) }
setupConnectionInfo(serverUrl)
logout(null)
}
} catch (exception: Exception) {
exception.message?.let {
view.showMessage(it)
......
......@@ -2,8 +2,9 @@ package chat.rocket.android.profile.presentation
import chat.rocket.android.core.behaviours.LoadingView
import chat.rocket.android.core.behaviours.MessageView
import chat.rocket.android.server.presentation.TokenView
interface ProfileView : LoadingView, MessageView {
interface ProfileView : TokenView, LoadingView, MessageView {
/**
* Shows the user profile.
......
......@@ -32,6 +32,7 @@ import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.extensions.textContent
import chat.rocket.android.util.extensions.ui
import chat.rocket.android.util.invalidateFirebaseToken
import com.facebook.drawee.backends.pipeline.Fresco
import dagger.android.support.AndroidSupportInjection
import io.reactivex.disposables.CompositeDisposable
......@@ -146,6 +147,8 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
showMessage(getString(R.string.msg_profile_update_successfully))
}
override fun invalidateToken(token: String) = invalidateFirebaseToken(token)
override fun showLoading() {
enableUserInput(false)
ui { view_loading.isVisible = true }
......
......@@ -3,7 +3,11 @@ package chat.rocket.android.server.presentation
import chat.rocket.android.BuildConfig
import chat.rocket.android.authentication.server.presentation.VersionCheckView
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.db.DatabaseManager
import chat.rocket.android.db.DatabaseManagerFactory
import chat.rocket.android.helper.OauthHelper
import chat.rocket.android.infrastructure.LocalRepository
import chat.rocket.android.main.presentation.MainNavigator
import chat.rocket.android.server.domain.GetSettingsInteractor
import chat.rocket.android.server.domain.PublicSettings
import chat.rocket.android.server.domain.casLoginUrl
......@@ -18,6 +22,12 @@ import chat.rocket.android.server.domain.isLoginFormEnabled
import chat.rocket.android.server.domain.isRegistrationEnabledForNewUsers
import chat.rocket.android.server.domain.isWordpressAuthenticationEnabled
import chat.rocket.android.server.domain.wordpressUrl
import chat.rocket.android.server.domain.GetCurrentServerInteractor
import chat.rocket.android.server.domain.RemoveAccountInteractor
import chat.rocket.android.server.domain.TokenRepository
import chat.rocket.android.server.domain.RefreshSettingsInteractor
import chat.rocket.android.server.infraestructure.ConnectionManager
import chat.rocket.android.server.infraestructure.ConnectionManagerFactory
import chat.rocket.android.server.infraestructure.RocketChatClientFactory
import chat.rocket.android.util.VersionInfo
import chat.rocket.android.util.extension.launchUI
......@@ -30,9 +40,15 @@ import chat.rocket.common.RocketChatException
import chat.rocket.common.RocketChatInvalidProtocolException
import chat.rocket.common.model.ServerInfo
import chat.rocket.core.RocketChatClient
import chat.rocket.core.internal.rest.logout
import chat.rocket.core.internal.rest.serverInfo
import chat.rocket.core.internal.rest.settingsOauth
import chat.rocket.core.internal.rest.unregisterPushToken
import chat.rocket.core.model.Myself
import kotlinx.coroutines.experimental.CommonPool
import kotlinx.coroutines.experimental.Job
import kotlinx.coroutines.experimental.channels.Channel
import kotlinx.coroutines.experimental.withContext
import timber.log.Timber
private const val SERVICE_NAME_FACEBOOK = "facebook"
......@@ -42,16 +58,26 @@ private const val SERVICE_NAME_LINKEDIN = "linkedin"
private const val SERVICE_NAME_GILAB = "gitlab"
private const val SERVICE_NAME_WORDPRESS = "wordpress"
abstract class CheckServerPresenter constructor(
private val strategy: CancelStrategy,
private val factory: RocketChatClientFactory,
private val settingsInteractor: GetSettingsInteractor? = null,
private val view: VersionCheckView? = null
private val serverInteractor: GetCurrentServerInteractor? = null,
private val localRepository: LocalRepository? = null,
private val removeAccountInteractor: RemoveAccountInteractor? = null,
private val tokenRepository: TokenRepository? = null,
private val managerFactory: ConnectionManagerFactory? = null,
private val dbManagerFactory: DatabaseManagerFactory? = null,
private val versionCheckView: VersionCheckView? = null,
private val tokenView: TokenView? = null,
private val navigator: MainNavigator? = null,
private val refreshSettingsInteractor: RefreshSettingsInteractor? = null
) {
private lateinit var currentServer: String
private lateinit var client: RocketChatClient
private lateinit var settings: PublicSettings
private lateinit var manager: ConnectionManager
private lateinit var dbManager: DatabaseManager
internal var state: String = ""
internal var facebookOauthUrl: String? = null
internal var githubOauthUrl: String? = null
......@@ -78,10 +104,22 @@ abstract class CheckServerPresenter constructor(
internal var isNewAccountCreationEnabled = false
internal fun setupConnectionInfo(serverUrl: String) {
settingsInteractor?.get(serverUrl)?.let {
currentServer = serverUrl
client = factory.create(serverUrl)
managerFactory?.create(serverUrl)?.let {
manager = it
}
dbManagerFactory?.create(serverUrl)?.let {
dbManager = it
}
}
internal suspend fun refreshServerAccounts() {
refreshSettingsInteractor?.refresh(currentServer)
settingsInteractor?.get(currentServer)?.let {
settings = it
}
client = factory.create(serverUrl)
state = ""
facebookOauthUrl = null
......@@ -117,28 +155,28 @@ abstract class CheckServerPresenter constructor(
client.serverInfo()
}
if (serverInfo.redirected) {
view?.updateServerUrl(serverInfo.url)
versionCheckView?.updateServerUrl(serverInfo.url)
}
val version = checkServerVersion(serverInfo)
when (version) {
is Version.VersionOk -> {
Timber.i("Your version is nice! (Requires: 0.62.0, Yours: ${version.version})")
view?.versionOk()
versionCheckView?.versionOk()
}
is Version.RecommendedVersionWarning -> {
Timber.i("Your server ${version.version} is bellow recommended version ${BuildConfig.RECOMMENDED_SERVER_VERSION}")
view?.alertNotRecommendedVersion()
versionCheckView?.alertNotRecommendedVersion()
}
is Version.OutOfDateError -> {
Timber.i("Oops. Looks like your server ${version.version} is out-of-date! Minimum server version required ${BuildConfig.REQUIRED_SERVER_VERSION}!")
view?.blockAndAlertNotRequiredVersion()
versionCheckView?.blockAndAlertNotRequiredVersion()
}
}
} catch (ex: Exception) {
Timber.d(ex, "Error getting server info")
when (ex) {
is RocketChatInvalidProtocolException -> view?.errorInvalidProtocol()
else -> view?.errorCheckingServerVersion()
is RocketChatInvalidProtocolException -> versionCheckView?.errorInvalidProtocol()
else -> versionCheckView?.errorCheckingServerVersion()
}
}
}
......@@ -162,8 +200,59 @@ abstract class CheckServerPresenter constructor(
}
}
private fun checkEnabledOauthAccounts(services: List<Map<String,Any>>, serverUrl: String) {
/**
* Logout the user from the current server.
*
* @param userDataChannel the user data channel to stop listening to changes (if currently subscribed).
*/
internal fun logout(userDataChannel: Channel<Myself>?) {
launchUI(strategy) {
try {
clearTokens()
retryIO("logout") { client.logout() }
} catch (exception: RocketChatException) {
Timber.e(exception, "Error calling logout")
}
try {
if (userDataChannel != null) {
disconnect(userDataChannel)
}
removeAccountInteractor?.remove(currentServer)
tokenRepository?.remove(currentServer)
withContext(CommonPool) { dbManager.logout() }
navigator?.switchOrAddNewServer()
} catch (ex: Exception) {
Timber.e(ex, "Error cleaning up the session...")
}
}
}
/**
* Stops listening to user data changes and disconnects the user.
*
* @param userDataChannel the user data channel to stop listening to changes.
*/
fun disconnect(userDataChannel: Channel<Myself>) {
manager.removeUserDataChannel(userDataChannel)
manager.disconnect()
}
private suspend fun clearTokens() {
serverInteractor?.clear()
val pushToken = localRepository?.get(LocalRepository.KEY_PUSH_TOKEN)
if (pushToken != null) {
try {
retryIO("unregisterPushToken") { client.unregisterPushToken(pushToken) }
tokenView?.invalidateToken(pushToken)
} catch (ex: Exception) {
Timber.e(ex, "Error unregistering push token")
}
}
localRepository?.clearAllFromServer(currentServer)
}
private fun checkEnabledOauthAccounts(services: List<Map<String,Any>>, serverUrl: String) {
if (settings.isFacebookAuthenticationEnabled()) {
getServiceMap(services, SERVICE_NAME_FACEBOOK)?.let { serviceMap ->
getOauthClientId(serviceMap)?.let { clientId ->
......@@ -552,4 +641,4 @@ abstract class CheckServerPresenter constructor(
data class OutOfDateError(private val currentVersion: String) : Version(currentVersion)
}
}
\ No newline at end of file
}
package chat.rocket.android.server.presentation
interface TokenView {
fun invalidateToken(token: String)
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment