From 91bed976d2463f34d4bcff5f1addb8b46387a137 Mon Sep 17 00:00:00 2001
From: Boris Zbarsky <bzbarsky@apple.com>
Date: Tue, 14 Feb 2023 12:02:22 -0500
Subject: [PATCH] Make sure to generate events when we clear credentials.
 (#25028)

* Make sure to generate events when we clear credentials.

We could end up in a situation where we cleared some credentials, then
hit an error, and never generated the event for the credentials we had
cleared.

* Address review comment.
---
 .../door-lock-server/door-lock-server.cpp     | 26 ++++++++++++++-----
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/src/app/clusters/door-lock-server/door-lock-server.cpp b/src/app/clusters/door-lock-server/door-lock-server.cpp
index 9d769fa4c8b3b3..4e4cf02c5e0872 100644
--- a/src/app/clusters/door-lock-server/door-lock-server.cpp
+++ b/src/app/clusters/door-lock-server/door-lock-server.cpp
@@ -2895,23 +2895,37 @@ EmberAfStatus DoorLockServer::clearCredentials(chip::EndpointId endpointId, chip
         return EMBER_ZCL_STATUS_FAILURE;
     }
 
+    EmberAfStatus status   = EMBER_ZCL_STATUS_SUCCESS;
+    bool clearedCredential = false;
     for (uint16_t i = 1; i < maxNumberOfCredentials; ++i)
     {
-        auto status = clearCredential(endpointId, modifier, sourceNodeId, credentialType, i, false);
-        if (EMBER_ZCL_STATUS_SUCCESS != status)
+        EmberAfStatus clearStatus = clearCredential(endpointId, modifier, sourceNodeId, credentialType, i, false);
+        if (EMBER_ZCL_STATUS_SUCCESS != clearStatus)
         {
             ChipLogError(Zcl,
                          "[clearCredentials] Unable to clear the credential - internal error "
                          "[endpointId=%d,credentialType=%u,credentialIndex=%d,status=%d]",
                          endpointId, to_underlying(credentialType), i, status);
-            return status;
+            if (status == EMBER_ZCL_STATUS_SUCCESS)
+            {
+                status = clearStatus;
+            }
+        }
+        else
+        {
+            clearedCredential = true;
         }
     }
 
-    sendRemoteLockUserChange(endpointId, credentialTypeToLockDataType(credentialType), DataOperationTypeEnum::kClear, sourceNodeId,
-                             modifier, 0xFFFE, 0xFFFE);
+    // Generate the event if we cleared any credentials, even if we then had errors
+    // clearing other ones, so we don't have credentials silently disappearing.
+    if (clearedCredential)
+    {
+        sendRemoteLockUserChange(endpointId, credentialTypeToLockDataType(credentialType), DataOperationTypeEnum::kClear,
+                                 sourceNodeId, modifier, 0xFFFE, 0xFFFE);
+    }
 
-    return EMBER_ZCL_STATUS_SUCCESS;
+    return status;
 }
 
 bool DoorLockServer::clearFabricFromCredentials(chip::EndpointId endpointId, CredentialTypeEnum credentialType,