Skip to content

Commit

Permalink
feat(access control): Fine-Grained Access Control M1 (#3182)
Browse files Browse the repository at this point in the history
  • Loading branch information
jjoyce0510 authored Sep 3, 2021
1 parent 1f31735 commit ccb09a6
Show file tree
Hide file tree
Showing 195 changed files with 8,092 additions and 706 deletions.
11 changes: 6 additions & 5 deletions datahub-frontend/app/auth/sso/oidc/OidcCallbackLogic.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
@Slf4j
public class OidcCallbackLogic extends DefaultCallbackLogic<Result, PlayWebContext> {

private static final String SYSTEM_PRINCIPAL = "urn:li:corpuser:system";
private final EntityClient _entityClient = GmsClientFactory.getEntitiesClient();
private final SsoManager _ssoManager;

Expand Down Expand Up @@ -270,7 +271,7 @@ private void tryProvisionUser(CorpUserSnapshot corpUserSnapshot) {

// 1. Check if this user already exists.
try {
final Entity corpUser = _entityClient.get(corpUserSnapshot.getUrn());
final Entity corpUser = _entityClient.get(corpUserSnapshot.getUrn(), SYSTEM_PRINCIPAL);

log.debug(String.format("Fetched GMS user with urn %s",corpUserSnapshot.getUrn()));

Expand All @@ -280,7 +281,7 @@ private void tryProvisionUser(CorpUserSnapshot corpUserSnapshot) {
// 2. The user does not exist. Provision them.
final Entity newEntity = new Entity();
newEntity.setValue(Snapshot.create(corpUserSnapshot));
_entityClient.update(newEntity);
_entityClient.update(newEntity, SYSTEM_PRINCIPAL);

log.debug(String.format("Successfully provisioned user %s", corpUserSnapshot.getUrn()));
}
Expand All @@ -301,7 +302,7 @@ private void tryProvisionGroups(List<CorpGroupSnapshot> corpGroups) {
// 1. Check if this user already exists.
try {
final Set<Urn> urnsToFetch = corpGroups.stream().map(CorpGroupSnapshot::getUrn).collect(Collectors.toSet());
final Map<Urn, Entity> existingGroups = _entityClient.batchGet(urnsToFetch);
final Map<Urn, Entity> existingGroups = _entityClient.batchGet(urnsToFetch, SYSTEM_PRINCIPAL);

log.debug(String.format("Fetched GMS groups with urns %s", existingGroups.keySet()));

Expand Down Expand Up @@ -334,7 +335,7 @@ private void tryProvisionGroups(List<CorpGroupSnapshot> corpGroups) {
// Now batch create all entities identified to create.
_entityClient.batchUpdate(groupsToCreate.stream().map(groupSnapshot ->
new Entity().setValue(Snapshot.create(groupSnapshot))
).collect(Collectors.toSet()));
).collect(Collectors.toSet()), SYSTEM_PRINCIPAL);

log.debug(String.format("Successfully provisioned groups with urns %s", groupsToCreateUrns));

Expand All @@ -348,7 +349,7 @@ private void tryProvisionGroups(List<CorpGroupSnapshot> corpGroups) {
private void verifyPreProvisionedUser(CorpuserUrn urn) {
// Validate that the user exists in the system (there is more than just a key aspect for them, as of today).
try {
final Entity corpUser = _entityClient.get(urn);
final Entity corpUser = _entityClient.get(urn, SYSTEM_PRINCIPAL);

log.debug(String.format("Fetched GMS user with urn %s", urn));

Expand Down
3 changes: 2 additions & 1 deletion datahub-frontend/app/controllers/Application.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import akka.util.ByteString;
import auth.Authenticator;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.linkedin.metadata.Constants;
import com.linkedin.util.Configuration;
import com.linkedin.util.Pair;
import com.typesafe.config.Config;
Expand Down Expand Up @@ -116,7 +117,7 @@ public CompletableFuture<Result> proxy(String path) throws ExecutionException, I
.filter(entry -> !Http.HeaderNames.CONTENT_LENGTH.equals(entry.getKey()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))
)
.addHeader("X-DataHub-Principal", ctx().session().get(ACTOR)) // TODO: Replace with a token to GMS.
.addHeader(Constants.ACTOR_HEADER_NAME, ctx().session().get(ACTOR)) // TODO: Replace with a token to GMS.
.setBody(new InMemoryBodyWritable(ByteString.fromByteBuffer(request().body().asBytes().asByteBuffer()), "application/json"))
.execute()
.thenApply(apiResponse -> {
Expand Down
3 changes: 3 additions & 0 deletions datahub-gms-graphql-service/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# DataHub GMS GraphQL Service

> **Disclaimer**: DataHub's standalone GraphQL Service is now deprecated. The GraphQL API is now served from the [Metadata Service](../metadata-service/README.md) directly.
> To explore the GraphQL Query & Mutation types, visit `<your-datahub-url>/api/graphiql`.
Datahub GMS GraphQL Service wraps the Generalized Metadata Store (GMS) Rest.li calls around a GraphQL API.

## Pre-requisites
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package com.linkedin.datahub.graphql.context;

import com.datahub.metadata.authorization.Authorizer;
import org.springframework.stereotype.Component;

import com.linkedin.datahub.graphql.QueryContext;

import lombok.AllArgsConstructor;
import lombok.Data;

Expand All @@ -15,4 +14,7 @@ public class SpringQueryContext implements QueryContext {
boolean isAuthenticated;

String actor;

Authorizer authorizer;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.linkedin.datahub.graphql.service;

import com.datahub.metadata.authorization.AuthorizationRequest;
import com.datahub.metadata.authorization.AuthorizationResult;
import com.datahub.metadata.authorization.Authorizer;


/**
* Implementation of {@link Authorizer} that allows all authorization requests. Used to keep backwards
* compatibility with the deprecated DataHub Standalone GraphQL service.
*/
public class AllowAllAuthorizer implements Authorizer {

public AllowAllAuthorizer() { }

@Override
public AuthorizationResult authorize(AuthorizationRequest request) {
return new AuthorizationResult(null, null, AuthorizationResult.Type.ALLOW);
}

@Override
public AuthorizationMode mode() {
return AuthorizationMode.ALLOW_ALL;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public class QueryGraphQLInvocation implements GraphQLInvocation {

@Override
public CompletableFuture<ExecutionResult> invoke(GraphQLInvocationData invocationData, WebRequest webRequest) {
QueryContext queryContext = new SpringQueryContext(true, APPNAME);
QueryContext queryContext = new SpringQueryContext(true, APPNAME, new AllowAllAuthorizer());

return CompletableFuture.supplyAsync(() -> graphQLEngine.execute(invocationData.getQuery(),
invocationData.getVariables(),
Expand Down
1 change: 1 addition & 0 deletions datahub-graphql-core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ apply plugin: 'java'

dependencies {
compile project(':metadata-service:restli-client')
compile project(':metadata-service:auth')
compile project(':metadata-io')
compile project(':metadata-utils')

Expand Down
Loading

0 comments on commit ccb09a6

Please sign in to comment.