Skip to content

Commit 81ebe0b

Browse files
committed
fix bugs and add new a test case
1 parent 0ea7689 commit 81ebe0b

File tree

10 files changed

+102
-15
lines changed

10 files changed

+102
-15
lines changed

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/internal/OneSignalImp.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ import org.json.JSONObject
5858
internal class OneSignalImp : IOneSignal, IServiceProvider {
5959
override val sdkVersion: String = OneSignalUtils.SDK_VERSION
6060
override var isInitialized: Boolean = false
61-
override val isIdentityVerificationEnabled: Boolean = false
61+
override val isIdentityVerificationEnabled: Boolean
62+
get() = configModel?.useIdentityVerification?: false
6263

6364
override var consentRequired: Boolean
6465
get() = configModel?.consentRequired ?: (_consentRequired == true)
@@ -136,6 +137,7 @@ internal class OneSignalImp : IOneSignal, IServiceProvider {
136137
private var sessionModel: SessionModel? = null
137138
private var _consentRequired: Boolean? = null
138139
private var _consentGiven: Boolean? = null
140+
private var _useIdentityVerification: Boolean? = false
139141
private var _disableGMSMissingPrompt: Boolean? = null
140142
private val initLock: Any = Any()
141143
private val loginLock: Any = Any()

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/UserManager.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ internal open class UserManager(
279279
// Fire the event when the JWT has been invalidated.
280280
val oldJwt = args.oldValue.toString()
281281
val newJwt = args.newValue.toString()
282-
if (OneSignal.isIdentityVerificationEnabled && oldJwt == newJwt && newJwt.isEmpty()) {
282+
if (OneSignal.isIdentityVerificationEnabled && oldJwt != newJwt && newJwt.isEmpty()) {
283283
jwtInvalidatedCallback.fire {
284284
it.onUserJwtInvalidated(UserJwtInvalidatedEvent((externalId)))
285285
}

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/identity/IdentityModelStore.kt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,15 @@ package com.onesignal.user.internal.identity
33
import com.onesignal.common.modeling.SimpleModelStore
44
import com.onesignal.common.modeling.SingletonModelStore
55
import com.onesignal.core.internal.preferences.IPreferencesService
6+
import com.onesignal.user.internal.backend.IdentityConstants
67

78
open class IdentityModelStore(prefs: IPreferencesService) : SingletonModelStore<IdentityModel>(
89
SimpleModelStore({ IdentityModel() }, "identity", prefs),
9-
)
10+
) {
11+
fun invalidateJwt() {
12+
model.setStringProperty(
13+
IdentityConstants.JWT_TOKEN,
14+
"",
15+
)
16+
}
17+
}

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/IdentityOperationExecutor.kt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,10 @@ internal class IdentityOperationExecutor(
5555
ExecutionResponse(ExecutionResult.FAIL_NORETRY)
5656
NetworkUtils.ResponseStatusType.CONFLICT ->
5757
ExecutionResponse(ExecutionResult.FAIL_CONFLICT)
58-
NetworkUtils.ResponseStatusType.UNAUTHORIZED ->
59-
ExecutionResponse(ExecutionResult.FAIL_UNAUTHORIZED)
58+
NetworkUtils.ResponseStatusType.UNAUTHORIZED -> {
59+
_identityModelStore.invalidateJwt()
60+
return ExecutionResponse(ExecutionResult.FAIL_UNAUTHORIZED)
61+
}
6062
NetworkUtils.ResponseStatusType.MISSING -> {
6163
val operations = _buildUserService.getRebuildOperationsIfCurrentUser(lastOperation.appId, lastOperation.onesignalId)
6264
if (operations == null) {
@@ -92,8 +94,10 @@ internal class IdentityOperationExecutor(
9294
ExecutionResponse(ExecutionResult.SUCCESS)
9395
NetworkUtils.ResponseStatusType.INVALID ->
9496
ExecutionResponse(ExecutionResult.FAIL_NORETRY)
95-
NetworkUtils.ResponseStatusType.UNAUTHORIZED ->
96-
ExecutionResponse(ExecutionResult.FAIL_UNAUTHORIZED)
97+
NetworkUtils.ResponseStatusType.UNAUTHORIZED -> {
98+
_identityModelStore.invalidateJwt()
99+
return ExecutionResponse(ExecutionResult.FAIL_UNAUTHORIZED)
100+
}
97101
NetworkUtils.ResponseStatusType.MISSING -> {
98102
val operations = _buildUserService.getRebuildOperationsIfCurrentUser(lastOperation.appId, lastOperation.onesignalId)
99103
if (operations == null) {

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/LoginUserFromSubscriptionOperationExecutor.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,10 @@ internal class LoginUserFromSubscriptionOperationExecutor(
7979
return when (responseType) {
8080
NetworkUtils.ResponseStatusType.RETRYABLE ->
8181
ExecutionResponse(ExecutionResult.FAIL_RETRY)
82-
NetworkUtils.ResponseStatusType.UNAUTHORIZED ->
82+
NetworkUtils.ResponseStatusType.UNAUTHORIZED -> {
83+
_identityModelStore.invalidateJwt()
8384
ExecutionResponse(ExecutionResult.FAIL_UNAUTHORIZED)
85+
}
8486
else ->
8587
ExecutionResponse(ExecutionResult.FAIL_NORETRY)
8688
}

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/LoginUserOperationExecutor.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,8 +209,10 @@ internal class LoginUserOperationExecutor(
209209
return when (responseType) {
210210
NetworkUtils.ResponseStatusType.RETRYABLE ->
211211
ExecutionResponse(ExecutionResult.FAIL_RETRY)
212-
NetworkUtils.ResponseStatusType.UNAUTHORIZED ->
212+
NetworkUtils.ResponseStatusType.UNAUTHORIZED -> {
213+
_identityModelStore.invalidateJwt()
213214
ExecutionResponse(ExecutionResult.FAIL_UNAUTHORIZED)
215+
}
214216
else ->
215217
ExecutionResponse(ExecutionResult.FAIL_PAUSE_OPREPO)
216218
}

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/RefreshUserOperationExecutor.kt

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,7 @@ internal class RefreshUserOperationExecutor(
130130
NetworkUtils.ResponseStatusType.RETRYABLE ->
131131
ExecutionResponse(ExecutionResult.FAIL_RETRY)
132132
NetworkUtils.ResponseStatusType.UNAUTHORIZED -> {
133-
_identityModelStore.model.setStringProperty(
134-
IdentityConstants.JWT_TOKEN,
135-
"",
136-
)
133+
_identityModelStore.invalidateJwt()
137134
ExecutionResponse(ExecutionResult.FAIL_UNAUTHORIZED)
138135
}
139136
NetworkUtils.ResponseStatusType.MISSING -> {

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/SubscriptionOperationExecutor.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,10 @@ internal class SubscriptionOperationExecutor(
129129
NetworkUtils.ResponseStatusType.INVALID,
130130
->
131131
ExecutionResponse(ExecutionResult.FAIL_NORETRY)
132-
NetworkUtils.ResponseStatusType.UNAUTHORIZED ->
132+
NetworkUtils.ResponseStatusType.UNAUTHORIZED -> {
133+
_identityModelStore.invalidateJwt()
133134
ExecutionResponse(ExecutionResult.FAIL_UNAUTHORIZED)
135+
}
134136
NetworkUtils.ResponseStatusType.MISSING -> {
135137
val operations = _buildUserService.getRebuildOperationsIfCurrentUser(createOperation.appId, createOperation.onesignalId)
136138
if (operations == null) {

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/UpdateUserOperationExecutor.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,10 @@ internal class UpdateUserOperationExecutor(
160160
return when (responseType) {
161161
NetworkUtils.ResponseStatusType.RETRYABLE ->
162162
ExecutionResponse(ExecutionResult.FAIL_RETRY)
163-
NetworkUtils.ResponseStatusType.UNAUTHORIZED ->
163+
NetworkUtils.ResponseStatusType.UNAUTHORIZED -> {
164+
_identityModelStore.invalidateJwt()
164165
ExecutionResponse(ExecutionResult.FAIL_UNAUTHORIZED)
166+
}
165167
NetworkUtils.ResponseStatusType.MISSING -> {
166168
val operations = _buildUserService.getRebuildOperationsIfCurrentUser(appId, onesignalId)
167169
if (operations == null) {

OneSignalSDK/onesignal/core/src/test/java/com/onesignal/user/internal/UserManagerTests.kt

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,33 @@
11
package com.onesignal.user.internal
22

3+
import com.onesignal.IUserJwtInvalidatedListener
4+
import com.onesignal.common.modeling.ModelChangeTags
5+
import com.onesignal.common.modeling.ModelChangedArgs
36
import com.onesignal.core.internal.language.ILanguageContext
7+
import com.onesignal.core.internal.operations.ExecutionResponse
8+
import com.onesignal.core.internal.operations.ExecutionResult
9+
import com.onesignal.core.internal.operations.Operation
410
import com.onesignal.mocks.MockHelper
11+
import com.onesignal.user.internal.backend.CreateUserResponse
12+
import com.onesignal.user.internal.backend.IUserBackendService
13+
import com.onesignal.user.internal.backend.IdentityConstants
14+
import com.onesignal.user.internal.backend.PropertiesObject
15+
import com.onesignal.user.internal.operations.LoginUserOperation
16+
import com.onesignal.user.internal.operations.impl.executors.IdentityOperationExecutor
17+
import com.onesignal.user.internal.operations.impl.executors.LoginUserOperationExecutor
518
import com.onesignal.user.internal.subscriptions.ISubscriptionManager
619
import com.onesignal.user.internal.subscriptions.SubscriptionList
20+
import com.onesignal.user.internal.subscriptions.SubscriptionModelStore
721
import io.kotest.core.spec.style.FunSpec
822
import io.kotest.matchers.shouldBe
923
import io.kotest.matchers.shouldNotBe
24+
import io.mockk.coEvery
1025
import io.mockk.every
1126
import io.mockk.just
1227
import io.mockk.mockk
1328
import io.mockk.runs
1429
import io.mockk.slot
30+
import io.mockk.spyk
1531
import io.mockk.verify
1632

1733
class UserManagerTests : FunSpec({
@@ -191,4 +207,56 @@ class UserManagerTests : FunSpec({
191207
verify(exactly = 1) { mockSubscriptionManager.addSmsSubscription("+15558675309") }
192208
verify(exactly = 1) { mockSubscriptionManager.removeSmsSubscription("+15558675309") }
193209
}
210+
211+
test("login user with jwt calls onUserJwtInvalidated() when the jwt is unauthorized") {
212+
// Given
213+
val appId = "appId"
214+
val localOneSignalId = "local-onesignalId"
215+
val remoteOneSignalId = "remote-onesignalId"
216+
217+
// mock components
218+
val mockSubscriptionManager = mockk<ISubscriptionManager>()
219+
val mockIdentityModelStore = MockHelper.identityModelStore()
220+
val mockPropertiesModelStore = MockHelper.propertiesModelStore()
221+
val mockSubscriptionsModelStore = mockk<SubscriptionModelStore>()
222+
val mockLanguageContext = MockHelper.languageContext()
223+
224+
// mock backend service
225+
val mockUserBackendService = mockk<IUserBackendService>()
226+
coEvery { mockUserBackendService.createUser(any(), any(), any(), any()) } returns
227+
CreateUserResponse(mapOf(IdentityConstants.ONESIGNAL_ID to remoteOneSignalId), PropertiesObject(), listOf())
228+
229+
// mock operation for login user
230+
val mockIdentityOperationExecutor = mockk<IdentityOperationExecutor>()
231+
coEvery { mockIdentityOperationExecutor.execute(any()) } returns
232+
ExecutionResponse(ExecutionResult.FAIL_UNAUTHORIZED)
233+
val loginUserOperationExecutor =
234+
LoginUserOperationExecutor(mockIdentityOperationExecutor, MockHelper.applicationService(), MockHelper.deviceService(), mockUserBackendService, mockIdentityModelStore, mockPropertiesModelStore, mockSubscriptionsModelStore, MockHelper.configModelStore(), mockLanguageContext)
235+
val operations = listOf<Operation>(LoginUserOperation(appId, localOneSignalId, "externalId", "existingOneSignalId"))
236+
237+
// mock user manager with jwtInvalidatedListener added
238+
val userManager =
239+
UserManager(mockSubscriptionManager, mockIdentityModelStore, mockPropertiesModelStore, mockLanguageContext)
240+
mockIdentityModelStore.subscribe(userManager)
241+
val spyJwtInvalidatedListener = spyk<IUserJwtInvalidatedListener>()
242+
userManager.addUserJwtInvalidatedListner(spyJwtInvalidatedListener)
243+
244+
// When
245+
val response = loginUserOperationExecutor.execute(operations)
246+
userManager.onModelUpdated(
247+
ModelChangedArgs(
248+
mockIdentityModelStore.model,
249+
IdentityConstants.JWT_TOKEN,
250+
IdentityConstants.JWT_TOKEN,
251+
"abc",
252+
""),
253+
ModelChangeTags.NORMAL
254+
)
255+
256+
// Then
257+
userManager.jwtInvalidatedCallback.hasSubscribers shouldBe true
258+
response.result shouldBe ExecutionResult.FAIL_UNAUTHORIZED
259+
// TODO: set the default value of isIdentityVerificationEnabled in OneSignalImp.kt to pass the test
260+
verify(exactly = 1) { spyJwtInvalidatedListener.onUserJwtInvalidated(any()) }
261+
}
194262
})

0 commit comments

Comments
 (0)