Skip to content

Commit e57d8cc

Browse files
authored
fix: remove sensitive fields from user API response and improve home page error handling (#288)
1 parent d60612a commit e57d8cc

File tree

15 files changed

+165
-175
lines changed

15 files changed

+165
-175
lines changed

app/src/main/resources/sql/h2/init_data_for_test_v1.0.0.sql

Lines changed: 0 additions & 2 deletions
Large diffs are not rendered by default.

app/src/main/resources/sql/mysql/init_data_for_test_v1.0.0.sql

Lines changed: 0 additions & 2 deletions
Large diffs are not rendered by default.

base/src/main/java/com/tinyengine/it/common/exception/ExceptionEnum.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,8 +321,22 @@ public enum ExceptionEnum implements IBaseError {
321321
/**
322322
* Cm 339 exception enum.
323323
*/
324-
CM339("CM339", "token检验失败,请重新登录");
324+
CM339("CM339", "token检验失败,请重新登录"),
325325

326+
/**
327+
* Cm 340 exception enum.
328+
*/
329+
CM340("CM340", "请求资源不存在"),
330+
331+
/**
332+
* Cm 341 exception enum.
333+
*/
334+
CM341("CM341", "组织在当前用户组织列表中匹配不到"),
335+
336+
/**
337+
* Cm 342 exception enum.
338+
*/
339+
CM342("CM342", "数字格式异常");
326340
/**
327341
* 错误码
328342
*/

base/src/main/java/com/tinyengine/it/controller/AiChatController.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ public class AiChatController {
7878
@SystemControllerLog(description = "AI chat")
7979
@PostMapping("/ai/chat")
8080
public ResponseEntity<?> aiChat(@RequestBody ChatRequest request,
81-
@RequestHeader(value = "Authorization", required = false) String authorization) throws Exception {
81+
@RequestHeader(value = "Authorization", required = true) String authorization) throws Exception {
8282

8383
if (authorization != null && authorization.startsWith("Bearer ")) {
8484
String token = authorization.replace("Bearer ", "");
@@ -117,7 +117,7 @@ public ResponseEntity<?> aiChat(@RequestBody ChatRequest request,
117117
@SystemControllerLog(description = "AI completions")
118118
@PostMapping("/chat/completions")
119119
public ResponseEntity<?> completions(@RequestBody ChatRequest request,
120-
@RequestHeader(value = "Authorization", required = false) String authorization) throws Exception {
120+
@RequestHeader(value = "Authorization", required = true) String authorization) throws Exception {
121121
if (authorization != null && authorization.startsWith("Bearer ")) {
122122
String token = authorization.replace("Bearer ", "");
123123
request.setApiKey(token);

base/src/main/java/com/tinyengine/it/controller/UserController.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,10 @@ public Result<User> me() {
8888
user.setUsername(loginUserContext.getLoginUserId());
8989
}
9090
user.setTenant(tenants);
91-
91+
user.setPassword(null);
92+
user.setPrivateKey(null);
93+
user.setPublicKey(null);
94+
user.setSalt(null);
9295
return Result.success(user);
9396
}
9497

base/src/main/java/com/tinyengine/it/login/config/LoginConfig.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,10 @@ public void addInterceptors(InterceptorRegistry registry) {
3939
// 登录相关
4040
"/platform-center/api/user/login",
4141
// 忘记密码
42-
"/platform-center/api/user/forgot-password"
42+
"/platform-center/api/user/forgot-password",
43+
// AI
44+
"/app-center/api/ai/chat",
45+
"/app-center/api/chat/completions"
4346
);
4447
}
4548
}
Lines changed: 99 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
/**
22
* Copyright (c) 2023 - present TinyEngine Authors.
33
* Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
4-
*
4+
* <p>
55
* Use of this source code is governed by an MIT-style license.
6-
*
6+
* <p>
77
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
88
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
99
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
10-
*
1110
*/
1211

1312
package com.tinyengine.it.login.config;
@@ -17,6 +16,7 @@
1716
import com.tinyengine.it.login.utils.JwtUtil;
1817
import com.tinyengine.it.login.config.context.DefaultLoginUserContext;
1918
import com.tinyengine.it.login.model.UserInfo;
19+
import com.tinyengine.it.mapper.AuthUsersUnitsRolesMapper;
2020
import com.tinyengine.it.model.entity.Tenant;
2121
import jakarta.servlet.http.HttpServletRequest;
2222
import jakarta.servlet.http.HttpServletResponse;
@@ -34,69 +34,100 @@
3434
@Component
3535
public class SSOInterceptor implements HandlerInterceptor {
3636

37-
@Autowired
38-
private JwtUtil jwtUtil;
39-
40-
@Override
41-
public boolean preHandle(HttpServletRequest request,
42-
HttpServletResponse response, Object handler) throws Exception {
43-
44-
String authorization = request.getHeader("Authorization");
45-
// 如果没有token,重定向到登录页
46-
if (authorization == null || authorization.isEmpty()) {
47-
log.info("No token");
48-
throw new ServiceException(ExceptionEnum.CM336.getResultCode(), ExceptionEnum.CM336.getResultMsg());
49-
}
50-
String token = jwtUtil.getTokenFromRequest(authorization);
51-
String requestURI = request.getRequestURI();
52-
53-
log.info("Intercepting: {}, Token: {}", requestURI, token != null ? "present" : "null");
54-
55-
try {
56-
// 验证token
57-
if (!jwtUtil.validateToken(token)) {
58-
log.warn("Token validation failed");
59-
throw new ServiceException(ExceptionEnum.CM339.getResultCode(), ExceptionEnum.CM339.getResultMsg());
60-
}
61-
62-
// 从token中获取用户信息
63-
String username = jwtUtil.getUsernameFromToken(token);
64-
String userId = jwtUtil.getUserIdFromToken(token);
65-
List<Tenant> tenants = jwtUtil.getTenantIdFromToken(token);
66-
String roles = jwtUtil.getRolesFromToken(token);
67-
Integer platformId = jwtUtil.getPlatformIdFromToken(token);
68-
69-
70-
// 检查必需的用户信息
71-
if (username == null || username.isEmpty() || userId == null) {
72-
log.warn("User information is incomplete - username: {}, userId: {}", username, userId);
73-
throw new ServiceException(ExceptionEnum.CM339.getResultCode(), ExceptionEnum.CM339.getResultMsg());
74-
}
75-
76-
// 存储用户信息到LoginUserContext
77-
UserInfo userInfo = new UserInfo(userId, username, tenants);
78-
79-
userInfo.setPlatformId(platformId != null ? platformId : 0);
80-
userInfo.setRoles(roles != null ? roles : "USER");
81-
userInfo.setToken(token);
82-
83-
DefaultLoginUserContext.setCurrentUser(userInfo);
84-
85-
log.info("Token validated and user context set for user: {}", username);
86-
return true;
87-
88-
} catch (Exception e) {
89-
log.error("Token validation exception: {}", e.getMessage(), e);
90-
DefaultLoginUserContext.clear();
91-
throw new ServiceException(ExceptionEnum.CM339.getResultCode(), ExceptionEnum.CM339.getResultMsg());
92-
}
93-
}
94-
95-
@Override
96-
public void afterCompletion(HttpServletRequest request,
97-
HttpServletResponse response, Object handler, Exception ex) {
98-
// 请求完成后清理用户上下文
99-
DefaultLoginUserContext.clear();
100-
log.debug("Cleared user context for request completion");
101-
}
37+
@Autowired
38+
private JwtUtil jwtUtil;
39+
@Autowired
40+
AuthUsersUnitsRolesMapper authUsersUnitsRolesMapper;
41+
42+
@Override
43+
public boolean preHandle(HttpServletRequest request,
44+
HttpServletResponse response, Object handler) throws Exception {
45+
46+
String authorization = request.getHeader("Authorization");
47+
String org = request.getHeader("X-Lowcode-Org");
48+
// 如果没有token,重定向到登录页
49+
if (authorization == null || authorization.isEmpty()) {
50+
log.info("No token");
51+
throw new ServiceException(ExceptionEnum.CM336.getResultCode(), ExceptionEnum.CM336.getResultMsg());
52+
}
53+
String token = jwtUtil.getTokenFromRequest(authorization);
54+
String requestURI = request.getRequestURI();
55+
56+
log.info("Intercepting: {}, Token: {}", requestURI, token != null ? "present" : "null");
57+
58+
try {
59+
// 验证token
60+
if (!jwtUtil.validateToken(token)) {
61+
log.warn("Token validation failed");
62+
throw new ServiceException(ExceptionEnum.CM339.getResultCode(), ExceptionEnum.CM339.getResultMsg());
63+
}
64+
65+
// 从token中获取用户信息
66+
String username = jwtUtil.getUsernameFromToken(token);
67+
String userId = jwtUtil.getUserIdFromToken(token);
68+
String roles = jwtUtil.getRolesFromToken(token);
69+
Integer platformId = jwtUtil.getPlatformIdFromToken(token);
70+
71+
72+
// 检查必需的用户信息
73+
if (username == null || username.isEmpty() || userId == null) {
74+
log.warn("User information is incomplete - username: {}, userId: {}", username, userId);
75+
throw new ServiceException(ExceptionEnum.CM339.getResultCode(), ExceptionEnum.CM339.getResultMsg());
76+
}
77+
int userIdInt;
78+
try {
79+
userIdInt = Integer.parseInt(userId);
80+
} catch (NumberFormatException e) {
81+
log.error("Invalid userId format: {}", userId);
82+
throw new ServiceException(ExceptionEnum.CM342.getResultCode(), ExceptionEnum.CM342.getResultMsg());
83+
}
84+
List<Tenant> tenants = authUsersUnitsRolesMapper.queryAllTenantByUserId(userIdInt);
85+
if (tenants == null) {
86+
log.warn("No tenants found for userId: {}", userId);
87+
throw new ServiceException(ExceptionEnum.CM340.getResultCode(), ExceptionEnum.CM340.getResultMsg());
88+
}
89+
90+
if (!"null".equals(org) && org != null) {
91+
boolean findOrg = false;
92+
for (Tenant tenant : tenants) {
93+
tenant.setIsInUse(tenant.getId().equals(org));
94+
if (tenant.getIsInUse()) {
95+
findOrg = true;
96+
}
97+
}
98+
if (!findOrg) {
99+
log.warn("X-Lowcode-Org not found in user's tenants - X-Lowcode-Org: {}", org);
100+
throw new ServiceException(ExceptionEnum.CM341.getResultCode(), ExceptionEnum.CM341.getResultMsg());
101+
}
102+
}
103+
// 存储用户信息到LoginUserContext
104+
UserInfo userInfo = new UserInfo(userId, username, tenants);
105+
106+
userInfo.setPlatformId(platformId != null ? platformId : 0);
107+
userInfo.setRoles(roles != null ? roles : "USER");
108+
userInfo.setToken(token);
109+
110+
DefaultLoginUserContext.setCurrentUser(userInfo);
111+
112+
log.info("Token validated and user context set for user: {}", username);
113+
return true;
114+
115+
} catch (Exception e) {
116+
log.error("Token validation exception: {}", e.getMessage(), e);
117+
DefaultLoginUserContext.clear();
118+
if(e instanceof ServiceException) {
119+
throw e;
120+
}
121+
throw new ServiceException(ExceptionEnum.CM339.getResultCode(), ExceptionEnum.CM339.getResultMsg());
122+
}
123+
}
124+
125+
@Override
126+
public void afterCompletion(HttpServletRequest request,
127+
HttpServletResponse response, Object handler, Exception ex) {
128+
// 请求完成后清理用户上下文
129+
DefaultLoginUserContext.clear();
130+
131+
log.debug("Cleared user context for request completion");
132+
}
102133
}

base/src/main/java/com/tinyengine/it/login/config/context/DefaultLoginUserContext.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ public class DefaultLoginUserContext implements LoginUserContext {
1818
private static final int DEFAULT_PLATFORM = 1;
1919
private static final String DEFAULT_TENANT = "1";
2020

21+
22+
2123
/**
2224
* 返回当前用户所在的业务租户id
2325
*
@@ -31,11 +33,15 @@ public String getTenantId() {
3133
return DEFAULT_TENANT;
3234
}
3335
for (Tenant tenant : tenantList) {
34-
if (tenant.getIsInUse()) {
35-
return tenant.getId();
36+
if(tenant.getIsInUse()!=null){
37+
if (tenant.getIsInUse()) {
38+
return tenant.getId();
39+
}
40+
}else{
41+
return tenantList.get(0).getId();
3642
}
37-
}
3843

44+
}
3945
return DEFAULT_TENANT;
4046
}
4147

@@ -69,6 +75,7 @@ public void setTenants(List<Tenant> tenants) {
6975
CURRENT_USER.set(userInfo);
7076
}
7177

78+
7279
/**
7380
* 设置当前用户信息
7481
*/

0 commit comments

Comments
 (0)