Skip to content

Commit 5d3d994

Browse files
committed
Provide @ApplicationPasswordsClientId binding and guard SiteStore
The WordPress/Jetpack app had never bound a `@ApplicationPasswordsClientId` in its Dagger graph, so any call into `ApplicationPasswordsStore` would throw NoSuchElementException. This was latent — no production caller hit the path on this app — until the new `SiteStore.createApplicationPassword` started routing My Site through it and crashed the app on launch. - Provide `@ApplicationPasswordsClientId` from a new `ApplicationPasswordsClientIdModule`, using the same device-interpolated app name the Custom Tab flow already passes through `app_name` ("Jetpack Android App on <device>" / "WordPress Android App on …"). - Short-circuit `SiteStore.createApplicationPassword` to NotSupported when the configuration is disabled, so we degrade gracefully rather than crash if the binding is ever absent again.
1 parent 86cb425 commit 5d3d994

2 files changed

Lines changed: 46 additions & 0 deletions

File tree

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package org.wordpress.android.modules
2+
3+
import android.content.Context
4+
import dagger.Module
5+
import dagger.Provides
6+
import dagger.hilt.InstallIn
7+
import dagger.hilt.android.qualifiers.ApplicationContext
8+
import dagger.hilt.components.SingletonComponent
9+
import org.wordpress.android.R
10+
import org.wordpress.android.fluxc.module.ApplicationPasswordsClientId
11+
import org.wordpress.android.util.BuildConfigWrapper
12+
import org.wordpress.android.util.DeviceUtils
13+
import javax.inject.Singleton
14+
15+
@InstallIn(SingletonComponent::class)
16+
@Module
17+
object ApplicationPasswordsClientIdModule {
18+
@Provides
19+
@Singleton
20+
@ApplicationPasswordsClientId
21+
fun provideApplicationPasswordsClientId(
22+
@ApplicationContext context: Context,
23+
buildConfigWrapper: BuildConfigWrapper,
24+
): String {
25+
val deviceName = DeviceUtils.getInstance().getDeviceName(context)
26+
val resId = if (buildConfigWrapper.isJetpackApp) {
27+
R.string.application_password_app_name_jetpack
28+
} else {
29+
R.string.application_password_app_name_wordpress
30+
}
31+
return context.getString(resId, deviceName)
32+
}
33+
}

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,13 @@ import org.wordpress.android.fluxc.model.asDomainModel
8383
import org.wordpress.android.fluxc.model.jetpacksocial.JetpackSocial
8484
import org.wordpress.android.fluxc.model.jetpacksocial.JetpackSocialMapper
8585
import org.wordpress.android.fluxc.network.BaseRequest.BaseNetworkError
86+
import org.wordpress.android.fluxc.network.BaseRequest.GenericErrorType
8687
import org.wordpress.android.fluxc.network.rest.wpapi.WPAPINetworkError
8788
import org.wordpress.android.fluxc.network.rest.wpapi.WPAPIResponse
8889
import org.wordpress.android.fluxc.network.rest.wpapi.applicationpasswords.ApplicationPasswordCreationResult
8990
import org.wordpress.android.fluxc.network.rest.wpapi.applicationpasswords.ApplicationPasswordCredentials
9091
import org.wordpress.android.fluxc.network.rest.wpapi.applicationpasswords.ApplicationPasswordDeletionResult
92+
import org.wordpress.android.fluxc.network.rest.wpapi.applicationpasswords.ApplicationPasswordsConfiguration
9193
import org.wordpress.android.fluxc.network.rest.wpapi.applicationpasswords.ApplicationPasswordsManager
9294
import org.wordpress.android.fluxc.network.rest.wpapi.site.SiteWPAPIRestClient
9395
import org.wordpress.android.fluxc.network.rest.wpcom.WPComGsonRequest.WPComGsonNetworkError
@@ -163,6 +165,7 @@ open class SiteStore @Inject constructor(
163165
private val coroutineEngine: CoroutineEngine
164166
) : Store(dispatcher) {
165167
@Inject internal lateinit var applicationPasswordsManagerProvider: Provider<ApplicationPasswordsManager>
168+
@Inject internal lateinit var applicationPasswordsConfigurationProvider: Provider<ApplicationPasswordsConfiguration>
166169

167170
// Payloads
168171
data class CompleteQuickStartPayload(
@@ -2402,6 +2405,16 @@ open class SiteStore @Inject constructor(
24022405

24032406
suspend fun createApplicationPassword(site: SiteModel): OnApplicationPasswordCreated =
24042407
coroutineEngine.withDefaultContext(T.API, this, "Create Application Password") {
2408+
if (!applicationPasswordsConfigurationProvider.get().isEnabled) {
2409+
return@withDefaultContext OnApplicationPasswordCreated(
2410+
site,
2411+
BaseNetworkError(
2412+
GenericErrorType.UNKNOWN,
2413+
"Application Passwords feature is not configured for this app"
2414+
),
2415+
notSupported = true,
2416+
)
2417+
}
24052418
when (val result = applicationPasswordsManagerProvider.get().getApplicationCredentials(site)) {
24062419
is ApplicationPasswordCreationResult.Created -> {
24072420
persistApplicationPasswordCredentials(site, result.credentials)

0 commit comments

Comments
 (0)