Skip to content

Commit 4a44be8

Browse files
committed
wip - access controls
TODO: * cache keys - need to be context aware to prevent incorrect results * ownership migration upgrade step * complete unit tests for access controls * restricted entity hydration and graphql response (chris)
1 parent 62f2789 commit 4a44be8

File tree

212 files changed

+3164
-970
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

212 files changed

+3164
-970
lines changed

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/QueryContext.java

+6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.datahub.authentication.Actor;
44
import com.datahub.authentication.Authentication;
55
import com.datahub.plugins.auth.authorization.Authorizer;
6+
import io.datahubproject.metadata.context.OperationContext;
67

78
/** Provided as input to GraphQL resolvers; used to carry information about GQL request context. */
89
public interface QueryContext {
@@ -25,4 +26,9 @@ default String getActorUrn() {
2526

2627
/** Returns the authorizer used to authorize specific actions. */
2728
Authorizer getAuthorizer();
29+
30+
/**
31+
* @return Returns the operational context
32+
*/
33+
OperationContext getOperationContext();
2834
}

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/analytics/resolver/GetMetadataAnalyticsResolver.java

+10-11
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,16 @@
22

33
import static com.linkedin.datahub.graphql.resolvers.ResolverUtils.bindArgument;
44

5-
import com.datahub.authentication.Authentication;
65
import com.google.common.collect.ImmutableList;
76
import com.google.common.collect.ImmutableSet;
7+
import com.linkedin.datahub.graphql.QueryContext;
88
import com.linkedin.datahub.graphql.analytics.service.AnalyticsUtil;
99
import com.linkedin.datahub.graphql.generated.AnalyticsChart;
1010
import com.linkedin.datahub.graphql.generated.AnalyticsChartGroup;
1111
import com.linkedin.datahub.graphql.generated.BarChart;
1212
import com.linkedin.datahub.graphql.generated.BarSegment;
1313
import com.linkedin.datahub.graphql.generated.MetadataAnalyticsInput;
1414
import com.linkedin.datahub.graphql.generated.NamedBar;
15-
import com.linkedin.datahub.graphql.resolvers.ResolverUtils;
1615
import com.linkedin.datahub.graphql.types.entitytype.EntityTypeMapper;
1716
import com.linkedin.entity.client.EntityClient;
1817
import com.linkedin.metadata.Constants;
@@ -22,6 +21,7 @@
2221
import com.linkedin.metadata.search.utils.QueryUtils;
2322
import graphql.schema.DataFetcher;
2423
import graphql.schema.DataFetchingEnvironment;
24+
import io.datahubproject.metadata.context.OperationContext;
2525
import java.util.ArrayList;
2626
import java.util.Collections;
2727
import java.util.List;
@@ -41,24 +41,24 @@ public final class GetMetadataAnalyticsResolver implements DataFetcher<List<Anal
4141

4242
@Override
4343
public final List<AnalyticsChartGroup> get(DataFetchingEnvironment environment) throws Exception {
44-
final Authentication authentication = ResolverUtils.getAuthentication(environment);
44+
final QueryContext context = environment.getContext();
4545
final MetadataAnalyticsInput input =
4646
bindArgument(environment.getArgument("input"), MetadataAnalyticsInput.class);
4747

4848
try {
4949
final AnalyticsChartGroup group = new AnalyticsChartGroup();
5050
group.setGroupId("FilteredMetadataAnalytics");
5151
group.setTitle("");
52-
group.setCharts(getCharts(input, authentication));
52+
group.setCharts(getCharts(input, context.getOperationContext()));
5353
return ImmutableList.of(group);
5454
} catch (Exception e) {
5555
log.error("Failed to retrieve metadata analytics!", e);
5656
return Collections.emptyList(); // Simply return nothing.
5757
}
5858
}
5959

60-
private List<AnalyticsChart> getCharts(
61-
MetadataAnalyticsInput input, Authentication authentication) throws Exception {
60+
private List<AnalyticsChart> getCharts(MetadataAnalyticsInput input, OperationContext opContext)
61+
throws Exception {
6262
final List<AnalyticsChart> charts = new ArrayList<>();
6363

6464
List<String> entities = Collections.emptyList();
@@ -77,8 +77,7 @@ private List<AnalyticsChart> getCharts(
7777
}
7878

7979
SearchResult searchResult =
80-
_entityClient.searchAcrossEntities(
81-
entities, query, filter, 0, 0, null, null, authentication);
80+
_entityClient.searchAcrossEntities(opContext, entities, query, filter, 0, 0, null, null);
8281

8382
List<AggregationMetadata> aggregationMetadataList =
8483
searchResult.getMetadata().getAggregations();
@@ -96,7 +95,7 @@ private List<AnalyticsChart> getCharts(
9695
Constants.DOMAIN_ENTITY_NAME,
9796
ImmutableSet.of(Constants.DOMAIN_PROPERTIES_ASPECT_NAME),
9897
AnalyticsUtil::getDomainName,
99-
authentication);
98+
opContext.getSessionAuthentication());
10099
charts.add(BarChart.builder().setTitle("Entities by Domain").setBars(domainChart).build());
101100
}
102101

@@ -113,7 +112,7 @@ private List<AnalyticsChart> getCharts(
113112
Constants.DATA_PLATFORM_ENTITY_NAME,
114113
ImmutableSet.of(Constants.DATA_PLATFORM_INFO_ASPECT_NAME),
115114
AnalyticsUtil::getPlatformName,
116-
authentication);
115+
opContext.getSessionAuthentication());
117116
charts.add(
118117
BarChart.builder().setTitle("Entities by Platform").setBars(platformChart).build());
119118
}
@@ -132,7 +131,7 @@ private List<AnalyticsChart> getCharts(
132131
ImmutableSet.of(
133132
Constants.GLOSSARY_TERM_KEY_ASPECT_NAME, Constants.GLOSSARY_TERM_INFO_ASPECT_NAME),
134133
AnalyticsUtil::getTermName,
135-
authentication);
134+
opContext.getSessionAuthentication());
136135
charts.add(BarChart.builder().setTitle("Entities by Term").setBars(termChart).build());
137136
}
138137

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/auth/ListAccessTokensResolver.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,13 @@ public CompletableFuture<ListAccessTokenResult> get(DataFetchingEnvironment envi
6565
.setOrder(SortOrder.DESCENDING);
6666
final SearchResult searchResult =
6767
_entityClient.search(
68+
context.getOperationContext(),
6869
Constants.ACCESS_TOKEN_ENTITY_NAME,
6970
"",
7071
buildFilter(filters, Collections.emptyList()),
7172
sortCriterion,
7273
start,
7374
count,
74-
getAuthentication(environment),
7575
new SearchFlags().setFulltext(true));
7676

7777
final List<AccessTokenMetadata> tokens =

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/container/ContainerEntitiesResolver.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ public CompletableFuture<SearchResults> get(final DataFetchingEnvironment enviro
7979

8080
return UrnSearchResultsMapper.map(
8181
_entityClient.searchAcrossEntities(
82+
context.getOperationContext(),
8283
CONTAINABLE_ENTITY_NAMES,
8384
query,
8485
new Filter()
@@ -90,8 +91,7 @@ public CompletableFuture<SearchResults> get(final DataFetchingEnvironment enviro
9091
start,
9192
count,
9293
null,
93-
null,
94-
context.getAuthentication()));
94+
null));
9595

9696
} catch (Exception e) {
9797
throw new RuntimeException(

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/dataproduct/ListDataProductAssetsResolver.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -151,14 +151,14 @@ public CompletableFuture<SearchResults> get(DataFetchingEnvironment environment)
151151

152152
return UrnSearchResultsMapper.map(
153153
_entityClient.searchAcrossEntities(
154+
context.getOperationContext(),
154155
finalEntityNames,
155156
sanitizedQuery,
156157
finalFilter,
157158
start,
158159
count,
159160
searchFlags,
160-
null,
161-
ResolverUtils.getAuthentication(environment)));
161+
null));
162162
} catch (Exception e) {
163163
log.error(
164164
"Failed to execute search for data product assets: entity types {}, query {}, filters: {}, start: {}, count: {}",

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/domain/DomainEntitiesResolver.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ public CompletableFuture<SearchResults> get(final DataFetchingEnvironment enviro
8686

8787
return UrnSearchResultsMapper.map(
8888
_entityClient.searchAcrossEntities(
89+
context.getOperationContext(),
8990
SEARCHABLE_ENTITY_TYPES.stream()
9091
.map(EntityTypeMapper::getName)
9192
.collect(Collectors.toList()),
@@ -97,8 +98,7 @@ public CompletableFuture<SearchResults> get(final DataFetchingEnvironment enviro
9798
start,
9899
count,
99100
null,
100-
null,
101-
context.getAuthentication()));
101+
null));
102102

103103
} catch (Exception e) {
104104
throw new RuntimeException(

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/domain/ListDomainsResolver.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ public CompletableFuture<ListDomainsResult> get(final DataFetchingEnvironment en
6262
// First, get all domain Urns.
6363
final SearchResult gmsResult =
6464
_entityClient.search(
65+
context.getOperationContext(),
6566
Constants.DOMAIN_ENTITY_NAME,
6667
query,
6768
filter,
@@ -70,7 +71,6 @@ public CompletableFuture<ListDomainsResult> get(final DataFetchingEnvironment en
7071
.setOrder(SortOrder.DESCENDING),
7172
start,
7273
count,
73-
context.getAuthentication(),
7474
new SearchFlags().setFulltext(true));
7575

7676
// Now that we have entities we can bind this to a result.

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/glossary/CreateGlossaryTermResolver.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ private Map<Urn, EntityResponse> getTermsWithSameParent(Urn parentNode, QueryCon
140140
final Filter filter = buildParentNodeFilter(parentNode);
141141
final SearchResult searchResult =
142142
_entityClient.filter(
143-
GLOSSARY_TERM_ENTITY_NAME, filter, null, 0, 1000, context.getAuthentication());
143+
context.getOperationContext(), GLOSSARY_TERM_ENTITY_NAME, filter, null, 0, 1000);
144144

145145
final List<Urn> termUrns =
146146
searchResult.getEntities().stream()

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/glossary/GetRootGlossaryNodesResolver.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,12 @@ public CompletableFuture<GetRootGlossaryNodesResult> get(
5353
final Filter filter = buildGlossaryEntitiesFilter();
5454
final SearchResult gmsNodesResult =
5555
_entityClient.filter(
56+
context.getOperationContext(),
5657
Constants.GLOSSARY_NODE_ENTITY_NAME,
5758
filter,
5859
null,
5960
start,
60-
count,
61-
context.getAuthentication());
61+
count);
6262

6363
final List<Urn> glossaryNodeUrns =
6464
gmsNodesResult.getEntities().stream()

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/glossary/GetRootGlossaryTermsResolver.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,12 @@ public CompletableFuture<GetRootGlossaryTermsResult> get(
5353
final Filter filter = buildGlossaryEntitiesFilter();
5454
final SearchResult gmsTermsResult =
5555
_entityClient.filter(
56+
context.getOperationContext(),
5657
Constants.GLOSSARY_TERM_ENTITY_NAME,
5758
filter,
5859
null,
5960
start,
60-
count,
61-
context.getAuthentication());
61+
count);
6262

6363
final List<Urn> glossaryTermUrns =
6464
gmsTermsResult.getEntities().stream()

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/group/ListGroupsResolver.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ public CompletableFuture<ListGroupsResult> get(final DataFetchingEnvironment env
5858
// First, get all group Urns.
5959
final SearchResult gmsResult =
6060
_entityClient.search(
61+
context.getOperationContext(),
6162
CORP_GROUP_ENTITY_NAME,
6263
query,
6364
null,
@@ -66,7 +67,6 @@ public CompletableFuture<ListGroupsResult> get(final DataFetchingEnvironment env
6667
.setOrder(SortOrder.DESCENDING),
6768
start,
6869
count,
69-
context.getAuthentication(),
7070
new SearchFlags().setFulltext(true));
7171

7272
// Then, get hydrate all groups.

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/ingest/execution/IngestionSourceExecutionRequestsResolver.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ public CompletableFuture<IngestionSourceExecutionRequests> get(
6767

6868
final SearchResult executionsSearchResult =
6969
_entityClient.filter(
70+
context.getOperationContext(),
7071
Constants.EXECUTION_REQUEST_ENTITY_NAME,
7172
new Filter()
7273
.setOr(
@@ -78,8 +79,7 @@ public CompletableFuture<IngestionSourceExecutionRequests> get(
7879
.setField(REQUEST_TIME_MS_FIELD_NAME)
7980
.setOrder(SortOrder.DESCENDING),
8081
start,
81-
count,
82-
context.getAuthentication());
82+
count);
8383

8484
// 2. Batch fetch the related ExecutionRequests
8585
final Set<Urn> relatedExecRequests =

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/ingest/secret/ListSecretsResolver.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ public CompletableFuture<ListSecretsResult> get(final DataFetchingEnvironment en
6767
// First, get all secrets
6868
final SearchResult gmsResult =
6969
_entityClient.search(
70+
context.getOperationContext(),
7071
Constants.SECRETS_ENTITY_NAME,
7172
query,
7273
null,
@@ -75,7 +76,6 @@ public CompletableFuture<ListSecretsResult> get(final DataFetchingEnvironment en
7576
.setOrder(SortOrder.DESCENDING),
7677
start,
7778
count,
78-
context.getAuthentication(),
7979
new SearchFlags().setFulltext(true));
8080

8181
// Then, resolve all secrets

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/ingest/source/ListIngestionSourcesResolver.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,13 @@ public CompletableFuture<ListIngestionSourcesResult> get(
6363
// First, get all ingestion sources Urns.
6464
final SearchResult gmsResult =
6565
_entityClient.search(
66+
context.getOperationContext(),
6667
Constants.INGESTION_SOURCE_ENTITY_NAME,
6768
query,
6869
buildFilter(filters, Collections.emptyList()),
6970
null,
7071
start,
7172
count,
72-
context.getAuthentication(),
7373
new SearchFlags().setFulltext(true));
7474

7575
// Then, resolve all ingestion sources

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/jobs/DataJobRunsResolver.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,12 @@ public CompletableFuture<DataProcessInstanceResult> get(DataFetchingEnvironment
6363
final SortCriterion sortCriterion = buildTaskRunsSortCriterion();
6464
final SearchResult gmsResult =
6565
_entityClient.filter(
66+
context.getOperationContext(),
6667
Constants.DATA_PROCESS_INSTANCE_ENTITY_NAME,
6768
filter,
6869
sortCriterion,
6970
start,
70-
count,
71-
context.getAuthentication());
71+
count);
7272
final List<Urn> dataProcessInstanceUrns =
7373
gmsResult.getEntities().stream()
7474
.map(SearchEntity::getEntity)

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/jobs/EntityRunsResolver.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,12 @@ public CompletableFuture<DataProcessInstanceResult> get(DataFetchingEnvironment
6969
final SortCriterion sortCriterion = buildTaskRunsSortCriterion();
7070
final SearchResult gmsResult =
7171
_entityClient.filter(
72+
context.getOperationContext(),
7273
Constants.DATA_PROCESS_INSTANCE_ENTITY_NAME,
7374
filter,
7475
sortCriterion,
7576
start,
76-
count,
77-
context.getAuthentication());
77+
count);
7878
final List<Urn> dataProcessInstanceUrns =
7979
gmsResult.getEntities().stream()
8080
.map(SearchEntity::getEntity)

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/mutate/util/DomainUtils.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ public static boolean hasChildDomains(
212212
// Limit count to 1 for existence check
213213
final SearchResult searchResult =
214214
entityClient.filter(
215-
DOMAIN_ENTITY_NAME, parentDomainFilter, null, 0, 1, context.getAuthentication());
215+
context.getOperationContext(), DOMAIN_ENTITY_NAME, parentDomainFilter, null, 0, 1);
216216
return (searchResult.getNumEntities() > 0);
217217
}
218218

@@ -226,7 +226,7 @@ private static Map<Urn, EntityResponse> getDomainsByNameAndParent(
226226

227227
final SearchResult searchResult =
228228
entityClient.filter(
229-
DOMAIN_ENTITY_NAME, filter, null, 0, 1000, context.getAuthentication());
229+
context.getOperationContext(), DOMAIN_ENTITY_NAME, filter, null, 0, 1000);
230230

231231
final Set<Urn> domainUrns =
232232
searchResult.getEntities().stream()

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/ownership/ListOwnershipTypesResolver.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,13 @@ public CompletableFuture<ListOwnershipTypesResult> get(DataFetchingEnvironment e
6060

6161
final SearchResult gmsResult =
6262
_entityClient.search(
63+
context.getOperationContext(),
6364
Constants.OWNERSHIP_TYPE_ENTITY_NAME,
6465
query,
6566
buildFilter(filters, Collections.emptyList()),
6667
DEFAULT_SORT_CRITERION,
6768
start,
6869
count,
69-
context.getAuthentication(),
7070
new SearchFlags().setFulltext(true));
7171

7272
final ListOwnershipTypesResult result = new ListOwnershipTypesResult();

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/policy/ListPoliciesResolver.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public CompletableFuture<ListPoliciesResult> get(final DataFetchingEnvironment e
4242
final String query = input.getQuery() == null ? DEFAULT_QUERY : input.getQuery();
4343

4444
return _policyFetcher
45-
.fetchPolicies(start, query, count, context.getAuthentication())
45+
.fetchPolicies(context.getOperationContext(), start, query, count)
4646
.thenApply(
4747
policyFetchResult -> {
4848
final ListPoliciesResult result = new ListPoliciesResult();

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/post/ListPostsResolver.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,13 @@ public CompletableFuture<ListPostsResult> get(final DataFetchingEnvironment envi
5757
// First, get all Post Urns.
5858
final SearchResult gmsResult =
5959
_entityClient.search(
60+
context.getOperationContext(),
6061
POST_ENTITY_NAME,
6162
query,
6263
null,
6364
sortCriterion,
6465
start,
6566
count,
66-
context.getAuthentication(),
6767
new SearchFlags().setFulltext(true));
6868

6969
// Then, get and hydrate all Posts.

0 commit comments

Comments
 (0)