Skip to content

Commit 2fe7364

Browse files
committed
Add UNAUTHORIZED handling to OperationRepo and operation executors
1 parent 77e414d commit 2fe7364

File tree

8 files changed

+74
-23
lines changed

8 files changed

+74
-23
lines changed

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/operations/IOperationRepo.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ interface IOperationRepo {
4242
suspend fun awaitInitialized()
4343

4444
fun forceExecuteOperations()
45+
46+
fun setPaused(paused: Boolean)
4547
}
4648

4749
// Extension function so the syntax containsInstanceOf<Operation>() can be used over

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/operations/impl/OperationRepo.kt

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,10 @@ internal class OperationRepo(
199199
waiter.wake(LoopWaiterMessage(false))
200200
}
201201

202+
override fun setPaused(paused: Boolean) {
203+
this.paused = paused
204+
}
205+
202206
/**
203207
* Waits until a new operation is enqueued, then wait an additional
204208
* amount of time afterwards, so operations can be grouped/batched.
@@ -260,7 +264,15 @@ internal class OperationRepo(
260264
ops.forEach { _operationModelStore.remove(it.operation.id) }
261265
ops.forEach { it.waiter?.wake(true) }
262266
}
263-
ExecutionResult.FAIL_UNAUTHORIZED, // TODO: Need to provide callback for app to reset JWT. For now, fail with no retry.
267+
ExecutionResult.FAIL_UNAUTHORIZED -> {
268+
Logging.error("Operation execution failed with invalid jwt, pausing the operation repo: $operations")
269+
// keep the failed operation and pause the operation repo from executing
270+
paused = true
271+
// add back all operations to the front of the queue to be re-executed.
272+
synchronized(queue) {
273+
ops.reversed().forEach { queue.add(0, it) }
274+
}
275+
}
264276
ExecutionResult.FAIL_NORETRY,
265277
ExecutionResult.FAIL_CONFLICT,
266278
-> {

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

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,13 @@ internal class IdentityOperationExecutor(
4545

4646
if (lastOperation is SetAliasOperation) {
4747
try {
48+
val identityAlias = _identityModelStore.getIdentityAlias()
4849
_identityBackend.setAlias(
4950
lastOperation.appId,
50-
IdentityConstants.ONESIGNAL_ID,
51-
lastOperation.onesignalId,
51+
identityAlias.first,
52+
identityAlias.second,
5253
mapOf(lastOperation.label to lastOperation.value),
54+
_identityModelStore.model.jwtToken,
5355
)
5456

5557
// ensure the now created alias is in the model as long as the user is still current.
@@ -66,8 +68,10 @@ internal class IdentityOperationExecutor(
6668
ExecutionResponse(ExecutionResult.FAIL_NORETRY)
6769
NetworkUtils.ResponseStatusType.CONFLICT ->
6870
ExecutionResponse(ExecutionResult.FAIL_CONFLICT, retryAfterSeconds = ex.retryAfterSeconds)
69-
NetworkUtils.ResponseStatusType.UNAUTHORIZED ->
70-
ExecutionResponse(ExecutionResult.FAIL_UNAUTHORIZED, retryAfterSeconds = ex.retryAfterSeconds)
71+
NetworkUtils.ResponseStatusType.UNAUTHORIZED -> {
72+
_identityModelStore.invalidateJwt()
73+
return ExecutionResponse(ExecutionResult.FAIL_UNAUTHORIZED)
74+
}
7175
NetworkUtils.ResponseStatusType.MISSING -> {
7276
if (ex.statusCode == 404 && _newRecordState.isInMissingRetryWindow(lastOperation.onesignalId)) {
7377
return ExecutionResponse(ExecutionResult.FAIL_RETRY, retryAfterSeconds = ex.retryAfterSeconds)
@@ -93,6 +97,7 @@ internal class IdentityOperationExecutor(
9397
IdentityConstants.ONESIGNAL_ID,
9498
lastOperation.onesignalId,
9599
lastOperation.label,
100+
_identityModelStore.model.jwtToken,
96101
)
97102

98103
// ensure the now deleted alias is not in the model as long as the user is still current.
@@ -110,8 +115,10 @@ internal class IdentityOperationExecutor(
110115
ExecutionResponse(ExecutionResult.SUCCESS)
111116
NetworkUtils.ResponseStatusType.INVALID ->
112117
ExecutionResponse(ExecutionResult.FAIL_NORETRY)
113-
NetworkUtils.ResponseStatusType.UNAUTHORIZED ->
114-
ExecutionResponse(ExecutionResult.FAIL_UNAUTHORIZED, retryAfterSeconds = ex.retryAfterSeconds)
118+
NetworkUtils.ResponseStatusType.UNAUTHORIZED -> {
119+
_identityModelStore.invalidateJwt()
120+
return ExecutionResponse(ExecutionResult.FAIL_UNAUTHORIZED)
121+
}
115122
NetworkUtils.ResponseStatusType.MISSING -> {
116123
return if (ex.statusCode == 404 && _newRecordState.isInMissingRetryWindow(lastOperation.onesignalId)) {
117124
ExecutionResponse(ExecutionResult.FAIL_RETRY, retryAfterSeconds = ex.retryAfterSeconds)

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ internal class LoginUserFromSubscriptionOperationExecutor(
4646
_subscriptionBackend.getIdentityFromSubscription(
4747
loginUserOp.appId,
4848
loginUserOp.subscriptionId,
49+
_identityModelStore.model.jwtToken,
4950
)
5051
val backendOneSignalId = identities.getOrDefault(IdentityConstants.ONESIGNAL_ID, null)
5152

@@ -82,8 +83,10 @@ internal class LoginUserFromSubscriptionOperationExecutor(
8283
return when (responseType) {
8384
NetworkUtils.ResponseStatusType.RETRYABLE ->
8485
ExecutionResponse(ExecutionResult.FAIL_RETRY)
85-
NetworkUtils.ResponseStatusType.UNAUTHORIZED ->
86+
NetworkUtils.ResponseStatusType.UNAUTHORIZED -> {
87+
_identityModelStore.invalidateJwt()
8688
ExecutionResponse(ExecutionResult.FAIL_UNAUTHORIZED)
89+
}
8790
else ->
8891
ExecutionResponse(ExecutionResult.FAIL_NORETRY)
8992
}

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,10 @@ internal class LoginUserOperationExecutor(
133133
)
134134
createUser(loginUserOp, operations)
135135
}
136+
ExecutionResult.FAIL_UNAUTHORIZED -> {
137+
_identityModelStore.invalidateJwt()
138+
ExecutionResponse(result.result)
139+
}
136140
else -> ExecutionResponse(result.result)
137141
}
138142
}
@@ -219,8 +223,10 @@ internal class LoginUserOperationExecutor(
219223
return when (responseType) {
220224
NetworkUtils.ResponseStatusType.RETRYABLE ->
221225
ExecutionResponse(ExecutionResult.FAIL_RETRY, retryAfterSeconds = ex.retryAfterSeconds)
222-
NetworkUtils.ResponseStatusType.UNAUTHORIZED ->
223-
ExecutionResponse(ExecutionResult.FAIL_UNAUTHORIZED, retryAfterSeconds = ex.retryAfterSeconds)
226+
NetworkUtils.ResponseStatusType.UNAUTHORIZED -> {
227+
_identityModelStore.invalidateJwt()
228+
ExecutionResponse(ExecutionResult.FAIL_UNAUTHORIZED)
229+
}
224230
else ->
225231
ExecutionResponse(ExecutionResult.FAIL_PAUSE_OPREPO)
226232
}

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,12 @@ internal class RefreshUserOperationExecutor(
5353

5454
private suspend fun getUser(op: RefreshUserOperation): ExecutionResponse {
5555
try {
56-
val alias = _identityModelStore.getIdentityAlias()
56+
val identityAlias = _identityModelStore.getIdentityAlias()
5757
val response =
5858
_userBackend.getUser(
5959
op.appId,
60-
alias.first,
61-
alias.second,
60+
identityAlias.first,
61+
identityAlias.second,
6262
_identityModelStore.model.jwtToken,
6363
)
6464

@@ -70,6 +70,7 @@ internal class RefreshUserOperationExecutor(
7070
for (aliasKVP in response.identities) {
7171
identityModel[aliasKVP.key] = aliasKVP.value
7272
}
73+
identityModel.jwtToken = _identityModelStore.model.jwtToken
7374

7475
val propertiesModel = PropertiesModel()
7576
propertiesModel.onesignalId = op.onesignalId

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

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import com.onesignal.user.internal.backend.IdentityConstants
2525
import com.onesignal.user.internal.backend.SubscriptionObject
2626
import com.onesignal.user.internal.backend.SubscriptionObjectType
2727
import com.onesignal.user.internal.builduser.IRebuildUserService
28+
import com.onesignal.user.internal.identity.IdentityModelStore
2829
import com.onesignal.user.internal.operations.CreateSubscriptionOperation
2930
import com.onesignal.user.internal.operations.DeleteSubscriptionOperation
3031
import com.onesignal.user.internal.operations.TransferSubscriptionOperation
@@ -38,6 +39,7 @@ internal class SubscriptionOperationExecutor(
3839
private val _subscriptionBackend: ISubscriptionBackendService,
3940
private val _deviceService: IDeviceService,
4041
private val _applicationService: IApplicationService,
42+
private val _identityModelStore: IdentityModelStore,
4143
private val _subscriptionModelStore: SubscriptionModelStore,
4244
private val _configModelStore: ConfigModelStore,
4345
private val _buildUserService: IRebuildUserService,
@@ -105,12 +107,14 @@ internal class SubscriptionOperationExecutor(
105107
AndroidUtils.getAppVersion(_applicationService.appContext),
106108
)
107109

110+
val identityAlias = _identityModelStore.getIdentityAlias()
108111
val result =
109112
_subscriptionBackend.createSubscription(
110113
createOperation.appId,
111-
IdentityConstants.ONESIGNAL_ID,
112-
createOperation.onesignalId,
114+
identityAlias.first,
115+
identityAlias.second,
113116
subscription,
117+
_identityModelStore.model.jwtToken,
114118
) ?: return ExecutionResponse(ExecutionResult.SUCCESS)
115119

116120
val backendSubscriptionId = result.first
@@ -148,8 +152,10 @@ internal class SubscriptionOperationExecutor(
148152
NetworkUtils.ResponseStatusType.INVALID,
149153
->
150154
ExecutionResponse(ExecutionResult.FAIL_NORETRY)
151-
NetworkUtils.ResponseStatusType.UNAUTHORIZED ->
155+
NetworkUtils.ResponseStatusType.UNAUTHORIZED -> {
156+
_identityModelStore.invalidateJwt()
152157
ExecutionResponse(ExecutionResult.FAIL_UNAUTHORIZED, retryAfterSeconds = ex.retryAfterSeconds)
158+
}
153159
NetworkUtils.ResponseStatusType.MISSING -> {
154160
if (ex.statusCode == 404 && _newRecordState.isInMissingRetryWindow(createOperation.onesignalId)) {
155161
return ExecutionResponse(ExecutionResult.FAIL_RETRY, retryAfterSeconds = ex.retryAfterSeconds)
@@ -247,6 +253,7 @@ internal class SubscriptionOperationExecutor(
247253
startingOperation.subscriptionId,
248254
IdentityConstants.ONESIGNAL_ID,
249255
startingOperation.onesignalId,
256+
_identityModelStore.model.jwtToken,
250257
)
251258
} catch (ex: BackendException) {
252259
val responseType = NetworkUtils.getResponseStatusType(ex.statusCode)
@@ -278,7 +285,7 @@ internal class SubscriptionOperationExecutor(
278285

279286
private suspend fun deleteSubscription(op: DeleteSubscriptionOperation): ExecutionResponse {
280287
try {
281-
_subscriptionBackend.deleteSubscription(op.appId, op.subscriptionId)
288+
_subscriptionBackend.deleteSubscription(op.appId, op.subscriptionId, _identityModelStore.model.jwtToken)
282289

283290
// remove the subscription model as a HYDRATE in case for some reason it still exists.
284291
_subscriptionModelStore.remove(op.subscriptionId, ModelChangeTags.HYDRATE)

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

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import com.onesignal.core.internal.operations.Operation
1313
import com.onesignal.debug.LogLevel
1414
import com.onesignal.debug.internal.logging.Logging
1515
import com.onesignal.user.internal.backend.IUserBackendService
16-
import com.onesignal.user.internal.backend.IdentityConstants
1716
import com.onesignal.user.internal.backend.PropertiesDeltasObject
1817
import com.onesignal.user.internal.backend.PropertiesObject
1918
import com.onesignal.user.internal.backend.PurchaseObject
@@ -88,7 +87,12 @@ internal class UpdateUserOperationExecutor(
8887
val sessionCount = if (deltasObject.sessionCount != null) deltasObject.sessionCount!! + 1 else 1
8988

9089
deltasObject =
91-
PropertiesDeltasObject(deltasObject.sessionTime, sessionCount, deltasObject.amountSpent, deltasObject.purchases)
90+
PropertiesDeltasObject(
91+
deltasObject.sessionTime,
92+
sessionCount,
93+
deltasObject.amountSpent,
94+
deltasObject.purchases,
95+
)
9296
refreshDeviceMetadata = true
9397
}
9498
is TrackSessionEndOperation -> {
@@ -107,7 +111,12 @@ internal class UpdateUserOperationExecutor(
107111
}
108112

109113
deltasObject =
110-
PropertiesDeltasObject(sessionTime, deltasObject.sessionCount, deltasObject.amountSpent, deltasObject.purchases)
114+
PropertiesDeltasObject(
115+
sessionTime,
116+
deltasObject.sessionCount,
117+
deltasObject.amountSpent,
118+
deltasObject.purchases,
119+
)
111120
}
112121
is TrackPurchaseOperation -> {
113122
if (appId == null) {
@@ -138,14 +147,16 @@ internal class UpdateUserOperationExecutor(
138147

139148
if (appId != null && onesignalId != null) {
140149
try {
150+
val identityAlias = _identityModelStore.getIdentityAlias()
141151
val rywData =
142152
_userBackend.updateUser(
143153
appId,
144-
IdentityConstants.ONESIGNAL_ID,
145-
onesignalId,
154+
identityAlias.first,
155+
identityAlias.second,
146156
propertiesObject,
147157
refreshDeviceMetadata,
148158
deltasObject,
159+
_identityModelStore.model.jwtToken,
149160
)
150161

151162
if (rywData != null) {
@@ -185,8 +196,10 @@ internal class UpdateUserOperationExecutor(
185196
return when (responseType) {
186197
NetworkUtils.ResponseStatusType.RETRYABLE ->
187198
ExecutionResponse(ExecutionResult.FAIL_RETRY, retryAfterSeconds = ex.retryAfterSeconds)
188-
NetworkUtils.ResponseStatusType.UNAUTHORIZED ->
199+
NetworkUtils.ResponseStatusType.UNAUTHORIZED -> {
200+
_identityModelStore.invalidateJwt()
189201
ExecutionResponse(ExecutionResult.FAIL_UNAUTHORIZED, retryAfterSeconds = ex.retryAfterSeconds)
202+
}
190203
NetworkUtils.ResponseStatusType.MISSING -> {
191204
if (ex.statusCode == 404 && _newRecordState.isInMissingRetryWindow(onesignalId)) {
192205
return ExecutionResponse(ExecutionResult.FAIL_RETRY, retryAfterSeconds = ex.retryAfterSeconds)

0 commit comments

Comments
 (0)