From c3165dcc8ca60efecd87076661f5e53de0867fdd Mon Sep 17 00:00:00 2001 From: "saimu.msm" Date: Mon, 3 Jun 2024 17:54:01 +0800 Subject: [PATCH] userinfo checker --- .../alert/plugin/AlertSaveHistoryHandler.java | 10 +- .../web/controller/UserinfoFacadeImpl.java | 54 ++--- .../custom/UserinfoFacadeImplChecker.java | 201 ++++++++++++++++++ 3 files changed, 219 insertions(+), 46 deletions(-) create mode 100644 server/home/home-web/src/main/java/io/holoinsight/server/home/web/security/custom/UserinfoFacadeImplChecker.java diff --git a/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/plugin/AlertSaveHistoryHandler.java b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/plugin/AlertSaveHistoryHandler.java index 60aade1a7..31057e65d 100644 --- a/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/plugin/AlertSaveHistoryHandler.java +++ b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/plugin/AlertSaveHistoryHandler.java @@ -159,12 +159,10 @@ private void tryQueryLogSample(List alertNotifyList) { QueryProto.QueryResponse response = this.queryClientService.queryData(queryRequest, "LOG_ALERT"); if (response != null && !CollectionUtils.isEmpty(response.getResultsList())) { - LOGGER.debug("{} log sample result {} request {}", alertNotify.getTraceId(), - response, queryRequest); + LOGGER.debug("{} log sample result {} request {}", alertNotify.getTraceId(), response, + queryRequest); for (QueryProto.Result result : response.getResultsList()) { - Map tagMap = result.getTagsMap(); List points = result.getPointsList(); - LOGGER.debug("{} tagMap {} ", alertNotify.getTraceId(), tagMap); if (CollectionUtils.isEmpty(points)) { continue; } @@ -174,8 +172,6 @@ private void tryQueryLogSample(List alertNotifyList) { continue; } long timestamp = point.getTimestamp(); - LOGGER.debug("{} alertTime {} timestamp {}", alertNotify.getTraceId(), - alertTime, timestamp); if (alertTime == null || alertTime < timestamp) { // Logs outside the time window continue; @@ -190,7 +186,6 @@ private void tryQueryLogSample(List alertNotifyList) { alertNotify.setLogSample(logs); } } - LOGGER.debug("{} alertNotify LogSample {}", alertNotify.getTraceId(), alertNotify.getLogSample()); } } @@ -263,7 +258,6 @@ private void tryQueryLogAnalysis(List alertNotifyList) { alertNotify.setLogAnalysis(logs); } } - LOGGER.debug("{} alertNotify LogAnalysis {}", alertNotify.getTraceId(), alertNotify.getLogAnalysis()); } } diff --git a/server/home/home-web/src/main/java/io/holoinsight/server/home/web/controller/UserinfoFacadeImpl.java b/server/home/home-web/src/main/java/io/holoinsight/server/home/web/controller/UserinfoFacadeImpl.java index d5251b06b..a795f3d87 100644 --- a/server/home/home-web/src/main/java/io/holoinsight/server/home/web/controller/UserinfoFacadeImpl.java +++ b/server/home/home-web/src/main/java/io/holoinsight/server/home/web/controller/UserinfoFacadeImpl.java @@ -26,6 +26,7 @@ import io.holoinsight.server.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 lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -70,6 +71,8 @@ public class UserinfoFacadeImpl extends BaseFacade { @Autowired private ULAFacade ulaFacade; + @LevelAuthorizationAccess(paramConfigs = {"PARAMETER" + ":$!userinfoDTO"}, + levelAuthorizationCheckeClass = "io.holoinsight.server.home.web.security.custom.UserinfoFacadeImplChecker") @PostMapping("/create") @ResponseBody @MonitorScopeAuth(targetType = AuthTargetType.TENANT, needPower = PowerConstants.EDIT) @@ -79,18 +82,7 @@ public JsonResult create(@RequestBody UserinfoDTO userinfoDTO) { try { facadeTemplate.manage(result, new ManageCallback() { @Override - public void checkParameter() { - ParaCheckUtil.checkParaNotBlank(userinfoDTO.getNickname(), "nickname"); - if (StringUtils.isNotBlank(userinfoDTO.getNickname())) { - ParaCheckUtil.checkInvalidCharacter(userinfoDTO.getNickname(), - "invalid nickname, please use a-z A-Z 0-9 Chinese - _ , . spaces"); - } - ParaCheckUtil.checkParaNotBlank(userinfoDTO.getUid(), "uid"); - ParaCheckUtil.checkParaBoolean( - checkMembers(Collections.singletonList(userinfoDTO.getUid())), - userinfoDTO.getUid() + " is not in current tenant scope."); - ParaCheckUtil.checkParaId(userinfoDTO.getId()); - } + public void checkParameter() {} @Override public void doManage() { @@ -157,6 +149,8 @@ private void doVerify(Userinfo userinfo, UserinfoDTO userinfoDTO) { } } + @LevelAuthorizationAccess(paramConfigs = {"PARAMETER" + ":$!userinfoDTO"}, + levelAuthorizationCheckeClass = "io.holoinsight.server.home.web.security.custom.UserinfoFacadeImplChecker") @PostMapping("/update") @ResponseBody @MonitorScopeAuth(targetType = AuthTargetType.TENANT, needPower = PowerConstants.EDIT) @@ -166,23 +160,7 @@ public JsonResult update(@RequestBody UserinfoDTO userinfoDTO) { try { facadeTemplate.manage(result, new ManageCallback() { @Override - public void checkParameter() { - ParaCheckUtil.checkParaNotNull(userinfoDTO.getId(), "id"); - - if (StringUtils.isNotBlank(userinfoDTO.getTenant())) { - ParaCheckUtil.checkEquals(userinfoDTO.getTenant(), - RequestContext.getContext().ms.getTenant(), "tenant is illegal"); - } - if (StringUtils.isNotBlank(userinfoDTO.getNickname())) { - ParaCheckUtil.checkInvalidCharacter(userinfoDTO.getNickname(), - "invalid nickname, please use a-z A-Z 0-9 Chinese - _ , . spaces"); - } - if (StringUtils.isNotEmpty(userinfoDTO.getUid())) { - ParaCheckUtil.checkParaBoolean( - checkMembers(Collections.singletonList(userinfoDTO.getUid())), - userinfoDTO.getUid() + " is not in current tenant scope."); - } - } + public void checkParameter() {} @Override public void doManage() { @@ -248,6 +226,8 @@ private boolean validVerification(UserinfoVerification userinfoVerification, return false; } + @LevelAuthorizationAccess(paramConfigs = {"PARAMETER" + ":$!id"}, + levelAuthorizationCheckeClass = "io.holoinsight.server.home.web.security.custom.UserinfoFacadeImplChecker") @GetMapping("/query/{id}") @ResponseBody @MonitorScopeAuth(targetType = AuthTargetType.TENANT, needPower = PowerConstants.VIEW) @@ -258,9 +238,7 @@ public JsonResult queryById(@PathVariable("id") Long id) { try { facadeTemplate.manage(result, new ManageCallback() { @Override - public void checkParameter() { - ParaCheckUtil.checkParaNotNull(id, "id"); - } + public void checkParameter() {} @Override public void doManage() { @@ -293,6 +271,8 @@ public void doManage() { return result; } + @LevelAuthorizationAccess(paramConfigs = {"PARAMETER" + ":$!id"}, + levelAuthorizationCheckeClass = "io.holoinsight.server.home.web.security.custom.UserinfoFacadeImplChecker") @DeleteMapping(value = "/delete/{id}") @MonitorScopeAuth(targetType = AuthTargetType.TENANT, needPower = PowerConstants.EDIT) public JsonResult deleteById(@PathVariable("id") Long id) { @@ -302,9 +282,7 @@ public JsonResult deleteById(@PathVariable("id") Long id) { try { facadeTemplate.manage(result, new ManageCallback() { @Override - public void checkParameter() { - ParaCheckUtil.checkParaNotNull(id, "id"); - } + public void checkParameter() {} @Override public void doManage() { @@ -348,6 +326,8 @@ public void doManage() { return result; } + @LevelAuthorizationAccess(paramConfigs = {"PARAMETER" + ":$!pageRequest"}, + levelAuthorizationCheckeClass = "io.holoinsight.server.home.web.security.custom.UserinfoFacadeImplChecker") @PostMapping("/pageQuery") @ResponseBody @MonitorScopeAuth(targetType = AuthTargetType.TENANT, needPower = PowerConstants.VIEW) @@ -358,9 +338,7 @@ public JsonResult> pageQuery( try { facadeTemplate.manage(result, new ManageCallback() { @Override - public void checkParameter() { - ParaCheckUtil.checkParaNotNull(pageRequest.getTarget(), "target"); - } + public void checkParameter() {} @Override public void doManage() { diff --git a/server/home/home-web/src/main/java/io/holoinsight/server/home/web/security/custom/UserinfoFacadeImplChecker.java b/server/home/home-web/src/main/java/io/holoinsight/server/home/web/security/custom/UserinfoFacadeImplChecker.java new file mode 100644 index 000000000..7e20e3f7c --- /dev/null +++ b/server/home/home-web/src/main/java/io/holoinsight/server/home/web/security/custom/UserinfoFacadeImplChecker.java @@ -0,0 +1,201 @@ +/* + * Alipay.com Inc. Copyright (c) 2004-2018 All Rights Reserved. + */ +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.common.MonitorPageRequest; +import io.holoinsight.server.common.RequestContext; +import io.holoinsight.server.common.dao.entity.dto.AlarmBlockDTO; +import io.holoinsight.server.common.dao.entity.dto.UserinfoDTO; +import io.holoinsight.server.common.scope.MonitorScope; +import io.holoinsight.server.common.scope.MonitorUser; +import io.holoinsight.server.common.service.RequestContextAdapter; +import io.holoinsight.server.home.biz.ula.ULAFacade; +import io.holoinsight.server.home.dal.mapper.UserinfoVerificationMapper; +import io.holoinsight.server.home.dal.model.UserinfoVerification; +import io.holoinsight.server.home.web.security.LevelAuthorizationCheck; +import io.holoinsight.server.home.web.security.LevelAuthorizationCheckResult; +import io.holoinsight.server.home.web.security.LevelAuthorizationMetaData; +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 javax.annotation.Resource; +import java.util.Collection; +import java.util.List; +import java.util.Set; + +import static io.holoinsight.server.home.web.security.LevelAuthorizationCheckResult.failCheckResult; +import static io.holoinsight.server.home.web.security.LevelAuthorizationCheckResult.successCheckResult; + +/** + * @author masaimu + * @version 2024-06-03 17:18:00 + */ +@Slf4j +@Service +public class UserinfoFacadeImplChecker implements AbstractResourceChecker, LevelAuthorizationCheck { + + @Autowired + private RequestContextAdapter requestContextAdapter; + @Autowired + private ULAFacade ulaFacade; + @Resource + private UserinfoVerificationMapper verificationMapper; + + @Override + public LevelAuthorizationCheckResult check(LevelAuthorizationMetaData levelAuthMetaData, + MethodInvocation methodInvocation) { + RequestContext.Context context = RequestContext.getContext(); + String workspace = this.requestContextAdapter.getWorkspaceFromContext(context); + String tenant = this.requestContextAdapter.getTenantFromContext(context); + + List parameters = levelAuthMetaData.getParameters(); + String methodName = methodInvocation.getMethod().getName(); + return checkParameters(methodName, parameters, tenant, workspace); + } + + private LevelAuthorizationCheckResult checkParameters(String methodName, List parameters, + String tenant, String workspace) { + switch (methodName) { + case "create": + case "update": + return checkUserinfoDTO(methodName, parameters, tenant, workspace); + case "queryById": + case "deleteById": + return checkIdExists(parameters, tenant, workspace); + case "pageQuery": + return checkPageRequest(methodName, parameters, tenant, workspace); + default: + return successCheckResult(); + } + } + + private LevelAuthorizationCheckResult checkPageRequest(String methodName, List parameters, + String tenant, String workspace) { + if (CollectionUtils.isEmpty(parameters) || StringUtils.isBlank(parameters.get(0))) { + return failCheckResult("parameters is empty"); + } + String parameter = parameters.get(0); + MonitorPageRequest pageRequest = + J.fromJson(parameter, new TypeToken>() {}.getType()); + + if (pageRequest.getFrom() != null && pageRequest.getTo() != null) { + if (pageRequest.getFrom() > pageRequest.getTo()) { + return failCheckResult("fail to check time range for start %d larger than end %d", + pageRequest.getFrom(), pageRequest.getTo()); + } + } + + UserinfoDTO target = pageRequest.getTarget(); + if (target == null) { + return failCheckResult("fail to check target, target can not be null"); + } + return checkUserinfoDTO(methodName, target, tenant, workspace); + } + + private LevelAuthorizationCheckResult checkUserinfoDTO(String methodName, List parameters, + String tenant, String workspace) { + if (CollectionUtils.isEmpty(parameters) || StringUtils.isBlank(parameters.get(0))) { + return failCheckResult("parameters is empty"); + } + log.info("checkParameters {} parameter {}", methodName, parameters.get(0)); + UserinfoDTO userinfoDTO = J.fromJson(parameters.get(0), UserinfoDTO.class); + return checkUserinfoDTO(methodName, userinfoDTO, tenant, workspace); + } + + private LevelAuthorizationCheckResult checkUserinfoDTO(String methodName, UserinfoDTO userinfoDTO, + String tenant, String workspace) { + if (methodName.equals("create")) { + if (userinfoDTO.getId() != null) { + return failCheckResult("fail to check %s for id is not null", methodName); + } + } + + if (methodName.equals("update")) { + if (userinfoDTO.getId() == null) { + return failCheckResult("fail to check %s for id is null", methodName); + } + LevelAuthorizationCheckResult updateCheckResult = + checkIdExists(userinfoDTO.getId(), tenant, workspace); + if (!updateCheckResult.isSuccess()) { + return updateCheckResult; + } + } + + if (StringUtils.isNotEmpty(userinfoDTO.getNickname()) + && !checkSqlName(userinfoDTO.getNickname())) { + return failCheckResult("invalid nickname %s, please use a-z A-Z 0-9 Chinese - _ , . spaces", + userinfoDTO.getNickname()); + } + + if (StringUtils.isNotEmpty(userinfoDTO.getUid()) && !checkUid(userinfoDTO.getUid())) { + return failCheckResult("%s is not in current tenant scope.", userinfoDTO.getUid()); + } + if (StringUtils.isNotEmpty(userinfoDTO.getTenant()) + && !StringUtils.equals(userinfoDTO.getTenant(), tenant)) { + return failCheckResult("invalid tenant %s, real tenant %s", userinfoDTO.getTenant(), tenant); + } + if (StringUtils.isNotEmpty(userinfoDTO.getWorkspace()) + && !StringUtils.equals(userinfoDTO.getWorkspace(), workspace)) { + return failCheckResult("invalid workspace %s, real workspace %s", userinfoDTO.getWorkspace(), + workspace); + } + + if (!completeUserinfoVerification(userinfoDTO)) { + return failCheckResult("incomplete UserinfoVerification %d %s", + userinfoDTO.getUserinfoVerificationId(), userinfoDTO.getUserinfoVerificationCode()); + } + + if (userinfoDTO.getUserinfoVerificationId() != null) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("id", userinfoDTO.getUserinfoVerificationId()); + requestContextAdapter.queryWrapperTenantAdapt(queryWrapper, tenant, workspace); + List list = this.verificationMapper.selectList(queryWrapper); + if (CollectionUtils.isEmpty(list)) { + return failCheckResult("invalid UserinfoVerification id %d", + userinfoDTO.getUserinfoVerificationId()); + } + UserinfoVerification userinfoVerification = list.get(0); + if (!StringUtils.equals(userinfoVerification.getCode(), + userinfoDTO.getUserinfoVerificationCode())) { + return failCheckResult("invalid UserinfoVerification code %s", + userinfoDTO.getUserinfoVerificationCode()); + } + } + return successCheckResult(); + } + + private boolean completeUserinfoVerification(UserinfoDTO userinfoDTO) { + return (userinfoDTO.getUserinfoVerificationId() == null + && StringUtils.isEmpty(userinfoDTO.getUserinfoVerificationCode())) // + || (userinfoDTO.getUserinfoVerificationId() != null + && StringUtils.isNotEmpty(userinfoDTO.getUserinfoVerificationCode())); + } + + private boolean checkUid(String uid) { + MonitorScope ms = RequestContext.getContext().ms; + MonitorUser mu = RequestContext.getContext().mu; + + Set userIds = ulaFacade.getCurrentULA().getUserIds(mu, ms); + return !CollectionUtils.isEmpty(userIds) && userIds.contains(uid); + } + + @Override + public LevelAuthorizationCheckResult checkIdExists(Long id, String tenant, String workspace) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("id", id); + requestContextAdapter.queryWrapperTenantAdapt(queryWrapper, tenant, workspace); + List list = this.verificationMapper.selectList(queryWrapper); + if (CollectionUtils.isEmpty(list)) { + return failCheckResult("invalid UserinfoVerification id %d", id); + } + return successCheckResult(); + } +}