Skip to content

Commit 2a880c4

Browse files
committed
Collapse the app-password persist paths behind one helper
UPDATE_APPLICATION_PASSWORD, the WPAPI app-password fetch, and app-password XML-RPC login in createOrUpdateSites each duplicated the read-plain / null-guard / write-credentials-then-wpApiRestUrl logic, with subtle divergences (rowsAffected reassigned vs not; the URL write nested under the credentials check in one path, independent in another). Extract persistAppPasswordColumns(site, persistCredentials, persistWpApiRestUrl); each caller passes its targeted writer pair (local id or URL-keyed). wpApiRestUrl stays gated behind credentials on purpose: a credential-less /me/sites model can be a WP.com simple site whose getWpApiRestUrl() synthesizes a public-api proxy URL, and gating keeps that synthetic value out of the DB. removeApplicationPassword now sums both clear-writes instead of returning only the wpApiRestUrl count.
1 parent 95798b1 commit 2a880c4

1 file changed

Lines changed: 56 additions & 29 deletions

File tree

  • libs/fluxc/src/main/java/org/wordpress/android/fluxc/store

libs/fluxc/src/main/java/org/wordpress/android/fluxc/store/SiteStore.kt

Lines changed: 56 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1619,16 +1619,15 @@ open class SiteStore @Inject constructor(
16191619
// updateSite's full-row write skips WP_API_REST_URL and the credential columns, and this fresh
16201620
// site has no local id (it's matched by URL), so persist them via the URL-keyed writers.
16211621
if (!siteModel.isError) {
1622-
val username = siteModel.apiRestUsernamePlain
1623-
val password = siteModel.apiRestPasswordPlain
1624-
if (!username.isNullOrEmpty() && !password.isNullOrEmpty()) {
1625-
siteSqlUtils.updateApplicationPasswordCredentialsForWPAPISite(
1626-
siteModel.url, username, password
1627-
)
1628-
}
1629-
if (payload.apiRootUrl.isNotEmpty()) {
1630-
siteSqlUtils.updateWpApiRestUrlForWPAPISite(siteModel.url, payload.apiRootUrl)
1631-
}
1622+
persistAppPasswordColumns(
1623+
siteModel,
1624+
{ username, password ->
1625+
siteSqlUtils.updateApplicationPasswordCredentialsForWPAPISite(
1626+
siteModel.url, username, password
1627+
)
1628+
},
1629+
{ siteSqlUtils.updateWpApiRestUrlForWPAPISite(siteModel.url, it) }
1630+
)
16321631
}
16331632
result
16341633
} catch (e: Exception) {
@@ -1693,6 +1692,32 @@ open class SiteStore @Inject constructor(
16931692
OnSiteChanged(siteSqlUtils.updateXmlRpcUrl(localId, xmlRpcUrl))
16941693
}
16951694

1695+
/**
1696+
* Persists the application-password columns that the generic full-row write excludes — the encrypted
1697+
* credentials and, when present, [SiteModel.wpApiRestUrl] — via the supplied targeted writers, returning the
1698+
* number of rows written. The three post-write handlers (UPDATE_APPLICATION_PASSWORD, the WPAPI app-password
1699+
* fetch, and app-password XML-RPC login in createOrUpdateSites) differ only in targeting the row by local id
1700+
* or by URL, so each passes its matching writer pair.
1701+
*
1702+
* wpApiRestUrl is written only alongside credentials. A credential-less /me/sites model can be a WP.com simple
1703+
* site whose getWpApiRestUrl() synthesizes a public-api proxy URL; gating on credentials keeps that synthetic
1704+
* value out of the DB (such sites never carry app-password credentials).
1705+
*/
1706+
private fun persistAppPasswordColumns(
1707+
site: SiteModel,
1708+
persistCredentials: (username: String, password: String) -> Int,
1709+
persistWpApiRestUrl: (wpApiRestUrl: String) -> Int
1710+
): Int {
1711+
val username = site.apiRestUsernamePlain
1712+
val password = site.apiRestPasswordPlain
1713+
if (username.isNullOrEmpty() || password.isNullOrEmpty()) return 0
1714+
var rowsAffected = persistCredentials(username, password)
1715+
site.wpApiRestUrl?.takeIf { it.isNotEmpty() }?.let {
1716+
rowsAffected += persistWpApiRestUrl(it)
1717+
}
1718+
return rowsAffected
1719+
}
1720+
16961721
@Suppress("SwallowedException", "TooGenericExceptionCaught")
16971722
private fun updateApplicationPassword(siteModel: SiteModel): OnSiteChanged {
16981723
return try {
@@ -1703,16 +1728,15 @@ open class SiteStore @Inject constructor(
17031728
} else {
17041729
// Existing site: credentials + WP_API_REST_URL are excluded from the full-row write, so
17051730
// persist them on the existing row via their targeted writers (nothing else changed).
1706-
val username = siteModel.apiRestUsernamePlain
1707-
val password = siteModel.apiRestPasswordPlain
1708-
var rowsAffected = 0
1709-
if (!username.isNullOrEmpty() && !password.isNullOrEmpty()) {
1710-
rowsAffected = siteSqlUtils.updateApplicationPasswordCredentials(siteFromDB.id, username, password)
1711-
}
1712-
siteModel.wpApiRestUrl?.takeIf { it.isNotEmpty() }?.let {
1713-
rowsAffected = siteSqlUtils.updateWpApiRestUrl(siteFromDB.id, it)
1714-
}
1715-
OnSiteChanged(rowsAffected)
1731+
OnSiteChanged(
1732+
persistAppPasswordColumns(
1733+
siteModel,
1734+
{ username, password ->
1735+
siteSqlUtils.updateApplicationPasswordCredentials(siteFromDB.id, username, password)
1736+
},
1737+
{ siteSqlUtils.updateWpApiRestUrl(siteFromDB.id, it) }
1738+
)
1739+
)
17161740
}
17171741
} catch (e: DuplicateSiteException) {
17181742
OnSiteChanged(SiteError(DUPLICATE_SITE))
@@ -1737,8 +1761,9 @@ open class SiteStore @Inject constructor(
17371761
} else {
17381762
// Credentials + WP_API_REST_URL are excluded from the full-row write, so clear them on the
17391763
// existing row via their targeted writers now that the application password is gone.
1740-
siteSqlUtils.clearApplicationPasswordCredentials(siteFromDB.id)
1741-
OnSiteChanged(siteSqlUtils.clearWpApiRestUrl(siteFromDB.id))
1764+
val rowsAffected = siteSqlUtils.clearApplicationPasswordCredentials(siteFromDB.id) +
1765+
siteSqlUtils.clearWpApiRestUrl(siteFromDB.id)
1766+
OnSiteChanged(rowsAffected)
17421767
}
17431768
} catch (e: DuplicateSiteException) {
17441769
OnSiteChanged(SiteError(DUPLICATE_SITE))
@@ -1804,12 +1829,14 @@ open class SiteStore @Inject constructor(
18041829
// Credentials + wpApiRestUrl are excluded from the full-row write, so when this site carries
18051830
// app-password creds (XML-RPC app-password login), persist them on the row that was just
18061831
// written (localId) via the targeted writers.
1807-
val apUsername = site.apiRestUsernamePlain
1808-
val apPassword = site.apiRestPasswordPlain
1809-
if (localId != 0 && !apUsername.isNullOrEmpty() && !apPassword.isNullOrEmpty()) {
1810-
siteSqlUtils.updateApplicationPasswordCredentials(localId, apUsername, apPassword)
1811-
site.wpApiRestUrl?.takeIf { it.isNotEmpty() }
1812-
?.let { siteSqlUtils.updateWpApiRestUrl(localId, it) }
1832+
if (localId != 0) {
1833+
persistAppPasswordColumns(
1834+
site,
1835+
{ username, password ->
1836+
siteSqlUtils.updateApplicationPasswordCredentials(localId, username, password)
1837+
},
1838+
{ siteSqlUtils.updateWpApiRestUrl(localId, it) }
1839+
)
18131840
}
18141841
} catch (caughtException: DuplicateSiteException) {
18151842
duplicateSiteFound = true
@@ -2474,7 +2501,7 @@ open class SiteStore @Inject constructor(
24742501
val siteFromDB = getSiteByLocalId(siteModel.id)
24752502
?: return OnSiteChanged(SiteError(SiteErrorType.INVALID_SITE))
24762503
// Credentials are excluded from the full-row write, so clear them on the existing row via the
2477-
// targeted writer. wpApiRestUrl is intentionally preserved here (see KDoc) — rotation reuses it.
2504+
// targeted writer. wpApiRestUrl is intentionally preserved here — credential rotation reuses it.
24782505
OnSiteChanged(siteSqlUtils.clearApplicationPasswordCredentials(siteFromDB.id))
24792506
} catch (e: DuplicateSiteException) {
24802507
OnSiteChanged(SiteError(DUPLICATE_SITE))

0 commit comments

Comments
 (0)