Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: check userid in dingdingrobot facade #793

Merged
merged 2 commits into from
Jan 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import io.holoinsight.server.home.biz.service.AlertDingDingRobotService;
import io.holoinsight.server.home.biz.service.UserOpLogService;
import io.holoinsight.server.home.common.service.RequestContextAdapter;
import io.holoinsight.server.home.common.util.MonitorException;
import io.holoinsight.server.home.common.util.scope.AuthTargetType;
import io.holoinsight.server.home.common.util.scope.MonitorScope;
import io.holoinsight.server.home.common.util.scope.MonitorUser;
Expand All @@ -19,8 +18,8 @@
import io.holoinsight.server.home.facade.page.MonitorPageRequest;
import io.holoinsight.server.home.facade.page.MonitorPageResult;
import io.holoinsight.server.home.web.common.ManageCallback;
import io.holoinsight.server.home.web.common.ParaCheckUtil;
import io.holoinsight.server.home.web.interceptor.MonitorScopeAuth;
import io.holoinsight.server.home.web.security.LevelAuthorizationAccess;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
Expand All @@ -42,7 +41,7 @@
@RequestMapping("/webapi/alarmDingDingRobot")
public class AlarmDingDingRobotFacadeImpl extends BaseFacade {

private static final String dingdingUrlPrefix =
public static final String dingdingUrlPrefix =
"https://oapi.dingtalk.com/robot/send?access_token=";

@Autowired
Expand All @@ -54,19 +53,16 @@ public class AlarmDingDingRobotFacadeImpl extends BaseFacade {
@Autowired
private RequestContextAdapter requestContextAdapter;

@LevelAuthorizationAccess(paramConfigs = {"PARAMETER" + ":$!alarmDingDingRobotDTO"},
levelAuthorizationCheckeClass = "io.holoinsight.server.home.web.security.custom.AlarmDingDingRobotFacadeImplChecker")
@PostMapping("/create")
@ResponseBody
@MonitorScopeAuth(targetType = AuthTargetType.TENANT, needPower = PowerConstants.EDIT)
public JsonResult<Long> save(@RequestBody AlarmDingDingRobotDTO alarmDingDingRobotDTO) {
public JsonResult<Long> create(@RequestBody AlarmDingDingRobotDTO alarmDingDingRobotDTO) {
final JsonResult<Long> result = new JsonResult<>();
facadeTemplate.manage(result, new ManageCallback() {
@Override
public void checkParameter() {
ParaCheckUtil.checkParaNotBlank(alarmDingDingRobotDTO.getGroupName(), "groupName");
ParaCheckUtil.checkParaStartWith(alarmDingDingRobotDTO.getRobotUrl(), dingdingUrlPrefix,
"robotUrl");
ParaCheckUtil.checkParaId(alarmDingDingRobotDTO.getId());
}
public void checkParameter() {}

@Override
public void doManage() {
Expand Down Expand Up @@ -94,34 +90,22 @@ public void doManage() {
return result;
}

@LevelAuthorizationAccess(paramConfigs = {"PARAMETER" + ":$!alarmDingDingRobotDTO"},
levelAuthorizationCheckeClass = "io.holoinsight.server.home.web.security.custom.AlarmDingDingRobotFacadeImplChecker")
@PostMapping("/update")
@ResponseBody
@MonitorScopeAuth(targetType = AuthTargetType.TENANT, needPower = PowerConstants.EDIT)
public JsonResult<Boolean> update(@RequestBody AlarmDingDingRobotDTO alarmDingDingRobotDTO) {
final JsonResult<Boolean> result = new JsonResult<>();
facadeTemplate.manage(result, new ManageCallback() {
@Override
public void checkParameter() {
ParaCheckUtil.checkParaNotNull(alarmDingDingRobotDTO.getId(), "id");
ParaCheckUtil.checkParaNotNull(alarmDingDingRobotDTO.getTenant(), "tenant");
ParaCheckUtil.checkParaStartWith(alarmDingDingRobotDTO.getRobotUrl(), dingdingUrlPrefix,
"robotUrl");
ParaCheckUtil.checkEquals(alarmDingDingRobotDTO.getTenant(),
RequestContext.getContext().ms.getTenant(), "tenant is illegal");

}
public void checkParameter() {}

@Override
public void doManage() {

AlarmDingDingRobotDTO item = alarmDingDingRobotService
.queryById(alarmDingDingRobotDTO.getId(), RequestContext.getContext().ms.getTenant());
if (null == item) {
throw new MonitorException("cannot find record: " + alarmDingDingRobotDTO.getId());
}
if (!item.getTenant().equalsIgnoreCase(alarmDingDingRobotDTO.getTenant())) {
throw new MonitorException("the tenant parameter is invalid");
}

MonitorUser mu = RequestContext.getContext().mu;
if (null != mu) {
Expand All @@ -143,16 +127,16 @@ public void doManage() {
return result;
}

@LevelAuthorizationAccess(paramConfigs = {"PARAMETER" + ":$!id"},
levelAuthorizationCheckeClass = "io.holoinsight.server.home.web.security.custom.AlarmDingDingRobotFacadeImplChecker")
@GetMapping("/query/{id}")
@ResponseBody
@MonitorScopeAuth(targetType = AuthTargetType.TENANT, needPower = PowerConstants.VIEW)
public JsonResult<AlarmDingDingRobotDTO> queryById(@PathVariable("id") Long id) {
final JsonResult<AlarmDingDingRobotDTO> result = new JsonResult<>();
facadeTemplate.manage(result, new ManageCallback() {
@Override
public void checkParameter() {
ParaCheckUtil.checkParaNotNull(id, "id");
}
public void checkParameter() {}

@Override
public void doManage() {
Expand All @@ -166,15 +150,15 @@ public void doManage() {
return result;
}

@LevelAuthorizationAccess(paramConfigs = {"PARAMETER" + ":$!id"},
levelAuthorizationCheckeClass = "io.holoinsight.server.home.web.security.custom.AlarmDingDingRobotFacadeImplChecker")
@DeleteMapping(value = "/delete/{id}")
@MonitorScopeAuth(targetType = AuthTargetType.TENANT, needPower = PowerConstants.EDIT)
public JsonResult<Boolean> deleteById(@PathVariable("id") Long id) {
final JsonResult<Boolean> result = new JsonResult<>();
facadeTemplate.manage(result, new ManageCallback() {
@Override
public void checkParameter() {
ParaCheckUtil.checkParaNotNull(id, "id");
}
public void checkParameter() {}

@Override
public void doManage() {
Expand All @@ -197,6 +181,8 @@ public void doManage() {
return result;
}

@LevelAuthorizationAccess(paramConfigs = {"PARAMETER" + ":$!pageRequest"},
levelAuthorizationCheckeClass = "io.holoinsight.server.home.web.security.custom.AlarmDingDingRobotFacadeImplChecker")
@PostMapping("/pageQuery")
@ResponseBody
@MonitorScopeAuth(targetType = AuthTargetType.TENANT, needPower = PowerConstants.VIEW)
Expand All @@ -205,9 +191,7 @@ public JsonResult<MonitorPageResult<AlarmDingDingRobotDTO>> pageQuery(
final JsonResult<MonitorPageResult<AlarmDingDingRobotDTO>> result = new JsonResult<>();
facadeTemplate.manage(result, new ManageCallback() {
@Override
public void checkParameter() {
ParaCheckUtil.checkParaNotNull(pageRequest.getTarget(), "target");
}
public void checkParameter() {}

@Override
public void doManage() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,6 @@ default boolean checkSqlName(String sqlName) {
}
return true;
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
/*
* Copyright 2022 Holoinsight Project Authors. Licensed under Apache-2.0.
*/
package io.holoinsight.server.home.web.security.custom;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.reflect.TypeToken;
import io.holoinsight.server.common.J;
import io.holoinsight.server.home.common.service.RequestContextAdapter;
import io.holoinsight.server.home.common.util.scope.MonitorScope;
import io.holoinsight.server.home.common.util.scope.MonitorUser;
import io.holoinsight.server.home.common.util.scope.RequestContext;
import io.holoinsight.server.home.dal.mapper.AlarmDingDingRobotMapper;
import io.holoinsight.server.home.dal.model.AlarmDingDingRobot;
import io.holoinsight.server.home.dal.model.dto.AlarmDingDingRobotDTO;
import io.holoinsight.server.home.facade.page.MonitorPageRequest;
import io.holoinsight.server.home.web.security.LevelAuthorizationCheck;
import io.holoinsight.server.home.web.security.LevelAuthorizationMetaData;
import io.holoinsight.server.home.web.security.ParameterSecurityService;
import lombok.extern.slf4j.Slf4j;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;

import static io.holoinsight.server.home.web.controller.AlarmDingDingRobotFacadeImpl.dingdingUrlPrefix;

/**
* @author masaimu
* @version 2024-01-29 11:32:00
*/
@Slf4j
@Service
public class AlarmDingDingRobotFacadeImplChecker implements LevelAuthorizationCheck {

@Autowired
private AlarmDingDingRobotMapper alarmDingDingRobotMapper;
@Autowired
private ParameterSecurityService parameterSecurityService;

@Autowired
private RequestContextAdapter requestContextAdapter;

@Override
public boolean check(LevelAuthorizationMetaData levelAuthMetaData,
MethodInvocation methodInvocation) {
MonitorScope ms = RequestContext.getContext().ms;
String workspace = this.requestContextAdapter.getWorkspace(true);
String tenant = ms.getTenant();

List<String> parameters = levelAuthMetaData.getParameters();
String methodName = methodInvocation.getMethod().getName();
return checkParameters(methodName, parameters, tenant, workspace);
}

private boolean checkParameters(String methodName, List<String> parameters, String tenant,
String workspace) {
switch (methodName) {
case "create":
case "update":
return checkAlarmDingDingRobotDTO(methodName, parameters, tenant, workspace);
case "queryById":
return checkIdNotNull(parameters);
case "deleteById":
return checkIdExists(parameters, tenant, workspace);
case "pageQuery":
return checkPageRequest(methodName, parameters, tenant, workspace);
default:
return true;
}
}

private boolean checkIdNotNull(List<String> parameters) {
if (CollectionUtils.isEmpty(parameters) || !StringUtils.isNumeric(parameters.get(0))) {
log.error("parameters {} is empty or is not numeric.", parameters);
return false;
}
return true;
}

private boolean checkPageRequest(String methodName, List<String> parameters, String tenant,
String workspace) {
if (CollectionUtils.isEmpty(parameters) || StringUtils.isBlank(parameters.get(0))) {
return false;
}
String parameter = parameters.get(0);
MonitorPageRequest<AlarmDingDingRobotDTO> pageRequest = J.fromJson(parameter,
new TypeToken<MonitorPageRequest<AlarmDingDingRobotDTO>>() {}.getType());

if (pageRequest.getFrom() != null && pageRequest.getTo() != null) {
if (pageRequest.getFrom() > pageRequest.getTo()) {
log.error("fail to check time range for start {} larger than end {}", pageRequest.getFrom(),
pageRequest.getTo());
return false;
}
}

AlarmDingDingRobotDTO target = pageRequest.getTarget();
if (target == null) {
log.error("fail to check target, target can not be null");
return false;
}
return checkAlarmDingDingRobotDTO(methodName, target, tenant, workspace);
}

private boolean checkIdExists(List<String> parameters, String tenant, String workspace) {
if (!checkIdNotNull(parameters)) {
return false;
}
Long id = Long.parseLong(parameters.get(0));
return checkIdExists(id, tenant, workspace);
}

private boolean checkAlarmDingDingRobotDTO(String methodName, List<String> parameters,
String tenant, String workspace) {
if (CollectionUtils.isEmpty(parameters) || StringUtils.isBlank(parameters.get(0))) {
return false;
}
log.info("checkParameters {} parameter {}", methodName, parameters.get(0));
AlarmDingDingRobotDTO dto = J.fromJson(parameters.get(0), AlarmDingDingRobotDTO.class);
return checkAlarmDingDingRobotDTO(methodName, dto, tenant, workspace);
}

private boolean checkAlarmDingDingRobotDTO(String methodName, AlarmDingDingRobotDTO dto,
String tenant, String workspace) {
if (methodName.equals("create")) {
if (dto.getId() != null) {
log.error("fail to check {} for id is not null", methodName);
return false;
}
if (StringUtils.isBlank(dto.getGroupName())) {
log.error("group name can not be blank.");
return false;
}
}

if (methodName.equals("update")) {
if (dto.getId() == null) {
log.error("fail to check {} for id is null", methodName);
return false;
}
if (!checkIdExists(dto.getId(), tenant, workspace)) {
return false;
}
}

if (StringUtils.isNotEmpty(dto.getRobotUrl())
&& !dto.getRobotUrl().startsWith(dingdingUrlPrefix)) {
log.error("invalid robotUrl {}", dto.getRobotUrl());
return false;
}

if (StringUtils.isNotEmpty(dto.getCreator()) && !checkSqlField(dto.getCreator())) {
log.error("fail to check {} for invalid creator {}", methodName, dto.getCreator());
return false;
}

if (StringUtils.isNotEmpty(dto.getModifier()) && !checkSqlField(dto.getModifier())) {
log.error("fail to check {} for invalid modifier {}", methodName, dto.getModifier());
return false;
}

if (StringUtils.isNotEmpty(dto.getGroupName()) && !checkSqlField(dto.getGroupName())) {
log.error("fail to check {} for invalid group name {}", methodName, dto.getGroupName());
return false;
}

if (StringUtils.isNotEmpty(dto.getTenant()) && !StringUtils.equals(dto.getTenant(), tenant)) {
log.error("fail to check {} for invalid tenant {} for valid tenant {}", methodName,
dto.getTenant(), tenant);
return false;
}

if (StringUtils.isNotEmpty(dto.getWorkspace())
&& !StringUtils.equals(dto.getWorkspace(), workspace)) {
log.error("fail to check {} for invalid workspace {} for valid workspace {}", methodName,
dto.getWorkspace(), workspace);
return false;
}

if (StringUtils.isNotEmpty(dto.getExtra()) && !checkUserIds(dto.getExtra())) {
log.error("fail to check {} that userIds in extra {}", methodName, dto.getExtra());
return false;
}

return true;
}

private boolean checkUserIds(String extra) {
Map<String, Object> extraMap = J.toMap(extra);
List<String> userIds = (List<String>) extraMap.get("userIds");
if (CollectionUtils.isEmpty(userIds)) {
return true;
}
MonitorUser mu = RequestContext.getContext().mu;
for (String uid : userIds) {
if (!this.parameterSecurityService.checkUserTenantAndWorkspace(uid, mu)) {
log.error("fail to check uid {}", uid);
return false;
}
}
return true;
}

private boolean checkIdExists(Long id, String tenant, String workspace) {
QueryWrapper<AlarmDingDingRobot> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("id", id);
queryWrapper.eq("tenant", tenant);
if (StringUtils.isNotEmpty(workspace)) {
queryWrapper.eq("workspace", workspace);
}
List<AlarmDingDingRobot> exist = this.alarmDingDingRobotMapper.selectList(queryWrapper);
if (CollectionUtils.isEmpty(exist)) {
log.error("fail to check id for no existed {} {} {}", id, tenant, workspace);
return false;
}
return true;
}
}
Loading
Loading