Skip to content

Commit

Permalink
[ISSUE #11957] AuthModule add admin exist (#12066)
Browse files Browse the repository at this point in the history
* AuthModule add admin exist

* test fix

* fix state

* add state cache

* rename to auth_admin_request

* test fix

* auth_admin_request default value fix

* fix admin request
  • Loading branch information
godhth committed May 24, 2024
1 parent 6bee5c4 commit 992f10a
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,39 @@ public class AuthModuleStateBuilder implements ModuleStateBuilder {

public static final String AUTH_SYSTEM_TYPE = "auth_system_type";

public static final String AUTH_ADMIN_REQUEST = "auth_admin_request";

private boolean cacheable;

@Override
public ModuleState build() {
ModuleState result = new ModuleState(AUTH_MODULE);
AuthConfigs authConfigs = ApplicationUtils.getBean(AuthConfigs.class);
result.newState(AUTH_ENABLED, authConfigs.isAuthEnabled());
result.newState(LOGIN_PAGE_ENABLED, isLoginPageEnabled(authConfigs));
result.newState(AUTH_SYSTEM_TYPE, authConfigs.getNacosAuthSystemType());
result.newState(AUTH_ADMIN_REQUEST, isAdminRequest(authConfigs));
return result;
}

@Override
public boolean isCacheable() {
return cacheable;
}

private Boolean isLoginPageEnabled(AuthConfigs authConfigs) {
Optional<AuthPluginService> authPluginService = AuthPluginManager.getInstance()
.findAuthServiceSpiImpl(authConfigs.getNacosAuthSystemType());
return authPluginService.map(AuthPluginService::isLoginEnabled).orElse(false);
}

private Boolean isAdminRequest(AuthConfigs authConfigs) {
Optional<AuthPluginService> authPluginService = AuthPluginManager.getInstance()
.findAuthServiceSpiImpl(authConfigs.getNacosAuthSystemType());
boolean isAdminRequest = authPluginService.map(AuthPluginService::isAdminRequest).orElse(true);
if (!isAdminRequest) {
cacheable = true;
}
return isAdminRequest;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import static com.alibaba.nacos.auth.config.AuthModuleStateBuilder.AUTH_ENABLED;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
Expand Down Expand Up @@ -57,5 +58,6 @@ void testBuild() {
assertFalse((Boolean) actual.getStates().get(AUTH_ENABLED));
assertFalse((Boolean) actual.getStates().get("login_page_enabled"));
assertEquals("nacos", actual.getStates().get("auth_system_type"));
assertTrue((Boolean) actual.getStates().get("auth_admin_request"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@ public boolean isLoginEnabled() {
return ApplicationUtils.getBean(AuthConfigs.class).isAuthEnabled();
}

@Override
public boolean isAdminRequest() {
return !ApplicationUtils.getBean(IAuthenticationManager.class).hasGlobalAdminRole();
}

protected void checkNacosAuthManager() {
if (null == authenticationManager) {
authenticationManager = ApplicationUtils.getBean(DefaultAuthenticationManager.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,18 +115,16 @@ public Object createUser(@RequestParam String username, @RequestParam String pas
* Create a admin user only not exist admin user can use.
*/
@PostMapping("/admin")
public Object createAdminUser(@RequestParam(required = false) String username,
@RequestParam(required = false) String password) {
public Object createAdminUser(@RequestParam(required = false) String password) {
if (AuthSystemTypes.NACOS.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) {
if (roleService.hasGlobalAdminRole()) {
if (iAuthenticationManager.hasGlobalAdminRole()) {
return RestResultUtils.failed("have admin user cannot use it");
}
if (StringUtils.isBlank(password)) {
password = PasswordGeneratorUtil.generateRandomPassword();
}
if (StringUtils.isBlank(username)) {
username = AuthConstants.DEFAULT_USER;
}

String username = AuthConstants.DEFAULT_USER;
userDetailsService.createUser(username, PasswordEncoderUtil.encode(password));
roleService.addAdminRole(username);
ObjectNode result = JacksonUtils.createEmptyJsonNode();
Expand Down Expand Up @@ -266,10 +264,7 @@ public Object login(@RequestParam String username, @RequestParam String password

if (AuthSystemTypes.NACOS.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())
|| AuthSystemTypes.LDAP.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) {
if (!iAuthenticationManager.hasGlobalAdminRole()) {
response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED, "admin role user not exist");
return null;
}

NacosUser user = iAuthenticationManager.authenticate(request);

response.addHeader(AuthConstants.AUTHORIZATION_HEADER, AuthConstants.TOKEN_PREFIX + user.getToken());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ public void setUp() throws Exception {
public void testLoginWithAuthedUser() throws AccessException, IOException {
when(authenticationManager.authenticate(request)).thenReturn(user);
when(authenticationManager.hasGlobalAdminRole(user)).thenReturn(true);
when(authenticationManager.hasGlobalAdminRole()).thenReturn(true);
when(authConfigs.getNacosAuthSystemType()).thenReturn(AuthSystemTypes.NACOS.name());
when(tokenManagerDelegate.getTokenTtlInSeconds(anyString())).thenReturn(18000L);
Object actual = userController.login("nacos", "nacos", response, request);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,13 @@ public interface AuthPluginService {
default boolean isLoginEnabled() {
return false;
}

/**
* Whether need administrator .
*
* @return if need the administrator role.
*/
default boolean isAdminRequest() {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,14 @@ public interface ModuleStateBuilder {
default boolean isIgnore() {
return false;
}

/**
* Whether module is cache, default return true.
*
* @return boolean
*/
default boolean isCacheable() {
return true;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
Expand All @@ -40,13 +42,16 @@ public class ModuleStateHolder {

private final Map<String, ModuleState> moduleStates;

private final List<ModuleStateBuilder> moduleStateBuilders = new ArrayList<>();

private ModuleStateHolder() {
this.moduleStates = new HashMap<>();
for (ModuleStateBuilder each : NacosServiceLoader.load(ModuleStateBuilder.class)) {
if (each.isIgnore()) {
continue;
}
try {
moduleStateBuilders.add(each);
ModuleState moduleState = each.build();
moduleStates.put(moduleState.getModuleName(), moduleState);
} catch (Exception e) {
Expand All @@ -59,11 +64,28 @@ public static ModuleStateHolder getInstance() {
return INSTANCE;
}

private void reBuildModuleState() {
for (ModuleStateBuilder each : moduleStateBuilders) {
if (each.isCacheable()) {
continue;
}
try {
ModuleState moduleState = each.build();
moduleStates.put(moduleState.getModuleName(), moduleState);
} catch (Exception e) {
LOGGER.warn("reBuild ModuleState failed in builder:{}", each.getClass().getCanonicalName(), e);
}
}

}

public Optional<ModuleState> getModuleState(String moduleName) {
reBuildModuleState();
return Optional.ofNullable(moduleStates.get(moduleName));
}

public Set<ModuleState> getAllModuleStates() {
reBuildModuleState();
return new HashSet<>(moduleStates.values());
}

Expand Down

0 comments on commit 992f10a

Please sign in to comment.