Skip to content

Commit 14a65bc

Browse files
authored
Route the application-passwords list screen through Basic auth (#22894)
* Add getApplicationPasswordClient to WpApiClientProvider Companion to `getWpApiClient` that always returns a direct-host Basic-auth client built from the SiteModel's application-password credentials, regardless of WP.com routing. `getWpApiClient` sends WPCom-flagged sites (including Atomic) through the bearer-token path and the WP.com REST proxy, which doesn't expose all of the application-password-authenticated routes. The list-screen change in the next commit needs to talk to the direct host; the auto-mint + validator work in the headless-creation PR uses this same method. * Route the application-passwords list screen through Basic auth `ApplicationPasswordsViewModel.getApplicationPasswordsList` called `WpApiClientProvider.getWpApiClient(site)`, which for any WPCom-flagged site (including Atomic) routes through the WP.com REST proxy. That proxy doesn't expose the `application-passwords` routes — every request 404s with `rest_no_route`, the same upstream wordpress-rs limitation that drove dropping the headless mint attempt in this project (Automattic/wordpress-rs#1350). As a result, the list screen appeared empty / errored on Atomic sites: `getCurrentUserId` would 404, return null, and `getApplicationPasswordsList` would early-return an empty list. Switch to `WpApiClientProvider.getApplicationPasswordClient(site)`, which always builds a direct-host Basic-auth client from the stored application-password credentials. The direct host serves the `application-passwords` routes on every WordPress install, so the listing call works for Atomic and Jetpack-WPCom-REST sites in addition to true self-hosted. For self-hosted, behavior is unchanged: both client providers route self-hosted sites through `selfHostedClients.getOrPut(site.id) { createSelfHostedClient(site, ...) }`, returning the same Basic-auth client. Precondition: the SiteModel must already have credentials — typically populated by the My Site auto-mint flow on first foreground. A user reaching the list screen without ever visiting My Site would 401 instead of seeing an empty screen. That edge case can be handled separately (e.g. by minting on demand here) and is out of scope.
1 parent 82411a0 commit 14a65bc

2 files changed

Lines changed: 21 additions & 1 deletion

File tree

WordPress/src/main/java/org/wordpress/android/ui/accounts/applicationpassword/ApplicationPasswordsViewModel.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,13 @@ class ApplicationPasswordsViewModel @Inject constructor(
186186
}
187187

188188
private suspend fun getApplicationPasswordsList(site: SiteModel): List<ApplicationPasswordWithViewContext> {
189-
val wpApiClient = wpApiClientProvider.getWpApiClient(site)
189+
// Always use the direct-host Basic-auth client. `getWpApiClient` routes WPCom-flagged
190+
// sites (including Atomic) through the WP.com REST proxy, which doesn't expose the
191+
// `application-passwords` routes — every call 404s with `rest_no_route`. Talking to the
192+
// site directly with the stored application password sidesteps that limitation.
193+
// Requires the SiteModel to have credentials already (e.g. via the My Site auto-mint
194+
// flow); otherwise the call will 401.
195+
val wpApiClient = wpApiClientProvider.getApplicationPasswordClient(site)
190196

191197
val currentUserId = getCurrentUserId(wpApiClient)
192198
return if (currentUserId == null) {

libs/fluxc/src/main/java/org/wordpress/android/fluxc/network/rest/wpapi/rs/WpApiClientProvider.kt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,20 @@ class WpApiClientProvider @Inject constructor(
7070
}
7171
}
7272

73+
/**
74+
* Always returns a Basic-auth client against the direct host using the SiteModel's
75+
* application-password credentials, regardless of WP.com routing. Use this when you need to
76+
* talk to the site's own REST endpoints with the application password — `getWpApiClient`
77+
* routes WPCom-flagged sites (including Atomic) through the bearer-token path and the WP.com
78+
* REST proxy, which doesn't expose application-password-authenticated routes like
79+
* `/wp/v2/users/{id}/application-passwords`.
80+
*/
81+
@Synchronized
82+
fun getApplicationPasswordClient(site: SiteModel): WpApiClient =
83+
selfHostedClients.getOrPut(site.id) {
84+
createSelfHostedClient(site, uploadListener = null)
85+
}
86+
7387
private fun createSelfHostedClient(
7488
site: SiteModel,
7589
uploadListener: WpRequestExecutor.UploadListener?,

0 commit comments

Comments
 (0)