fix: PII permission (#16149)

This commit is contained in:
Teddy 2024-05-14 12:42:01 +02:00 committed by GitHub
parent c277233ef1
commit 3322406be4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 61 additions and 5 deletions

View File

@ -477,7 +477,8 @@ public class TableRepository extends EntityRepository<Table> {
tableProfiles, startTs.toString(), endTs.toString(), tableProfiles.size());
}
public ResultList<ColumnProfile> getColumnProfiles(String fqn, Long startTs, Long endTs) {
public ResultList<ColumnProfile> getColumnProfiles(
String fqn, Long startTs, Long endTs, boolean authorizePII) {
List<ColumnProfile> columnProfiles;
columnProfiles =
JsonUtils.readObjects(
@ -490,8 +491,15 @@ public class TableRepository extends EntityRepository<Table> {
endTs,
EntityTimeSeriesDAO.OrderBy.DESC),
ColumnProfile.class);
return new ResultList<>(
columnProfiles, startTs.toString(), endTs.toString(), columnProfiles.size());
ResultList<ColumnProfile> columnProfileResultList =
new ResultList<>(
columnProfiles, startTs.toString(), endTs.toString(), columnProfiles.size());
if (!authorizePII) {
// Mask the PII data
columnProfileResultList.setData(
PIIMasker.getColumnProfile(fqn, columnProfileResultList.getData()));
}
return columnProfileResultList;
}
public ResultList<SystemProfile> getSystemProfiles(String fqn, Long startTs, Long endTs) {

View File

@ -75,6 +75,7 @@ import org.openmetadata.service.resources.EntityResource;
import org.openmetadata.service.security.Authorizer;
import org.openmetadata.service.security.policyevaluator.OperationContext;
import org.openmetadata.service.security.policyevaluator.ResourceContext;
import org.openmetadata.service.util.FullyQualifiedName;
import org.openmetadata.service.util.JsonUtils;
import org.openmetadata.service.util.ResultList;
@ -926,8 +927,13 @@ public class TableResource extends EntityResource<Table, TableRepository> {
Long endTs) {
OperationContext operationContext =
new OperationContext(entityType, MetadataOperation.VIEW_DATA_PROFILE);
authorizer.authorize(securityContext, operationContext, getResourceContextByName(fqn));
return repository.getColumnProfiles(fqn, startTs, endTs);
String tableFqn =
FullyQualifiedName.getTableFQN(
fqn); // get table fqn for the resource context (vs column fqn)
ResourceContext<?> resourceContext = getResourceContextByName(tableFqn);
authorizer.authorize(securityContext, operationContext, resourceContext);
boolean authorizePII = authorizer.authorizePII(securityContext, resourceContext.getOwner());
return repository.getColumnProfiles(fqn, startTs, endTs, authorizePII);
}
@GET

View File

@ -3,6 +3,7 @@ package org.openmetadata.service.security.mask;
import static org.openmetadata.common.utils.CommonUtil.listOrEmpty;
import static org.openmetadata.service.jdbi3.TopicRepository.getAllFieldTags;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@ -20,6 +21,7 @@ import org.openmetadata.schema.entity.data.Topic;
import org.openmetadata.schema.entity.teams.User;
import org.openmetadata.schema.tests.TestCase;
import org.openmetadata.schema.type.Column;
import org.openmetadata.schema.type.ColumnProfile;
import org.openmetadata.schema.type.Field;
import org.openmetadata.schema.type.Include;
import org.openmetadata.schema.type.TableData;
@ -30,6 +32,7 @@ import org.openmetadata.service.Entity;
import org.openmetadata.service.jdbi3.ColumnUtil;
import org.openmetadata.service.resources.feeds.MessageParser;
import org.openmetadata.service.security.Authorizer;
import org.openmetadata.service.util.FullyQualifiedName;
import org.openmetadata.service.util.ResultList;
public class PIIMasker {
@ -137,6 +140,22 @@ public class PIIMasker {
return table;
}
public static List<ColumnProfile> getColumnProfile(
String fqn, List<ColumnProfile> columnProfiles) {
Table table =
Entity.getEntityByName(
Entity.TABLE, FullyQualifiedName.getTableFQN(fqn), "columns,tags", Include.ALL);
Column column =
table.getColumns().stream()
.filter(c -> c.getFullyQualifiedName().equals(fqn))
.findFirst()
.orElse(null);
if (column != null && hasPiiSensitiveTag(column)) {
return Collections.nCopies(columnProfiles.size(), new ColumnProfile());
}
return columnProfiles;
}
private static TestCase getTestCase(Column column, TestCase testCase) {
if (!hasPiiSensitiveTag(column)) return testCase;

View File

@ -2484,15 +2484,38 @@ public class TableResourceTest extends EntityResourceTest<Table, CreateTable> {
createRequest(test, 1).withOwner(USER_TEAM21.getEntityReference()), ADMIN_AUTH_HEADERS);
putTableProfile(table, table1, ADMIN_AUTH_HEADERS);
Column c3 = table.getColumns().stream().filter(c -> c.getName().equals(C3)).findFirst().get();
// Owner can read the column profile of C3
Table tableWithProfileFromOwner =
getLatestTableProfile(table.getFullyQualifiedName(), authHeaders(USER_TEAM21.getName()));
assertNotNull(tableWithProfileFromOwner.getColumns().get(2).getProfile());
ResultList<ColumnProfile> columnProfiles =
getColumnProfiles(
c3.getFullyQualifiedName(),
TestUtils.dateToTimestamp("2021-09-01"),
TestUtils.dateToTimestamp("2021-09-30"),
authHeaders(USER_TEAM21.getName()));
for (ColumnProfile columnProfile : columnProfiles.getData()) {
assertNotNull(columnProfile.getMax());
assertNotNull(columnProfile.getMin());
}
// Non owners cannot read the column profile of C3
Table tableWithProfileFromNotOwner =
getLatestTableProfile(table.getFullyQualifiedName(), authHeaders(USER1_REF.getName()));
assertNull(tableWithProfileFromNotOwner.getColumns().get(2).getProfile());
ResultList<ColumnProfile> maskedColumnProfiles =
getColumnProfiles(
c3.getFullyQualifiedName(),
TestUtils.dateToTimestamp("2021-09-01"),
TestUtils.dateToTimestamp("2021-09-30"),
authHeaders(USER1_REF.getName()));
for (ColumnProfile columnProfile : maskedColumnProfiles.getData()) {
assertNull(columnProfile.getMax());
assertNull(columnProfile.getMin());
}
assertEquals(maskedColumnProfiles.getData().size(), columnProfiles.getData().size());
}
@Test