feat: app password use ciphertext

This commit is contained in:
tjq 2024-08-10 14:42:09 +08:00
parent e711ed7251
commit eb4d7ab8eb
14 changed files with 250 additions and 65 deletions

View File

@ -11,6 +11,7 @@ import tech.powerjob.client.service.PowerRequestBody;
import tech.powerjob.client.service.RequestService; import tech.powerjob.client.service.RequestService;
import tech.powerjob.client.service.impl.ClusterRequestServiceOkHttp3Impl; import tech.powerjob.client.service.impl.ClusterRequestServiceOkHttp3Impl;
import tech.powerjob.common.OpenAPIConstant; import tech.powerjob.common.OpenAPIConstant;
import tech.powerjob.common.enums.EncryptType;
import tech.powerjob.common.enums.InstanceStatus; import tech.powerjob.common.enums.InstanceStatus;
import tech.powerjob.common.exception.PowerJobException; import tech.powerjob.common.exception.PowerJobException;
import tech.powerjob.common.request.http.SaveJobInfoRequest; import tech.powerjob.common.request.http.SaveJobInfoRequest;
@ -53,6 +54,7 @@ public class PowerJobClient implements IPowerJobClient {
AppAuthRequest appAuthRequest = new AppAuthRequest(); AppAuthRequest appAuthRequest = new AppAuthRequest();
appAuthRequest.setAppName(appName); appAuthRequest.setAppName(appName);
appAuthRequest.setEncryptedPassword(DigestUtils.md5(config.getPassword())); appAuthRequest.setEncryptedPassword(DigestUtils.md5(config.getPassword()));
appAuthRequest.setEncryptType(EncryptType.MD5.getCode());
String assertResponse = requestService.request(OpenAPIConstant.AUTH_APP, PowerRequestBody.newJsonRequestBody(appAuthRequest)); String assertResponse = requestService.request(OpenAPIConstant.AUTH_APP, PowerRequestBody.newJsonRequestBody(appAuthRequest));

View File

@ -26,6 +26,12 @@ public class AppAuthRequest implements Serializable {
* 加密后密码 * 加密后密码
*/ */
private String encryptedPassword; private String encryptedPassword;
/**
* 加密类型
*/
private String encryptType;
/** /**
* 额外参数方便开发者传递其他参数 * 额外参数方便开发者传递其他参数
*/ */

View File

@ -10,6 +10,7 @@ import tech.powerjob.client.module.AppAuthResult;
import tech.powerjob.client.service.HttpResponse; import tech.powerjob.client.service.HttpResponse;
import tech.powerjob.client.service.PowerRequestBody; import tech.powerjob.client.service.PowerRequestBody;
import tech.powerjob.common.OpenAPIConstant; import tech.powerjob.common.OpenAPIConstant;
import tech.powerjob.common.enums.EncryptType;
import tech.powerjob.common.exception.PowerJobException; import tech.powerjob.common.exception.PowerJobException;
import tech.powerjob.common.response.ResultDTO; import tech.powerjob.common.response.ResultDTO;
import tech.powerjob.common.utils.DigestUtils; import tech.powerjob.common.utils.DigestUtils;
@ -95,6 +96,7 @@ abstract class AppAuthClusterRequestService extends ClusterRequestService {
AppAuthRequest appAuthRequest = new AppAuthRequest(); AppAuthRequest appAuthRequest = new AppAuthRequest();
appAuthRequest.setAppName(config.getAppName()); appAuthRequest.setAppName(config.getAppName());
appAuthRequest.setEncryptedPassword(DigestUtils.md5(config.getPassword())); appAuthRequest.setEncryptedPassword(DigestUtils.md5(config.getPassword()));
appAuthRequest.setEncryptType(EncryptType.MD5.getCode());
return appAuthRequest; return appAuthRequest;
} }
} }

View File

