mirror of https://github.com/halo-dev/halo
fix: initialization status of the privileged auth provider is OFF (#3627)
#### What type of PR is this? /kind feature /area core /milestone 2.4.x #### What this PR does / why we need it: 修复 Local 认证方式的开关初始化状态为关闭 #### Which issue(s) this PR fixes: Fixes #3602 #### Does this PR introduce a user-facing change? ```release-note None ```pull/3626/head
parent
d355e797bd
commit
520074bd9c
|
@ -0,0 +1,90 @@
|
||||||
|
package run.halo.app.core.extension.reconciler;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.apache.commons.lang3.BooleanUtils;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import run.halo.app.core.extension.AuthProvider;
|
||||||
|
import run.halo.app.extension.ExtensionClient;
|
||||||
|
import run.halo.app.extension.MetadataUtil;
|
||||||
|
import run.halo.app.extension.controller.Controller;
|
||||||
|
import run.halo.app.extension.controller.ControllerBuilder;
|
||||||
|
import run.halo.app.extension.controller.Reconciler;
|
||||||
|
import run.halo.app.security.AuthProviderService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reconciler for {@link AuthProvider}.
|
||||||
|
*
|
||||||
|
* @author guqing
|
||||||
|
* @since 2.4.0
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class AuthProviderReconciler implements Reconciler<Reconciler.Request> {
|
||||||
|
private static final String FINALIZER_NAME = "auth-provider-protection";
|
||||||
|
private final ExtensionClient client;
|
||||||
|
private final AuthProviderService authProviderService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Result reconcile(Request request) {
|
||||||
|
client.fetch(AuthProvider.class, request.name())
|
||||||
|
.ifPresent(authProvider -> {
|
||||||
|
if (authProvider.getMetadata().getDeletionTimestamp() != null) {
|
||||||
|
removeFinalizer(request.name());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
addFinalizerIfNecessary(authProvider);
|
||||||
|
handlePrivileged(authProvider);
|
||||||
|
});
|
||||||
|
return Result.doNotRetry();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Controller setupWith(ControllerBuilder builder) {
|
||||||
|
return builder
|
||||||
|
.extension(new AuthProvider())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handlePrivileged(AuthProvider authProvider) {
|
||||||
|
if (privileged(authProvider)) {
|
||||||
|
authProviderService.enable(authProvider.getMetadata().getName()).block();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addFinalizerIfNecessary(AuthProvider oldAuthProvider) {
|
||||||
|
Set<String> finalizers = oldAuthProvider.getMetadata().getFinalizers();
|
||||||
|
if (finalizers != null && finalizers.contains(FINALIZER_NAME)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
client.fetch(AuthProvider.class, oldAuthProvider.getMetadata().getName())
|
||||||
|
.ifPresent(authProvider -> {
|
||||||
|
Set<String> newFinalizers = authProvider.getMetadata().getFinalizers();
|
||||||
|
if (newFinalizers == null) {
|
||||||
|
newFinalizers = new HashSet<>();
|
||||||
|
authProvider.getMetadata().setFinalizers(newFinalizers);
|
||||||
|
}
|
||||||
|
newFinalizers.add(FINALIZER_NAME);
|
||||||
|
client.update(authProvider);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeFinalizer(String authProviderName) {
|
||||||
|
client.fetch(AuthProvider.class, authProviderName)
|
||||||
|
.ifPresent(authProvider -> {
|
||||||
|
// Disable auth provider
|
||||||
|
authProviderService.disable(authProviderName).block();
|
||||||
|
|
||||||
|
if (authProvider.getMetadata().getFinalizers() != null) {
|
||||||
|
authProvider.getMetadata().getFinalizers().remove(FINALIZER_NAME);
|
||||||
|
}
|
||||||
|
client.update(authProvider);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean privileged(AuthProvider authProvider) {
|
||||||
|
return BooleanUtils.TRUE.equals(MetadataUtil.nullSafeLabels(authProvider)
|
||||||
|
.get(AuthProvider.PRIVILEGED_LABEL));
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,6 +19,7 @@ import reactor.core.publisher.Mono;
|
||||||
import run.halo.app.core.extension.AuthProvider;
|
import run.halo.app.core.extension.AuthProvider;
|
||||||
import run.halo.app.core.extension.UserConnection;
|
import run.halo.app.core.extension.UserConnection;
|
||||||
import run.halo.app.extension.ConfigMap;
|
import run.halo.app.extension.ConfigMap;
|
||||||
|
import run.halo.app.extension.Metadata;
|
||||||
import run.halo.app.extension.MetadataUtil;
|
import run.halo.app.extension.MetadataUtil;
|
||||||
import run.halo.app.extension.ReactiveExtensionClient;
|
import run.halo.app.extension.ReactiveExtensionClient;
|
||||||
import run.halo.app.infra.SystemSetting;
|
import run.halo.app.infra.SystemSetting;
|
||||||
|
@ -45,7 +46,9 @@ public class AuthProviderServiceImpl implements AuthProviderService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mono<AuthProvider> disable(String name) {
|
public Mono<AuthProvider> disable(String name) {
|
||||||
|
// privileged auth provider cannot be disabled
|
||||||
return client.get(AuthProvider.class, name)
|
return client.get(AuthProvider.class, name)
|
||||||
|
.filter(authProvider -> !privileged(authProvider))
|
||||||
.flatMap(authProvider -> updateAuthProviderEnabled(enabled -> enabled.remove(name))
|
.flatMap(authProvider -> updateAuthProviderEnabled(enabled -> enabled.remove(name))
|
||||||
.thenReturn(authProvider)
|
.thenReturn(authProvider)
|
||||||
);
|
);
|
||||||
|
@ -104,30 +107,24 @@ public class AuthProviderServiceImpl implements AuthProviderService {
|
||||||
|
|
||||||
private Mono<ConfigMap> updateAuthProviderEnabled(Consumer<Set<String>> consumer) {
|
private Mono<ConfigMap> updateAuthProviderEnabled(Consumer<Set<String>> consumer) {
|
||||||
return client.fetch(ConfigMap.class, SystemSetting.SYSTEM_CONFIG)
|
return client.fetch(ConfigMap.class, SystemSetting.SYSTEM_CONFIG)
|
||||||
|
.switchIfEmpty(Mono.defer(() -> {
|
||||||
|
ConfigMap configMap = new ConfigMap();
|
||||||
|
configMap.setMetadata(new Metadata());
|
||||||
|
configMap.getMetadata().setName(SystemSetting.SYSTEM_CONFIG);
|
||||||
|
configMap.setData(new HashMap<>());
|
||||||
|
return client.create(configMap);
|
||||||
|
}))
|
||||||
.flatMap(configMap -> {
|
.flatMap(configMap -> {
|
||||||
SystemSetting.AuthProvider authProvider = getAuthProvider(configMap);
|
SystemSetting.AuthProvider authProvider = getAuthProvider(configMap);
|
||||||
consumer.accept(authProvider.getEnabled());
|
consumer.accept(authProvider.getEnabled());
|
||||||
return fetchPrivilegedProviders()
|
|
||||||
.doOnNext(privileged -> {
|
|
||||||
authProvider.getEnabled().addAll(privileged);
|
|
||||||
})
|
|
||||||
.then(Mono.defer(() -> {
|
|
||||||
final Map<String, String> data = configMap.getData();
|
final Map<String, String> data = configMap.getData();
|
||||||
data.put(SystemSetting.AuthProvider.GROUP,
|
data.put(SystemSetting.AuthProvider.GROUP,
|
||||||
JsonUtils.objectToJson(authProvider));
|
JsonUtils.objectToJson(authProvider));
|
||||||
return client.update(configMap);
|
return client.update(configMap);
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private Mono<List<String>> fetchPrivilegedProviders() {
|
|
||||||
return client.list(AuthProvider.class,
|
|
||||||
provider -> privileged(provider),
|
|
||||||
null)
|
|
||||||
.map(provider -> provider.getMetadata().getName())
|
|
||||||
.collectList();
|
|
||||||
}
|
|
||||||
|
|
||||||
private ListedAuthProvider convertTo(AuthProvider authProvider) {
|
private ListedAuthProvider convertTo(AuthProvider authProvider) {
|
||||||
return ListedAuthProvider.builder()
|
return ListedAuthProvider.builder()
|
||||||
.name(authProvider.getMetadata().getName())
|
.name(authProvider.getMetadata().getName())
|
||||||
|
|
|
@ -70,7 +70,7 @@ class AuthProviderServiceImplTest {
|
||||||
Set<String> enabled =
|
Set<String> enabled =
|
||||||
JsonUtils.jsonToObject(providerSettingStr, SystemSetting.AuthProvider.class)
|
JsonUtils.jsonToObject(providerSettingStr, SystemSetting.AuthProvider.class)
|
||||||
.getEnabled();
|
.getEnabled();
|
||||||
assertThat(enabled).containsExactly("github", "local");
|
assertThat(enabled).containsExactly("github");
|
||||||
// Verify the result
|
// Verify the result
|
||||||
verify(client).get(AuthProvider.class, "github");
|
verify(client).get(AuthProvider.class, "github");
|
||||||
verify(client).fetch(eq(ConfigMap.class), eq(SystemSetting.SYSTEM_CONFIG));
|
verify(client).fetch(eq(ConfigMap.class), eq(SystemSetting.SYSTEM_CONFIG));
|
||||||
|
@ -104,7 +104,7 @@ class AuthProviderServiceImplTest {
|
||||||
Set<String> enabled =
|
Set<String> enabled =
|
||||||
JsonUtils.jsonToObject(providerSettingStr, SystemSetting.AuthProvider.class)
|
JsonUtils.jsonToObject(providerSettingStr, SystemSetting.AuthProvider.class)
|
||||||
.getEnabled();
|
.getEnabled();
|
||||||
assertThat(enabled).containsExactly("local");
|
assertThat(enabled).isEmpty();
|
||||||
// Verify the result
|
// Verify the result
|
||||||
verify(client).get(AuthProvider.class, "github");
|
verify(client).get(AuthProvider.class, "github");
|
||||||
verify(client).fetch(eq(ConfigMap.class), eq(SystemSetting.SYSTEM_CONFIG));
|
verify(client).fetch(eq(ConfigMap.class), eq(SystemSetting.SYSTEM_CONFIG));
|
||||||
|
|
Loading…
Reference in New Issue