mirror of https://github.com/halo-dev/halo
refactor: delete dependent userconnection resources when an user is deleted (#3640)
#### 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 ```pull/3608/head^2
parent
ff466f5de6
commit
7b43d21866
|
@ -1,13 +1,15 @@
|
||||||
package run.halo.app.core.extension.reconciler;
|
package run.halo.app.core.extension.reconciler;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.context.ApplicationEventPublisher;
|
import org.springframework.retry.support.RetryTemplate;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import run.halo.app.core.extension.User;
|
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.ExtensionClient;
|
||||||
import run.halo.app.extension.controller.Controller;
|
import run.halo.app.extension.controller.Controller;
|
||||||
import run.halo.app.extension.controller.ControllerBuilder;
|
import run.halo.app.extension.controller.ControllerBuilder;
|
||||||
|
@ -23,8 +25,12 @@ import run.halo.app.infra.utils.PathUtils;
|
||||||
public class UserReconciler implements Reconciler<Request> {
|
public class UserReconciler implements Reconciler<Request> {
|
||||||
private static final String FINALIZER_NAME = "user-protection";
|
private static final String FINALIZER_NAME = "user-protection";
|
||||||
private final ExtensionClient client;
|
private final ExtensionClient client;
|
||||||
private final ApplicationEventPublisher eventPublisher;
|
|
||||||
private final ExternalUrlSupplier externalUrlSupplier;
|
private final ExternalUrlSupplier externalUrlSupplier;
|
||||||
|
private final RetryTemplate retryTemplate = RetryTemplate.builder()
|
||||||
|
.maxAttempts(20)
|
||||||
|
.fixedBackoff(300)
|
||||||
|
.retryOn(IllegalStateException.class)
|
||||||
|
.build();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result reconcile(Request request) {
|
public Result reconcile(Request request) {
|
||||||
|
@ -85,6 +91,10 @@ public class UserReconciler implements Reconciler<Request> {
|
||||||
|
|
||||||
private void cleanUpResourcesAndRemoveFinalizer(String userName) {
|
private void cleanUpResourcesAndRemoveFinalizer(String userName) {
|
||||||
client.fetch(User.class, userName).ifPresent(user -> {
|
client.fetch(User.class, userName).ifPresent(user -> {
|
||||||
|
// wait for dependent resources to be deleted
|
||||||
|
deleteUserConnections(userName);
|
||||||
|
|
||||||
|
// remove finalizer
|
||||||
if (user.getMetadata().getFinalizers() != null) {
|
if (user.getMetadata().getFinalizers() != null) {
|
||||||
user.getMetadata().getFinalizers().remove(FINALIZER_NAME);
|
user.getMetadata().getFinalizers().remove(FINALIZER_NAME);
|
||||||
}
|
}
|
||||||
|
@ -92,6 +102,22 @@ public class UserReconciler implements Reconciler<Request> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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<UserConnection> listConnectionsByUsername(String username) {
|
||||||
|
return client.list(UserConnection.class,
|
||||||
|
connection -> connection.getSpec().getUsername().equals(username), null);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Controller setupWith(ControllerBuilder builder) {
|
public Controller setupWith(ControllerBuilder builder) {
|
||||||
return builder
|
return builder
|
||||||
|
|
Loading…
Reference in New Issue