记录下工作中使用钉钉的情况,此文仅为记录,有些业务并没有写出来,仅限参考
首先你需要加到你企业的钉钉组织中
然后就可以开始钉钉的审批流程,需要先创建表单
在表单中设置你需要的东西
之后点击发布会生成一个processCode
将这个code持久化到数据库,便于下次赋值的时候使用
业务内赋值
//审批
@Transactional
@Override
public String InitiateApproval(String processCode,SecurityDanger securityDanger) {
SysForm formByProcessCode = sysFormService.getSysFormByProcessCode(processCode);
for (QuerySchemaByProcessCodeResponseBody.QuerySchemaByProcessCodeResponseBodyResultSchemaContentItems item : formByProcessCode.getSchemaContent().getItems()) {
if("险情名称".equals(item.getProps().getLabel())){
//设置表单值
item.getProps().setPlaceholder(securityDanger.getDaName());
}
if("发现时间".equals(item.getProps().getLabel())){
//设置表单值
item.getProps().setPlaceholder(securityDanger.getDaTime());
}
if("上报人".equals(item.getProps().getLabel())){
//设置表单值
item.getProps().setPlaceholder(sysUserService.querySysUserByUserId(securityDanger.getFindUser()).getName());
}
if("负责人".equals(item.getProps().getLabel())){
//设置表单值
item.getProps().setPlaceholder(sysUserService.querySysUserByUserId(securityDanger.getManageUser()).getName());
}
if("处理人".equals(item.getProps().getLabel())){
//设置表单值
item.getProps().setPlaceholder(sysUserService.querySysUserByUserId(securityDanger.getHandleUser()).getName());
}
if("险情记录".equals(item.getProps().getLabel())){
//设置表单值
item.getProps().setPlaceholder(securityDanger.getDaRecord());
}
// if(item.getChildren() != null &&item.getChildren().size() >0 ){
// for (QuerySchemaByProcessCodeResponseBody.QuerySchemaByProcessCodeResponseBodyResultSchemaContentItemsChildren child : item.getChildren()) {
// if(child.getProps().getLabel().equals("物品")){
// child.getProps().setBizAlias("篮球");
// }
// if(child.getProps().getLabel().equals("数量")){
// child.getProps().setBizAlias("20");
// }
// }
// }
}
List<StartProcessInstanceRequest.StartProcessInstanceRequestApprovers> approvers =new ArrayList<>();
StartProcessInstanceRequest.StartProcessInstanceRequestApprovers requestApprovers=new StartProcessInstanceRequest.StartProcessInstanceRequestApprovers();
requestApprovers.setActionType(APPROVE_NONE);
requestApprovers.setUserIds(Arrays.asList(securityDanger.getHandleUser())); //处理人
approvers.add(requestApprovers);
//发起人, processCode,...
return dockDingTalkService.automaticInitiateProcess(securityDanger.getLaunchUser(), formByProcessCode, null, approvers);
}
/**
* 自动匹配规则 发起审核流程
* @param userId 流程发起人id
* @param form 表单值
* @return
*/
String automaticInitiateProcess(String userId, SysForm form, HashMap<String,List<String>> userIds,List<StartProcessInstanceRequest.StartProcessInstanceRequestApprovers> approvers);
@Override
public String automaticInitiateProcess(String userId,SysForm form,HashMap<String,List<String>> userIds,List<StartProcessInstanceRequest.StartProcessInstanceRequestApprovers> approvers) {
if(form == null){
throw new BusinessException(OAEXCEPTION_FORM_NOTEXIST);
}
//获取用户信息
SysUser user = sysUserService.querySysUserByUserId(userId);
if(StringUtils.isBlank(form.getFormCode())){
throw new BusinessException(OAEXCEPTION_FORM_IDISNULL);
}
if(user==null){
throw new BusinessException("用户不存在");
}
com.aliyun.dingtalkworkflow_1_0.Client client = null;
try {
client = createClient();
} catch (Exception e) {
e.printStackTrace();
}
//获取用户部门信息
UserDept dept = userDeptService.getUserDeptByUserId(userId);
//获取钉钉token
String talkToken = redisTemplate.opsForValue().get("DingTalkToken");
//创建流程对象
StartProcessInstanceHeaders startProcessInstanceHeaders = new StartProcessInstanceHeaders();
//设置钉钉token
startProcessInstanceHeaders.xAcsDingtalkAccessToken = talkToken;
//todo 获取钉钉表单设置的流程节点
ProcessForecastResponseBody.ProcessForecastResponseBodyResult responseBodyResult = getNode(form, form.getFormCode(), dept.getDeptId(), userId);
//转化节点
List<StartProcessInstanceRequest.StartProcessInstanceRequestTargetSelectActioners> targetSelectActioners = dingTalkUtils.setStartProcessInstanceRequestTargetSelectActioners(responseBodyResult,userIds);
//转化表单
List<StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues> formComponentValues = dingTalkUtils.toFormOne(form);
StartProcessInstanceRequest startProcessInstanceRequest = new StartProcessInstanceRequest()
//设置审批发起人的userId
.setOriginatorUserId(userId)
//设置审批流的唯一码
.setProcessCode(form.getFormCode())
//设置部门id
.setDeptId(dept.getDeptId())
//设置应用编码
.setMicroappAgentId(agentId)
//设置表单
.setFormComponentValues(
formComponentValues
);
//如果是自定义审核人 走自定义流程
if(approvers != null && approvers.size() >0){
//设置审核人
startProcessInstanceRequest.setApprovers(approvers);
}else{
//设置默认流程节点
startProcessInstanceRequest.setTargetSelectActioners(
targetSelectActioners
);
}
try {
//发起流程
StartProcessInstanceResponse response = client.startProcessInstanceWithOptions(startProcessInstanceRequest, startProcessInstanceHeaders, new RuntimeOptions());
//返回流程id
return response.getBody().getInstanceId();
} catch (TeaException err) {
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
log.error(err.message);
// err 中含有 code 和 message 属性,可帮助开发定位问题
}
} catch (Exception _err) {
TeaException err = new TeaException(_err.getMessage(), _err);
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
log.error(err.message);
// err 中含有 code 和 message 属性,可帮助开发定位问题
}
}
return null;
}
toFormOne方法
public List<StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues> toFormOne(SysForm sysForm) {
List<StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues> formComponentValues0 = new ArrayList<>();
for (QuerySchemaByProcessCodeResponseBody.QuerySchemaByProcessCodeResponseBodyResultSchemaContentItems item : sysForm
.getSchemaContent().getItems()) {
StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues requestFormComponentValues = new StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues();
requestFormComponentValues.setName(item.getProps().getLabel());
if (item.getChildren() == null || item.getChildren().size() == 0) {
requestFormComponentValues.setValue(item.getProps().getPlaceholder());
}
else {
JSONArray rowValue2 = new JSONArray();
for (QuerySchemaByProcessCodeResponseBody.QuerySchemaByProcessCodeResponseBodyResultSchemaContentItemsChildren child : item
.getChildren()) {
JSONObject rowValue3 = new JSONObject();
rowValue3.put("name", child.getProps().getLabel());
rowValue3.put("value", child.getProps().getBizAlias());
rowValue2.add(rowValue3);
}
JSONArray rowValue3 = new JSONArray();
rowValue3.add(rowValue2);
requestFormComponentValues.setValue(rowValue3.toJSONString());
}
formComponentValues0.add(requestFormComponentValues);
}
return formComponentValues0;
}
之后就可以收到信息啦钉钉
DingTalkUtils
package com.youming.shuiku.dingding.provider.utils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.dingtalkworkflow_1_0.models.ProcessForecastResponseBody;
import com.aliyun.dingtalkworkflow_1_0.models.QuerySchemaByProcessCodeResponseBody;
import com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceRequest;
import com.dingtalk.api.request.OapiProcessinstanceCreateRequest;
import com.youming.shuiku.dingding.domain.SysForm;
import com.youming.shuiku.dingding.vo.FormVo;
import com.youming.shuiku.dingding.vo.NodeVo;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@Component
public class DingTalkUtils {
/**
* 设置表单
* @param list
* @return
*/
public List<OapiProcessinstanceCreateRequest.FormComponentValueVo> setForm(List<FormVo> list) {
List<OapiProcessinstanceCreateRequest.FormComponentValueVo> formComponentValueVoList = new ArrayList<OapiProcessinstanceCreateRequest.FormComponentValueVo>();
if (list != null && list.size() > 0) {
for (FormVo formVo : list) {
OapiProcessinstanceCreateRequest.FormComponentValueVo formComponentValueVo = new OapiProcessinstanceCreateRequest.FormComponentValueVo();
formComponentValueVoList.add(formComponentValueVo);
formComponentValueVo.setName(formVo.getName());
formComponentValueVo.setValue(formVo.getValue());
}
return formComponentValueVoList;
}
return formComponentValueVoList;
}
/**
* 设置审核节点
* @param list
* @return
*/
public List<OapiProcessinstanceCreateRequest.ProcessInstanceApproverVo> setNode(List<NodeVo> list) {
List<OapiProcessinstanceCreateRequest.ProcessInstanceApproverVo> processInstanceApproverVoList = new ArrayList<OapiProcessinstanceCreateRequest.ProcessInstanceApproverVo>();
if (list != null && list.size() > 0) {
for (NodeVo nodeVo : list) {
OapiProcessinstanceCreateRequest.ProcessInstanceApproverVo processInstanceApproverVo = new OapiProcessinstanceCreateRequest.ProcessInstanceApproverVo();
processInstanceApproverVoList.add(processInstanceApproverVo);
processInstanceApproverVo.setTaskActionType(nodeVo.getTaskActionType());
processInstanceApproverVo.setUserIds(nodeVo.getUserIds());
}
return processInstanceApproverVoList;
}
return processInstanceApproverVoList;
}
/**
* 转化节点规则
* @return
*/
public List<StartProcessInstanceRequest.StartProcessInstanceRequestTargetSelectActioners> setStartProcessInstanceRequestTargetSelectActioners(
ProcessForecastResponseBody.ProcessForecastResponseBodyResult forecastResponseBodyResult,
HashMap<String, List<String>> node) {
List<StartProcessInstanceRequest.StartProcessInstanceRequestTargetSelectActioners> selectActioners = new ArrayList<>();
if (forecastResponseBodyResult != null) {
List<ProcessForecastResponseBody.ProcessForecastResponseBodyResultWorkflowActivityRules> activityRules = forecastResponseBodyResult
.getWorkflowActivityRules();
for (ProcessForecastResponseBody.ProcessForecastResponseBodyResultWorkflowActivityRules activityRule : activityRules) {
if (activityRule.isTargetSelect) {
if (node != null && !node.isEmpty()) {
if (node.keySet().equals(activityRule.getWorkflowActor().getActorKey())) {
StartProcessInstanceRequest.StartProcessInstanceRequestTargetSelectActioners targetSelectActioners = new StartProcessInstanceRequest.StartProcessInstanceRequestTargetSelectActioners();
// 设置节点key
targetSelectActioners.setActionerKey(activityRule.getWorkflowActor().getActorKey());
// 设置操作人
targetSelectActioners
.setActionerUserIds(node.get(activityRule.getWorkflowActor().getActorKey()));
selectActioners.add(targetSelectActioners);
}
}
}
}
}
return selectActioners;
}
/**
* 转化表单
* @param schemaContent
* @return
*/
public List<StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues> toForm(
QuerySchemaByProcessCodeResponseBody.QuerySchemaByProcessCodeResponseBodyResultSchemaContent schemaContent) {
List<StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues> formComponentValues = new ArrayList<>();
for (QuerySchemaByProcessCodeResponseBody.QuerySchemaByProcessCodeResponseBodyResultSchemaContentItems schema : schemaContent
.getItems()) {
StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValuesDetailsDetails formComponentValues0Details0Details0 = new StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValuesDetailsDetails()
.setId(schema.getProps().getId()).setBizAlias(schema.getProps().getBizAlias())
.setName(schema.getProps().getLabel()).setValue(schema.getProps().getPlaceholder())
.setComponentType(schema.getComponentName());
StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValuesDetails formComponentValues0Details0 = new StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValuesDetails()
.setId(schema.getProps().getId()).setBizAlias(schema.getProps().getBizAlias())
.setName(schema.getProps().getLabel()).setValue(schema.getProps().getPlaceholder())
.setDetails(java.util.Arrays.asList(formComponentValues0Details0Details0));
StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues requestFormComponentValues = new StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues();
// 设置控件id。
requestFormComponentValues.setId(schema.getProps().getId());
// 控件别名。
requestFormComponentValues.setBizAlias(schema.getProps().getBizAlias());
// 控件名称。
requestFormComponentValues.setName(schema.getProps().getLabel());
// 控件值。
requestFormComponentValues.setValue(schema.getProps().getPlaceholder());
// 控件类型
requestFormComponentValues.setComponentType(schema.getComponentName());
requestFormComponentValues.setDetails(java.util.Arrays.asList(formComponentValues0Details0));
formComponentValues.add(requestFormComponentValues);
}
return formComponentValues;
}
public List<StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues> toFormOne(SysForm sysForm) {
List<StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues> formComponentValues0 = new ArrayList<>();
for (QuerySchemaByProcessCodeResponseBody.QuerySchemaByProcessCodeResponseBodyResultSchemaContentItems item : sysForm
.getSchemaContent().getItems()) {
StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues requestFormComponentValues = new StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues();
requestFormComponentValues.setName(item.getProps().getLabel());
if (item.getChildren() == null || item.getChildren().size() == 0) {
requestFormComponentValues.setValue(item.getProps().getPlaceholder());
}
else {
JSONArray rowValue2 = new JSONArray();
for (QuerySchemaByProcessCodeResponseBody.QuerySchemaByProcessCodeResponseBodyResultSchemaContentItemsChildren child : item
.getChildren()) {
JSONObject rowValue3 = new JSONObject();
rowValue3.put("name", child.getProps().getLabel());
rowValue3.put("value", child.getProps().getBizAlias());
rowValue2.add(rowValue3);
}
JSONArray rowValue3 = new JSONArray();
rowValue3.add(rowValue2);
requestFormComponentValues.setValue(rowValue3.toJSONString());
}
formComponentValues0.add(requestFormComponentValues);
}
return formComponentValues0;
}
}
DingCallbackCrypto
package com.youming.shuiku.dingding.provider.utils;
import com.alibaba.fastjson.JSON;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.ByteArrayOutputStream;
import java.lang.reflect.Field;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.Security;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
/**
* 钉钉开放平台加解密方法 在ORACLE官方网站下载JCE无限制权限策略文件
* JDK6的下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html
* JDK7的下载地址:
* http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
* JDK8的下载地址 https://www.oracle.com/java/technologies/javase-jce8-downloads.html
*/
public class DingCallbackCrypto {
private static final Charset CHARSET = Charset.forName("utf-8");
private static final Base64 base64 = new Base64();
private byte[] aesKey;
private String token;
private String corpId;
/**
* ask getPaddingBytes key固定长度
**/
private static final Integer AES_ENCODE_KEY_LENGTH = 43;
/**
* 加密随机字符串字节长度
**/
private static final Integer RANDOM_LENGTH = 16;
/**
* 构造函数
* @param token 钉钉开放平台上,开发者设置的token
* @param encodingAesKey 钉钉开放台上,开发者设置的EncodingAESKey
* @param corpId 企业自建应用-事件订阅, 使用appKey 企业自建应用-注册回调地址, 使用corpId 第三方企业应用, 使用suiteKey
* @throws DingTalkEncryptException 执行失败,请查看该异常的错误码和具体的错误信息
*/
public DingCallbackCrypto(String token, String encodingAesKey, String corpId) throws DingTalkEncryptException {
if (null == encodingAesKey || encodingAesKey.length() != AES_ENCODE_KEY_LENGTH) {
throw new DingTalkEncryptException(DingTalkEncryptException.AES_KEY_ILLEGAL);
}
this.token = token;
this.corpId = corpId;
aesKey = Base64.decodeBase64(encodingAesKey + "=");
}
public Map<String, String> getEncryptedMap(String plaintext) throws DingTalkEncryptException {
return getEncryptedMap(plaintext, System.currentTimeMillis(), Utils.getRandomStr(16));
}
/**
* 将和钉钉开放平台同步的消息体加密,返回加密Map
* @param plaintext 传递的消息体明文
* @param timeStamp 时间戳
* @param nonce 随机字符串
* @return
* @throws DingTalkEncryptException
*/
public Map<String, String> getEncryptedMap(String plaintext, Long timeStamp, String nonce)
throws DingTalkEncryptException {
if (null == plaintext) {
throw new DingTalkEncryptException(DingTalkEncryptException.ENCRYPTION_PLAINTEXT_ILLEGAL);
}
if (null == timeStamp) {
throw new DingTalkEncryptException(DingTalkEncryptException.ENCRYPTION_TIMESTAMP_ILLEGAL);
}
if (null == nonce) {
throw new DingTalkEncryptException(DingTalkEncryptException.ENCRYPTION_NONCE_ILLEGAL);
}
// 加密
String encrypt = encrypt(Utils.getRandomStr(RANDOM_LENGTH), plaintext);
String signature = getSignature(token, String.valueOf(timeStamp), nonce, encrypt);
Map<String, String> resultMap = new HashMap<String, String>();
resultMap.put("msg_signature", signature);
resultMap.put("encrypt", encrypt);
resultMap.put("timeStamp", String.valueOf(timeStamp));
resultMap.put("nonce", nonce);
return resultMap;
}
/**
* 密文解密
* @param msgSignature 签名串
* @param timeStamp 时间戳
* @param nonce 随机串
* @param encryptMsg 密文
* @return 解密后的原文
* @throws DingTalkEncryptException
*/
public String getDecryptMsg(String msgSignature, String timeStamp, String nonce, String encryptMsg)
throws DingTalkEncryptException {
// 校验签名
String signature = getSignature(token, timeStamp, nonce, encryptMsg);
if (!signature.equals(msgSignature)) {
throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_SIGNATURE_ERROR);
}
// 解密
String result = decrypt(encryptMsg);
return result;
}
/*
* 对明文加密.
*
* @param text 需要加密的明文
*
* @return 加密后base64编码的字符串
*/
private String encrypt(String random, String plaintext) throws DingTalkEncryptException {
try {
byte[] randomBytes = random.getBytes(CHARSET);
byte[] plainTextBytes = plaintext.getBytes(CHARSET);
byte[] lengthByte = Utils.int2Bytes(plainTextBytes.length);
byte[] corpidBytes = corpId.getBytes(CHARSET);
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
byteStream.write(randomBytes);
byteStream.write(lengthByte);
byteStream.write(plainTextBytes);
byteStream.write(corpidBytes);
byte[] padBytes = PKCS7Padding.getPaddingBytes(byteStream.size());
byteStream.write(padBytes);
byte[] unencrypted = byteStream.toByteArray();
byteStream.close();
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES");
IvParameterSpec iv = new IvParameterSpec(aesKey, 0, 16);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
byte[] encrypted = cipher.doFinal(unencrypted);
String result = base64.encodeToString(encrypted);
return result;
}
catch (Exception e) {
throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_ENCRYPT_TEXT_ERROR);
}
}
/*
* 对密文进行解密.
*
* @param text 需要解密的密文
*
* @return 解密得到的明文
*/
private String decrypt(String text) throws DingTalkEncryptException {
byte[] originalArr;
try {
// 设置解密模式为AES的CBC模式
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES");
IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(aesKey, 0, 16));
cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
// 使用BASE64对密文进行解码
byte[] encrypted = Base64.decodeBase64(text);
// 解密
originalArr = cipher.doFinal(encrypted);
}
catch (Exception e) {
throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_DECRYPT_TEXT_ERROR);
}
String plainText;
String fromCorpid;
try {
// 去除补位字符
byte[] bytes = PKCS7Padding.removePaddingBytes(originalArr);
// 分离16位随机字符串,网络字节序和corpId
byte[] networkOrder = Arrays.copyOfRange(bytes, 16, 20);
int plainTextLegth = Utils.bytes2int(networkOrder);
plainText = new String(Arrays.copyOfRange(bytes, 20, 20 + plainTextLegth), CHARSET);
fromCorpid = new String(Arrays.copyOfRange(bytes, 20 + plainTextLegth, bytes.length), CHARSET);
}
catch (Exception e) {
throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_DECRYPT_TEXT_LENGTH_ERROR);
}
// corpid不相同的情况
if (!fromCorpid.equals(corpId)) {
throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_DECRYPT_TEXT_CORPID_ERROR);
}
return plainText;
}
/**
* 数字签名
* @param token isv token
* @param timestamp 时间戳
* @param nonce 随机串
* @param encrypt 加密文本
* @return
* @throws DingTalkEncryptException
*/
public String getSignature(String token, String timestamp, String nonce, String encrypt)
throws DingTalkEncryptException {
try {
String[] array = new String[] { token, timestamp, nonce, encrypt };
Arrays.sort(array);
System.out.println(JSON.toJSONString(array));
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 4; i++) {
sb.append(array[i]);
}
String str = sb.toString();
System.out.println(str);
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(str.getBytes());
byte[] digest = md.digest();
StringBuffer hexstr = new StringBuffer();
String shaHex = "";
for (int i = 0; i < digest.length; i++) {
shaHex = Integer.toHexString(digest[i] & 0xFF);
if (shaHex.length() < 2) {
hexstr.append(0);
}
hexstr.append(shaHex);
}
return hexstr.toString();
}
catch (Exception e) {
throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_SIGNATURE_ERROR);
}
}
public static class Utils {
public Utils() {
}
public static String getRandomStr(int count) {
String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
Random random = new Random();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < count; ++i) {
int number = random.nextInt(base.length());
sb.append(base.charAt(number));
}
return sb.toString();
}
public static byte[] int2Bytes(int count) {
byte[] byteArr = new byte[] { (byte) (count >> 24 & 255), (byte) (count >> 16 & 255),
(byte) (count >> 8 & 255), (byte) (count & 255) };
return byteArr;
}
public static int bytes2int(byte[] byteArr) {
int count = 0;
for (int i = 0; i < 4; ++i) {
count <<= 8;
count |= byteArr[i] & 255;
}
return count;
}
}
public static class PKCS7Padding {
private static final Charset CHARSET = Charset.forName("utf-8");
private static final int BLOCK_SIZE = 32;
public PKCS7Padding() {
}
public static byte[] getPaddingBytes(int count) {
int amountToPad = 32 - count % 32;
if (amountToPad == 0) {
amountToPad = 32;
}
char padChr = chr(amountToPad);
String tmp = new String();
for (int index = 0; index < amountToPad; ++index) {
tmp = tmp + padChr;
}
return tmp.getBytes(CHARSET);
}
public static byte[] removePaddingBytes(byte[] decrypted) {
int pad = decrypted[decrypted.length - 1];
if (pad < 1 || pad > 32) {
pad = 0;
}
return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad);
}
private static char chr(int a) {
byte target = (byte) (a & 255);
return (char) target;
}
}
public static class DingTalkEncryptException extends Exception {
public static final int SUCCESS = 0;
public static final int ENCRYPTION_PLAINTEXT_ILLEGAL = 900001;
public static final int ENCRYPTION_TIMESTAMP_ILLEGAL = 900002;
public static final int ENCRYPTION_NONCE_ILLEGAL = 900003;
public static final int AES_KEY_ILLEGAL = 900004;
public static final int SIGNATURE_NOT_MATCH = 900005;
public static final int COMPUTE_SIGNATURE_ERROR = 900006;
public static final int COMPUTE_ENCRYPT_TEXT_ERROR = 900007;
public static final int COMPUTE_DECRYPT_TEXT_ERROR = 900008;
public static final int COMPUTE_DECRYPT_TEXT_LENGTH_ERROR = 900009;
public static final int COMPUTE_DECRYPT_TEXT_CORPID_ERROR = 900010;
private static Map<Integer, String> msgMap = new HashMap();
private Integer code;
static {
msgMap.put(0, "成功");
msgMap.put(900001, "加密明文文本非法");
msgMap.put(900002, "加密时间戳参数非法");
msgMap.put(900003, "加密随机字符串参数非法");
msgMap.put(900005, "签名不匹配");
msgMap.put(900006, "签名计算失败");
msgMap.put(900004, "不合法的aes key");
msgMap.put(900007, "计算加密文字错误");
msgMap.put(900008, "计算解密文字错误");
msgMap.put(900009, "计算解密文字长度不匹配");
msgMap.put(900010, "计算解密文字corpid不匹配");
}
public Integer getCode() {
return this.code;
}
public DingTalkEncryptException(Integer exceptionCode) {
super((String) msgMap.get(exceptionCode));
this.code = exceptionCode;
}
}
static {
try {
Security.setProperty("crypto.policy", "limited");
RemoveCryptographyRestrictions();
}
catch (Exception var1) {
}
}
private static void RemoveCryptographyRestrictions() throws Exception {
Class<?> jceSecurity = getClazz("javax.crypto.JceSecurity");
Class<?> cryptoPermissions = getClazz("javax.crypto.CryptoPermissions");
Class<?> cryptoAllPermission = getClazz("javax.crypto.CryptoAllPermission");
if (jceSecurity != null) {
setFinalStaticValue(jceSecurity, "isRestricted", false);
PermissionCollection defaultPolicy = (PermissionCollection) getFieldValue(jceSecurity, "defaultPolicy",
(Object) null, PermissionCollection.class);
if (cryptoPermissions != null) {
Map<?, ?> map = (Map) getFieldValue(cryptoPermissions, "perms", defaultPolicy, Map.class);
map.clear();
}
if (cryptoAllPermission != null) {
Permission permission = (Permission) getFieldValue(cryptoAllPermission, "INSTANCE", (Object) null,
Permission.class);
defaultPolicy.add(permission);
}
}
}
private static Class<?> getClazz(String className) {
Class clazz = null;
try {
clazz = Class.forName(className);
}
catch (Exception var3) {
}
return clazz;
}
private static void setFinalStaticValue(Class<?> srcClazz, String fieldName, Object newValue) throws Exception {
Field field = srcClazz.getDeclaredField(fieldName);
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & -17);
field.set((Object) null, newValue);
}
private static <T> T getFieldValue(Class<?> srcClazz, String fieldName, Object owner, Class<T> dstClazz)
throws Exception {
Field field = srcClazz.getDeclaredField(fieldName);
field.setAccessible(true);
return dstClazz.cast(field.get(owner));
}
}