From 7b43d21866c840e792bac1f757364a66aa218d90 Mon Sep 17 00:00:00 2001 From: guqing <38999863+guqing@users.noreply.github.com> Date: Thu, 30 Mar 2023 23:40:19 +0800 Subject: [PATCH] refactor: delete dependent userconnection resources when an user is deleted (#3640) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What type of PR is this? /kind improvement /area core /milestone 2.4.0 #### What this PR does / why we need it: 当用户被删除时关联删除用户的绑定账号信息 how to test it? 1. 创建用户 2. 绑定账号 3. 使用管理员删除此用户并查看关联的 UserConnection 是否被删除 ```shell curl -u 'your-username:your-password' http://127.0.0.1:8090/apis/auth.halo.run/v1alpha1/userconnections | jq -r '.' ``` #### Which issue(s) this PR fixes: Fixes #3639 #### Does this PR introduce a user-facing change? ```release-note None ``` --- .../extension/reconciler/UserReconciler.java | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/application/src/main/java/run/halo/app/core/extension/reconciler/UserReconciler.java b/application/src/main/java/run/halo/app/core/extension/reconciler/UserReconciler.java index f54ad2ae8..5e540d85a 100644 --- a/application/src/main/java/run/halo/app/core/extension/reconciler/UserReconciler.java +++ b/application/src/main/java/run/halo/app/core/extension/reconciler/UserReconciler.java @@ -1,13 +1,15 @@ package run.halo.app.core.extension.reconciler; import java.util.HashSet; +import java.util.List; import java.util.Set; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; -import org.springframework.context.ApplicationEventPublisher; +import org.springframework.retry.support.RetryTemplate; import org.springframework.stereotype.Component; import run.halo.app.core.extension.User; +import run.halo.app.core.extension.UserConnection; import run.halo.app.extension.ExtensionClient; import run.halo.app.extension.controller.Controller; import run.halo.app.extension.controller.ControllerBuilder; @@ -23,8 +25,12 @@ import run.halo.app.infra.utils.PathUtils; public class UserReconciler implements Reconciler { private static final String FINALIZER_NAME = "user-protection"; private final ExtensionClient client; - private final ApplicationEventPublisher eventPublisher; private final ExternalUrlSupplier externalUrlSupplier; + private final RetryTemplate retryTemplate = RetryTemplate.builder() + .maxAttempts(20) + .fixedBackoff(300) + .retryOn(IllegalStateException.class) + .build(); @Override public Result reconcile(Request request) { @@ -85,6 +91,10 @@ public class UserReconciler implements Reconciler { private void cleanUpResourcesAndRemoveFinalizer(String userName) { client.fetch(User.class, userName).ifPresent(user -> { + // wait for dependent resources to be deleted + deleteUserConnections(userName); + + // remove finalizer if (user.getMetadata().getFinalizers() != null) { user.getMetadata().getFinalizers().remove(FINALIZER_NAME); } @@ -92,6 +102,22 @@ public class UserReconciler implements Reconciler { }); } + void deleteUserConnections(String userName) { + listConnectionsByUsername(userName).forEach(client::delete); + // wait for user connection to be deleted + retryTemplate.execute(callback -> { + if (listConnectionsByUsername(userName).size() > 0) { + throw new IllegalStateException("User connection is not deleted yet"); + } + return null; + }); + } + + List listConnectionsByUsername(String username) { + return client.list(UserConnection.class, + connection -> connection.getSpec().getUsername().equals(username), null); + } + @Override public Controller setupWith(ControllerBuilder builder) { return builder