Skip to content

Commit 17a2c01

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 b4ffda0 commit 17a2c01

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) {
@@ -1694,6 +1693,32 @@ open class SiteStore @Inject constructor(
16941693
OnSiteChanged(siteSqlUtils.updateXmlRpcUrl(localId, xmlRpcUrl))
16951694
}
16961695

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

0 commit comments

Comments
 (0)