[ISSUES-3623] Project management encrypts user warehouse passwords (#3630)
* [ISSUES-3623] Project management encrypts user warehouse passwords
* [ISSUES-3623] Project management encrypts user warehouse passwords
* [ISSUES-3623] checkstyle & spotless:apply
---------
Co-authored-by: jianjun.xu <jianjun.xu@ly.com>
diff --git a/streampark-console/streampark-console-service/src/main/assembly/script/data/mysql-data.sql b/streampark-console/streampark-console-service/src/main/assembly/script/data/mysql-data.sql
index b478103..8b232c9 100644
--- a/streampark-console/streampark-console-service/src/main/assembly/script/data/mysql-data.sql
+++ b/streampark-console/streampark-console-service/src/main/assembly/script/data/mysql-data.sql
@@ -40,7 +40,7 @@
-- ----------------------------
-- Records of t_flink_project
-- ----------------------------
-insert into `t_flink_project` values (100000, 100000, 'streampark-quickstart', 'https://github.com/apache/incubator-streampark-quickstart', 'release-2.0.0', null, null, null, null, null, 1, 1, null, 'streampark-quickstart', -1, now(), now());
+insert into `t_flink_project` values (100000, 100000, 'streampark-quickstart', 'https://github.com/apache/incubator-streampark-quickstart', 'release-2.0.0', null, null, null, null, null, null, 1, 1, null, 'streampark-quickstart', -1, now(), now());
-- ----------------------------
-- Records of t_flink_sql
@@ -87,10 +87,10 @@
insert into `t_menu` values (130300, 130000, 'resource.upload', '/resource/upload', 'resource/upload/View', null, null, '0', 1, 3, now(), now());
insert into `t_menu` values (130101, 130100, 'project view', null, null, 'project:view', null, '1', 1, null, now(), now());
-insert into `t_menu` values (130102, 130100, 'project add', '/project/add', 'project/Add', 'project:create', '', '0', 0, null, now(), now());
+insert into `t_menu` values (130102, 130100, 'project add', '/project/add', 'resource/project/Add', 'project:create', '', '0', 0, null, now(), now());
insert into `t_menu` values (130103, 130100, 'project build', null, null, 'project:build', null, '1', 1, null, now(), now());
insert into `t_menu` values (130104, 130100, 'project delete', null, null, 'project:delete', null, '1', 1, null, now(), now());
-insert into `t_menu` values (130105, 130100, 'project edit', '/project/edit', 'project/Edit', 'project:update', null, '0', 0, null, now(), now());
+insert into `t_menu` values (130105, 130100, 'project edit', '/project/edit', 'resource/project/Edit', 'project:update', null, '0', 0, null, now(), now());
insert into `t_menu` values (130201, 130200, 'variable view', NULL, NULL, 'variable:view', NULL, '1', 1, null, now(), now());
insert into `t_menu` values (130202, 130200, 'variable depend view', null, null, 'variable:depend_apps', null, '1', 1, NULL, now(), now());
diff --git a/streampark-console/streampark-console-service/src/main/assembly/script/data/pgsql-data.sql b/streampark-console/streampark-console-service/src/main/assembly/script/data/pgsql-data.sql
index d9105e5..ee914d3 100644
--- a/streampark-console/streampark-console-service/src/main/assembly/script/data/pgsql-data.sql
+++ b/streampark-console/streampark-console-service/src/main/assembly/script/data/pgsql-data.sql
@@ -35,7 +35,7 @@
-- ----------------------------
-- Records of t_flink_project
-- ----------------------------
-insert into "public"."t_flink_project" values (100000, 100000, 'streampark-quickstart', 'https://github.com/apache/incubator-streampark-quickstart', 'release-2.0.0', null, null, null, null, null, 1, 1, null, 'streampark-quickstart', -1, now(), now());
+insert into "public"."t_flink_project" values (100000, 100000, 'streampark-quickstart', 'https://github.com/apache/incubator-streampark-quickstart', 'release-2.0.0', null, null, null, null, null, null, 1, 1, null, 'streampark-quickstart', -1, now(), now());
-- ----------------------------
@@ -87,10 +87,10 @@
insert into "public"."t_menu" values (110603, 110600, 'delete', null, null, 'member:delete', null, '1', '1', null, now(), now());
insert into "public"."t_menu" values (110604, 110600, 'role view', null, null, 'role:view', null, '1', '1', null, now(), now());
insert into "public"."t_menu" values (110605, 110600, 'view', null, null, 'member:view', null, '1', '1', null, now(), now());
-insert into "public"."t_menu" values (120101, 120100, 'add', '/flink/project/add', 'flink/project/Add', 'project:create', '', '0', '0', null, now(), now());
+insert into "public"."t_menu" values (120101, 120100, 'add', '/flink/project/add', 'resource/project/Add', 'project:create', '', '0', '0', null, now(), now());
insert into "public"."t_menu" values (120102, 120100, 'build', null, null, 'project:build', null, '1', '1', null, now(), now());
insert into "public"."t_menu" values (120103, 120100, 'delete', null, null, 'project:delete', null, '1', '1', null, now(), now());
-insert into "public"."t_menu" values (120104, 120100, 'edit', '/flink/project/edit', 'flink/project/Edit', 'project:update', null, '0', '0', null, now(), now());
+insert into "public"."t_menu" values (120104, 120100, 'edit', '/flink/project/edit', 'resource/project/Edit', 'project:update', null, '0', '0', null, now(), now());
insert into "public"."t_menu" values (120105, 120100, 'view', null, null, 'project:view', null, '1', '1', null, now(), now());
insert into "public"."t_menu" values (120201, 120200, 'add', '/flink/app/add', 'flink/app/Add', 'app:create', '', '0', '0', null, now(), now());
insert into "public"."t_menu" values (120202, 120200, 'detail app', '/flink/app/detail', 'flink/app/Detail', 'app:detail', '', '0', '0', null, now(), now());
diff --git a/streampark-console/streampark-console-service/src/main/assembly/script/schema/mysql-schema.sql b/streampark-console/streampark-console-service/src/main/assembly/script/schema/mysql-schema.sql
index ac4e5f2..08fce99 100644
--- a/streampark-console/streampark-console-service/src/main/assembly/script/schema/mysql-schema.sql
+++ b/streampark-console/streampark-console-service/src/main/assembly/script/schema/mysql-schema.sql
@@ -189,8 +189,9 @@
`url` varchar(255) collate utf8mb4_general_ci default null,
`branches` varchar(64) collate utf8mb4_general_ci default null,
`user_name` varchar(64) collate utf8mb4_general_ci default null,
- `password` varchar(64) collate utf8mb4_general_ci default null,
+ `password` varchar(512) collate utf8mb4_general_ci default null,
`prvkey_path` varchar(128) collate utf8mb4_general_ci default null,
+ `salt` varchar(26) collate utf8mb4_general_ci default null,
`pom` varchar(255) collate utf8mb4_general_ci default null,
`build_args` varchar(255) default null,
`type` tinyint default null,
diff --git a/streampark-console/streampark-console-service/src/main/assembly/script/schema/pgsql-schema.sql b/streampark-console/streampark-console-service/src/main/assembly/script/schema/pgsql-schema.sql
index 3b4608b..c3eb9dc 100644
--- a/streampark-console/streampark-console-service/src/main/assembly/script/schema/pgsql-schema.sql
+++ b/streampark-console/streampark-console-service/src/main/assembly/script/schema/pgsql-schema.sql
@@ -434,8 +434,9 @@
"url" varchar(255) collate "pg_catalog"."default",
"branches" varchar(64) collate "pg_catalog"."default",
"user_name" varchar(64) collate "pg_catalog"."default",
- "password" varchar(64) collate "pg_catalog"."default",
+ "password" varchar(512) collate "pg_catalog"."default",
"prvkey_path" varchar(128) collate "pg_catalog"."default",
+ "salt" varchar(26) collate "pg_catalog"."default",
"pom" varchar(255) collate "pg_catalog"."default",
"build_args" varchar(255) collate "pg_catalog"."default",
"type" int2,
diff --git a/streampark-console/streampark-console-service/src/main/assembly/script/upgrade/mysql/2.2.2.sql b/streampark-console/streampark-console-service/src/main/assembly/script/upgrade/mysql/2.2.2.sql
index d4707a8..5c6652f 100644
--- a/streampark-console/streampark-console-service/src/main/assembly/script/upgrade/mysql/2.2.2.sql
+++ b/streampark-console/streampark-console-service/src/main/assembly/script/upgrade/mysql/2.2.2.sql
@@ -244,3 +244,7 @@
alter table `t_flink_log`
add column `user_id` bigint default null comment 'operator user id';
+
+alter table `t_flink_project`
+ add column `salt` varchar(26) collate utf8mb4_general_ci default null comment 'password salt',
+ modify column `password` varchar(512) collate utf8mb4_general_ci default null comment 'password';
diff --git a/streampark-console/streampark-console-service/src/main/assembly/script/upgrade/pgsql/2.2.2.sql b/streampark-console/streampark-console-service/src/main/assembly/script/upgrade/pgsql/2.2.2.sql
index c8d023b..bc69fb9 100644
--- a/streampark-console/streampark-console-service/src/main/assembly/script/upgrade/pgsql/2.2.2.sql
+++ b/streampark-console/streampark-console-service/src/main/assembly/script/upgrade/pgsql/2.2.2.sql
@@ -22,3 +22,11 @@
add column "user_id" int8 collate "pg_catalog"."default";
comment on column "public"."t_flink_log"."user_id" is 'operator user id';
+
+alter table "public"."t_flink_project"
+ add column `salt` varchar(26) collate "pg_catalog"."default";
+
+comment on column "public"."t_flink_project"."salt" is 'password salt';
+
+alter table "public"."t_flink_project"
+ alter column `password` type varchar(512) collate "pg_catalog"."default";
diff --git a/streampark-console/streampark-console-service/src/main/java/org/apache/streampark/console/base/util/GitUtils.java b/streampark-console/streampark-console-service/src/main/java/org/apache/streampark/console/base/util/GitUtils.java
index 4fa5548..72dc1f1 100644
--- a/streampark-console/streampark-console-service/src/main/java/org/apache/streampark/console/base/util/GitUtils.java
+++ b/streampark-console/streampark-console-service/src/main/java/org/apache/streampark/console/base/util/GitUtils.java
@@ -84,9 +84,18 @@
private static void setCredentials(TransportCommand<?, ?> transportCommand, Project project) {
if (project.isHttpRepositoryUrl()) {
if (!StringUtils.isAllEmpty(project.getUserName(), project.getPassword())) {
- UsernamePasswordCredentialsProvider credentialsProvider =
- new UsernamePasswordCredentialsProvider(project.getUserName(), project.getPassword());
- transportCommand.setCredentialsProvider(credentialsProvider);
+ try {
+ String decrypt =
+ StringUtils.isNotBlank(project.getSalt())
+ ? EncryptUtils.decrypt(project.getPassword(), project.getSalt())
+ : project.getPassword();
+ UsernamePasswordCredentialsProvider credentialsProvider =
+ new UsernamePasswordCredentialsProvider(project.getUserName(), decrypt);
+ transportCommand.setCredentialsProvider(credentialsProvider);
+ } catch (Exception e) {
+ throw new IllegalStateException(
+ "[StreamPark] git setCredentials: project password decrypt failed", e);
+ }
}
} else if (project.isSshRepositoryUrl()) {
transportCommand.setTransportConfigCallback(
diff --git a/streampark-console/streampark-console-service/src/main/java/org/apache/streampark/console/core/controller/ProjectController.java b/streampark-console/streampark-console-service/src/main/java/org/apache/streampark/console/core/controller/ProjectController.java
index bbbb2f9..191e8ae 100644
--- a/streampark-console/streampark-console-service/src/main/java/org/apache/streampark/console/core/controller/ProjectController.java
+++ b/streampark-console/streampark-console-service/src/main/java/org/apache/streampark/console/core/controller/ProjectController.java
@@ -105,7 +105,7 @@
@Operation(summary = "List git project branches")
@PostMapping("branches")
public RestResponse branches(Project project) {
- List<String> branches = project.getAllBranches();
+ List<String> branches = projectService.getAllBranches(project);
return RestResponse.success().data(branches);
}
@@ -120,7 +120,7 @@
@Operation(summary = "Authenticate git project")
@PostMapping("gitcheck")
public RestResponse gitCheck(Project project) {
- GitAuthorizedErrorEnum error = project.gitCheck();
+ GitAuthorizedErrorEnum error = projectService.gitCheck(project);
return RestResponse.success().data(error.getType());
}
diff --git a/streampark-console/streampark-console-service/src/main/java/org/apache/streampark/console/core/entity/Project.java b/streampark-console/streampark-console-service/src/main/java/org/apache/streampark/console/core/entity/Project.java
index 9f5bd6c..8efaa0e 100644
--- a/streampark-console/streampark-console-service/src/main/java/org/apache/streampark/console/core/entity/Project.java
+++ b/streampark-console/streampark-console-service/src/main/java/org/apache/streampark/console/core/entity/Project.java
@@ -77,6 +77,9 @@
@TableField(updateStrategy = FieldStrategy.IGNORED)
private String prvkeyPath;
+ /** No salt value is returned */
+ @JsonIgnore private String salt;
+
/** 1:git 2:svn */
private Integer repository;
diff --git a/streampark-console/streampark-console-service/src/main/java/org/apache/streampark/console/core/service/ProjectService.java b/streampark-console/streampark-console-service/src/main/java/org/apache/streampark/console/core/service/ProjectService.java
index ec9d096..6767b24 100644
--- a/streampark-console/streampark-console-service/src/main/java/org/apache/streampark/console/core/service/ProjectService.java
+++ b/streampark-console/streampark-console-service/src/main/java/org/apache/streampark/console/core/service/ProjectService.java
@@ -21,6 +21,7 @@
import org.apache.streampark.console.base.domain.RestResponse;
import org.apache.streampark.console.core.entity.Application;
import org.apache.streampark.console.core.entity.Project;
+import org.apache.streampark.console.core.enums.GitAuthorizedErrorEnum;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
@@ -145,4 +146,20 @@
* @return whether the corresponding project exists
*/
boolean exists(Project project);
+
+ /**
+ * Gets branch information under the project
+ *
+ * @param project Project
+ * @return branch information under the project
+ */
+ List<String> getAllBranches(Project project);
+
+ /**
+ * Check git
+ *
+ * @param project Project
+ * @return Check git
+ */
+ GitAuthorizedErrorEnum gitCheck(Project project);
}
diff --git a/streampark-console/streampark-console-service/src/main/java/org/apache/streampark/console/core/service/impl/ProjectServiceImpl.java b/streampark-console/streampark-console-service/src/main/java/org/apache/streampark/console/core/service/impl/ProjectServiceImpl.java
index 778b1a0..1bc0478 100644
--- a/streampark-console/streampark-console-service/src/main/java/org/apache/streampark/console/core/service/impl/ProjectServiceImpl.java
+++ b/streampark-console/streampark-console-service/src/main/java/org/apache/streampark/console/core/service/impl/ProjectServiceImpl.java
@@ -28,11 +28,16 @@
import org.apache.streampark.console.base.domain.RestRequest;
import org.apache.streampark.console.base.domain.RestResponse;
import org.apache.streampark.console.base.exception.ApiAlertException;
+import org.apache.streampark.console.base.exception.ApiDetailException;
import org.apache.streampark.console.base.mybatis.pager.MybatisPager;
+import org.apache.streampark.console.base.util.EncryptUtils;
import org.apache.streampark.console.base.util.GZipUtils;
+import org.apache.streampark.console.base.util.GitUtils;
+import org.apache.streampark.console.base.util.ShaHashUtils;
import org.apache.streampark.console.core.entity.Application;
import org.apache.streampark.console.core.entity.Project;
import org.apache.streampark.console.core.enums.BuildStateEnum;
+import org.apache.streampark.console.core.enums.GitAuthorizedErrorEnum;
import org.apache.streampark.console.core.enums.ReleaseStateEnum;
import org.apache.streampark.console.core.mapper.ProjectMapper;
import org.apache.streampark.console.core.service.ProjectService;
@@ -40,6 +45,7 @@
import org.apache.streampark.console.core.task.ProjectBuildTask;
import org.apache.streampark.console.core.watcher.FlinkAppHttpWatcher;
+import org.apache.commons.lang3.StringUtils;
import org.apache.flink.configuration.MemorySize;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -94,7 +100,17 @@
RestResponse response = RestResponse.success();
ApiAlertException.throwIfTrue(count > 0, "project name already exists, add project failed");
-
+ if (StringUtils.isNotBlank(project.getPassword())) {
+ String salt = ShaHashUtils.getRandomSalt();
+ try {
+ String encrypt = EncryptUtils.encrypt(project.getPassword(), salt);
+ project.setSalt(salt);
+ project.setPassword(encrypt);
+ } catch (Exception e) {
+ log.error("Project password decrypt failed", e);
+ throw new ApiAlertException("Project github/gitlab password decrypt failed");
+ }
+ }
Date date = new Date();
project.setCreateTime(date);
project.setModifyTime(date);
@@ -117,6 +133,26 @@
!project.getBuildState().equals(BuildStateEnum.BUILDING.get()),
"The project is being built, update project failed.");
updateInternal(projectParam, project);
+ if (project.isHttpRepositoryUrl()) {
+ if (StringUtils.isBlank(projectParam.getUserName())) {
+ project.setUserName(null);
+ project.setPassword(null);
+ project.setSalt(null);
+ } else {
+ project.setUserName(projectParam.getUserName());
+ if (!Objects.equals(projectParam.getPassword(), project.getPassword())) {
+ try {
+ String salt = ShaHashUtils.getRandomSalt();
+ String encrypt = EncryptUtils.encrypt(projectParam.getPassword(), salt);
+ project.setPassword(encrypt);
+ project.setSalt(salt);
+ } catch (Exception e) {
+ log.error("The project github/gitlab password encrypt failed");
+ throw new ApiAlertException(e);
+ }
+ }
+ }
+ }
if (project.isSshRepositoryUrl()) {
project.setUserName(null);
} else {
@@ -378,4 +414,36 @@
private String getBuildLogPath(Long projectId) {
return String.format("%s/%s/build.log", Workspace.PROJECT_BUILD_LOG_PATH(), projectId);
}
+
+ @Override
+ public List<String> getAllBranches(Project project) {
+ try {
+ return GitUtils.getBranchList(remakeProject(project));
+ } catch (Exception e) {
+ throw new ApiDetailException(e);
+ }
+ }
+
+ @Override
+ public GitAuthorizedErrorEnum gitCheck(Project project) {
+ try {
+ GitUtils.getBranchList(remakeProject(project));
+ return GitAuthorizedErrorEnum.SUCCESS;
+ } catch (Exception e) {
+ String err = e.getMessage();
+ if (err.contains("not authorized")) {
+ return GitAuthorizedErrorEnum.ERROR;
+ } else if (err.contains("Authentication is required")) {
+ return GitAuthorizedErrorEnum.REQUIRED;
+ }
+ return GitAuthorizedErrorEnum.UNKNOW;
+ }
+ }
+
+ private Project remakeProject(Project project) {
+ if (Objects.nonNull(project.getId())) {
+ return this.baseMapper.selectById(project.getId());
+ }
+ return project;
+ }
}
diff --git a/streampark-console/streampark-console-webapp/src/views/resource/project/useProject.tsx b/streampark-console/streampark-console-webapp/src/views/resource/project/useProject.tsx
index 5c04c71..67c3a15 100644
--- a/streampark-console/streampark-console-webapp/src/views/resource/project/useProject.tsx
+++ b/streampark-console/streampark-console-webapp/src/views/resource/project/useProject.tsx
@@ -244,6 +244,7 @@
userName: values.userName || null,
password: values.password || null,
prvkeyPath: values.prvkeyPath || null,
+ id: route?.query?.id || null,
});
if (res === 0) {
if (branchList.value.length === 0) {
@@ -282,8 +283,9 @@
const prvkeyPath = values.prvkeyPath || null;
const userNull = userName === null || userName === undefined || userName === '';
const passNull = password === null || password === undefined || password === '';
+ const id = route?.query?.id || null;
if ((userNull && passNull) || (!userNull && !passNull)) {
- const res = await fetchBranches({ url, userName, password, prvkeyPath });
+ const res = await fetchBranches({ url, userName, password, prvkeyPath, id });
if (res) branchList.value = res.map((i) => ({ label: i, value: i }));
}
}