1
1
package com.woocommerce.android.ui.login.accountmismatch
2
2
3
3
import com.woocommerce.android.OnChangedException
4
+ import com.woocommerce.android.ui.login.WPApiSiteRepository
4
5
import com.woocommerce.android.util.WooLog
5
- import com.woocommerce.android.util.awaitAny
6
- import com.woocommerce.android.util.awaitEvent
7
- import com.woocommerce.android.util.dispatchAndAwait
8
6
import kotlinx.coroutines.Dispatchers
9
- import kotlinx.coroutines.async
10
- import kotlinx.coroutines.coroutineScope
11
7
import kotlinx.coroutines.withContext
12
8
import org.wordpress.android.fluxc.Dispatcher
13
- import org.wordpress.android.fluxc.generated.AuthenticationActionBuilder
14
9
import org.wordpress.android.fluxc.generated.SiteActionBuilder
15
10
import org.wordpress.android.fluxc.model.SiteModel
16
- import org.wordpress.android.fluxc.store.AccountStore.OnAuthenticationChanged
17
- import org.wordpress.android.fluxc.store.AccountStore.OnDiscoveryResponse
11
+ import org.wordpress.android.fluxc.model.jetpack.JetpackUser
18
12
import org.wordpress.android.fluxc.store.JetpackStore
19
13
import org.wordpress.android.fluxc.store.SiteStore
20
- import org.wordpress.android.fluxc.store.SiteStore.OnSiteChanged
21
- import org.wordpress.android.fluxc.store.SiteStore.RefreshSitesXMLRPCPayload
22
14
import org.wordpress.android.login.util.SiteUtils
23
15
import javax.inject.Inject
24
16
25
17
class AccountMismatchRepository @Inject constructor(
26
18
private val jetpackStore : JetpackStore ,
27
19
private val siteStore : SiteStore ,
20
+ private val wpApiSiteRepository : WPApiSiteRepository ,
28
21
private val dispatcher : Dispatcher
29
22
) {
30
23
suspend fun getSiteByUrl (url : String ): SiteModel ? = withContext(Dispatchers .IO ) {
31
24
SiteUtils .getSiteByMatchingUrl(siteStore, url)
32
25
}
33
26
27
+ fun removeSiteFromDB (site : SiteModel ) {
28
+ dispatcher.dispatch(SiteActionBuilder .newRemoveSiteAction(site))
29
+ }
30
+
34
31
suspend fun fetchJetpackConnectionUrl (site : SiteModel ): Result <String > {
35
32
WooLog .d(WooLog .T .LOGIN , " Fetching Jetpack Connection URL" )
36
33
val result = jetpackStore.fetchJetpackConnectionUrl(site, autoRegisterSiteIfNeeded = true )
@@ -39,6 +36,7 @@ class AccountMismatchRepository @Inject constructor(
39
36
WooLog .w(WooLog .T .LOGIN , " Fetching Jetpack Connection URL failed: ${result.error.message} " )
40
37
Result .failure(OnChangedException (result.error, result.error.message))
41
38
}
39
+
42
40
else -> {
43
41
WooLog .d(WooLog .T .LOGIN , " Jetpack connection URL fetched successfully" )
44
42
Result .success(result.url)
@@ -48,21 +46,21 @@ class AccountMismatchRepository @Inject constructor(
48
46
49
47
suspend fun fetchJetpackConnectedEmail (site : SiteModel ): Result <String > {
50
48
WooLog .d(WooLog .T .LOGIN , " Fetching email of Jetpack User" )
51
- val result = jetpackStore.fetchJetpackUser(site)
52
- return when {
53
- result.isError -> {
54
- WooLog .w(WooLog .T .LOGIN , " Fetching Jetpack User failed error: $result .error.message" )
55
- Result .failure(OnChangedException (result.error, result.error.message))
56
- }
57
- result.user?.wpcomEmail.isNullOrEmpty() -> {
58
- WooLog .w(WooLog .T .LOGIN , " Cannot find Jetpack Email in response" )
59
- Result .failure(Exception (" Email missing from response" ))
60
- }
61
- else -> {
62
- WooLog .d(WooLog .T .LOGIN , " Jetpack User fetched successfully" )
63
- Result .success(result.user!! .wpcomEmail)
49
+
50
+ return fetchJetpackUser(site)
51
+ .onFailure {
52
+ WooLog .w(WooLog .T .LOGIN , " Fetching Jetpack User failed error: ${it.message} " )
53
+ }.mapCatching {
54
+ val wpcomEmail = it?.wpcomEmail
55
+ if (wpcomEmail.isNullOrEmpty()) {
56
+ WooLog .w(WooLog .T .LOGIN , " Cannot find Jetpack Email in response" )
57
+ @Suppress(" TooGenericExceptionThrown" )
58
+ throw Exception (" Email missing from response" )
59
+ } else {
60
+ WooLog .d(WooLog .T .LOGIN , " Jetpack User fetched successfully" )
61
+ wpcomEmail
62
+ }
64
63
}
65
- }
66
64
}
67
65
68
66
suspend fun checkJetpackConnection (
@@ -72,121 +70,39 @@ class AccountMismatchRepository @Inject constructor(
72
70
): Result <JetpackConnectionStatus > {
73
71
WooLog .d(WooLog .T .LOGIN , " Checking Jetpack Connection status for site $siteUrl " )
74
72
75
- return discoverXMLRPCAddress(siteUrl)
76
- .mapCatching { xmlrpcEndpoint ->
77
- val xmlrpcSite = fetchXMLRPCSite(siteUrl, xmlrpcEndpoint, username, password).getOrThrow()
78
- when {
79
- xmlrpcSite.jetpackUserEmail.isNullOrEmpty() -> {
80
- WooLog .d(WooLog .T .LOGIN , " Jetpack site is not connected to a WPCom account" )
81
- JetpackConnectionStatus .NotConnected
82
- }
83
- else -> {
84
- WooLog .d(
85
- tag = WooLog .T .LOGIN ,
86
- message = " Jetpack site is connected to different WPCom account:" +
87
- " ${xmlrpcSite.jetpackUserEmail} "
88
- )
89
- JetpackConnectionStatus .ConnectedToDifferentAccount (xmlrpcSite.jetpackUserEmail)
90
- }
91
- }
92
- }
93
- }
94
-
95
- /* *
96
- * Represents Jetpack Connection status for the current wp-admin account
97
- */
98
- sealed interface JetpackConnectionStatus {
99
- object NotConnected : JetpackConnectionStatus
100
- data class ConnectedToDifferentAccount (val wpcomEmail : String ) : JetpackConnectionStatus
101
- }
102
-
103
- private suspend fun discoverXMLRPCAddress (siteUrl : String ): Result <String > {
104
- WooLog .d(WooLog .T .LOGIN , " Running discovery to fetch XMLRPC endpoint for site $siteUrl " )
105
-
106
- val action = AuthenticationActionBuilder .newDiscoverEndpointAction(siteUrl)
107
- val event: OnDiscoveryResponse = dispatcher.dispatchAndAwait(action)
108
-
109
- return if (event.isError) {
110
- WooLog .w(WooLog .T .LOGIN , " XMLRPC Discovery failed, error: ${event.error} " )
111
- Result .failure(OnChangedException (event.error, event.error.name))
112
- } else {
113
- WooLog .d(
114
- tag = WooLog .T .LOGIN ,
115
- message = " XMLRPC Discovery succeeded, xmrlpc endpoint: ${event.xmlRpcEndpoint} "
116
- )
117
- Result .success(event.xmlRpcEndpoint)
73
+ val site = wpApiSiteRepository.fetchSite(siteUrl, username, password).getOrElse {
74
+ WooLog .w(WooLog .T .LOGIN , " Site fetch failed, error: ${it.message} " )
75
+ return Result .failure(it)
118
76
}
119
- }
120
77
121
- @Suppress(" ReturnCount" )
122
- private suspend fun fetchXMLRPCSite (
123
- siteUrl : String ,
124
- xmlrpcEndpoint : String ,
125
- username : String ,
126
- password : String
127
- ): Result <SiteModel > = coroutineScope {
128
- val authenticationTask = async {
129
- dispatcher.awaitEvent<OnAuthenticationChanged >().also { event ->
130
- if (event.isError) {
131
- WooLog .w(
132
- tag = WooLog .T .LOGIN ,
133
- message = " Authenticating to XMLRPC site $xmlrpcEndpoint failed, " +
134
- " error: ${event.error.message} "
135
- )
136
- }
78
+ return fetchJetpackUser(site).onFailure {
79
+ WooLog .w(WooLog .T .LOGIN , " Jetpack User fetch failed, error: ${it.message} " )
80
+ }.map {
81
+ if (it?.isConnected != true ) {
82
+ WooLog .w(WooLog .T .LOGIN , " Account is not connected to a WPCom account" )
83
+ JetpackConnectionStatus .NotConnected
84
+ } else {
85
+ WooLog .d(WooLog .T .LOGIN , " Account is connected to different WPCom account: ${it.wpcomEmail} " )
86
+ JetpackConnectionStatus .ConnectedToDifferentAccount (it.wpcomEmail)
137
87
}
138
88
}
139
- val siteTask = async {
140
- val selfHostedPayload = RefreshSitesXMLRPCPayload (
141
- username = username,
142
- password = password,
143
- url = xmlrpcEndpoint
144
- )
145
- dispatcher.dispatchAndAwait<RefreshSitesXMLRPCPayload , OnSiteChanged >(
146
- action = SiteActionBuilder .newFetchSitesXmlRpcAction(
147
- selfHostedPayload
148
- )
149
- ).also { event ->
150
- if (event.isError) {
151
- WooLog .w(
152
- tag = WooLog .T .LOGIN ,
153
- message = " XMLRPC site $xmlrpcEndpoint fetch failed, error: ${event.error.message} "
154
- )
155
- } else {
156
- WooLog .d(WooLog .T .LOGIN , " XMLRPC site $xmlrpcEndpoint fetch succeeded" )
157
- }
158
- }
159
- }
160
-
161
- val tasks = listOf (authenticationTask, siteTask)
162
-
163
- val event = tasks.awaitAny()
164
-
165
- if (event.isError) return @coroutineScope Result .failure(OnChangedException (event.error))
166
-
167
- return @coroutineScope fetchSiteOptions(siteUrl)
168
89
}
169
90
170
- private suspend fun fetchSiteOptions (siteUrl : String ): Result <SiteModel > {
171
- WooLog .d(WooLog .T .LOGIN , " Fetch XMLRPC site options" )
172
- val site = getSiteByUrl(siteUrl) ? : run {
173
- WooLog .e(WooLog .T .LOGIN , " XMLRPC site null after fetching!!" )
174
- return Result .failure(IllegalStateException (" XMLRPC Site not found" ))
175
- }
176
-
177
- val fetchSiteResult = siteStore.fetchSite(site)
178
- return when {
179
- fetchSiteResult.isError -> {
180
- WooLog .w(
181
- tag = WooLog .T .LOGIN ,
182
- message = " XMLRPC site $siteUrl fetch failed, error: ${fetchSiteResult.error.message} "
183
- )
184
- Result .failure(OnChangedException (fetchSiteResult.error, fetchSiteResult.error.message))
185
- }
186
- else -> {
187
- WooLog .d(WooLog .T .LOGIN , " XMLRPC site $siteUrl fetch succeeded" )
188
- Result .success(getSiteByUrl(siteUrl)!! )
91
+ private suspend fun fetchJetpackUser (site : SiteModel ): Result <JetpackUser ?> {
92
+ return jetpackStore.fetchJetpackUser(site).let {
93
+ if (it.isError) {
94
+ Result .failure(OnChangedException (it.error, it.error.message))
95
+ } else {
96
+ Result .success(it.user)
189
97
}
190
98
}
191
99
}
100
+
101
+ /* *
102
+ * Represents Jetpack Connection status for the current wp-admin account
103
+ */
104
+ sealed interface JetpackConnectionStatus {
105
+ data object NotConnected : JetpackConnectionStatus
106
+ data class ConnectedToDifferentAccount (val wpcomEmail : String ) : JetpackConnectionStatus
107
+ }
192
108
}
0 commit comments