Skip to content

Commit

Permalink
Merge branch 'datahub-project:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
anshbansal authored Jan 11, 2024
2 parents ea16284 + 990bb65 commit 2537017
Show file tree
Hide file tree
Showing 180 changed files with 8,383 additions and 2,157 deletions.
3 changes: 2 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,8 @@ project.ext.externalDependency = [
'common': 'commons-io:commons-io:2.7',
'jline':'jline:jline:1.4.1',
'jetbrains':' org.jetbrains.kotlin:kotlin-stdlib:1.6.0',
'annotationApi': 'javax.annotation:javax.annotation-api:1.3.2'
'annotationApi': 'javax.annotation:javax.annotation-api:1.3.2',
'classGraph': 'io.github.classgraph:classgraph:4.8.165',
]

allprojects {
Expand Down
15 changes: 14 additions & 1 deletion datahub-frontend/app/controllers/AuthenticationController.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@
import com.linkedin.common.urn.CorpuserUrn;
import com.linkedin.common.urn.Urn;
import com.typesafe.config.Config;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Optional;
import javax.annotation.Nonnull;
import javax.inject.Inject;
import org.apache.commons.httpclient.InvalidRedirectLocationException;
import org.apache.commons.lang3.StringUtils;
import org.pac4j.core.client.Client;
import org.pac4j.core.context.Cookie;
Expand Down Expand Up @@ -86,7 +89,17 @@ public Result authenticate(Http.Request request) {

final Optional<String> maybeRedirectPath =
Optional.ofNullable(request.getQueryString(AUTH_REDIRECT_URI_PARAM));
final String redirectPath = maybeRedirectPath.orElse("/");
String redirectPath = maybeRedirectPath.orElse("/");
try {
URI redirectUri = new URI(redirectPath);
if (redirectUri.getScheme() != null || redirectUri.getAuthority() != null) {
throw new InvalidRedirectLocationException("Redirect location must be relative to the base url, cannot "
+ "redirect to other domains: " + redirectPath, redirectPath);
}
} catch (URISyntaxException | InvalidRedirectLocationException e) {
_logger.warn(e.getMessage());
redirectPath = "/";
}

if (AuthUtils.hasValidSessionCookie(request)) {
return Results.redirect(redirectPath);
Expand Down
21 changes: 20 additions & 1 deletion datahub-frontend/test/app/ApplicationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,27 @@ public void testAPI() throws ParseException {
}

@Test
public void testOidcRedirectToRequestedUrl() throws InterruptedException {
public void testOidcRedirectToRequestedUrl() {
browser.goTo("/authenticate?redirect_uri=%2Fcontainer%2Furn%3Ali%3Acontainer%3ADATABASE");
assertEquals("container/urn:li:container:DATABASE", browser.url());
}

/**
* The Redirect Uri parameter is used to store a previous relative location within the app to be able to
* take a user back to their expected page. Redirecting to other domains should be blocked.
*/
@Test
public void testInvalidRedirectUrl() {
browser.goTo("/authenticate?redirect_uri=https%3A%2F%2Fwww.google.com");
assertEquals("", browser.url());

browser.goTo("/authenticate?redirect_uri=file%3A%2F%2FmyFile");
assertEquals("", browser.url());

browser.goTo("/authenticate?redirect_uri=ftp%3A%2F%2FsomeFtp");
assertEquals("", browser.url());

browser.goTo("/authenticate?redirect_uri=localhost%3A9002%2Flogin");
assertEquals("", browser.url());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import static com.linkedin.datahub.graphql.resolvers.ResolverUtils.*;
import static com.linkedin.datahub.graphql.resolvers.mutate.MutationUtils.*;
import static com.linkedin.datahub.graphql.resolvers.mutate.util.OwnerUtils.*;
import static com.linkedin.metadata.Constants.*;

import com.linkedin.common.AuditStamp;
Expand All @@ -16,7 +15,6 @@
import com.linkedin.datahub.graphql.exception.DataHubGraphQLException;
import com.linkedin.datahub.graphql.generated.CreateDomainInput;
import com.linkedin.datahub.graphql.generated.OwnerEntityType;
import com.linkedin.datahub.graphql.generated.OwnershipType;
import com.linkedin.datahub.graphql.resolvers.mutate.util.DomainUtils;
import com.linkedin.datahub.graphql.resolvers.mutate.util.OwnerUtils;
import com.linkedin.domain.DomainProperties;
Expand Down Expand Up @@ -100,14 +98,8 @@ public CompletableFuture<String> get(DataFetchingEnvironment environment) throws

String domainUrn =
_entityClient.ingestProposal(proposal, context.getAuthentication(), false);
OwnershipType ownershipType = OwnershipType.TECHNICAL_OWNER;
if (!_entityService.exists(
UrnUtils.getUrn(mapOwnershipTypeToEntity(ownershipType.name())))) {
log.warn("Technical owner does not exist, defaulting to None ownership.");
ownershipType = OwnershipType.NONE;
}
OwnerUtils.addCreatorAsOwner(
context, domainUrn, OwnerEntityType.CORP_USER, ownershipType, _entityService);
context, domainUrn, OwnerEntityType.CORP_USER, _entityService);
return domainUrn;
} catch (DataHubGraphQLException e) {
throw e;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import static com.linkedin.datahub.graphql.resolvers.ResolverUtils.bindArgument;
import static com.linkedin.datahub.graphql.resolvers.mutate.MutationUtils.*;
import static com.linkedin.datahub.graphql.resolvers.mutate.util.OwnerUtils.*;
import static com.linkedin.metadata.Constants.*;

import com.linkedin.common.urn.GlossaryNodeUrn;
Expand All @@ -13,7 +12,6 @@
import com.linkedin.datahub.graphql.exception.AuthorizationException;
import com.linkedin.datahub.graphql.generated.CreateGlossaryEntityInput;
import com.linkedin.datahub.graphql.generated.OwnerEntityType;
import com.linkedin.datahub.graphql.generated.OwnershipType;
import com.linkedin.datahub.graphql.resolvers.mutate.util.GlossaryUtils;
import com.linkedin.datahub.graphql.resolvers.mutate.util.OwnerUtils;
import com.linkedin.entity.client.EntityClient;
Expand Down Expand Up @@ -72,19 +70,8 @@ public CompletableFuture<String> get(DataFetchingEnvironment environment) throws
String glossaryNodeUrn =
_entityClient.ingestProposal(proposal, context.getAuthentication(), false);

OwnershipType ownershipType = OwnershipType.TECHNICAL_OWNER;
if (!_entityService.exists(
UrnUtils.getUrn(mapOwnershipTypeToEntity(ownershipType.name())))) {
log.warn("Technical owner does not exist, defaulting to None ownership.");
ownershipType = OwnershipType.NONE;
}

OwnerUtils.addCreatorAsOwner(
context,
glossaryNodeUrn,
OwnerEntityType.CORP_USER,
ownershipType,
_entityService);
context, glossaryNodeUrn, OwnerEntityType.CORP_USER, _entityService);
return glossaryNodeUrn;
} catch (Exception e) {
log.error(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import static com.linkedin.datahub.graphql.resolvers.ResolverUtils.bindArgument;
import static com.linkedin.datahub.graphql.resolvers.mutate.MutationUtils.*;
import static com.linkedin.datahub.graphql.resolvers.mutate.util.OwnerUtils.*;
import static com.linkedin.metadata.Constants.*;

import com.linkedin.common.urn.GlossaryNodeUrn;
Expand All @@ -14,7 +13,6 @@
import com.linkedin.datahub.graphql.exception.AuthorizationException;
import com.linkedin.datahub.graphql.generated.CreateGlossaryEntityInput;
import com.linkedin.datahub.graphql.generated.OwnerEntityType;
import com.linkedin.datahub.graphql.generated.OwnershipType;
import com.linkedin.datahub.graphql.resolvers.mutate.util.GlossaryUtils;
import com.linkedin.datahub.graphql.resolvers.mutate.util.OwnerUtils;
import com.linkedin.entity.EntityResponse;
Expand Down Expand Up @@ -88,19 +86,9 @@ public CompletableFuture<String> get(DataFetchingEnvironment environment) throws

String glossaryTermUrn =
_entityClient.ingestProposal(proposal, context.getAuthentication(), false);
OwnershipType ownershipType = OwnershipType.TECHNICAL_OWNER;
if (!_entityService.exists(
UrnUtils.getUrn(mapOwnershipTypeToEntity(ownershipType.name())))) {
log.warn("Technical owner does not exist, defaulting to None ownership.");
ownershipType = OwnershipType.NONE;
}

OwnerUtils.addCreatorAsOwner(
context,
glossaryTermUrn,
OwnerEntityType.CORP_USER,
ownershipType,
_entityService);
context, glossaryTermUrn, OwnerEntityType.CORP_USER, _entityService);
return glossaryTermUrn;
} catch (Exception e) {
log.error(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import com.linkedin.common.urn.CorpuserUrn;
import com.linkedin.common.urn.Urn;
import com.linkedin.datahub.graphql.QueryContext;
import com.linkedin.datahub.graphql.exception.AuthorizationException;
import com.linkedin.datahub.graphql.generated.AddOwnerInput;
import com.linkedin.datahub.graphql.generated.OwnerInput;
import com.linkedin.datahub.graphql.generated.ResourceRefInput;
Expand Down Expand Up @@ -40,10 +39,7 @@ public CompletableFuture<Boolean> get(DataFetchingEnvironment environment) throw
}

OwnerInput ownerInput = ownerInputBuilder.build();
if (!OwnerUtils.isAuthorizedToUpdateOwners(environment.getContext(), targetUrn)) {
throw new AuthorizationException(
"Unauthorized to perform this action. Please contact your DataHub administrator.");
}
OwnerUtils.validateAuthorizedToUpdateOwners(environment.getContext(), targetUrn);

return CompletableFuture.supplyAsync(
() -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import com.linkedin.common.urn.CorpuserUrn;
import com.linkedin.common.urn.Urn;
import com.linkedin.datahub.graphql.QueryContext;
import com.linkedin.datahub.graphql.exception.AuthorizationException;
import com.linkedin.datahub.graphql.generated.AddOwnersInput;
import com.linkedin.datahub.graphql.generated.OwnerInput;
import com.linkedin.datahub.graphql.generated.ResourceRefInput;
Expand Down Expand Up @@ -34,10 +33,7 @@ public CompletableFuture<Boolean> get(DataFetchingEnvironment environment) throw

return CompletableFuture.supplyAsync(
() -> {
if (!OwnerUtils.isAuthorizedToUpdateOwners(environment.getContext(), targetUrn)) {
throw new AuthorizationException(
"Unauthorized to perform this action. Please contact your DataHub administrator.");
}
OwnerUtils.validateAuthorizedToUpdateOwners(environment.getContext(), targetUrn);

OwnerUtils.validateAddOwnerInput(owners, targetUrn, _entityService);
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import com.linkedin.common.urn.Urn;
import com.linkedin.common.urn.UrnUtils;
import com.linkedin.datahub.graphql.QueryContext;
import com.linkedin.datahub.graphql.exception.AuthorizationException;
import com.linkedin.datahub.graphql.generated.BatchAddOwnersInput;
import com.linkedin.datahub.graphql.generated.OwnerInput;
import com.linkedin.datahub.graphql.generated.ResourceRefInput;
Expand Down Expand Up @@ -74,10 +73,7 @@ private void validateInputResource(ResourceRefInput resource, QueryContext conte
"Malformed input provided: owners cannot be applied to subresources.");
}

if (!OwnerUtils.isAuthorizedToUpdateOwners(context, resourceUrn)) {
throw new AuthorizationException(
"Unauthorized to perform this action. Please contact your DataHub administrator.");
}
OwnerUtils.validateAuthorizedToUpdateOwners(context, resourceUrn);
LabelUtils.validateResource(
resourceUrn, resource.getSubResource(), resource.getSubResourceType(), _entityService);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import com.linkedin.common.urn.Urn;
import com.linkedin.common.urn.UrnUtils;
import com.linkedin.datahub.graphql.QueryContext;
import com.linkedin.datahub.graphql.exception.AuthorizationException;
import com.linkedin.datahub.graphql.generated.BatchRemoveOwnersInput;
import com.linkedin.datahub.graphql.generated.ResourceRefInput;
import com.linkedin.datahub.graphql.resolvers.mutate.util.LabelUtils;
Expand All @@ -14,7 +13,6 @@
import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
Expand All @@ -32,10 +30,10 @@ public CompletableFuture<Boolean> get(DataFetchingEnvironment environment) throw
bindArgument(environment.getArgument("input"), BatchRemoveOwnersInput.class);
final List<String> owners = input.getOwnerUrns();
final List<ResourceRefInput> resources = input.getResources();
final Optional<Urn> maybeOwnershipTypeUrn =
final Urn ownershipTypeUrn =
input.getOwnershipTypeUrn() == null
? Optional.empty()
: Optional.of(Urn.createFromString(input.getOwnershipTypeUrn()));
? null
: Urn.createFromString(input.getOwnershipTypeUrn());
final QueryContext context = environment.getContext();

return CompletableFuture.supplyAsync(
Expand All @@ -46,7 +44,7 @@ public CompletableFuture<Boolean> get(DataFetchingEnvironment environment) throw

try {
// Then execute the bulk remove
batchRemoveOwners(owners, maybeOwnershipTypeUrn, resources, context);
batchRemoveOwners(owners, ownershipTypeUrn, resources, context);
return true;
} catch (Exception e) {
log.error(
Expand All @@ -71,24 +69,21 @@ private void validateInputResource(ResourceRefInput resource, QueryContext conte
"Malformed input provided: owners cannot be removed from subresources.");
}

if (!OwnerUtils.isAuthorizedToUpdateOwners(context, resourceUrn)) {
throw new AuthorizationException(
"Unauthorized to perform this action. Please contact your DataHub administrator.");
}
OwnerUtils.validateAuthorizedToUpdateOwners(context, resourceUrn);
LabelUtils.validateResource(
resourceUrn, resource.getSubResource(), resource.getSubResourceType(), _entityService);
}

private void batchRemoveOwners(
List<String> ownerUrns,
Optional<Urn> maybeOwnershipTypeUrn,
Urn ownershipTypeUrn,
List<ResourceRefInput> resources,
QueryContext context) {
log.debug("Batch removing owners. owners: {}, resources: {}", ownerUrns, resources);
try {
OwnerUtils.removeOwnersFromResources(
ownerUrns.stream().map(UrnUtils::getUrn).collect(Collectors.toList()),
maybeOwnershipTypeUrn,
ownershipTypeUrn,
resources,
UrnUtils.getUrn(context.getActorUrn()),
_entityService);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,12 @@
import com.linkedin.common.urn.CorpuserUrn;
import com.linkedin.common.urn.Urn;
import com.linkedin.datahub.graphql.QueryContext;
import com.linkedin.datahub.graphql.exception.AuthorizationException;
import com.linkedin.datahub.graphql.generated.RemoveOwnerInput;
import com.linkedin.datahub.graphql.generated.ResourceRefInput;
import com.linkedin.datahub.graphql.resolvers.mutate.util.OwnerUtils;
import com.linkedin.metadata.entity.EntityService;
import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -31,15 +29,12 @@ public CompletableFuture<Boolean> get(DataFetchingEnvironment environment) throw

Urn ownerUrn = Urn.createFromString(input.getOwnerUrn());
Urn targetUrn = Urn.createFromString(input.getResourceUrn());
Optional<Urn> maybeOwnershipTypeUrn =
Urn ownershipTypeUrn =
input.getOwnershipTypeUrn() == null
? Optional.empty()
: Optional.of(Urn.createFromString(input.getOwnershipTypeUrn()));
? null
: Urn.createFromString(input.getOwnershipTypeUrn());

if (!OwnerUtils.isAuthorizedToUpdateOwners(environment.getContext(), targetUrn)) {
throw new AuthorizationException(
"Unauthorized to perform this action. Please contact your DataHub administrator.");
}
OwnerUtils.validateAuthorizedToUpdateOwners(environment.getContext(), targetUrn);

return CompletableFuture.supplyAsync(
() -> {
Expand All @@ -50,7 +45,7 @@ public CompletableFuture<Boolean> get(DataFetchingEnvironment environment) throw
((QueryContext) environment.getContext()).getActorUrn());
OwnerUtils.removeOwnersFromResources(
ImmutableList.of(ownerUrn),
maybeOwnershipTypeUrn,
ownershipTypeUrn,
ImmutableList.of(new ResourceRefInput(input.getResourceUrn(), null, null)),
actor,
_entityService);
Expand Down
Loading

0 comments on commit 2537017

Please sign in to comment.