@ -16,6 +16,6 @@ public class ClientInitializer {
@BeforeAll @BeforeAll
public static void initClient() throws Exception { public static void initClient() throws Exception {
powerJobClient = new PowerJobClient("127.0.0.1:7700", "powerjob-worker-samples", "powerjob123"); powerJobClient = new PowerJobClient("127.0.0.1:7700", "powerjob-worker-samples", "powerjob12345");
} }
} }

View File

@ -0,0 +1,22 @@
package tech.powerjob.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 加密类型
*
* @author tjq
* @since 2024/8/10
*/
@Getter
@AllArgsConstructor
public enum EncryptType {
NONE("none"),
MD5("md5")
;
private final String code;
}

View File

@ -43,7 +43,6 @@ public enum ErrorCodes {
/** /**
* OPENAPI 错误码号段 -10XX * OPENAPI 错误码号段 -10XX
*/ */
OPEN_API_PASSWORD_ERROR("-1001", "OPEN_API_PASSWORD_ERROR"),
OPEN_API_AUTH_FAILED("-1002", "OPEN_API_AUTH_FAILED"), OPEN_API_AUTH_FAILED("-1002", "OPEN_API_AUTH_FAILED"),
/** /**

View File

@ -0,0 +1,71 @@
package tech.powerjob.server.common.utils;
import lombok.SneakyThrows;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Base64;
public class AESUtil {
// 加密算法的名称
private static final String ALGORITHM = "AES";
// 加密/解密模式和填充方式
private static final String TRANSFORMATION = "AES/ECB/PKCS5Padding";
// 密钥长度128192 256
private static final int KEY_SIZE = 128;
/**
* 生成密钥
*
* @param key 密钥的种子可以是任意字符串
* @return 生成的密钥
* @throws Exception 异常
*/
private static SecretKeySpec generateKey(String key) throws Exception {
KeyGenerator keyGen = KeyGenerator.getInstance(ALGORITHM);
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(key.getBytes());
keyGen.init(KEY_SIZE, secureRandom);
SecretKey secretKey = keyGen.generateKey();
return new SecretKeySpec(secretKey.getEncoded(), ALGORITHM);
}
/**
* 加密
*
* @param data 要加密的数据
* @param key 密钥
* @return 加密后的数据Base64 编码
* @throws Exception 异常
*/
@SneakyThrows
public static String encrypt(String data, String key) {
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
SecretKeySpec secretKey = generateKey(key);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encryptedData = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(encryptedData);
}
/**
* 解密
*
* @param encryptedData 要解密的数据Base64 编码
* @param key 密钥
* @return 解密后的数据
* @throws Exception 异常
*/
@SneakyThrows
public static String decrypt(String encryptedData, String key) {
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
SecretKeySpec secretKey = generateKey(key);
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] decryptedData = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
return new String(decryptedData, StandardCharsets.UTF_8);
}
}

View File

@ -0,0 +1,28 @@
package tech.powerjob.server.common.utils;
import org.junit.jupiter.api.Test;
/**
* AESUtilTest
*
* @author tjq
* @since 2024/8/10
*/
class AESUtilTest {
@Test
void testAes() throws Exception {
String sk = "cmxzjzty";
String txt = "kyksjdfh";
String encrypt = AESUtil.encrypt(txt, sk);
System.out.println(encrypt);
String decrypt = AESUtil.decrypt(encrypt, sk);
System.out.println(decrypt);
assert txt.equals(decrypt);
}
}

View File

