提交 69b04a25 作者: zhaibin

新增员工权限校验

父级 57e13f4e
package com.cmeeting;
import com.azure.core.credential.TokenRequestContext;
import com.azure.identity.ClientSecretCredential;
import com.azure.identity.ClientSecretCredentialBuilder;
import com.nimbusds.jose.shaded.gson.Gson;
import okhttp3.*;
import com.google.gson.JsonObject;
import java.io.IOException;
public class GraphApiWithOkHttp {
static String CLIENT_ID = "d65aa91b-05f4-42b2-9/**/02f-4d82ea5a2b93";
static String TENANT_ID = "74cc8acf-aacc-4514-9bbb-dc27ce3096bb"; // or "common" for multi-tenant apps
static String CLIENT_SECRET = "~N98Q~83v6dViQFIofwr0fRn4J5VEZ2tvwOz.bPX";
private static final String USER_EMAIL = "binzhai321@outlook.com"; // 发送邮件的用户
public static void main(String[] args) throws IOException {
ClientSecretCredential credential = new ClientSecretCredentialBuilder()
.clientId("d65aa91b-05f4-42b2-902f-4d82ea5a2b93")
.clientSecret("~N98Q~83v6dViQFIofwr0fRn4J5VEZ2tvwOz.bPX")
.tenantId("74cc8acf-aacc-4514-9bbb-dc27ce3096bb")
.build();
// 1. 获取 Access Token
String token = credential.getToken(
new TokenRequestContext()
.addScopes("https://graph.microsoft.com/.default"))
.block().getToken();
System.out.println("获取到的令牌: " + token);
String token1 ="EwBYBMl6BAAUBKgm8k1UswUNwklmy2v7U/S+1fEAAUa0jd3QNQBdqTy9ZwEaLPqqapU5zHFRz4XvGqbI7jN7x01mEvBtCSFgYtNiSOEb5s1UwLxl6HwlHFqfJsqDsoCicvnlqCWjsaR/4wPZgXxd+pBhHRSPl+tJcSzz2NJB+dy81wHcSaU4bRxCIgoU7MtrW2ak9DhGisnK4/vxHkzxuIjHe9IDOZBzwzAtTZhycWRoAtuQrC1iu/kuKGJaU9noNjsOwfHUaXRz68g6niSdPT8P6zOa2vlOHjhXh478ms1PhqKeTkS+nkTurT2Gc5qRJviICiiAlK4BlxV70tOA6xEtl2ApXOrfFr+rlv4pASmPewtbdkTHnpP3H0R9L0kQZgAAEF4HO14XaFxPCdIqniVBvSkgA75wLsTuUZragTXGu71SV7ccLi26nZ+9KZlulf8dAlj/NEdheqtdEHb+BOLknQoXFEJ0UNj6PLkczzHfV3Yr5zlXJICwb3yI9vrFTUCb555ux/P904vXCY900UNgX81gBIYJQIJtOCURDAcHWtxyWvfNlkr17fKgnX5KdDyec6JK9tgzPi62LlqhDcoR/W/4MTCZhfJRlZgdYkI52pQSbDJItR6W7xfZguXPgKRHVcZJTzlybtOW0kbrfv96CKrryKzGeRjZyEcov1U3VjAoBUllgi3+LdIFK86aojMuBP+v5PvRq81qZS2q5roIRJD5zydu1selrpwhrZjm2nupDxHGjvfj2TVZJlz1zGYsVYrSRz2+st+2UbZagR1fbPRX2GilTfDyN05HV//LrfdrddbffMImxY2M8D9iQZFSjBYSFa20S9Vs9/yj08M9ljwiJifHGjX2o/arR63SWe3pbga26EC+j8JaBemhAhPsu91xW4o7+j/xEUadXR2NDbuogMq+MeINKe3PqAAFeTva1ZWZF5p3oGVIQKL4pcQFA9xEwopoN+vSeHDuAOvTFQ/4PukxicJdFTiaZquGeQMF0sLFvLdddpvS3Xaf17fPxjMUlMGcjYQ8gK5XG5wzjR8Up4MZZyX3xiK/hccGOp5pwi8WAN5cVmTKZOSXTkHUGEQT4rcGUYTPduHYMjjrVpzffpnmqfO92VA7a7fuYqXKp3NPikv17s6PTVr6b4+24AP8u3MEhDHU2YjaMuFR3jBUYLxtm443Gn58MC7oYrmQIVN2VYJrxADgStqpE+3nUCyKajmF0q5U+LUI1cCYnOKgmAkrpN71qlB9GeQLLQDJytG2sg64NG/h3CN1SseudSYtmqM3XUURSsztB9dNL7xmHQAcEBYMVjec5N5jHLhIs48rxAqI/WAJ/2RFKWgJIeCUJ8v4oQYEI9lAlWgReVhrjcNxRsbuVDFFwU7cTSeY9bJzxSX5kWJ8TXr/Q/SELEViUVCz10Cw/sOtm4urke538R4yXlR1wfMk3S86xlOfc3HJ6Iz7hi1h2fovWA9T1ceFWQM=";
// 2. 使用 OkHttp 发送邮件
sendEmail(token1);
}
// 使用 Graph API 发送邮件
private static void sendEmail(String accessToken) throws IOException {
OkHttpClient client = new OkHttpClient();
// 构建邮件内容 (JSON 格式)
String emailJson = "{\n" +
" \"message\": {\n" +
" \"subject\": \"Test Email\",\n" +
" \"body\": {\n" +
" \"contentType\": \"Text\",\n" +
" \"content\": \"This is a test email.\"\n" +
" },\n" +
" \"toRecipients\": [\n" +
" {\n" +
" \"emailAddress\": {\n" +
" \"address\": \"mengfan@itcast.cn\"\n" +
" }\n" +
" }\n" +
" ]\n" +
" }\n" +
"}";
// 构建请求
Request request = new Request.Builder()
.url("https://graph.microsoft.com/v1.0/users/" + USER_EMAIL + "/sendMail")
.post(RequestBody.create(emailJson, MediaType.parse("application/json")))
.addHeader("authorization", "Bearer " + accessToken)
.addHeader("Content-Type", "application/json")
.build();
// 发送请求
try (Response response = client.newCall(request).execute()) {
if (response.isSuccessful()) {
System.out.println("Email sent successfully!");
} else {
System.err.println("Failed to send email: " + response.code() + " - " + response.message());
System.err.println(response.body().string()); // 打印错误详情
}
}
}
}
\ No newline at end of file
package com.cmeeting; package com.cmeeting;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.cmeeting.mapper.primary.AuthMapper;
import com.cmeeting.mapper.primary.UserCompanyMapper; import com.cmeeting.mapper.primary.UserCompanyMapper;
import com.cmeeting.mapper.primary.UserIdMapper; import com.cmeeting.mapper.primary.UserIdMapper;
import com.cmeeting.mapper.secondary.SysUserMapper;
import com.cmeeting.pojo.CoreModulePermissions;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
...@@ -22,7 +25,6 @@ import org.springframework.beans.factory.annotation.Autowired; ...@@ -22,7 +25,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import javax.crypto.Cipher; import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec; import javax.crypto.spec.SecretKeySpec;
...@@ -34,6 +36,7 @@ import java.util.*; ...@@ -34,6 +36,7 @@ import java.util.*;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Base64; import java.util.Base64;
import java.util.stream.Collectors;
@RestController @RestController
@RequestMapping @RequestMapping
...@@ -41,19 +44,22 @@ public class TencentMeetingCallbackController { ...@@ -41,19 +44,22 @@ public class TencentMeetingCallbackController {
private static final Logger logger = LoggerFactory.getLogger(TencentMeetingCallbackController.class); private static final Logger logger = LoggerFactory.getLogger(TencentMeetingCallbackController.class);
// 配置参数 - 从配置文件或环境变量获取 // 配置参数 - 从配置文件或环境变量获取
private final String token = "RTLqcY5yXzPleC8MubLdoSwrQ"; private final String token = "abIDNnBYRXMIZ5kbLjzjQ8Xz3";
private final String encodingAESKey = "Fo8Kb9ooj2Jd2E0GwSRT6OoZ7Pim8Ndmk0CSVkC5RX1"; private final String encodingAESKey = "1S47Q21Yz6Bdcxm5obrer4JEeeT61NW2WJCPV7C7Xz6";
// 1.构造 client 客户端(jwt 鉴权需要配置 appId sdkId secretID 和 secretKey) // 1.构造 client 客户端(jwt 鉴权需要配置 appId sdkId secretID 和 secretKey)
Client client = new Client.Builder() Client client = new Client.Builder()
.withAppId("211153201").withSdkId("28370276340") .withAppId("210468336").withSdkId("28790143843")
.withSecret("BKOMDZVbvh0iT7k6UHsSizAWBCOVDtT6", "3Y1j0mzNp7KChKFJGyaEnZHLobFoAQ8eLwfaMx8nLbtXAerO") .withSecret("0ks7u8cgQ8DGVtlYZeRA9TxZCjvUT3oL", "gQU09rkJjiQfiGcUYdhiKq5Ol6LebXg4w7F7Ol0rwvvdv3Xy")
.build(); .build();
@Autowired @Autowired
private UserIdMapper userIdMapper; private UserIdMapper userIdMapper;
@Autowired @Autowired
private UserCompanyMapper userCompanyMapper; private UserCompanyMapper userCompanyMapper;
@Autowired
private SysUserMapper sysUserMapper;
@Autowired
private AuthMapper authMapper;
/** /**
* 处理GET请求 - URL验证 * 处理GET请求 - URL验证
*/ */
...@@ -110,38 +116,70 @@ public class TencentMeetingCallbackController { ...@@ -110,38 +116,70 @@ public class TencentMeetingCallbackController {
// 3. 解密data // 3. 解密data
String decryptedData = decryptData(encryptedData); String decryptedData = decryptData(encryptedData);
logger.info("Decrypted event data: {}", decryptedData); logger.info("Decrypted event data: {}", decryptedData);
// 4. 处理业务逻辑(可根据需要扩展)
//todo 调用AIGC接口 查询该用户是否有会议助手权限,如果有则执行,如果没有则直接返回
try { try {
ObjectMapper objectMapper = new ObjectMapper(); ObjectMapper objectMapper = new ObjectMapper();
JsonNode rootNode = objectMapper.readTree(decryptedData); JsonNode rootNode = objectMapper.readTree(decryptedData);
JsonNode firstPayload = rootNode.path("payload").get(0); JsonNode firstPayload = rootNode.path("payload").get(0);
String userId = firstPayload.path("operator").path("userid").asText(); String userId = firstPayload.path("operator").path("userid").asText();
// 通过腾讯的userid查询到企业微信的userid
String wid = userIdMapper.getWidByTid(userId);
logger.info("该用户的工号id:{},",wid);
// 调用admin的find接口查询用户信息包括用户的部门id路径
String userDeptPath = sysUserMapper.getUserDeptPath(wid);
logger.info("该用户的部门路径:{},",userDeptPath);
List<String> deptPath = null;
if (userDeptPath != null && !userDeptPath.isEmpty()) {
// 使用split方法分割字符串,并过滤掉空字符串
deptPath = Arrays.stream(userDeptPath.split("/"))
.filter(s -> !s.isEmpty())
.collect(Collectors.toList());
}
logger.info("分割后的部门路径列表:{}", deptPath);
//todo authList接口对应方法获取语音助手的权限的用户和部门列表
//通过智能体id查询该id下的部门和用户
String targetId = "1815393211829587968";
String teantId = "1806976109082972160";
List<CoreModulePermissions> auths = authMapper.getAuthByTargrtId(targetId,teantId);
// 创建两个集合分别存储type=0(部门)和type=1(员工)的数据
List<CoreModulePermissions> type0List = new ArrayList<>();
List<CoreModulePermissions> type1List = new ArrayList<>();
for (CoreModulePermissions auth : auths) {
if (auth.getType() == 0) {
type0List.add(auth);
} else if (auth.getType() == 1) {
type1List.add(auth);
}
// 如果type为null或其他值,这里会被忽略
}
// 检查权限
boolean hasPermission = false;
// 1. 先检查员工是否在type1List中
for (CoreModulePermissions empAuth : type1List) {
if (wid.equals(empAuth.getRelId())) {
hasPermission = true;
logger.info("员工{}在直接授权列表中", wid);
break;
}
}
// 2. 如果员工不在直接授权列表中,检查部门权限
if (!hasPermission && !deptPath.isEmpty()) {
for (CoreModulePermissions deptAuth : type0List) {
if (deptPath.contains(deptAuth.getRelId())) {
hasPermission = true;
logger.info("员工{}通过部门{}获得权限", wid, deptAuth.getRelId());
break;
}
}
}
if (hasPermission){
processEvent(decryptedData);
}
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
//todo 通过腾讯的userid查询到企业微信的userid
//todo 调用admin的find接口查询用户信息包括用户的部门id路径
//todo authList接口对应方法获取语音助手的权限的用户和部门列表
//todo 判断该用户是否在该列表中
processEvent(decryptedData);
// 5. 返回成功响应(必须严格匹配) // 5. 返回成功响应(必须严格匹配)
return ResponseEntity.ok("successfully received callback"); return ResponseEntity.ok("successfully received callback");
} catch (Exception e) { } catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("Error: " + e.getMessage()); .body("Error: " + e.getMessage());
...@@ -347,7 +385,7 @@ public class TencentMeetingCallbackController { ...@@ -347,7 +385,7 @@ public class TencentMeetingCallbackController {
java.util.Map<String, Object> result = resultmapper.readValue(rawBodyString, java.util.Map.class); java.util.Map<String, Object> result = resultmapper.readValue(rawBodyString, java.util.Map.class);
String downloadUrl = ((java.util.List<String>) result.get("download_url")).get(0); String downloadUrl = ((java.util.List<String>) result.get("download_url")).get(0);
// 设置保存路径为D盘根目录 // 设置保存路径为D盘根目录
String savePath = "D:/" + meetingId + ".docx"; // 或者 "D:\\downloaded_file.docx" String savePath = "D:/" + meetingId + ".docx";
String targetPath = "D:/" + meetingId + "纪要" + ".docx"; String targetPath = "D:/" + meetingId + "纪要" + ".docx";
// 下载文件 // 下载文件
// System.out.println("开始下载文件到: " + savePath); // System.out.println("开始下载文件到: " + savePath);
......
package com.cmeeting.mapper.primary;
import com.cmeeting.pojo.CoreModulePermissions;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface AuthMapper {
List<CoreModulePermissions> getAuthByTargrtId(String targetId, String teantId);
}
package com.cmeeting.mapper.secondary;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper
public interface SysUserMapper {
String getUserDeptPath(@Param("userId") String userId);
}
package com.cmeeting.pojo;
import lombok.Data;
import java.util.Date;
/**
* 核心模块权限实体类
*/
@Data
public class CoreModulePermissions {
/**
* 主键ID
*/
private String id;
/**
* 类型(0:分类, 1:用户)
*/
private Integer type;
/**
* 用户类型(0:自建, 1:应用, 2:通讯录)
*/
private Integer userType;
/**
* 来源(0:角色授权, 1:应用授权, 2:文档授权)
*/
private Integer source;
/**
* 关联ID
*/
private String relId;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
/**
* 目标ID
*/
private String targetId;
/**
* 租户ID
*/
private String tenantId;
// 无参构造方法
public CoreModulePermissions() {
}
// 全参构造方法
public CoreModulePermissions(String id, Integer type, Integer userType, Integer source,
String relId, Date createTime, Date updateTime,
String targetId, String tenantId) {
this.id = id;
this.type = type;
this.userType = userType;
this.source = source;
this.relId = relId;
this.createTime = createTime;
this.updateTime = updateTime;
this.targetId = targetId;
this.tenantId = tenantId;
}
@Override
public String toString() {
return "CoreModulePermissions{" +
"id='" + id + '\'' +
", type=" + type +
", userType=" + userType +
", source=" + source +
", relId='" + relId + '\'' +
", createTime=" + createTime +
", updateTime=" + updateTime +
", targetId='" + targetId + '\'' +
", tenantId='" + tenantId + '\'' +
'}';
}
}
\ No newline at end of file
...@@ -10,13 +10,13 @@ tencent.meeting.aesKey=agy6ALUePp34lljWz1uIQWa7yQq3dgxxQNmfaN9GROm ...@@ -10,13 +10,13 @@ tencent.meeting.aesKey=agy6ALUePp34lljWz1uIQWa7yQq3dgxxQNmfaN9GROm
# spring.datasource.driver-class-name=com.mysql.jdbc.Driver # spring.datasource.driver-class-name=com.mysql.jdbc.Driver
# ?????primary? # ?????primary?
spring.datasource.primary.jdbc-url=jdbc:mysql://192.168.10.155:3306/cmeeting?useSSL=false&characterEncoding=utf8&serverTimezone=UTC spring.datasource.primary.jdbc-url=jdbc:mysql://192.168.10.155:3306/robot-standard-enterprise-aigc?useSSL=false&characterEncoding=utf8&serverTimezone=UTC
spring.datasource.primary.username=root spring.datasource.primary.username=root
spring.datasource.primary.password=qizhi123 spring.datasource.primary.password=qizhi123
spring.datasource.primary.driver-class-name=com.mysql.jdbc.Driver spring.datasource.primary.driver-class-name=com.mysql.jdbc.Driver
# ?????secondary? # ?????secondary?
spring.datasource.secondary.jdbc-url=jdbc:mysql://192.168.10.155:3306/user_admin?useSSL=false&characterEncoding=utf8&serverTimezone=UTC spring.datasource.secondary.jdbc-url=jdbc:mysql://192.168.10.155:3306/user-admin?useSSL=false&characterEncoding=utf8&serverTimezone=UTC
spring.datasource.secondary.username=root spring.datasource.secondary.username=root
spring.datasource.secondary.password=qizhi123 spring.datasource.secondary.password=qizhi123
spring.datasource.secondary.driver-class-name=com.mysql.jdbc.Driver spring.datasource.secondary.driver-class-name=com.mysql.jdbc.Driver
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cmeeting.mapper.primary.AuthMapper">
<select id="getAuthByTargrtId" resultType="com.cmeeting.pojo.CoreModulePermissions">
SELECT
id,
type,
user_type AS userType,
source,
rel_id AS relId,
create_time AS createTime,
update_time AS updateTime,
target_id AS targetId,
tenant_id AS tenantId
FROM
core_module_permissions
WHERE
target_id = #{targetId}
<if test="teantId != null and teantId != ''">
AND tenant_id = #{teantId}
</if>
</select>
</mapper>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cmeeting.mapper.secondary.SysUserMapper">
<select id="getUserDeptPath" resultType="java.lang.String">
SELECT t2.path
FROM sys_user t1
LEFT JOIN sys_user_category t2 ON t1.category_id = t2.id AND t2.is_del = 0
WHERE t1.id = #{userId} AND t1.is_del = 0
</select>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cmeeting.mapper.primary.UserCompanyMapper">
<!-- 根据 userId 查询 email -->
<select id="selectEmailByUserId" parameterType="string" resultType="string">
SELECT email
FROM user_company
WHERE user_id = #{userId}
</select>
</mapper>
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论