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
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"); |
|
} |
|
} |