From d0d2b843d2fc0b2aea47a692235a375eb4b4e079 Mon Sep 17 00:00:00 2001 From: Josh Kasten Date: Mon, 8 Apr 2024 20:32:34 -0400 Subject: [PATCH] add operation checks to all executors To ensure operations are not silently skipped each executor now checks if it can process all the operations. This is important since bugs can go unnoticed for a while and without this it's hard to debug too. --- .../impl/executors/IdentityOperationExecutor.kt | 10 ++++++++++ .../LoginUserFromSubscriptionOperationExecutor.kt | 4 ++++ .../impl/executors/LoginUserOperationExecutor.kt | 1 + .../impl/executors/RefreshUserOperationExecutor.kt | 4 ++++ .../impl/executors/SubscriptionOperationExecutor.kt | 9 ++++++++- .../impl/executors/UpdateUserOperationExecutor.kt | 1 + 6 files changed, 28 insertions(+), 1 deletion(-) diff --git a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/IdentityOperationExecutor.kt b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/IdentityOperationExecutor.kt index 80b991b441..68ce3663d8 100644 --- a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/IdentityOperationExecutor.kt +++ b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/IdentityOperationExecutor.kt @@ -26,6 +26,16 @@ internal class IdentityOperationExecutor( override suspend fun execute(operations: List): ExecutionResponse { Logging.debug("IdentityOperationExecutor(operations: $operations)") + if (operations.any { it !is SetAliasOperation && it !is DeleteAliasOperation }) { + throw Exception("Unrecognized operation(s)! Attempted operations:\n$operations") + } + + if (operations.any { it is SetAliasOperation } && + operations.any { it is DeleteAliasOperation } + ) { + throw Exception("Can't process SetAliasOperation and DeleteAliasOperation at the same time.") + } + // An alias group is an appId/onesignalId/aliasLabel combo, so we only care // about the last operation in the group, as that will be the effective end // state to this specific alias for this user. diff --git a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/LoginUserFromSubscriptionOperationExecutor.kt b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/LoginUserFromSubscriptionOperationExecutor.kt index e60ee5b8dc..9a1178999d 100644 --- a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/LoginUserFromSubscriptionOperationExecutor.kt +++ b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/LoginUserFromSubscriptionOperationExecutor.kt @@ -27,6 +27,10 @@ internal class LoginUserFromSubscriptionOperationExecutor( override suspend fun execute(operations: List): ExecutionResponse { Logging.debug("LoginUserFromSubscriptionOperationExecutor(operation: $operations)") + if (operations.size > 1) { + throw Exception("Only supports one operation! Attempted operations:\n$operations") + } + val startingOp = operations.first() if (startingOp is LoginUserFromSubscriptionOperation) { diff --git a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/LoginUserOperationExecutor.kt b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/LoginUserOperationExecutor.kt index 3f29b90975..50aea377a4 100644 --- a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/LoginUserOperationExecutor.kt +++ b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/LoginUserOperationExecutor.kt @@ -153,6 +153,7 @@ internal class LoginUserOperationExecutor( is TransferSubscriptionOperation -> subscriptions = createSubscriptionsFromOperation(operation, subscriptions) is UpdateSubscriptionOperation -> subscriptions = createSubscriptionsFromOperation(operation, subscriptions) is DeleteSubscriptionOperation -> subscriptions = createSubscriptionsFromOperation(operation, subscriptions) + else -> throw Exception("Unrecognized operation: $operation") } } diff --git a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/RefreshUserOperationExecutor.kt b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/RefreshUserOperationExecutor.kt index d71991de30..4266ab9037 100644 --- a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/RefreshUserOperationExecutor.kt +++ b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/RefreshUserOperationExecutor.kt @@ -38,6 +38,10 @@ internal class RefreshUserOperationExecutor( override suspend fun execute(operations: List): ExecutionResponse { Logging.log(LogLevel.DEBUG, "RefreshUserOperationExecutor(operation: $operations)") + if (operations.any { it !is RefreshUserOperation }) { + throw Exception("Unrecognized operation(s)! Attempted operations:\n$operations") + } + val startingOp = operations.first() if (startingOp is RefreshUserOperation) { return getUser(startingOp) diff --git a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/SubscriptionOperationExecutor.kt b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/SubscriptionOperationExecutor.kt index a13f47c3f6..a9cdf9fe97 100644 --- a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/SubscriptionOperationExecutor.kt +++ b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/SubscriptionOperationExecutor.kt @@ -49,10 +49,17 @@ internal class SubscriptionOperationExecutor( return if (startingOp is CreateSubscriptionOperation) { createSubscription(startingOp, operations) } else if (operations.any { it is DeleteSubscriptionOperation }) { - deleteSubscription(operations.first { it is DeleteSubscriptionOperation } as DeleteSubscriptionOperation) + if (operations.size > 1) { + throw Exception("Only supports one operation! Attempted operations:\n$operations") + } + val deleteSubOps = operations.filterIsInstance() + deleteSubscription(deleteSubOps.first()) } else if (startingOp is UpdateSubscriptionOperation) { updateSubscription(startingOp, operations) } else if (startingOp is TransferSubscriptionOperation) { + if (operations.size > 1) { + throw Exception("TransferSubscriptionOperation only supports one operation! Attempted operations:\n$operations") + } transferSubscription(startingOp) } else { throw Exception("Unrecognized operation: $startingOp") diff --git a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/UpdateUserOperationExecutor.kt b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/UpdateUserOperationExecutor.kt index 19551eaca1..1002ee1f0f 100644 --- a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/UpdateUserOperationExecutor.kt +++ b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/UpdateUserOperationExecutor.kt @@ -114,6 +114,7 @@ internal class UpdateUserOperationExecutor( deltasObject = PropertiesDeltasObject(deltasObject.sessionTime, deltasObject.sessionCount, amountSpent, purchasesArray) } + else -> throw Exception("Unrecognized operation: $operation") } }