You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

413 lines
16 KiB

/*
* Copyright (C), 2018-2021
* Project: starter
* FileName: CallBackController
* Author: xxx
* Date: 2021/3/29 22:36
*/
package com.fr.plugin.xxx.dingtalksyn.request;
import com.dingtalk.api.response.OapiRoleGetroleResponse;
import com.dingtalk.api.response.OapiV2DepartmentGetResponse;
import com.dingtalk.api.response.OapiV2UserGetResponse;
import com.dingtalk.oapi.lib.aes.DingTalkEncryptor;
import com.fanruan.api.decision.user.UserKit;
import com.fanruan.api.i18n.I18nKit;
import com.fanruan.api.log.LogKit;
import com.fanruan.api.util.StringKit;
import com.fr.decision.authority.base.constant.type.operation.ManualOperationType;
import com.fr.decision.authority.data.User;
import com.fr.decision.webservice.annotation.LoginStatusChecker;
import com.fr.decision.webservice.bean.user.RoleBean;
import com.fr.decision.webservice.bean.user.UserBean;
import com.fr.decision.webservice.bean.user.UserUpdateBean;
import com.fr.decision.webservice.v10.user.CustomRoleService;
import com.fr.decision.webservice.v10.user.DepartmentService;
import com.fr.decision.webservice.v10.user.UserService;
import com.fr.json.JSONArray;
import com.fr.json.JSONObject;
import com.fr.plugin.context.PluginContexts;
import com.fr.plugin.xxx.dingtalksyn.bean.DataResponse;
import com.fr.plugin.xxx.dingtalksyn.config.DingSynConfig;
import com.fr.plugin.xxx.dingtalksyn.kit.CustomRoleServiceKit;
import com.fr.plugin.xxx.dingtalksyn.kit.DepartmentServiceKit;
import com.fr.plugin.xxx.dingtalksyn.kit.UserServiceKit;
import com.fr.plugin.xxx.dingtalksyn.utils.DingTokenUtils;
import com.fr.third.springframework.stereotype.Controller;
import com.fr.third.springframework.web.bind.annotation.*;
import com.taobao.api.ApiException;
import javax.servlet.http.HttpServletResponse;
import static com.fr.plugin.xxx.dingtalksyn.utils.DingAPI.*;
/**
* <Function Description><br>
* <CallBackController>
*
* @author xxx
* @since 1.0.0
*/
@Controller
@RequestMapping("dingCallback")
public class CallBackController {
/**
* 测试检查url
*/
public static final String EVENT_CHECK_URL = "check_url";
/**
* 创建应用,验证回调URL创建有效事件(第一次保存回调URL之前)
*/
public static final String EVENT_CHECK_CREATE_SUITE_URL = "check_create_suite_url";
/**
* 创建应用,验证回调URL变更有效事件(第一次保存回调URL之后)
*/
public static final String EVENT_CHECK_UPADTE_SUITE_URL = "check_update_suite_url";
/**
* suite_ticket推送事件
*/
public static final String EVENT_SUITE_TICKET = "suite_ticket";
/**
* 企业授权开通应用事件
*/
public static final String EVENT_TMP_AUTH_CODE = "tmp_auth_code";
public static final String USER_ADD_ORG = "user_add_org";
public static final String USER_MODIFY_ORG = "user_modify_org";
public static final String USER_LEAVE_ORG = "user_leave_org";
public static final String USER_ACTIVE_ORG = "user_active_org";
public static final String ORG_DEPT_CREATE = "org_dept_create";
public static final String ORG_DEPT_MODIFY = "org_dept_modify";
public static final String ORG_DEPT_REMOVE = "org_dept_remove";
public static final String LABEL_USER_CHANGE = "label_user_change";
public static final String LABEL_CONF_ADD = "label_conf_add";
public static final String LABEL_CONF_DEL = "label_conf_del";
public static final String LABEL_CONF_MODIFY = "label_conf_modify";
public static final String ACTION_ADD = "add";
public static final String ACTION_REMOVE = "remove";
private DingSynConfig config;
private String adminName;
public CallBackController() {
this.config = DingSynConfig.getInstance();
}
@RequestMapping(method = RequestMethod.POST)
@ResponseBody
@LoginStatusChecker(required = false)
public DataResponse doAction(@RequestParam(value = "signature") String signature,
@RequestParam(value = "timestamp") Long timestamp,
@RequestParam(value = "nonce") String nonce,
@RequestBody(required = false) String bodyContent,
HttpServletResponse res) {
if (!PluginContexts.currentContext().isAvailable()) {
DingSynConfig.getInstance().setSsoEnable(false);
return DataResponse.error("501", I18nKit.getLocText("Plugin-dingtalksyn_Error_501"));
}
try {
JSONObject bodyJson = new JSONObject(bodyContent);
String encryptMsg = bodyJson.getString("encrypt");
DingTalkEncryptor dingTalkEncryptor = new DingTalkEncryptor(this.config.getToken(), this.config.getAesKey(), this.config.getAppKey());
String decryptMsg = dingTalkEncryptor.getDecryptMsg(signature, timestamp.toString(), nonce, encryptMsg);
JSONObject event = new JSONObject(decryptMsg);
this.adminName = UserService.getInstance().getAdminUserNameList().get(0);
setHeader(res);
operation(event);
return DataResponse.success(dingTalkEncryptor.getEncryptedMap("success", timestamp, nonce));
} catch (Exception e) {
LogKit.error(e.getMessage(), e);
return DataResponse.error("500", I18nKit.getLocText("Plugin-dingtalksyn_Error_500"));
}
}
/**
* 企业应用业务事件处理
*
* @param event
* @return
*/
private void operation(JSONObject event) throws Exception {
String eventType = event.getString("EventType");
LogKit.info("dingtalksyn-CallBackController-operation-eventType:{}", eventType);
switch (eventType) {
case EVENT_CHECK_URL:
// 测试回调url事件 无操作,只返回success信息
break;
case EVENT_CHECK_CREATE_SUITE_URL:
// 验证新创建的回调URL,只返回success信息
break;
case EVENT_CHECK_UPADTE_SUITE_URL:
// 验证更新回调URL,只返回success信息
break;
case EVENT_SUITE_TICKET:
// 推送suite_ticket事件,保存
DingTokenUtils.setSuiteTicket(event.getString("SuiteTicket"));
break;
case USER_ADD_ORG:
createUser(event);
break;
case USER_MODIFY_ORG:
updateUser(event);
break;
case USER_LEAVE_ORG:
deleteUser(event);
break;
case USER_ACTIVE_ORG:
addOrUpdateUser(event);
break;
case ORG_DEPT_CREATE:
createOrganization(event);
break;
case ORG_DEPT_MODIFY:
updateOrganization(event);
break;
case ORG_DEPT_REMOVE:
deleteOrganization(event);
break;
case LABEL_USER_CHANGE:
changeRoleUsers(event);
break;
case LABEL_CONF_ADD:
addRoles(event);
break;
case LABEL_CONF_DEL:
deleteRoles(event);
break;
case LABEL_CONF_MODIFY:
updateRoles(event);
break;
}
}
/**
* 员工角色信息发生变更
*
* @param event
*/
private void changeRoleUsers(JSONObject event) throws Exception {
String action = event.getString("action");
JSONArray roleIdArray = event.getJSONArray("LabelIdList");
JSONArray userIdArray = event.getJSONArray("UserIdList");
String[] userIds = new String[userIdArray.size()];
for (int i = 0; i < userIdArray.size(); i++) {
User user = UserService.getInstance().getUserByUserName(userIdArray.getString(i));
if (user == null) {
continue;
}
userIds[i] = user.getId();
}
UserUpdateBean userUpdateBean;
for (int j = 0; j < roleIdArray.size(); j++) {
userUpdateBean = new UserUpdateBean();
if (StringKit.equals(action, ACTION_ADD)) {
userUpdateBean.setAddUserIds(userIds);
}
if (StringKit.equals(action, ACTION_REMOVE)) {
userUpdateBean.setRemoveUserIds(userIds);
}
UserServiceKit.getInstance().updateRoleUsers(roleIdArray.getString(j), userUpdateBean);
}
}
/**
* 修改角色或者角色组
*
* @param event
*/
private void updateRoles(JSONObject event) throws Exception {
JSONArray roleIds = event.getJSONArray("LabelIdList");
for (int i = 0; i < roleIds.size(); i++) {
OapiRoleGetroleResponse.OpenRole openRole = getRoleResponse(roleIds.getLong(i));
RoleBean roleBean = CustomRoleService.getInstance().getCustomRole(roleIds.getString(i));
roleBean.setText(openRole.getName());
roleBean.setDescription(openRole.getName());
CustomRoleService.getInstance().editCustomRole(roleBean.getId(), roleBean);
}
}
/**
* 删除角色或者角色组
*
* @param event
*/
private void deleteRoles(JSONObject event) throws Exception {
JSONArray roleIds = event.getJSONArray("LabelIdList");
for (int i = 0; i < roleIds.size(); i++) {
CustomRoleService.getInstance().deleteCustomRole(roleIds.getString(i));
}
}
/**
* 增加角色或者角色组
*
* @param event
* @throws ApiException
*/
private void addRoles(JSONObject event) throws Exception {
JSONArray roleIds = event.getJSONArray("LabelIdList");
long roleId;
for (int i = 0; i < roleIds.size(); i++) {
roleId = roleIds.getLong(i);
OapiRoleGetroleResponse.OpenRole openRole = getRoleResponse(roleId);
RoleBean roleBean = new RoleBean(openRole.getName(), String.valueOf(roleId), openRole.getName(), ManualOperationType.KEY.toInteger());
CustomRoleServiceKit.getInstance().addCustomRole(UserServiceKit.getInstance().getAdminUserId(), roleBean);
}
}
/**
* 通讯录企业部门创建
*
* @param event
* @return
*/
private void createOrganization(JSONObject event) throws Exception {
JSONArray deptIds = event.getJSONArray("DeptId");
long deptId;
for (int i = 0; i < deptIds.size(); i++) {
deptId = deptIds.getLong(i);
OapiV2DepartmentGetResponse.DeptGetResponse deptGetResponse = getDeptResponse(deptId);
String parentId = String.valueOf(deptGetResponse.getParentId());
parentId = DepartmentServiceKit.getInstance().changeRootId(parentId);
String depName = deptGetResponse.getName();
DepartmentServiceKit.getInstance().addDepartment(String.valueOf(deptId), parentId, depName);
}
}
/**
* 更新组织事件
*
* @param event
* @return
*/
private void updateOrganization(JSONObject event) throws Exception {
JSONArray deptIds = event.getJSONArray("DeptId");
long deptId;
for (int i = 0; i < deptIds.size(); i++) {
deptId = deptIds.getLong(i);
OapiV2DepartmentGetResponse.DeptGetResponse deptGetResponse = getDeptResponse(deptId);
String departmentId = String.valueOf(deptGetResponse.getDeptId());
String depName = deptGetResponse.getName();
String parentId = String.valueOf(deptGetResponse.getParentId());
parentId = DepartmentServiceKit.getInstance().changeRootId(parentId);
DepartmentServiceKit.getInstance().editDepartment(departmentId, depName, parentId);
}
}
/**
* 删除组织事件
*
* @param event
* @return
*/
private void deleteOrganization(JSONObject event) throws Exception {
JSONArray deptIds = event.getJSONArray("DeptId");
for (int i = 0; i < deptIds.size(); i++) {
DepartmentService.getInstance().deleteDepartment(deptIds.getString(i));
}
}
/**
* 新增用户事件
*
* @param event
* @return
*/
private void createUser(JSONObject event) throws Exception {
JSONArray userIds = event.getJSONArray("UserId");
String userId;
for (int i = 0; i < userIds.size(); i++) {
userId = userIds.getString(i);
OapiV2UserGetResponse.UserGetResponse userGetResponse = getUserResponse(userId);
UserBean userBean = UserServiceKit.getInstance().createUserBean(userGetResponse);
UserService.getInstance().addUser(userBean);
}
}
/**
* 更新用户事件
*
* @param event
* @return
*/
private void updateUser(JSONObject event) throws Exception {
JSONArray userIds = event.getJSONArray("UserId");
String userId;
for (int i = 0; i < userIds.size(); i++) {
userId = userIds.getString(i);
OapiV2UserGetResponse.UserGetResponse userGetResponse = getUserResponse(userId);
UserBean userBean = UserServiceKit.getInstance().updateUserBean(userGetResponse);
if (userBean == null) {
continue;
}
UserServiceKit.getInstance().editUser(userBean);
}
}
/**
* 加入企业后用户激活
* 新增或更新用户
*
* @param event
* @throws Exception
*/
private void addOrUpdateUser(JSONObject event) throws Exception {
JSONArray userIds = event.getJSONArray("UserId");
String userId;
for (int i = 0; i < userIds.size(); i++) {
userId = userIds.getString(i);
OapiV2UserGetResponse.UserGetResponse userGetResponse = getUserResponse(userId);
UserBean userBean;
if (UserKit.existUsername(userGetResponse.getMobile())) {
userBean = UserServiceKit.getInstance().updateUserBean(userGetResponse);
if (userBean == null) {
continue;
}
UserServiceKit.getInstance().editUser(userBean);
} else {
userBean = UserServiceKit.getInstance().createUserBean(userGetResponse);
UserService.getInstance().addUser(userBean);
}
}
}
/**
* 用户离职事件
*
* @param event
* @return
*/
private void deleteUser(JSONObject event) {
JSONArray userIds = event.getJSONArray("UserId");
User user;
OapiV2UserGetResponse.UserGetResponse userGetResponse;
for (int i = 0; i < userIds.size(); i++) {
try {
userGetResponse = getUserResponse(userIds.getString(i));
if (userGetResponse == null) {
continue;
}
user = UserService.getInstance().getUserByUserName(userGetResponse.getMobile());
String[] removeUserIds = new String[]{user.getId()};
UserUpdateBean userUpdateBean = new UserUpdateBean();
userUpdateBean.setRemoveUserIds(removeUserIds);
UserService.getInstance().deleteUsers(userUpdateBean);
} catch (Exception e) {
LogKit.error(e.getMessage(), e);
}
}
}
/**
* 解决跨域访问问题
*
* @param res
*/
private void setHeader(HttpServletResponse res) {
// 跨域设置header
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
res.setHeader("Access-Control-Max-Age", "3600");
res.setHeader("Access-Control-Allow-Headers", "x-requested-with");
}
}