This is an automated email from the ASF dual-hosted git repository. xiangying pushed a commit to branch branch-0.5.0 in repository https://gitbox.apache.org/repos/asf/pulsar-manager.git
commit 98a37711cfa9a8aea292411cfba692bcceb6144d Author: Marko Urh <urh.ma...@gmail.com> AuthorDate: Mon May 6 13:49:14 2024 +0200 feat: support seeding default superuser via application.properties (#565) * feat: support default superuser * seed only necessary props add enable flag * remove obsolete pulsar-manager.account * import * fix build - imports * disable superuser seed flag by default * queue pr checks * adjust check (cherry picked from commit 5e3eebd4ecb94afbcc677feb71034e5693c43d69) --- src/README.md | 16 ++-- .../pulsar/manager/PulsarApplicationListener.java | 89 ++++++++++++++++++++-- .../pulsar/manager/controller/LoginController.java | 6 -- .../pulsar/manager/controller/UsersController.java | 6 -- src/main/resources/application.properties | 12 +-- 5 files changed, 95 insertions(+), 34 deletions(-) diff --git a/src/README.md b/src/README.md index 319f4f7..9689209 100644 --- a/src/README.md +++ b/src/README.md @@ -8,15 +8,13 @@ Pulsar manager backend is a supplement and improvement to Pulsar broker. ### Supported configurations of backend -| Name | Default |Description -| ------- | ------- | ------- | -| `server.port` | 7750 | Port of backend service | -| `pulsar-manager.account` | pulsar | Login account | -| `pulsar-manager.password` | pulsar | Login password | -| `redirect.host` | localhost | IP address of front-end service | -| `redirect.port` | 9527 | Port of front-end service | -| `insert.stats.interval` | 30000ms | Time interval for collecting statistical information | -| `clear.stats.interval` | 300000ms | Time interval for cleaning statistics | +| Name | Default | Description | +| ----------------------- | --------- | ---------------------------------------------------- | +| `server.port` | 7750 | Port of backend service | +| `redirect.host` | localhost | IP address of front-end service | +| `redirect.port` | 9527 | Port of front-end service | +| `insert.stats.interval` | 30000ms | Time interval for collecting statistical information | +| `clear.stats.interval` | 300000ms | Time interval for cleaning statistics | ### How to set parameters when starting back-end services diff --git a/src/main/java/org/apache/pulsar/manager/PulsarApplicationListener.java b/src/main/java/org/apache/pulsar/manager/PulsarApplicationListener.java index 9f3941a..912061e 100644 --- a/src/main/java/org/apache/pulsar/manager/PulsarApplicationListener.java +++ b/src/main/java/org/apache/pulsar/manager/PulsarApplicationListener.java @@ -13,19 +13,28 @@ */ package org.apache.pulsar.manager; -import com.github.pagehelper.Page; -import lombok.extern.slf4j.Slf4j; +import java.util.Map; +import java.util.Optional; + +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.lang.StringUtils; import org.apache.pulsar.client.admin.PulsarAdminException; import org.apache.pulsar.manager.entity.EnvironmentEntity; import org.apache.pulsar.manager.entity.EnvironmentsRepository; +import org.apache.pulsar.manager.entity.UserInfoEntity; +import org.apache.pulsar.manager.entity.UsersRepository; import org.apache.pulsar.manager.service.PulsarAdminService; +import org.apache.pulsar.manager.service.UsersService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.stereotype.Component; -import java.util.Optional; +import com.github.pagehelper.Page; + +import lombok.extern.slf4j.Slf4j; + /** * PulsarApplicationListener do something after the spring framework initialization is complete. @@ -38,6 +47,10 @@ public class PulsarApplicationListener implements ApplicationListener<ContextRef private final PulsarAdminService pulsarAdminService; + private final UsersRepository usersRepository; + + private final UsersService usersService; + @Value("${default.environment.name}") private String defaultEnvironmentName; @@ -47,20 +60,79 @@ public class PulsarApplicationListener implements ApplicationListener<ContextRef @Value("${default.environment.bookie_url}") private String defaultEnvironmentBookieUrl; + @Value("${default.superuser.enable}") + private Boolean defaultSuperuserEnable = false; + + @Value("${default.superuser.name}") + private String defaultSuperuserName; + + @Value("${default.superuser.email}") + private String defaultSuperuserEmail; + + @Value("${default.superuser.password}") + private String defaultSuperuserPassword; + @Autowired - public PulsarApplicationListener(EnvironmentsRepository environmentsRepository, PulsarAdminService pulsarAdminService) { + public PulsarApplicationListener( + EnvironmentsRepository environmentsRepository, + PulsarAdminService pulsarAdminService, + UsersRepository usersRepository, + UsersService usersService + ) { this.environmentsRepository = environmentsRepository; this.pulsarAdminService = pulsarAdminService; + this.usersRepository = usersRepository; + this.usersService = usersService; } @Override public void onApplicationEvent(ContextRefreshedEvent event) { log.info("Start onApplicationEvent"); - Page<EnvironmentEntity> environmentEntities = environmentsRepository - .getEnvironmentsList(1, 1); + + seedDefaultSuperuser(); + seedDefaultEnvironment(); + } + + private void seedDefaultSuperuser() { + if(defaultSuperuserEnable == false) { + log.debug("Superuser seed disabled"); + return; + } + + UserInfoEntity userInfoEntity = new UserInfoEntity(); + userInfoEntity.setName(defaultSuperuserName); + userInfoEntity.setEmail(defaultSuperuserEmail); + userInfoEntity.setPassword(defaultSuperuserPassword); + + Map<String, String> userValidateResult = usersService.validateUserInfo(userInfoEntity); + if (userValidateResult.get("error") != null) { + log.error("Superuser seed failed.", userValidateResult.get("error")); + System.exit(-1); + } + if (StringUtils.isBlank(userInfoEntity.getPassword())) { + log.error("Superuser seed failed. Password is required."); + System.exit(-1); + } + + Optional<UserInfoEntity> optionalUserEntity = usersRepository.findByUserName(userInfoEntity.getName()); + if (optionalUserEntity.isPresent()) { + log.warn("Superuser already exists."); + return; + } + + userInfoEntity.setPassword(DigestUtils.sha256Hex(userInfoEntity.getPassword())); + usersRepository.save(userInfoEntity); + + log.info("Successfully added a default superuser: name = {}, email = {}, password = {}.", + defaultSuperuserName, defaultSuperuserEmail, defaultSuperuserPassword); + } + + private void seedDefaultEnvironment() { + Page<EnvironmentEntity> environmentEntities = environmentsRepository.getEnvironmentsList(1, 1); + if (environmentEntities.getResult().size() <= 0) { - Optional<EnvironmentEntity> environmentEntityOptional = environmentsRepository - .findByName(defaultEnvironmentName); + Optional<EnvironmentEntity> environmentEntityOptional = environmentsRepository.findByName(defaultEnvironmentName); + if (defaultEnvironmentName != null && defaultEnvironmentServiceUrl != null && defaultEnvironmentName.length() > 0 @@ -89,6 +161,7 @@ public class PulsarApplicationListener implements ApplicationListener<ContextRef log.warn("The default environment already exists."); } } + log.debug("Environments already exist."); } } diff --git a/src/main/java/org/apache/pulsar/manager/controller/LoginController.java b/src/main/java/org/apache/pulsar/manager/controller/LoginController.java index 08e8563..893ed02 100644 --- a/src/main/java/org/apache/pulsar/manager/controller/LoginController.java +++ b/src/main/java/org/apache/pulsar/manager/controller/LoginController.java @@ -65,12 +65,6 @@ public class LoginController { @Autowired private CasdoorAuthService casdoorAuthService; - @Value("${pulsar-manager.account}") - private String account; - - @Value("${pulsar-manager.password}") - private String password; - @ApiOperation(value = "Login pulsar manager") @ApiResponses({@ApiResponse(code = 200, message = "ok"), @ApiResponse(code = 500, message = "Internal server error")}) @RequestMapping(value = "/login", method = RequestMethod.POST) diff --git a/src/main/java/org/apache/pulsar/manager/controller/UsersController.java b/src/main/java/org/apache/pulsar/manager/controller/UsersController.java index 21f2f24..1203220 100644 --- a/src/main/java/org/apache/pulsar/manager/controller/UsersController.java +++ b/src/main/java/org/apache/pulsar/manager/controller/UsersController.java @@ -54,12 +54,6 @@ import java.util.Set; @Api(description = "Functions under this class are available to super user.") public class UsersController { - @Value("${user.management.enable}") - private boolean userManagementEnable; - - @Value("${pulsar-manager.account}") - private String account; - private final UsersRepository usersRepository; private final UsersService usersService; diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index b038a25..80828a2 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -84,11 +84,6 @@ backend.broker.pulsarAdmin.tlsEnableHostnameVerification=false jwt.secret=dab1c8ba-b01b-11e9-b384-186590e06885 jwt.sessionTime=2592000 -# If user.management.enable is true, the following account and password will no longer be valid. -pulsar-manager.account=pulsar -pulsar-manager.password=pulsar -# If true, the database is used for user management -user.management.enable=true # Optional -> SECRET, PRIVATE, default -> PRIVATE, empty -> disable auth # SECRET mode -> bin/pulsar tokens create --secret-key file:///path/to/my-secret.key --subject test-user @@ -132,6 +127,13 @@ spring.thymeleaf.mode=HTML5 default.environment.name= default.environment.service_url= default.environment.bookie_url= + +# default superuser configuration +default.superuser.enable= +default.superuser.name= +default.superuser.password= +default.superuser.email= + # enable tls encryption # keytool -import -alias test-keystore -keystore ca-certs -file certs/ca.cert.pem tls.enabled=false