|
@@ -1,16 +1,21 @@
|
|
|
package cn.cslg.permission.service;
|
|
|
|
|
|
import cn.cslg.permission.common.core.base.RedisConf;
|
|
|
-import cn.cslg.permission.common.model.vo.LoginRecordVO;
|
|
|
-import cn.cslg.permission.common.model.vo.LoginVO;
|
|
|
-import cn.cslg.permission.common.model.vo.PersonnelVO;
|
|
|
-import cn.cslg.permission.common.model.vo.RoleVO;
|
|
|
+import cn.cslg.permission.common.model.dto.EncryptionFunctionDTO;
|
|
|
+import cn.cslg.permission.common.model.dto.EncryptionLoginDTO;
|
|
|
+import cn.cslg.permission.common.model.vo.*;
|
|
|
import cn.cslg.permission.common.utils.*;
|
|
|
import cn.cslg.permission.common.utils.message.MessageUtils;
|
|
|
+import cn.cslg.permission.domain.Function;
|
|
|
import cn.cslg.permission.domain.Personnel;
|
|
|
import cn.cslg.permission.domain.ReSetPasswordDTO;
|
|
|
import cn.cslg.permission.domain.Tenant;
|
|
|
+import cn.cslg.permission.domain.associate.AssoFunctionModule;
|
|
|
+import cn.cslg.permission.domain.associate.AssoPersonnelMachine;
|
|
|
+import cn.cslg.permission.mapper.FunctionMapper;
|
|
|
import cn.cslg.permission.mapper.PersonnelMapper;
|
|
|
+import cn.cslg.permission.mapper.associate.AssoFunctionModuleMapper;
|
|
|
+import cn.cslg.permission.mapper.associate.AssoPersonnelMachineMapper;
|
|
|
import cn.cslg.permission.service.associate.PerDpService;
|
|
|
import cn.cslg.permission.service.associate.PersonRoleService;
|
|
|
import cn.dev33.satoken.stp.StpUtil;
|
|
@@ -28,10 +33,12 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.commons.lang3.ObjectUtils;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.context.annotation.Lazy;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
-
|
|
|
-import javax.servlet.ServletRequest;
|
|
|
+import org.springframework.transaction.annotation.Propagation;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
import java.util.*;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
|
@@ -54,6 +61,14 @@ public class LoginService extends ServiceImpl<PersonnelMapper, Personnel> {
|
|
|
private final SystemService systemService;
|
|
|
private final LoginRecordService loginRecordService;
|
|
|
private final HttpServletRequest request;
|
|
|
+ @Autowired
|
|
|
+ private PersonnelMapper personnelMapper;
|
|
|
+ @Autowired
|
|
|
+ private FunctionMapper functionMapper;
|
|
|
+ @Autowired
|
|
|
+ private AssoPersonnelMachineMapper assoPersonnelMachineMapper;
|
|
|
+ @Autowired
|
|
|
+ private AssoFunctionModuleMapper assoFunctionModuleMapper;
|
|
|
|
|
|
/**
|
|
|
* @param loginVO 登录参数类
|
|
@@ -314,8 +329,161 @@ public class LoginService extends ServiceImpl<PersonnelMapper, Personnel> {
|
|
|
map.put("value2", personnel.getPersonnelName());
|
|
|
mailUtils.sendEmailMessage(map);
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
+ /**
|
|
|
+ * 登录加密
|
|
|
+ * @param vo
|
|
|
+ * @return
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
|
|
|
+ public String loginByEncryption(EncryptionLoginDTO vo) {
|
|
|
+ final String username = vo.getUsername();
|
|
|
+ final String password = vo.getPassword();
|
|
|
+ String machineCode = vo.getMachineCode();
|
|
|
+ final String sign = vo.getSign();
|
|
|
+ final String appKey = vo.getAppKey();
|
|
|
+ long currentTimeMillis = vo.getCurrentTimeMillis() / 1000;
|
|
|
+ long currentTimeSecond = System.currentTimeMillis() / 1000;
|
|
|
+ final long second = currentTimeSecond - currentTimeMillis / 1000;
|
|
|
+ if (second > 5) {
|
|
|
+ return Response.error(ResponseEnum.THE_REQUEST_TIME_OVERTIME);
|
|
|
+ }
|
|
|
+ String appSecret = appKey + currentTimeMillis;
|
|
|
+ String md5Sign = SecureUtil.md5(appSecret);
|
|
|
+ if (Boolean.TRUE.equals(StringUtils.isEmpty(sign)) || !sign.equals(md5Sign)) {
|
|
|
+ return Response.error(ResponseEnum.THE_SIGN_IS_NOT_SAME);
|
|
|
+ }
|
|
|
+ if (Boolean.TRUE.equals(StringUtils.isEmpty(machineCode))) {
|
|
|
+ return Response.error(ResponseEnum.THE_MACHINE_CODE_IS_NULL);
|
|
|
+ }
|
|
|
+ //用用户名查询人员信息
|
|
|
+ LambdaQueryWrapper<Personnel> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ queryWrapper.eq(Personnel::getPersonnelUserName, username);
|
|
|
+ //获取一条
|
|
|
+ Personnel personnel = this.getOne(queryWrapper);
|
|
|
+ final Integer personId = personnel.getId();
|
|
|
+ //如果查不到 报错 用户名不存在
|
|
|
+ if (ObjectUtils.isEmpty(personnel)) {
|
|
|
+ return Response.error(ResponseEnum.USERNAME_ERROR);
|
|
|
+ }
|
|
|
+ //校验密码是否正确
|
|
|
+ boolean isPassword = personnel.getPersonnelPassword().equals(SecureUtil.md5(password));
|
|
|
+ if (!isPassword) {
|
|
|
+ //登录日志记录登录是否成功
|
|
|
+ return Response.error(ResponseEnum.PASSWORD_ERROR);
|
|
|
+ }
|
|
|
+ //人员信息中私钥或公钥为空则添加进去
|
|
|
+ updatePersonnel(personnel.getPrivateKey(), personnel.getPublicKey(), personId);
|
|
|
|
|
|
+ personnel = personnelMapper.selectById(personnel.getId());
|
|
|
+ List<AssoPersonnelMachine> machineList = assoPersonnelMachineMapper.selectList(new LambdaQueryWrapper<AssoPersonnelMachine>()
|
|
|
+ .eq(AssoPersonnelMachine::getPersonnelId, personId)
|
|
|
+ .ne(AssoPersonnelMachine::getMachineCode, SecureUtil.md5(machineCode)));
|
|
|
+ if (machineList.size() > 1) {
|
|
|
+ return Response.error(ResponseEnum.DO_NOT_LOG_IN_TO_MORE_THAN_TWO_NEW_MACHINES_WITH_THE_SAME_ACCOUNT);
|
|
|
+ }
|
|
|
+ boolean flag = addOrUpdatePersonnelMachine(machineCode, personnel);
|
|
|
+ EncryptionLoginVO loginVO = new EncryptionLoginVO();
|
|
|
+ if (flag) {
|
|
|
+ loginVO.setPrivateKey(personnel.getPrivateKey());
|
|
|
+ }
|
|
|
+ loginVO.setPersonId(personId);
|
|
|
+ loginVO.setPersonnelName(personnel.getPersonnelName());
|
|
|
+ loginVO.setPersonnelUserName(personnel.getPersonnelUserName());
|
|
|
+ loginVO.setPersonnelPhone(personnel.getPersonnelPhone());
|
|
|
+ loginVO.setMachineCode(vo.getMachineCode());
|
|
|
+ //Sa-token 登录方法 登录后 生成Token 如果集成了Redis的话 会自动存入Redis
|
|
|
+ StpUtil.login(personnel.getId());
|
|
|
+ loginVO.setToken(StpUtil.getTokenValue());
|
|
|
+ return Response.success(loginVO);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void updatePersonnel(String privateKey, String publicKey, Integer personId) {
|
|
|
+ if (StringUtils.isEmpty(privateKey) || StringUtils.isEmpty(publicKey)) {
|
|
|
+ Map<String, String> map = RSAUtils.generateKey();
|
|
|
+ String publicKeyStr = map.get("publicKeyStr");
|
|
|
+ String privateKeyStr = map.get("privateKeyStr");
|
|
|
+ Personnel newPersonnel = personnelMapper.selectById(personId);
|
|
|
+ newPersonnel.setPrivateKey(privateKeyStr);
|
|
|
+ newPersonnel.setPublicKey(publicKeyStr);
|
|
|
+ newPersonnel.updateById();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 新增或修改人员机器码关联表
|
|
|
+ *
|
|
|
+ * @param machineCode
|
|
|
+ * @param personnel
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private boolean addOrUpdatePersonnelMachine(String machineCode, Personnel personnel) {
|
|
|
+ AssoPersonnelMachine machine = assoPersonnelMachineMapper.selectOne(new LambdaQueryWrapper<AssoPersonnelMachine>()
|
|
|
+ .eq(AssoPersonnelMachine::getMachineCode, SecureUtil.md5(machineCode))
|
|
|
+ .eq(AssoPersonnelMachine::getPersonnelId, personnel.getId()));
|
|
|
+ if (ObjectUtils.isEmpty(machine)) {
|
|
|
+ AssoPersonnelMachine assoPersonnelMachine = new AssoPersonnelMachine();
|
|
|
+ assoPersonnelMachine.setPersonnelId(personnel.getId());
|
|
|
+ assoPersonnelMachine.setMachineCode(SecureUtil.md5(machineCode));
|
|
|
+ assoPersonnelMachine.setIfFirstActivation(true);
|
|
|
+ assoPersonnelMachine.setCreateUser(personnel.getCreateUser());
|
|
|
+ assoPersonnelMachine.setCreateTime(new Date());
|
|
|
+ assoPersonnelMachine.insert();
|
|
|
+ return true;
|
|
|
+ } else {
|
|
|
+ machine.setId(machine.getId());
|
|
|
+ machine.setIfFirstActivation(false);
|
|
|
+ machine.updateById();
|
|
|
+ return false;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 功能模块化代码加密
|
|
|
+ * @param vo
|
|
|
+ * @return
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public String functionByEncryption(EncryptionFunctionDTO vo) throws Exception {
|
|
|
+ final String sign = vo.getSign();
|
|
|
+ final String appKey = vo.getAppKey();
|
|
|
+ long currentTimeMillis = vo.getCurrentTimeMillis() / 1000;
|
|
|
+ long currentTimeSecond = System.currentTimeMillis() / 1000;
|
|
|
+ final long second = currentTimeSecond - currentTimeMillis;
|
|
|
+ if (second > 5) {
|
|
|
+ return Response.error(ResponseEnum.THE_REQUEST_TIME_OVERTIME);
|
|
|
+ }
|
|
|
+ String appSecret = appKey + currentTimeMillis;
|
|
|
+ String md5Sign = SecureUtil.md5(appSecret);
|
|
|
+ if (Boolean.TRUE.equals(StringUtils.isEmpty(sign)) || !sign.equals(md5Sign)) {
|
|
|
+ return Response.error(ResponseEnum.THE_SIGN_IS_NOT_SAME);
|
|
|
+ }
|
|
|
+ Integer userId = StpUtil.getLoginIdAsInt();
|
|
|
+ Personnel personnel = this.getById(userId);
|
|
|
+ if (ObjectUtils.isEmpty(personnel)) {
|
|
|
+ return Response.error(ResponseEnum.THE_TOKEN_IS_INVALID);
|
|
|
+ }
|
|
|
+ final String publicKey = personnel.getPublicKey();
|
|
|
+ final List<String> permissions = vo.getPermissions();
|
|
|
+ List<EncryptionFunctionVO> functionVOS = new ArrayList<>();
|
|
|
+ List<Function> functions = functionMapper.selectList(new LambdaQueryWrapper<Function>()
|
|
|
+ .in(Function::getFunctionPath, permissions));
|
|
|
+ for (Function function : functions) {
|
|
|
+ final Integer functionId = function.getId();
|
|
|
+ final String functionPath = function.getFunctionPath();
|
|
|
+ final AssoFunctionModule functionModule = assoFunctionModuleMapper.selectOne(new LambdaQueryWrapper<AssoFunctionModule>()
|
|
|
+ .eq(AssoFunctionModule::getFunctionId, functionId));
|
|
|
+ final String moduleCode = functionModule.getCode();
|
|
|
+ if (StringUtils.isNotEmpty(moduleCode)) {
|
|
|
+ final String encryptInfo = RSAUtils.encryptByPublicKey(moduleCode, publicKey);
|
|
|
+ EncryptionFunctionVO functionVO = new EncryptionFunctionVO();
|
|
|
+ functionVO.setPermission(functionPath);
|
|
|
+ functionVO.setEncryptionModuleCode(encryptInfo);
|
|
|
+ functionVOS.add(functionVO);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return Response.success(functionVOS);
|
|
|
+ }
|
|
|
}
|