mirror of https://github.com/halo-dev/halo
perf: hide the switch of local identity authentication (#3562)
#### What type of PR is this? /kind improvement /area console #### What this PR does / why we need it: 在身份认证的列表中隐藏本地身份认证的启用/禁用开关。 <img width="1402" alt="image" src="https://user-images.githubusercontent.com/21301288/226804384-e12ea447-d7ad-4429-82bc-2621fcca84dc.png"> #### Which issue(s) this PR fixes: Fixes #3557 #### Does this PR introduce a user-facing change? ```release-note None ```pull/3561/head
parent
5b3b473cb3
commit
fbe8e627e8
|
@ -23,6 +23,8 @@ import run.halo.app.extension.GVK;
|
||||||
singular = "authprovider", plural = "authproviders")
|
singular = "authprovider", plural = "authproviders")
|
||||||
public class AuthProvider extends AbstractExtension {
|
public class AuthProvider extends AbstractExtension {
|
||||||
|
|
||||||
|
public static final String PRIVILEGED_LABEL = "auth.halo.run/privileged";
|
||||||
|
|
||||||
@Schema(requiredMode = REQUIRED)
|
@Schema(requiredMode = REQUIRED)
|
||||||
private AuthProviderSpec spec;
|
private AuthProviderSpec spec;
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import java.util.Set;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.apache.commons.lang3.BooleanUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.lang.NonNull;
|
import org.springframework.lang.NonNull;
|
||||||
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
|
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
|
||||||
|
@ -18,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.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;
|
||||||
import run.halo.app.infra.utils.JsonUtils;
|
import run.halo.app.infra.utils.JsonUtils;
|
||||||
|
@ -104,13 +106,28 @@ public class AuthProviderServiceImpl implements AuthProviderService {
|
||||||
return client.fetch(ConfigMap.class, SystemSetting.SYSTEM_CONFIG)
|
return client.fetch(ConfigMap.class, SystemSetting.SYSTEM_CONFIG)
|
||||||
.flatMap(configMap -> {
|
.flatMap(configMap -> {
|
||||||
SystemSetting.AuthProvider authProvider = getAuthProvider(configMap);
|
SystemSetting.AuthProvider authProvider = getAuthProvider(configMap);
|
||||||
final Map<String, String> data = configMap.getData();
|
|
||||||
consumer.accept(authProvider.getEnabled());
|
consumer.accept(authProvider.getEnabled());
|
||||||
data.put(SystemSetting.AuthProvider.GROUP, JsonUtils.objectToJson(authProvider));
|
return fetchPrivilegedProviders()
|
||||||
return client.update(configMap);
|
.doOnNext(privileged -> {
|
||||||
|
authProvider.getEnabled().addAll(privileged);
|
||||||
|
})
|
||||||
|
.then(Mono.defer(() -> {
|
||||||
|
final Map<String, String> data = configMap.getData();
|
||||||
|
data.put(SystemSetting.AuthProvider.GROUP,
|
||||||
|
JsonUtils.objectToJson(authProvider));
|
||||||
|
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())
|
||||||
|
@ -124,9 +141,15 @@ public class AuthProviderServiceImpl implements AuthProviderService {
|
||||||
.unbindingUrl(authProvider.getSpec().getUnbindUrl())
|
.unbindingUrl(authProvider.getSpec().getUnbindUrl())
|
||||||
.isBound(false)
|
.isBound(false)
|
||||||
.enabled(false)
|
.enabled(false)
|
||||||
|
.privileged(privileged(authProvider))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean privileged(AuthProvider authProvider) {
|
||||||
|
return BooleanUtils.TRUE.equals(MetadataUtil.nullSafeLabels(authProvider)
|
||||||
|
.get(AuthProvider.PRIVILEGED_LABEL));
|
||||||
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private static SystemSetting.AuthProvider getAuthProvider(ConfigMap configMap) {
|
private static SystemSetting.AuthProvider getAuthProvider(ConfigMap configMap) {
|
||||||
if (configMap.getData() == null) {
|
if (configMap.getData() == null) {
|
||||||
|
@ -146,8 +169,6 @@ public class AuthProviderServiceImpl implements AuthProviderService {
|
||||||
if (authProvider.getEnabled() == null) {
|
if (authProvider.getEnabled() == null) {
|
||||||
authProvider.setEnabled(new HashSet<>());
|
authProvider.setEnabled(new HashSet<>());
|
||||||
}
|
}
|
||||||
// default enable local auth provider
|
|
||||||
authProvider.getEnabled().add("local");
|
|
||||||
return authProvider;
|
return authProvider;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,4 +38,6 @@ public class ListedAuthProvider {
|
||||||
Boolean isBound;
|
Boolean isBound;
|
||||||
|
|
||||||
Boolean enabled;
|
Boolean enabled;
|
||||||
|
|
||||||
|
Boolean privileged;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@ apiVersion: auth.halo.run/v1alpha1
|
||||||
kind: AuthProvider
|
kind: AuthProvider
|
||||||
metadata:
|
metadata:
|
||||||
name: local
|
name: local
|
||||||
|
labels:
|
||||||
|
auth.halo.run/privileged: "true"
|
||||||
finalizers:
|
finalizers:
|
||||||
- system-protection
|
- system-protection
|
||||||
spec:
|
spec:
|
||||||
|
|
|
@ -57,6 +57,10 @@ class AuthProviderServiceImplTest {
|
||||||
when(client.fetch(eq(ConfigMap.class), eq(SystemSetting.SYSTEM_CONFIG)))
|
when(client.fetch(eq(ConfigMap.class), eq(SystemSetting.SYSTEM_CONFIG)))
|
||||||
.thenReturn(Mono.just(configMap));
|
.thenReturn(Mono.just(configMap));
|
||||||
|
|
||||||
|
AuthProvider local = createAuthProvider("local");
|
||||||
|
local.getMetadata().getLabels().put(AuthProvider.PRIVILEGED_LABEL, "true");
|
||||||
|
when(client.list(eq(AuthProvider.class), any(), any())).thenReturn(Flux.just(local));
|
||||||
|
|
||||||
// Call the method being tested
|
// Call the method being tested
|
||||||
Mono<AuthProvider> result = authProviderService.enable("github");
|
Mono<AuthProvider> result = authProviderService.enable("github");
|
||||||
|
|
||||||
|
@ -78,6 +82,10 @@ class AuthProviderServiceImplTest {
|
||||||
AuthProvider authProvider = createAuthProvider("github");
|
AuthProvider authProvider = createAuthProvider("github");
|
||||||
when(client.get(eq(AuthProvider.class), eq("github"))).thenReturn(Mono.just(authProvider));
|
when(client.get(eq(AuthProvider.class), eq("github"))).thenReturn(Mono.just(authProvider));
|
||||||
|
|
||||||
|
AuthProvider local = createAuthProvider("local");
|
||||||
|
local.getMetadata().getLabels().put(AuthProvider.PRIVILEGED_LABEL, "true");
|
||||||
|
when(client.list(eq(AuthProvider.class), any(), any())).thenReturn(Flux.just(local));
|
||||||
|
|
||||||
ArgumentCaptor<ConfigMap> captor = ArgumentCaptor.forClass(ConfigMap.class);
|
ArgumentCaptor<ConfigMap> captor = ArgumentCaptor.forClass(ConfigMap.class);
|
||||||
when(client.update(captor.capture())).thenReturn(Mono.empty());
|
when(client.update(captor.capture())).thenReturn(Mono.empty());
|
||||||
|
|
||||||
|
@ -135,19 +143,22 @@ class AuthProviderServiceImplTest {
|
||||||
"displayName": "github",
|
"displayName": "github",
|
||||||
"bindingUrl": "fake-binding-url",
|
"bindingUrl": "fake-binding-url",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"isBound": false
|
"isBound": false,
|
||||||
|
"privileged": false
|
||||||
}, {
|
}, {
|
||||||
"name": "gitlab",
|
"name": "gitlab",
|
||||||
"displayName": "gitlab",
|
"displayName": "gitlab",
|
||||||
"bindingUrl": "fake-binding-url",
|
"bindingUrl": "fake-binding-url",
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"isBound": false
|
"isBound": false,
|
||||||
|
"privileged": false
|
||||||
},{
|
},{
|
||||||
|
|
||||||
"name": "gitee",
|
"name": "gitee",
|
||||||
"displayName": "gitee",
|
"displayName": "gitee",
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"isBound": false
|
"isBound": false,
|
||||||
|
"privileged": false
|
||||||
}]
|
}]
|
||||||
""",
|
""",
|
||||||
JsonUtils.objectToJson(result),
|
JsonUtils.objectToJson(result),
|
||||||
|
@ -163,6 +174,7 @@ class AuthProviderServiceImplTest {
|
||||||
AuthProvider authProvider = new AuthProvider();
|
AuthProvider authProvider = new AuthProvider();
|
||||||
authProvider.setMetadata(new Metadata());
|
authProvider.setMetadata(new Metadata());
|
||||||
authProvider.getMetadata().setName(name);
|
authProvider.getMetadata().setName(name);
|
||||||
|
authProvider.getMetadata().setLabels(new HashMap<>());
|
||||||
authProvider.setSpec(new AuthProvider.AuthProviderSpec());
|
authProvider.setSpec(new AuthProvider.AuthProviderSpec());
|
||||||
authProvider.getSpec().setDisplayName(name);
|
authProvider.getSpec().setDisplayName(name);
|
||||||
return authProvider;
|
return authProvider;
|
||||||
|
|
|
@ -72,6 +72,12 @@ export interface ListedAuthProvider {
|
||||||
* @memberof ListedAuthProvider
|
* @memberof ListedAuthProvider
|
||||||
*/
|
*/
|
||||||
name: string;
|
name: string;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {boolean}
|
||||||
|
* @memberof ListedAuthProvider
|
||||||
|
*/
|
||||||
|
privileged?: boolean;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @type {string}
|
* @type {string}
|
||||||
|
|
|
@ -870,6 +870,8 @@ core:
|
||||||
title: Are you sure you want to enable this identity authentication method?
|
title: Are you sure you want to enable this identity authentication method?
|
||||||
disable:
|
disable:
|
||||||
title: Are you sure you want to disable this identity authentication method?
|
title: Are you sure you want to disable this identity authentication method?
|
||||||
|
disable_privileged:
|
||||||
|
tooltip: The authentication method reserved by the system cannot be disabled
|
||||||
detail:
|
detail:
|
||||||
fields:
|
fields:
|
||||||
display_name: Display name
|
display_name: Display name
|
||||||
|
|
|
@ -870,6 +870,8 @@ core:
|
||||||
title: 确定要启用该身份认证方式吗?
|
title: 确定要启用该身份认证方式吗?
|
||||||
disable:
|
disable:
|
||||||
title: 确定要停用该身份认证方式吗?
|
title: 确定要停用该身份认证方式吗?
|
||||||
|
disable_privileged:
|
||||||
|
tooltip: 系统保留的认证方式,无法禁用
|
||||||
detail:
|
detail:
|
||||||
fields:
|
fields:
|
||||||
display_name: 名称
|
display_name: 名称
|
||||||
|
|
|
@ -76,11 +76,18 @@ const handleChangeStatus = async () => {
|
||||||
</VEntityField>
|
</VEntityField>
|
||||||
</template>
|
</template>
|
||||||
<template #end>
|
<template #end>
|
||||||
<VEntityField v-permission="['system:plugins:manage']">
|
<VEntityField>
|
||||||
<template #description>
|
<template #description>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<VSwitch
|
<VSwitch
|
||||||
|
v-tooltip="{
|
||||||
|
disabled: !authProvider.privileged,
|
||||||
|
content: $t(
|
||||||
|
'core.identity_authentication.operations.disable_privileged.tooltip'
|
||||||
|
),
|
||||||
|
}"
|
||||||
:model-value="authProvider.enabled"
|
:model-value="authProvider.enabled"
|
||||||
|
:disabled="authProvider.privileged"
|
||||||
@click="handleChangeStatus"
|
@click="handleChangeStatus"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue