diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/aspect/S2DataPermissionAspect.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/aspect/S2DataPermissionAspect.java index 5626cb28c..f7879cb94 100644 --- a/headless/server/src/main/java/com/tencent/supersonic/headless/server/aspect/S2DataPermissionAspect.java +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/aspect/S2DataPermissionAspect.java @@ -1,5 +1,6 @@ package com.tencent.supersonic.headless.server.aspect; +import com.google.common.collect.Sets; import com.tencent.supersonic.auth.api.authentication.pojo.User; import com.tencent.supersonic.auth.api.authorization.pojo.AuthRes; import com.tencent.supersonic.auth.api.authorization.pojo.DimensionFilter; @@ -81,7 +82,7 @@ public class S2DataPermissionAspect { } SemanticSchemaResp semanticSchemaResp = getSemanticSchemaResp(queryReq); - List modelIds = getModelIds(semanticSchemaResp); + Set modelIds = getModelIdInQuery(queryReq, semanticSchemaResp); // 2. determine whether admin of the model if (checkModelAdmin(user, modelIds)) { @@ -111,7 +112,7 @@ public class S2DataPermissionAspect { private void checkColPermission( SemanticQueryReq semanticQueryReq, AuthorizedResourceResp authorizedResource, - List modelIds, + Set modelIds, SemanticSchemaResp semanticSchemaResp) { // get high sensitive fields in query Set bizNamesInQueryReq = getBizNameInQueryReq(semanticQueryReq, semanticSchemaResp); @@ -132,13 +133,26 @@ public class S2DataPermissionAspect { if (!CollectionUtils.isEmpty(sensitiveBizNameInQuery)) { Set sensitiveResNames = semanticSchemaResp.getNameFromBizNames(sensitiveBizNameInQuery); - List modelAdmin = modelService.getModelAdmin(modelIds.get(0)); + List modelAdmin = modelService.getModelAdmin(modelIds.iterator().next()); String message = String.format("存在以下敏感资源:%s您暂无权限,请联系管理员%s申请", sensitiveResNames, modelAdmin); throw new InvalidPermissionException(message); } } + private Set getModelIdInQuery( + SemanticQueryReq semanticQueryReq, SemanticSchemaResp semanticSchemaResp) { + if (semanticQueryReq instanceof QuerySqlReq) { + QuerySqlReq querySqlReq = (QuerySqlReq) semanticQueryReq; + return queryStructUtils.getModelIdFromSql(querySqlReq, semanticSchemaResp); + } + if (semanticQueryReq instanceof QueryStructReq) { + QueryStructReq queryStructReq = (QueryStructReq) semanticQueryReq; + return queryStructUtils.getModelIdsFromStruct(queryStructReq, semanticSchemaResp); + } + return Sets.newHashSet(); + } + private void checkRowPermission( SemanticQueryReq queryReq, AuthorizedResourceResp authorizedResource) { if (queryReq instanceof QuerySqlReq) { @@ -167,12 +181,6 @@ public class S2DataPermissionAspect { return schemaService.fetchSemanticSchema(filter); } - private List getModelIds(SemanticSchemaResp semanticSchemaResp) { - return semanticSchemaResp.getModelResps().stream() - .map(ModelResp::getId) - .collect(Collectors.toList()); - } - private void doRowPermission( QuerySqlReq querySqlReq, AuthorizedResourceResp authorizedResource) { log.debug("start doRowPermission logic"); @@ -246,7 +254,7 @@ public class S2DataPermissionAspect { } } - public boolean checkModelAdmin(User user, List modelIds) { + public boolean checkModelAdmin(User user, Set modelIds) { List modelListAdmin = modelService.getModelListWithAuth(user, null, AuthType.ADMIN); if (CollectionUtils.isEmpty(modelListAdmin)) { @@ -258,7 +266,7 @@ public class S2DataPermissionAspect { } } - public void checkModelVisible(User user, List modelIds) { + public void checkModelVisible(User user, Set modelIds) { List modelListVisible = modelService.getModelListWithAuth(user, null, AuthType.VISIBLE).stream() .map(ModelResp::getId) @@ -303,9 +311,9 @@ public class S2DataPermissionAspect { return highSensitiveCols; } - public AuthorizedResourceResp getAuthorizedResource(User user, List modelIds) { + public AuthorizedResourceResp getAuthorizedResource(User user, Set modelIds) { QueryAuthResReq queryAuthResReq = new QueryAuthResReq(); - queryAuthResReq.setModelIds(modelIds); + queryAuthResReq.setModelIds(new ArrayList<>(modelIds)); AuthorizedResourceResp authorizedResource = fetchAuthRes(queryAuthResReq, user); log.info( "user:{}, domainId:{}, after queryAuthorizedResources:{}", @@ -321,17 +329,17 @@ public class S2DataPermissionAspect { } public void addHint( - List modelIds, + Set modelIds, SemanticQueryResp queryResultWithColumns, AuthorizedResourceResp authorizedResource) { List filters = authorizedResource.getFilters(); if (CollectionUtils.isEmpty(filters)) { return; } - List admins = modelService.getModelAdmin(modelIds.get(0)); + List admins = modelService.getModelAdmin(modelIds.iterator().next()); if (!CollectionUtils.isEmpty(filters)) { - ModelResp modelResp = modelService.getModel(modelIds.get(0)); + ModelResp modelResp = modelService.getModel(modelIds.iterator().next()); List exprList = new ArrayList<>(); List descList = new ArrayList<>(); filters.stream() diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/impl/ModelServiceImpl.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/impl/ModelServiceImpl.java index d7326a119..243b9cf90 100644 --- a/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/impl/ModelServiceImpl.java +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/impl/ModelServiceImpl.java @@ -214,7 +214,9 @@ public class ModelServiceImpl implements ModelService { String message = String.format("模型英文名[%s]需要为下划线字母数字组合, 请修改", modelReq.getBizName()); throw new InvalidArgumentException(message); } - + if (modelReq.getModelDetail() == null) { + return; + } List dims = modelReq.getModelDetail().getDimensions(); List measures = modelReq.getModelDetail().getMeasures(); List identifies = modelReq.getModelDetail().getIdentifiers(); diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/utils/QueryStructUtils.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/utils/QueryStructUtils.java index 1ed65393e..edd43cbef 100644 --- a/headless/server/src/main/java/com/tencent/supersonic/headless/server/utils/QueryStructUtils.java +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/utils/QueryStructUtils.java @@ -1,5 +1,7 @@ package com.tencent.supersonic.headless.server.utils; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; import com.tencent.supersonic.common.jsqlparser.FieldExpression; import com.tencent.supersonic.common.jsqlparser.SqlSelectHelper; import com.tencent.supersonic.common.pojo.Aggregator; @@ -15,10 +17,8 @@ import com.tencent.supersonic.headless.api.pojo.MetaFilter; import com.tencent.supersonic.headless.api.pojo.SchemaItem; import com.tencent.supersonic.headless.api.pojo.request.QuerySqlReq; import com.tencent.supersonic.headless.api.pojo.request.QueryStructReq; -import com.tencent.supersonic.headless.api.pojo.response.DimSchemaResp; import com.tencent.supersonic.headless.api.pojo.response.DimensionResp; import com.tencent.supersonic.headless.api.pojo.response.MetricResp; -import com.tencent.supersonic.headless.api.pojo.response.MetricSchemaResp; import com.tencent.supersonic.headless.api.pojo.response.SemanticSchemaResp; import com.tencent.supersonic.headless.server.service.SchemaService; import lombok.extern.slf4j.Slf4j; @@ -47,14 +47,8 @@ import static com.tencent.supersonic.common.pojo.Constants.DAY_FORMAT; @Component public class QueryStructUtils { - public static Set internalTimeCols = + public static Set internalCols = new HashSet<>(Arrays.asList("dayno", "sys_imp_date", "sys_imp_week", "sys_imp_month")); - public static Set internalCols; - - static { - internalCols = new HashSet<>(Arrays.asList("plat_sys_var")); - internalCols.addAll(internalTimeCols); - } private final DateModeUtils dateModeUtils; private final SqlFilterUtils sqlFilterUtils; @@ -127,33 +121,71 @@ public class QueryStructUtils { return new HashSet<>(SqlSelectHelper.getAllSelectFields(querySqlReq.getSql())); } - public Set getBizNameFromSql( + public Set getModelIdsFromStruct( + QueryStructReq queryStructReq, SemanticSchemaResp semanticSchemaResp) { + Set modelIds = Sets.newHashSet(); + Set bizNameFromStruct = getBizNameFromStruct(queryStructReq); + modelIds.addAll( + semanticSchemaResp.getMetrics().stream() + .filter(metric -> bizNameFromStruct.contains(metric.getBizName())) + .map(MetricResp::getModelId) + .collect(Collectors.toSet())); + modelIds.addAll( + semanticSchemaResp.getDimensions().stream() + .filter(dimension -> bizNameFromStruct.contains(dimension.getBizName())) + .map(DimensionResp::getModelId) + .collect(Collectors.toList())); + return modelIds; + } + + private List getMetricsFromSql( QuerySqlReq querySqlReq, SemanticSchemaResp semanticSchemaResp) { Set resNameSet = getResName(querySqlReq); - Set resNameEnSet = new HashSet<>(); if (semanticSchemaResp != null) { - List metrics = semanticSchemaResp.getMetrics(); - List dimensions = semanticSchemaResp.getDimensions(); - metrics.stream() - .forEach( - o -> { - if (resNameSet.contains(o.getName()) - || resNameSet.contains(o.getBizName())) { - resNameEnSet.add(o.getBizName()); - } - }); - dimensions.stream() - .forEach( - o -> { - if (resNameSet.contains(o.getName()) - || resNameSet.contains(o.getBizName())) { - resNameEnSet.add(o.getBizName()); - } - }); + return semanticSchemaResp.getMetrics().stream() + .filter( + m -> + resNameSet.contains(m.getName()) + || resNameSet.contains(m.getBizName())) + .collect(Collectors.toList()); } - return resNameEnSet.stream() - .filter(res -> !internalCols.contains(res)) - .collect(Collectors.toSet()); + return Lists.newArrayList(); + } + + private List getDimensionsFromSql( + QuerySqlReq querySqlReq, SemanticSchemaResp semanticSchemaResp) { + Set resNameSet = getResName(querySqlReq); + if (semanticSchemaResp != null) { + return semanticSchemaResp.getDimensions().stream() + .filter( + m -> + resNameSet.contains(m.getName()) + || resNameSet.contains(m.getBizName())) + .collect(Collectors.toList()); + } + return Lists.newArrayList(); + } + + public Set getModelIdFromSql( + QuerySqlReq querySqlReq, SemanticSchemaResp semanticSchemaResp) { + Set modelIds = Sets.newHashSet(); + List dimensions = getDimensionsFromSql(querySqlReq, semanticSchemaResp); + List metrics = getMetricsFromSql(querySqlReq, semanticSchemaResp); + modelIds.addAll( + dimensions.stream().map(DimensionResp::getModelId).collect(Collectors.toList())); + modelIds.addAll(metrics.stream().map(MetricResp::getModelId).collect(Collectors.toList())); + return modelIds; + } + + public Set getBizNameFromSql( + QuerySqlReq querySqlReq, SemanticSchemaResp semanticSchemaResp) { + Set bizNames = Sets.newHashSet(); + List dimensions = getDimensionsFromSql(querySqlReq, semanticSchemaResp); + List metrics = getMetricsFromSql(querySqlReq, semanticSchemaResp); + bizNames.addAll( + dimensions.stream().map(DimensionResp::getBizName).collect(Collectors.toList())); + bizNames.addAll(metrics.stream().map(MetricResp::getBizName).collect(Collectors.toList())); + return bizNames; } public ItemDateResp getItemDateResp(QueryStructReq queryStructCmd) { diff --git a/launchers/standalone/src/main/java/com/tencent/supersonic/demo/S2VisitsDemo.java b/launchers/standalone/src/main/java/com/tencent/supersonic/demo/S2VisitsDemo.java index 0f89d6e29..bf07824fa 100644 --- a/launchers/standalone/src/main/java/com/tencent/supersonic/demo/S2VisitsDemo.java +++ b/launchers/standalone/src/main/java/com/tencent/supersonic/demo/S2VisitsDemo.java @@ -101,7 +101,7 @@ public class S2VisitsDemo extends S2BaseDemo { // create data set DataSetResp s2DataSet = addDataSet(s2Domain); addAuthGroup_1(stayTimeModel); - addAuthGroup_2(stayTimeModel); + addAuthGroup_2(pvUvModel); // create terms and plugin addTerm(s2Domain); @@ -513,9 +513,9 @@ public class S2VisitsDemo extends S2BaseDemo { authService.addOrUpdateAuthGroup(authGroupReq); } - public void addAuthGroup_2(ModelResp stayTimeModel) { + public void addAuthGroup_2(ModelResp pvuvModel) { AuthGroup authGroupReq = new AuthGroup(); - authGroupReq.setModelId(stayTimeModel.getId()); + authGroupReq.setModelId(pvuvModel.getId()); authGroupReq.setName("tom_row_permission"); List authRules = new ArrayList<>();