@ -12,20 +12,35 @@ import java.util.Optional;
*/ */
public interface AppInfoService { public interface AppInfoService {
/**
* 验证 APP 账号密码
* @param appName 账号
* @param password 原文密码
* @return AppId
*/
Long assertApp(String appName, String password);
Optional<AppInfoDO> findByAppName(String appName); Optional<AppInfoDO> findByAppName(String appName);
/** /**
* 获取 AppInfo带缓存 * 获取 AppInfo带缓存
* @param appId appId * @param appId appId
* @param useCache cache
* @return App 信息 * @return App 信息
*/ */
Optional<AppInfoDO> findByIdWithCache(Long appId); Optional<AppInfoDO> findById(Long appId, boolean useCache);
void deleteById(Long appId);
/**
* 保存 App
* @param appInfo app 信息
* @return 保存后结果
*/
AppInfoDO save(AppInfoDO appInfo);
/**
*
* @param appName 验证 APP 账号密码
* @param password 密码
* @param encryptType 密码类型
* @return appId
*/
Long assertApp(String appName, String password, String encryptType);
Long assertApp(AppInfoDO appInfo, String password, String encryptType);
String fetchOriginAppPassword(AppInfoDO appInfo);
} }

View File

@ -4,13 +4,17 @@ import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import tech.powerjob.common.enums.EncryptType;
import tech.powerjob.common.enums.ErrorCodes;
import tech.powerjob.common.exception.PowerJobException; import tech.powerjob.common.exception.PowerJobException;
import tech.powerjob.common.utils.DigestUtils;
import tech.powerjob.server.common.utils.AESUtil;
import tech.powerjob.server.core.service.AppInfoService; import tech.powerjob.server.core.service.AppInfoService;
import tech.powerjob.server.persistence.remote.model.AppInfoDO; import tech.powerjob.server.persistence.remote.model.AppInfoDO;
import tech.powerjob.server.persistence.remote.repository.AppInfoRepository; import tech.powerjob.server.persistence.remote.repository.AppInfoRepository;
import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -33,21 +37,9 @@ public class AppInfoServiceImpl implements AppInfoService {
private final AppInfoRepository appInfoRepository; private final AppInfoRepository appInfoRepository;
/** private static final String ENCRYPT_KEY = "ChinaNo.1";
* 验证应用访问权限
* @param appName 应用名称
* @param password 密码
* @return 应用ID
*/
@Override
public Long assertApp(String appName, String password) {
AppInfoDO appInfo = appInfoRepository.findByAppName(appName).orElseThrow(() -> new PowerJobException("can't find appInfo by appName: " + appName)); private static final String ENCRYPT_PWD_PREFIX = "aes:";
if (Objects.equals(appInfo.getPassword(), password)) {
return appInfo.getId();
}
throw new PowerJobException("password error!");
}
@Override @Override
public Optional<AppInfoDO> findByAppName(String appName) { public Optional<AppInfoDO> findByAppName(String appName) {
@ -55,7 +47,10 @@ public class AppInfoServiceImpl implements AppInfoService {
} }
@Override @Override
public Optional<AppInfoDO> findByIdWithCache(Long appId) { public Optional<AppInfoDO> findById(Long appId, boolean useCache) {
if (!useCache) {
return appInfoRepository.findById(appId);
}
try { try {
AppInfoDO appInfoDO = appId2AppInfoDO.get(appId, () -> { AppInfoDO appInfoDO = appId2AppInfoDO.get(appId, () -> {
Optional<AppInfoDO> appInfoOpt = appInfoRepository.findById(appId); Optional<AppInfoDO> appInfoOpt = appInfoRepository.findById(appId);
@ -71,4 +66,61 @@ public class AppInfoServiceImpl implements AppInfoService {
return Optional.empty(); return Optional.empty();
} }
@Override
public void deleteById(Long appId) {
appInfoRepository.deleteById(appId);
}
@Override
public AppInfoDO save(AppInfoDO appInfo) {
String originPassword = appInfo.getPassword();
String encryptPassword = AESUtil.encrypt(originPassword, ENCRYPT_KEY);
String finalPassword = ENCRYPT_PWD_PREFIX.concat(encryptPassword);
appInfo.setPassword(finalPassword);
return appInfoRepository.saveAndFlush(appInfo);
}
@Override
public Long assertApp(String appName, String password, String encryptType) {
AppInfoDO appInfo = appInfoRepository.findByAppName(appName).orElseThrow(() -> new PowerJobException(ErrorCodes.INVALID_APP, appName));
return assertApp(appInfo, password, encryptType);
}
@Override
public Long assertApp(AppInfoDO appInfo, String password, String encryptType) {
boolean checkPass = checkPassword(appInfo, password, encryptType);
if (!checkPass) {
throw new PowerJobException(ErrorCodes.INCORRECT_PASSWORD, null);
}
return appInfo.getId();
}
private boolean checkPassword(AppInfoDO appInfo, String password, String encryptType) {
String originPwd = fetchOriginAppPassword(appInfo);
if (StringUtils.isEmpty(encryptType) || EncryptType.NONE.getCode().equalsIgnoreCase(encryptType)) {
return password.equals(originPwd);
}
if (EncryptType.MD5.getCode().equalsIgnoreCase(encryptType)) {
return password.equalsIgnoreCase(DigestUtils.md5(originPwd));
}
throw new PowerJobException(ErrorCodes.INVALID_REQUEST, "unknown_encryptType:" + encryptType);
}
@Override
public String fetchOriginAppPassword(AppInfoDO appInfo) {
String dbPwd = appInfo.getPassword();
if (StringUtils.isEmpty(dbPwd)) {
return dbPwd;
}
if (dbPwd.startsWith(ENCRYPT_PWD_PREFIX)) {
String encryptPassword = dbPwd.replaceFirst(ENCRYPT_PWD_PREFIX, StringUtils.EMPTY);
return AESUtil.decrypt(encryptPassword, ENCRYPT_KEY);
}
return dbPwd;
}
} }

View File

@ -58,7 +58,7 @@ public class OpenAPIController {
@PostMapping(OpenAPIConstant.ASSERT) @PostMapping(OpenAPIConstant.ASSERT)
public ResultDTO<Long> assertAppName(String appName, @RequestParam(required = false) String password) { public ResultDTO<Long> assertAppName(String appName, @RequestParam(required = false) String password) {
return ResultDTO.success(appInfoService.assertApp(appName, password)); return ResultDTO.success(appInfoService.assertApp(appName, password, null));
} }
/** /**

View File

@ -8,10 +8,8 @@ import org.springframework.stereotype.Service;
import tech.powerjob.client.module.AppAuthRequest; import tech.powerjob.client.module.AppAuthRequest;
import tech.powerjob.client.module.AppAuthResult; import tech.powerjob.client.module.AppAuthResult;
import tech.powerjob.common.OpenAPIConstant; import tech.powerjob.common.OpenAPIConstant;
import tech.powerjob.common.exception.PowerJobException;
import tech.powerjob.common.utils.DigestUtils;
import tech.powerjob.common.enums.ErrorCodes; import tech.powerjob.common.enums.ErrorCodes;
import tech.powerjob.server.auth.common.PowerJobAuthException; import tech.powerjob.common.exception.PowerJobException;
import tech.powerjob.server.auth.common.utils.HttpServletUtils; import tech.powerjob.server.auth.common.utils.HttpServletUtils;
import tech.powerjob.server.auth.jwt.JwtService; import tech.powerjob.server.auth.jwt.JwtService;
import tech.powerjob.server.core.service.AppInfoService; import tech.powerjob.server.core.service.AppInfoService;
@ -20,7 +18,6 @@ import tech.powerjob.server.persistence.remote.model.AppInfoDO;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.Optional; import java.util.Optional;
/** /**
@ -40,6 +37,7 @@ public class OpenApiSecurityServiceImpl implements OpenApiSecurityService {
private static final String JWT_KEY_APP_ID = "appId"; private static final String JWT_KEY_APP_ID = "appId";
private static final String JWT_KEY_APP_PASSWORD = "password"; private static final String JWT_KEY_APP_PASSWORD = "password";
private static final String JWT_KEY_ENCRYPT_TYPE = "encryptType";
@Override @Override
public void authAppByToken(HttpServletRequest httpServletRequest) { public void authAppByToken(HttpServletRequest httpServletRequest) {
@ -59,6 +57,7 @@ public class OpenApiSecurityServiceImpl implements OpenApiSecurityService {
Long appIdFromJwt = MapUtils.getLong(jwtResult, JWT_KEY_APP_ID); Long appIdFromJwt = MapUtils.getLong(jwtResult, JWT_KEY_APP_ID);
String passwordFromJwt = MapUtils.getString(jwtResult, JWT_KEY_APP_PASSWORD); String passwordFromJwt = MapUtils.getString(jwtResult, JWT_KEY_APP_PASSWORD);
String encryptType = MapUtils.getString(jwtResult, JWT_KEY_ENCRYPT_TYPE);
// 校验 appId 一致性 // 校验 appId 一致性
if (!StringUtils.equals(appIdFromHeader, String.valueOf(appIdFromJwt))) { if (!StringUtils.equals(appIdFromHeader, String.valueOf(appIdFromJwt))) {
@ -66,15 +65,12 @@ public class OpenApiSecurityServiceImpl implements OpenApiSecurityService {
} }
// 此处不考虑改密码后的缓存时间毕竟只要改了密码一定会报错换言之 OpenAPI 模式下密码不可更改 // 此处不考虑改密码后的缓存时间毕竟只要改了密码一定会报错换言之 OpenAPI 模式下密码不可更改
Optional<AppInfoDO> appInfoOpt = appInfoService.findByIdWithCache(appIdFromJwt); Optional<AppInfoDO> appInfoOpt = appInfoService.findById(appIdFromJwt, true);
if (!appInfoOpt.isPresent()) { if (!appInfoOpt.isPresent()) {
throw new PowerJobException(ErrorCodes.INVALID_APP, "can_not_find_app"); throw new PowerJobException(ErrorCodes.INVALID_APP, "can_not_find_app");
} }
String dbOriginPassword = appInfoOpt.get().getPassword(); appInfoService.assertApp(appInfoOpt.get(), passwordFromJwt, encryptType);
if (!StringUtils.equals(passwordFromJwt, DigestUtils.md5(dbOriginPassword))) {
throw new PowerJobException(ErrorCodes.OPEN_API_PASSWORD_ERROR, "password_compare_failed");
}
} }
@ -84,25 +80,16 @@ public class OpenApiSecurityServiceImpl implements OpenApiSecurityService {
String appName = appAuthRequest.getAppName(); String appName = appAuthRequest.getAppName();
String encryptedPassword = appAuthRequest.getEncryptedPassword(); String encryptedPassword = appAuthRequest.getEncryptedPassword();
Optional<AppInfoDO> appInfoOpt = appInfoService.findByAppName(appName); Long appId = appInfoService.assertApp(appName, encryptedPassword, appAuthRequest.getEncryptType());
if (!appInfoOpt.isPresent()) {
throw new PowerJobAuthException(ErrorCodes.INVALID_APP);
}
AppInfoDO appInfo = appInfoOpt.get();
// 密码验证失败
if (!Objects.equals(DigestUtils.md5(appInfo.getPassword()), encryptedPassword)) {
throw new PowerJobAuthException(ErrorCodes.OPEN_API_PASSWORD_ERROR);
}
Map<String, Object> jwtBody = Maps.newHashMap(); Map<String, Object> jwtBody = Maps.newHashMap();
jwtBody.put(JWT_KEY_APP_ID, appInfo.getId()); jwtBody.put(JWT_KEY_APP_ID, appId);
jwtBody.put(JWT_KEY_APP_PASSWORD, encryptedPassword); jwtBody.put(JWT_KEY_APP_PASSWORD, encryptedPassword);
jwtBody.put(JWT_KEY_ENCRYPT_TYPE, appAuthRequest.getEncryptType());
AppAuthResult appAuthResult = new AppAuthResult(); AppAuthResult appAuthResult = new AppAuthResult();
appAuthResult.setAppId(appInfo.getId()); appAuthResult.setAppId(appId);
appAuthResult.setToken(jwtService.build(jwtBody, null)); appAuthResult.setToken(jwtService.build(jwtBody, null));
return appAuthResult; return appAuthResult;

View File

@ -13,7 +13,10 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.domain.Specification;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import tech.powerjob.common.response.ResultDTO; import tech.powerjob.common.response.ResultDTO;
import tech.powerjob.common.serialize.JsonUtils; import tech.powerjob.common.serialize.JsonUtils;
import tech.powerjob.common.utils.CommonUtils; import tech.powerjob.common.utils.CommonUtils;
@ -22,13 +25,12 @@ import tech.powerjob.server.auth.Permission;
import tech.powerjob.server.auth.Role; import tech.powerjob.server.auth.Role;
import tech.powerjob.server.auth.RoleScope; import tech.powerjob.server.auth.RoleScope;
import tech.powerjob.server.auth.common.AuthConstants; import tech.powerjob.server.auth.common.AuthConstants;
import tech.powerjob.common.enums.ErrorCodes;
import tech.powerjob.server.auth.common.PowerJobAuthException;
import tech.powerjob.server.auth.interceptor.ApiPermission; import tech.powerjob.server.auth.interceptor.ApiPermission;
import tech.powerjob.server.auth.plugin.ModifyOrCreateDynamicPermission; import tech.powerjob.server.auth.plugin.ModifyOrCreateDynamicPermission;
import tech.powerjob.server.auth.plugin.SaveAppGrantPermissionPlugin; import tech.powerjob.server.auth.plugin.SaveAppGrantPermissionPlugin;
import tech.powerjob.server.auth.service.WebAuthService; import tech.powerjob.server.auth.service.WebAuthService;
import tech.powerjob.server.common.module.WorkerInfo; import tech.powerjob.server.common.module.WorkerInfo;
import tech.powerjob.server.core.service.AppInfoService;
import tech.powerjob.server.persistence.PageResult; import tech.powerjob.server.persistence.PageResult;
import tech.powerjob.server.persistence.QueryConvertUtils; import tech.powerjob.server.persistence.QueryConvertUtils;
import tech.powerjob.server.persistence.remote.model.AppInfoDO; import tech.powerjob.server.persistence.remote.model.AppInfoDO;
@ -67,6 +69,7 @@ public class AppInfoController {
private final UserWebService userWebService; private final UserWebService userWebService;
private final AppInfoService appInfoService;
private final AppInfoRepository appInfoRepository; private final AppInfoRepository appInfoRepository;
private final NamespaceWebService namespaceWebService; private final NamespaceWebService namespaceWebService;
@ -86,7 +89,7 @@ public class AppInfoController {
appInfoDO.setGmtCreate(new Date()); appInfoDO.setGmtCreate(new Date());
appInfoDO.setCreator(LoginUserHolder.getUserId()); appInfoDO.setCreator(LoginUserHolder.getUserId());
} else { } else {
appInfoDO = appInfoRepository.findById(id).orElseThrow(() -> new IllegalArgumentException("can't find appInfo by id:" + id)); appInfoDO = appInfoService.findById(id, false).orElseThrow(() -> new IllegalArgumentException("can't find appInfo by id:" + id));
// 不允许修改 appName // 不允许修改 appName
if (!appInfoDO.getAppName().equalsIgnoreCase(req.getAppName())) { if (!appInfoDO.getAppName().equalsIgnoreCase(req.getAppName())) {
@ -104,7 +107,7 @@ public class AppInfoController {
appInfoDO.setGmtModified(new Date()); appInfoDO.setGmtModified(new Date());
appInfoDO.setModifier(LoginUserHolder.getUserId()); appInfoDO.setModifier(LoginUserHolder.getUserId());
AppInfoDO savedAppInfo = appInfoRepository.saveAndFlush(appInfoDO); AppInfoDO savedAppInfo = appInfoService.save(appInfoDO);
// 重现授权 // 重现授权
webAuthService.processPermissionOnSave(RoleScope.APP, savedAppInfo.getId(), req.getComponentUserRoleInfo()); webAuthService.processPermissionOnSave(RoleScope.APP, savedAppInfo.getId(), req.getComponentUserRoleInfo());
@ -123,7 +126,7 @@ public class AppInfoController {
return ResultDTO.failed("Unable to delete apps with live workers, Please remove the worker dependency first!"); return ResultDTO.failed("Unable to delete apps with live workers, Please remove the worker dependency first!");
} }
appInfoRepository.deleteById(appId); appInfoService.deleteById(appId);
log.warn("[AppInfoController] delete app[id={}] successfully!", appId); log.warn("[AppInfoController] delete app[id={}] successfully!", appId);
return ResultDTO.success(null); return ResultDTO.success(null);
} }
@ -188,18 +191,13 @@ public class AppInfoController {
@ApiPermission(name = "App-BecomeAdmin", roleScope = RoleScope.GLOBAL, requiredPermission = Permission.NONE) @ApiPermission(name = "App-BecomeAdmin", roleScope = RoleScope.GLOBAL, requiredPermission = Permission.NONE)
public ResultDTO<Void> becomeAdminByAppNameAndPassword(@RequestBody AppAssertRequest appAssertRequest) { public ResultDTO<Void> becomeAdminByAppNameAndPassword(@RequestBody AppAssertRequest appAssertRequest) {
String appName = appAssertRequest.getAppName(); String appName = appAssertRequest.getAppName();
Optional<AppInfoDO> appInfoOpt = appInfoRepository.findByAppName(appName);
if (!appInfoOpt.isPresent()) { Long appId = appInfoService.assertApp(appName, appAssertRequest.getPassword(), appAssertRequest.getEncryptType());
throw new IllegalArgumentException("can't find app by appName: " + appName);
}
if (!StringUtils.equals(appInfoOpt.get().getPassword(), appAssertRequest.getPassword())) {
throw new PowerJobAuthException(ErrorCodes.INCORRECT_PASSWORD);
}
Map<String, Object> extra = Maps.newHashMap(); Map<String, Object> extra = Maps.newHashMap();
extra.put("source", "becomeAdminByAppNameAndPassword"); extra.put("source", "becomeAdminByAppNameAndPassword");
webAuthService.grantRole2LoginUser(RoleScope.APP, appInfoOpt.get().getId(), Role.ADMIN, JsonUtils.toJSONString(extra)); webAuthService.grantRole2LoginUser(RoleScope.APP, appId, Role.ADMIN, JsonUtils.toJSONString(extra));
return ResultDTO.success(null); return ResultDTO.success(null);
} }
@ -224,7 +222,8 @@ public class AppInfoController {
// 密码 // 密码
boolean hasPermission = webAuthService.hasPermission(RoleScope.APP, appInfoDO.getId(), Permission.READ); boolean hasPermission = webAuthService.hasPermission(RoleScope.APP, appInfoDO.getId(), Permission.READ);
appInfoVO.setPassword(hasPermission ? appInfoDO.getPassword() : AuthConstants.TIPS_NO_PERMISSION_TO_SEE); String originPassword = appInfoService.fetchOriginAppPassword(appInfoDO);
appInfoVO.setPassword(hasPermission ? originPassword : AuthConstants.TIPS_NO_PERMISSION_TO_SEE);
// namespace // namespace
Optional<NamespaceDO> namespaceOpt = namespaceWebService.findById(appInfoDO.getNamespaceId()); Optional<NamespaceDO> namespaceOpt = namespaceWebService.findById(appInfoDO.getNamespaceId());

View File

@ -12,4 +12,6 @@ import lombok.Data;
public class AppAssertRequest { public class AppAssertRequest {
private String appName; private String appName;
private String password; private String password;
private String encryptType;
} }