AuthzService.java
5.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package com.xly.service;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/**
* xlyAi 侧授权层 —— 表单级白名单(架构 §7)。
*
* <p>后端逐用户表单权限被关(只验登录 + 租户 + 行级),所以在 agent 侧按用户实际授权把可碰的
* 表单/菜单限制住。数据源与后端一致(`sysjurisdiction`,即 `getsAuthsIdNew` 的逻辑)——不新造。
*
* <p>管理员(sysadmin/admin) = 全部权限(返回 null);否则 = 该用户有权的 id 集合(菜单/表单/按钮,
* 由 `sysjurisdiction.sKey` 按 '-' 拆出)。当前本地 dev-login 以 admin 身份运行,因此实际全通;
* 生产透传用户 token 时即按各用户真实授权收紧。Read / Query / Write 共用此边界。
*/
@Service
public class AuthzService {
private final JdbcTemplate jdbc;
@Value("${erp.dev-login.username:admin}")
private String devUserNo;
@Value("${erp.dev-login.brand:1111111111}")
private String devBrand;
@Value("${erp.dev-login.subsidiary:1111111111}")
private String devSub;
@Value("${erp.dev-login.usertype:sysadmin}")
private String devUserType;
public AuthzService(JdbcTemplate jdbc) {
this.jdbc = jdbc;
}
/** 当前有效用户(本地=dev-login)能否访问该菜单/表单 id。 */
public boolean canAccessModule(String moduleId) {
Set<String> granted = grantedIds(resolveDevUserId(), devUserType, devBrand, devSub);
return isAllowed(granted, moduleId);
}
/** null = 全部(管理员);否则 = 有权的 id 集合。 */
public Set<String> grantedIds(String userId, String userType, String brandsId, String subsidiaryId) {
if (isAdmin(userType)) {
return null; // 超管全部权限
}
Set<String> ids = new HashSet<>();
if (userId == null) {
return ids;
}
List<Map<String, Object>> rows;
Integer direct = safeCount(
"SELECT COUNT(*) FROM sysjurisdiction WHERE sBrandsId=? AND sSubsidiaryId=? AND sUserId=?",
brandsId, subsidiaryId, userId);
if (direct != null && direct > 0) {
rows = jdbc.queryForList(
"SELECT J.sKey AS sKey FROM sysjurisdiction J WHERE J.sBrandsId=? AND J.sSubsidiaryId=? AND J.sUserId=?",
brandsId, subsidiaryId, userId);
} else {
String groups = queryStr(
"SELECT GROUP_CONCAT(sJurisdictionClassifyId) FROM sftlogininfojurisdictiongroup " +
"WHERE sBrandsId=? AND sSubsidiaryId=? AND sParentId=? " +
"AND sJurisdictionClassifyId IN (SELECT sId FROM sisjurisdictionclassify WHERE bLogininfoShow=0)",
brandsId, subsidiaryId, userId);
if (groups == null || groups.isBlank()) {
return ids;
}
List<String> gl = Arrays.asList(groups.split(","));
String in = gl.stream().map(g -> "?").collect(Collectors.joining(","));
List<Object> args = new ArrayList<>();
args.add(brandsId);
args.add(subsidiaryId);
args.addAll(gl);
rows = jdbc.queryForList(
"SELECT J.sKey AS sKey FROM sysjurisdiction J WHERE J.sBrandsId=? AND J.sSubsidiaryId=? " +
"AND J.sJurisdictionClassifyId IN (" + in + ")", args.toArray());
}
for (Map<String, Object> r : rows) {
Object k = r.get("sKey");
if (k != null) {
for (String part : k.toString().split("-")) {
if (!part.isBlank()) {
ids.add(part);
}
}
}
}
return ids;
}
public boolean isAllowed(Set<String> granted, String... ids) {
if (granted == null) {
return true; // 管理员
}
for (String id : ids) {
if (id != null && granted.contains(id)) {
return true;
}
}
return false;
}
private String resolveDevUserId() {
return queryStr("SELECT sId FROM gdslogininfo WHERE sUserNo=? AND sBrandsId=? LIMIT 1", devUserNo, devBrand);
}
private boolean isAdmin(String userType) {
return userType != null && (userType.equalsIgnoreCase("sysadmin") || userType.equalsIgnoreCase("admin"));
}
private Integer safeCount(String sql, Object... args) {
try {
return jdbc.queryForObject(sql, Integer.class, args);
} catch (Exception e) {
return 0;
}
}
private String queryStr(String sql, Object... args) {
try {
List<Map<String, Object>> r = jdbc.queryForList(sql, args);
if (!r.isEmpty()) {
Object v = r.get(0).values().iterator().next();
return v == null ? null : v.toString();
}
} catch (Exception ignore) {
}
return null;
}
}