Merge branch 'develop' into dev_shb
This commit is contained in:
@@ -45,8 +45,8 @@ public class AuthenticationFilter extends OncePerRequestFilter {
|
|||||||
"/webjars/", "/swagger-resources", "/v2/api-docs", "api/account/resetPwd",
|
"/webjars/", "/swagger-resources", "/v2/api-docs", "api/account/resetPwd",
|
||||||
"/api/python/saveGeneratePicture", "/api/python/getLibraryByUserId",
|
"/api/python/saveGeneratePicture", "/api/python/getLibraryByUserId",
|
||||||
"/api/third/party/addUser","/api/third/party/addTrialUser", "/api/third/party/editUser", "/api/element/initDefaultSysFile",
|
"/api/third/party/addUser","/api/third/party/addTrialUser", "/api/third/party/editUser", "/api/element/initDefaultSysFile",
|
||||||
"/api/third/party/addNoLoginRequired","/api/third/party/deleteNoLoginRequired",
|
"/api/third/party/addNoLoginRequiredNew","/api/third/party/deleteNoLoginRequiredNew",
|
||||||
"/api/third/party/existNoLoginRequired",
|
"/api/third/party/existNoLoginRequired","/api/third/party/getRedirectUrl",
|
||||||
"/api/python/chatStream",
|
"/api/python/chatStream",
|
||||||
"/api/python/flush",
|
"/api/python/flush",
|
||||||
"/api/account/healthy"
|
"/api/account/healthy"
|
||||||
|
|||||||
@@ -144,9 +144,9 @@ public class AccountController {
|
|||||||
return Response.success(accountService.getExpiredTime());
|
return Response.success(accountService.getExpiredTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation(value = "查询账号到期时间")
|
@ApiOperation(value = "免密登录")
|
||||||
@PostMapping("/noLoginRequired")
|
@PostMapping("/noLoginRequired")
|
||||||
public Response<AccountLoginVO> noLoginRequired(@RequestBody NoLoginRequiredDTO noLoginRequiredDTO){
|
public Response<AccountLoginVO> noLoginRequired(@RequestBody NoLoginRequiredDTO noLoginRequiredDTO, HttpServletRequest request){
|
||||||
return Response.success(accountService.noLoginRequired(noLoginRequiredDTO));
|
return Response.success(accountService.noLoginRequired(noLoginRequiredDTO, request));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,15 @@ import com.ai.da.service.AccountService;
|
|||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||||
|
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
|
|
||||||
|
|
||||||
@Api(tags = "Third Party Modules")
|
@Api(tags = "Third Party Modules")
|
||||||
@@ -59,7 +63,48 @@ public class ThirdPartyController {
|
|||||||
@CrossOrigin
|
@CrossOrigin
|
||||||
@ApiOperation(value = "add No Login Required")
|
@ApiOperation(value = "add No Login Required")
|
||||||
@PostMapping("/existNoLoginRequired")
|
@PostMapping("/existNoLoginRequired")
|
||||||
public Response<Boolean> existNoLoginRequired(@RequestBody NoLoginRequiredDTO noLoginRequiredDTO) {
|
public Response<Boolean> existNoLoginRequired(@RequestBody NoLoginRequiredDTO noLoginRequiredDTO, HttpServletRequest request) {
|
||||||
return Response.success(accountService.existNoLoginRequired(noLoginRequiredDTO));
|
return Response.success(accountService.existNoLoginRequired(noLoginRequiredDTO, request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/your-secured-endpoint")
|
||||||
|
// @PreAuthorize("hasRole('ROLE_USER')")
|
||||||
|
public String securedEndpoint(HttpServletRequest request, @AuthenticationPrincipal PreAuthenticatedAuthenticationToken authenticationToken) {
|
||||||
|
// 从请求属性中获取证书
|
||||||
|
X509Certificate[] certificates = (X509Certificate[]) request.getAttribute("javax.servlet.request.X509Certificate");
|
||||||
|
if (certificates != null && certificates.length > 0) {
|
||||||
|
X509Certificate clientCertificate = certificates[0];
|
||||||
|
// 可以从 clientCertificate 中获取证书信息,例如主题、颁发者等
|
||||||
|
String subject = clientCertificate.getSubjectX500Principal().getName();
|
||||||
|
String issuer = clientCertificate.getIssuerX500Principal().getName();
|
||||||
|
// 处理逻辑
|
||||||
|
return "Secured Endpoint. Client Subject: " + subject + ", Issuer: " + issuer;
|
||||||
|
} else {
|
||||||
|
// 证书不存在或获取失败
|
||||||
|
return "Failed to retrieve client certificate.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@CrossOrigin
|
||||||
|
@ApiOperation(value = "add No Login Required")
|
||||||
|
@PostMapping("/addNoLoginRequiredNew")
|
||||||
|
public Response<String> addNoLoginRequiredNew(@RequestBody NoLoginRequiredDTO noLoginRequiredDTO, HttpServletRequest request) {
|
||||||
|
return Response.success(accountService.addNoLoginRequiredNew(noLoginRequiredDTO, request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@CrossOrigin
|
||||||
|
@ApiOperation(value = "add No Login Required")
|
||||||
|
@PostMapping("/deleteNoLoginRequiredNew")
|
||||||
|
public Response<Boolean> deleteNoLoginRequiredNew(@RequestBody NoLoginRequiredDTO noLoginRequiredDTO, HttpServletRequest request) {
|
||||||
|
return Response.success(accountService.deleteNoLoginRequiredNew(noLoginRequiredDTO, request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Value("${redirect_url}")
|
||||||
|
private String REDIRECT_URL;
|
||||||
|
@CrossOrigin
|
||||||
|
@ApiOperation(value = "add No Login Required")
|
||||||
|
@PostMapping("/getRedirectUrl")
|
||||||
|
public Response<String> getRedirectUrl() {
|
||||||
|
return Response.success(REDIRECT_URL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,4 +5,6 @@ import lombok.Data;
|
|||||||
@Data
|
@Data
|
||||||
public class NoLoginRequiredDTO {
|
public class NoLoginRequiredDTO {
|
||||||
private String browserIdentifiers;
|
private String browserIdentifiers;
|
||||||
|
private String id;
|
||||||
|
private Boolean deleteById;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,7 +120,11 @@ public interface AccountService extends IService<Account> {
|
|||||||
|
|
||||||
Boolean deleteNoLoginRequired(NoLoginRequiredDTO noLoginRequiredDTO);
|
Boolean deleteNoLoginRequired(NoLoginRequiredDTO noLoginRequiredDTO);
|
||||||
|
|
||||||
AccountLoginVO noLoginRequired(NoLoginRequiredDTO noLoginRequiredDTO);
|
AccountLoginVO noLoginRequired(NoLoginRequiredDTO noLoginRequiredDTO, HttpServletRequest request);
|
||||||
|
|
||||||
Boolean existNoLoginRequired(NoLoginRequiredDTO noLoginRequiredDTO);
|
Boolean existNoLoginRequired(NoLoginRequiredDTO noLoginRequiredDTO, HttpServletRequest request);
|
||||||
|
|
||||||
|
String addNoLoginRequiredNew(NoLoginRequiredDTO noLoginRequiredDTO, HttpServletRequest request);
|
||||||
|
|
||||||
|
Boolean deleteNoLoginRequiredNew(NoLoginRequiredDTO noLoginRequiredDTO, HttpServletRequest request);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -647,12 +647,29 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AccountLoginVO noLoginRequired(NoLoginRequiredDTO noLoginRequiredDTO) {
|
public AccountLoginVO noLoginRequired(NoLoginRequiredDTO noLoginRequiredDTO, HttpServletRequest request) {
|
||||||
|
String id = noLoginRequiredDTO.getId();
|
||||||
|
if (!isStringInRange(id)) {
|
||||||
|
throw new BusinessException("Illegal serial number!");
|
||||||
|
}
|
||||||
|
// 获取真实 IP 地址,考虑了经过代理的情况
|
||||||
|
String ipAddress = request.getHeader("X-Forwarded-For");
|
||||||
|
if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
|
||||||
|
ipAddress = request.getHeader("Proxy-Client-IP");
|
||||||
|
}
|
||||||
|
if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
|
||||||
|
ipAddress = request.getHeader("WL-Proxy-Client-IP");
|
||||||
|
}
|
||||||
|
if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
|
||||||
|
ipAddress = request.getRemoteAddr();
|
||||||
|
}
|
||||||
|
String browserIdentifiers = ipAddress + "," + id;
|
||||||
QueryWrapper<Account> qw = new QueryWrapper<>();
|
QueryWrapper<Account> qw = new QueryWrapper<>();
|
||||||
qw.lambda().eq(Account::getBrowserIdentifiers, noLoginRequiredDTO.getBrowserIdentifiers());
|
qw.lambda().eq(Account::getUserName, "PolyU-SFT-" + id);
|
||||||
|
qw.lambda().eq(Account::getBrowserIdentifiers, browserIdentifiers);
|
||||||
List<Account> accountList = accountMapper.selectList(qw);
|
List<Account> accountList = accountMapper.selectList(qw);
|
||||||
if (CollectionUtil.isEmpty(accountList)) {
|
if (CollectionUtil.isEmpty(accountList)) {
|
||||||
throw new BusinessException("This browser is not registered as login free");
|
throw new BusinessException("Machine not registered or machine identification has changed, login free has failed, please contact us at help@aida.com.hk.");
|
||||||
}
|
}
|
||||||
Account account = accountList.get(0);
|
Account account = accountList.get(0);
|
||||||
AccountLoginVO response = CopyUtil.copyObject(account, AccountLoginVO.class);
|
AccountLoginVO response = CopyUtil.copyObject(account, AccountLoginVO.class);
|
||||||
@@ -668,12 +685,152 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Boolean existNoLoginRequired(NoLoginRequiredDTO noLoginRequiredDTO) {
|
public Boolean existNoLoginRequired(NoLoginRequiredDTO noLoginRequiredDTO, HttpServletRequest request) {
|
||||||
|
String id = noLoginRequiredDTO.getId();
|
||||||
|
// 获取真实 IP 地址,考虑了经过代理的情况
|
||||||
|
String ipAddress = request.getHeader("X-Forwarded-For");
|
||||||
|
if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
|
||||||
|
ipAddress = request.getHeader("Proxy-Client-IP");
|
||||||
|
}
|
||||||
|
if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
|
||||||
|
ipAddress = request.getHeader("WL-Proxy-Client-IP");
|
||||||
|
}
|
||||||
|
if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
|
||||||
|
ipAddress = request.getRemoteAddr();
|
||||||
|
}
|
||||||
|
String browserIdentifiers = ipAddress + "," + id;
|
||||||
QueryWrapper<Account> qw = new QueryWrapper<>();
|
QueryWrapper<Account> qw = new QueryWrapper<>();
|
||||||
qw.lambda().eq(Account::getBrowserIdentifiers, noLoginRequiredDTO.getBrowserIdentifiers());
|
qw.lambda().eq(Account::getUserName, "PolyU-SFT-" + id);
|
||||||
List<Account> accountList = accountMapper.selectList(qw);
|
List<Account> accountList = accountMapper.selectList(qw);
|
||||||
if (CollectionUtil.isEmpty(accountList)) {
|
if (!CollectionUtil.isEmpty(accountList)) {
|
||||||
return Boolean.FALSE;
|
throw new BusinessException("");
|
||||||
|
}
|
||||||
|
return Boolean.TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public String addNoLoginRequiredNew(NoLoginRequiredDTO noLoginRequiredDTO, HttpServletRequest request) {
|
||||||
|
// 验证机房注册序列号(001-100)
|
||||||
|
String id = noLoginRequiredDTO.getId();
|
||||||
|
if (!isStringInRange(id)) {
|
||||||
|
throw new BusinessException("Illegal serial number.");
|
||||||
|
}
|
||||||
|
// 获取真实 IP 地址,考虑了经过代理的情况
|
||||||
|
String ipAddress = request.getHeader("X-Forwarded-For");
|
||||||
|
if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
|
||||||
|
ipAddress = request.getHeader("Proxy-Client-IP");
|
||||||
|
}
|
||||||
|
if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
|
||||||
|
ipAddress = request.getHeader("WL-Proxy-Client-IP");
|
||||||
|
}
|
||||||
|
if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
|
||||||
|
ipAddress = request.getRemoteAddr();
|
||||||
|
}
|
||||||
|
String browserIdentifiers = ipAddress + "," + id;
|
||||||
|
// 构建查询条件,查找已注册的账户数量
|
||||||
|
QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.lambda().eq(Account::getUserName, "PolyU-SFT-" + id);
|
||||||
|
// queryWrapper.lambda().eq(Account::getBrowserIdentifiers, browserIdentifiers);
|
||||||
|
List<Account> existingAccounts = accountMapper.selectList(queryWrapper);
|
||||||
|
|
||||||
|
// 检查序列号是否被注册
|
||||||
|
if (CollectionUtil.isNotEmpty(existingAccounts)) {
|
||||||
|
throw new BusinessException("The serial number has already been registered.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查机器是否已经注册了别的序列号
|
||||||
|
queryWrapper.clear();
|
||||||
|
queryWrapper.lambda().like(Account::getBrowserIdentifiers, ipAddress);
|
||||||
|
List<Account> accountList = accountMapper.selectList(queryWrapper);
|
||||||
|
if (CollectionUtil.isNotEmpty(accountList)) {
|
||||||
|
throw new BusinessException("This machine has already been registered with serial number " + accountList.get(0).getUserName().split("-")[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建新账户
|
||||||
|
Account newAccount = new Account();
|
||||||
|
newAccount.setUserName("PolyU-SFT-" + id);
|
||||||
|
newAccount.setUserPassword("Third-000000");
|
||||||
|
newAccount.setValidStartTime(System.currentTimeMillis());
|
||||||
|
newAccount.setValidEndTime(System.currentTimeMillis() + 365L * 24 * 60 * 60 * 1000);
|
||||||
|
newAccount.setCreateDate(new Date());
|
||||||
|
newAccount.setIsBeginner(1);
|
||||||
|
newAccount.setIsTrial(0);
|
||||||
|
newAccount.setBrowserIdentifiers(browserIdentifiers);
|
||||||
|
newAccount.setLanguage(Language.ENGLISH.name());
|
||||||
|
|
||||||
|
// 插入新账户
|
||||||
|
accountMapper.insert(newAccount);
|
||||||
|
|
||||||
|
return "<!DOCTYPE html>\n" +
|
||||||
|
" <html lang=\"en\">\n" +
|
||||||
|
" <head>\n" +
|
||||||
|
" <meta charset=\"UTF-8\">\n" +
|
||||||
|
" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n" +
|
||||||
|
" <title>Document</title>\n" +
|
||||||
|
" <link rel=\"icon\" href=\"https://polyu.aida.com.hk/favicon.ico\">\n" +
|
||||||
|
" </head>\n" +
|
||||||
|
" <body>\n" +
|
||||||
|
" </body>\n" +
|
||||||
|
" <script>\n" +
|
||||||
|
" window.location.href = 'https://polyu.aida.com.hk?"+id+"';\n" +
|
||||||
|
" </script>\n" +
|
||||||
|
" </html>";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isStringInRange(String input) {
|
||||||
|
// 去除字符串两端的空格
|
||||||
|
input = input.trim();
|
||||||
|
|
||||||
|
// 使用正则表达式检查是否是三位数字
|
||||||
|
if (input.matches("\\d{3}")) {
|
||||||
|
// 将字符串转换为整数
|
||||||
|
int number = Integer.parseInt(input);
|
||||||
|
|
||||||
|
// 检查是否在指定范围内
|
||||||
|
return number >= 1 && number <= 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public Boolean deleteNoLoginRequiredNew(NoLoginRequiredDTO noLoginRequiredDTO, HttpServletRequest request) {
|
||||||
|
// 获取真实 IP 地址,考虑了经过代理的情况
|
||||||
|
String ipAddress = request.getHeader("X-Forwarded-For");
|
||||||
|
if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
|
||||||
|
ipAddress = request.getHeader("Proxy-Client-IP");
|
||||||
|
}
|
||||||
|
if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
|
||||||
|
ipAddress = request.getHeader("WL-Proxy-Client-IP");
|
||||||
|
}
|
||||||
|
if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
|
||||||
|
ipAddress = request.getRemoteAddr();
|
||||||
|
}
|
||||||
|
// 删除将被注销的用户
|
||||||
|
QueryWrapper<Account> queryWrapperDelete = new QueryWrapper<>();
|
||||||
|
if (StringUtils.isNotBlank(noLoginRequiredDTO.getId()) && noLoginRequiredDTO.getDeleteById()) {
|
||||||
|
// 验证机房注册序列号(001-100)
|
||||||
|
String id = noLoginRequiredDTO.getId();
|
||||||
|
if (!isStringInRange(id)) {
|
||||||
|
throw new BusinessException("Illegal serial number.");
|
||||||
|
}
|
||||||
|
queryWrapperDelete.lambda().eq(Account::getUserName, "PolyU-SFT-" + noLoginRequiredDTO.getId());
|
||||||
|
}else {
|
||||||
|
queryWrapperDelete.lambda().like(Account::getBrowserIdentifiers, ipAddress);
|
||||||
|
}
|
||||||
|
List<Account> accountList = accountMapper.selectList(queryWrapperDelete);
|
||||||
|
if (CollectionUtil.isNotEmpty(accountList)) {
|
||||||
|
for (Account account : accountList) {
|
||||||
|
//jwt本身失效比较难做 统一用缓存实现 删除缓存就失效
|
||||||
|
String token = LocalCacheUtils.getTokenCache(String.valueOf(account.getId()));
|
||||||
|
if (StringUtils.isNotBlank(token)) {
|
||||||
|
LocalCacheUtils.delTokenCache(String.valueOf(account.getId()));
|
||||||
|
}
|
||||||
|
accountMapper.deleteById(account.getId());
|
||||||
|
// TODO:注销时删除用户数据,workspace,like,library等
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return Boolean.TRUE;
|
return Boolean.TRUE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,3 +64,4 @@ minio.bucketName.results=aida-results
|
|||||||
minio.bucketName.sysImage=aida-sys-image
|
minio.bucketName.sysImage=aida-sys-image
|
||||||
minio.bucketName.users=aida-users
|
minio.bucketName.users=aida-users
|
||||||
minio.bucketName.collectionElement=aida-collection-element
|
minio.bucketName.collectionElement=aida-collection-element
|
||||||
|
redirect_url=http://18.167.251.121:7788
|
||||||
|
|||||||
Reference in New Issue
Block a user