Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(auth): add group membership field resolver provider #8846

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
8a645d5
feat(auth): add GroupMembershipFieldResolverProvider
amanda-her Sep 14, 2023
8d50908
feat(auth): use GroupMembershipFieldResolverProvider in PolicyEngine
amanda-her Sep 15, 2023
2bb8c7d
feat(auth): fix logic in isGroupMatch
amanda-her Sep 15, 2023
3996e45
Merge branch 'master' into add-GroupMembershipFieldResolverProvider
amanda-her Sep 15, 2023
fc2eee9
Merge branch 'master' into add-GroupMembershipFieldResolverProvider
amanda-her Sep 19, 2023
4981c39
Merge branch 'master' into add-GroupMembershipFieldResolverProvider
amanda-her Sep 25, 2023
6681e9b
Merge branch 'master' into add-GroupMembershipFieldResolverProvider
amanda-her Sep 25, 2023
233330d
feat(auth): Rename ResourceSpec to EntitySpec
amanda-her Sep 25, 2023
1dfb09d
feat(auth): Add GroupMembershipFieldResolverProviderTest
amanda-her Sep 25, 2023
a50a149
feat(auth): PolicyContext needed to cache groups
amanda-her Sep 26, 2023
48fb5f1
Merge branch 'master' into add-GroupMembershipFieldResolverProvider
amanda-her Sep 26, 2023
e09ac0d
Merge branch 'master' into add-GroupMembershipFieldResolverProvider
amanda-her Sep 27, 2023
1bf8509
Merge branch 'master' into add-GroupMembershipFieldResolverProvider
Khurzak Oct 4, 2023
2a7cf57
Merge branch 'master' into add-GroupMembershipFieldResolverProvider
amanda-her Oct 6, 2023
8b8ce34
Merge branch 'master' into add-GroupMembershipFieldResolverProvider
apertinez-tw Oct 11, 2023
8424d99
Resolve merge conflicts
apertinez-tw Oct 11, 2023
680c6ec
Solve compilation issue in tests
apertinez-tw Oct 11, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import com.datahub.plugins.auth.authorization.Authorizer;
import com.datahub.authorization.ConjunctivePrivilegeGroup;
import com.datahub.authorization.DisjunctivePrivilegeGroup;
import com.datahub.authorization.ResourceSpec;
import com.datahub.authorization.EntitySpec;
import com.google.common.collect.ImmutableList;
import com.linkedin.common.AuditStamp;
import com.linkedin.common.urn.Urn;
Expand Down Expand Up @@ -90,7 +90,7 @@ public static boolean canManageTags(@Nonnull QueryContext context) {
}

public static boolean canDeleteEntity(@Nonnull Urn entityUrn, @Nonnull QueryContext context) {
return isAuthorized(context, Optional.of(new ResourceSpec(entityUrn.getEntityType(), entityUrn.toString())), PoliciesConfig.DELETE_ENTITY_PRIVILEGE);
return isAuthorized(context, Optional.of(new EntitySpec(entityUrn.getEntityType(), entityUrn.toString())), PoliciesConfig.DELETE_ENTITY_PRIVILEGE);
}

public static boolean canManageUserCredentials(@Nonnull QueryContext context) {
Expand Down Expand Up @@ -173,7 +173,7 @@ public static boolean canDeleteQuery(@Nonnull Urn entityUrn, @Nonnull List<Urn>

public static boolean isAuthorized(
@Nonnull QueryContext context,
@Nonnull Optional<ResourceSpec> resourceSpec,
@Nonnull Optional<EntitySpec> resourceSpec,
@Nonnull PoliciesConfig.Privilege privilege) {
final Authorizer authorizer = context.getAuthorizer();
final String actor = context.getActorUrn();
Expand All @@ -196,7 +196,7 @@ public static boolean isAuthorized(
@Nonnull String resource,
@Nonnull DisjunctivePrivilegeGroup privilegeGroup
) {
final ResourceSpec resourceSpec = new ResourceSpec(resourceType, resource);
final EntitySpec resourceSpec = new EntitySpec(resourceType, resource);
return AuthUtil.isAuthorized(authorizer, actor, Optional.of(resourceSpec), privilegeGroup);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.linkedin.datahub.graphql.resolvers.dataset;

import com.datahub.authorization.ResourceSpec;
import com.datahub.authorization.EntitySpec;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.linkedin.common.urn.Urn;
Expand Down Expand Up @@ -104,7 +104,7 @@ private CorpUser createPartialUser(final Urn userUrn) {

private boolean isAuthorized(final Urn resourceUrn, final QueryContext context) {
return AuthorizationUtils.isAuthorized(context,
Optional.of(new ResourceSpec(resourceUrn.getEntityType(), resourceUrn.toString())),
Optional.of(new EntitySpec(resourceUrn.getEntityType(), resourceUrn.toString())),
PoliciesConfig.VIEW_DATASET_USAGE_PRIVILEGE);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.linkedin.datahub.graphql.resolvers.dataset;

import com.datahub.authorization.ResourceSpec;
import com.datahub.authorization.EntitySpec;
import com.linkedin.common.urn.Urn;
import com.linkedin.common.urn.UrnUtils;
import com.linkedin.datahub.graphql.QueryContext;
Expand Down Expand Up @@ -52,7 +52,7 @@ public CompletableFuture<UsageQueryResult> get(DataFetchingEnvironment environme

private boolean isAuthorized(final Urn resourceUrn, final QueryContext context) {
return AuthorizationUtils.isAuthorized(context,
Optional.of(new ResourceSpec(resourceUrn.getEntityType(), resourceUrn.toString())),
Optional.of(new EntitySpec(resourceUrn.getEntityType(), resourceUrn.toString())),
PoliciesConfig.VIEW_DATASET_USAGE_PRIVILEGE);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.linkedin.datahub.graphql.resolvers.load;

import com.datahub.authorization.ResourceSpec;
import com.datahub.authorization.EntitySpec;
import com.linkedin.datahub.graphql.QueryContext;
import com.linkedin.datahub.graphql.authorization.AuthorizationUtils;
import com.linkedin.datahub.graphql.generated.Entity;
Expand Down Expand Up @@ -79,7 +79,7 @@ public TimeSeriesAspectResolver(
private boolean isAuthorized(QueryContext context, String urn) {
if (_entityName.equals(Constants.DATASET_ENTITY_NAME) && _aspectName.equals(
Constants.DATASET_PROFILE_ASPECT_NAME)) {
return AuthorizationUtils.isAuthorized(context, Optional.of(new ResourceSpec(_entityName, urn)),
return AuthorizationUtils.isAuthorized(context, Optional.of(new EntitySpec(_entityName, urn)),
PoliciesConfig.VIEW_DATASET_PROFILE_PRIVILEGE);
}
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import com.datahub.authorization.AuthorizerChain;
import com.datahub.authorization.DataHubAuthorizer;
import com.datahub.authorization.ResourceSpec;
import com.datahub.authorization.EntitySpec;
import com.linkedin.datahub.graphql.QueryContext;
import com.linkedin.datahub.graphql.exception.AuthorizationException;
import com.linkedin.datahub.graphql.generated.GetGrantedPrivilegesInput;
Expand Down Expand Up @@ -33,8 +33,8 @@ public CompletableFuture<Privileges> get(final DataFetchingEnvironment environme
if (!isAuthorized(context, actor)) {
throw new AuthorizationException("Unauthorized to get privileges for the given author.");
}
final Optional<ResourceSpec> resourceSpec = Optional.ofNullable(input.getResourceSpec())
.map(spec -> new ResourceSpec(EntityTypeMapper.getName(spec.getResourceType()), spec.getResourceUrn()));
final Optional<EntitySpec> resourceSpec = Optional.ofNullable(input.getResourceSpec())
.map(spec -> new EntitySpec(EntityTypeMapper.getName(spec.getResourceType()), spec.getResourceUrn()));

if (context.getAuthorizer() instanceof AuthorizerChain) {
DataHubAuthorizer dataHubAuthorizer = ((AuthorizerChain) context.getAuthorizer()).getDefaultAuthorizer();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import com.datahub.authorization.AuthorizationRequest;
import com.datahub.authorization.AuthorizationResult;
import com.datahub.plugins.auth.authorization.Authorizer;
import com.datahub.authorization.ResourceSpec;
import com.datahub.authorization.EntitySpec;
import com.linkedin.common.urn.GlossaryNodeUrn;
import com.linkedin.common.urn.Urn;
import com.linkedin.common.urn.UrnUtils;
Expand Down Expand Up @@ -89,17 +89,17 @@ private void setUpTests() throws Exception {
Mockito.any(Authentication.class)
)).thenReturn(new EntityResponse().setAspects(new EnvelopedAspectMap(parentNode3Aspects)));

final ResourceSpec resourceSpec3 = new ResourceSpec(parentNodeUrn.getEntityType(), parentNodeUrn3.toString());
final EntitySpec resourceSpec3 = new EntitySpec(parentNodeUrn.getEntityType(), parentNodeUrn3.toString());
mockAuthRequest("MANAGE_GLOSSARY_CHILDREN", AuthorizationResult.Type.DENY, resourceSpec3);

final ResourceSpec resourceSpec2 = new ResourceSpec(parentNodeUrn.getEntityType(), parentNodeUrn2.toString());
final EntitySpec resourceSpec2 = new EntitySpec(parentNodeUrn.getEntityType(), parentNodeUrn2.toString());
mockAuthRequest("MANAGE_GLOSSARY_CHILDREN", AuthorizationResult.Type.DENY, resourceSpec2);

final ResourceSpec resourceSpec1 = new ResourceSpec(parentNodeUrn.getEntityType(), parentNodeUrn1.toString());
final EntitySpec resourceSpec1 = new EntitySpec(parentNodeUrn.getEntityType(), parentNodeUrn1.toString());
mockAuthRequest("MANAGE_GLOSSARY_CHILDREN", AuthorizationResult.Type.DENY, resourceSpec1);
}

private void mockAuthRequest(String privilege, AuthorizationResult.Type allowOrDeny, ResourceSpec resourceSpec) {
private void mockAuthRequest(String privilege, AuthorizationResult.Type allowOrDeny, EntitySpec resourceSpec) {
final AuthorizationRequest authorizationRequest = new AuthorizationRequest(
userUrn,
privilege,
Expand Down Expand Up @@ -150,7 +150,7 @@ public void testCanManageChildrenEntitiesAuthorized() throws Exception {
// they do NOT have the MANAGE_GLOSSARIES platform privilege
mockAuthRequest("MANAGE_GLOSSARIES", AuthorizationResult.Type.DENY, null);

final ResourceSpec resourceSpec = new ResourceSpec(parentNodeUrn.getEntityType(), parentNodeUrn.toString());
final EntitySpec resourceSpec = new EntitySpec(parentNodeUrn.getEntityType(), parentNodeUrn.toString());
mockAuthRequest("MANAGE_GLOSSARY_CHILDREN", AuthorizationResult.Type.ALLOW, resourceSpec);

assertTrue(GlossaryUtils.canManageChildrenEntities(mockContext, parentNodeUrn, mockClient));
Expand All @@ -162,7 +162,7 @@ public void testCanManageChildrenEntitiesUnauthorized() throws Exception {
// they do NOT have the MANAGE_GLOSSARIES platform privilege
mockAuthRequest("MANAGE_GLOSSARIES", AuthorizationResult.Type.DENY, null);

final ResourceSpec resourceSpec = new ResourceSpec(parentNodeUrn.getEntityType(), parentNodeUrn.toString());
final EntitySpec resourceSpec = new EntitySpec(parentNodeUrn.getEntityType(), parentNodeUrn.toString());
mockAuthRequest("MANAGE_GLOSSARY_CHILDREN", AuthorizationResult.Type.DENY, resourceSpec);
mockAuthRequest("MANAGE_ALL_GLOSSARY_CHILDREN", AuthorizationResult.Type.DENY, resourceSpec);

Expand All @@ -175,13 +175,13 @@ public void testCanManageChildrenRecursivelyEntitiesAuthorized() throws Exceptio
// they do NOT have the MANAGE_GLOSSARIES platform privilege
mockAuthRequest("MANAGE_GLOSSARIES", AuthorizationResult.Type.DENY, null);

final ResourceSpec resourceSpec3 = new ResourceSpec(parentNodeUrn.getEntityType(), parentNodeUrn3.toString());
final EntitySpec resourceSpec3 = new EntitySpec(parentNodeUrn.getEntityType(), parentNodeUrn3.toString());
mockAuthRequest("MANAGE_ALL_GLOSSARY_CHILDREN", AuthorizationResult.Type.ALLOW, resourceSpec3);

final ResourceSpec resourceSpec2 = new ResourceSpec(parentNodeUrn.getEntityType(), parentNodeUrn2.toString());
final EntitySpec resourceSpec2 = new EntitySpec(parentNodeUrn.getEntityType(), parentNodeUrn2.toString());
mockAuthRequest("MANAGE_ALL_GLOSSARY_CHILDREN", AuthorizationResult.Type.DENY, resourceSpec2);

final ResourceSpec resourceSpec1 = new ResourceSpec(parentNodeUrn.getEntityType(), parentNodeUrn1.toString());
final EntitySpec resourceSpec1 = new EntitySpec(parentNodeUrn.getEntityType(), parentNodeUrn1.toString());
mockAuthRequest("MANAGE_ALL_GLOSSARY_CHILDREN", AuthorizationResult.Type.DENY, resourceSpec1);

assertTrue(GlossaryUtils.canManageChildrenEntities(mockContext, parentNodeUrn1, mockClient));
Expand All @@ -193,13 +193,13 @@ public void testCanManageChildrenRecursivelyEntitiesUnauthorized() throws Except
// they do NOT have the MANAGE_GLOSSARIES platform privilege
mockAuthRequest("MANAGE_GLOSSARIES", AuthorizationResult.Type.DENY, null);

final ResourceSpec resourceSpec3 = new ResourceSpec(parentNodeUrn.getEntityType(), parentNodeUrn3.toString());
final EntitySpec resourceSpec3 = new EntitySpec(parentNodeUrn.getEntityType(), parentNodeUrn3.toString());
mockAuthRequest("MANAGE_ALL_GLOSSARY_CHILDREN", AuthorizationResult.Type.DENY, resourceSpec3);

final ResourceSpec resourceSpec2 = new ResourceSpec(parentNodeUrn.getEntityType(), parentNodeUrn2.toString());
final EntitySpec resourceSpec2 = new EntitySpec(parentNodeUrn.getEntityType(), parentNodeUrn2.toString());
mockAuthRequest("MANAGE_ALL_GLOSSARY_CHILDREN", AuthorizationResult.Type.DENY, resourceSpec2);

final ResourceSpec resourceSpec1 = new ResourceSpec(parentNodeUrn.getEntityType(), parentNodeUrn1.toString());
final EntitySpec resourceSpec1 = new EntitySpec(parentNodeUrn.getEntityType(), parentNodeUrn1.toString());
mockAuthRequest("MANAGE_ALL_GLOSSARY_CHILDREN", AuthorizationResult.Type.DENY, resourceSpec1);

assertFalse(GlossaryUtils.canManageChildrenEntities(mockContext, parentNodeUrn1, mockClient));
Expand All @@ -211,10 +211,10 @@ public void testCanManageChildrenRecursivelyEntitiesAuthorizedLevel2() throws Ex
// they do NOT have the MANAGE_GLOSSARIES platform privilege
mockAuthRequest("MANAGE_GLOSSARIES", AuthorizationResult.Type.DENY, null);

final ResourceSpec resourceSpec2 = new ResourceSpec(parentNodeUrn.getEntityType(), parentNodeUrn2.toString());
final EntitySpec resourceSpec2 = new EntitySpec(parentNodeUrn.getEntityType(), parentNodeUrn2.toString());
mockAuthRequest("MANAGE_ALL_GLOSSARY_CHILDREN", AuthorizationResult.Type.ALLOW, resourceSpec2);

final ResourceSpec resourceSpec1 = new ResourceSpec(parentNodeUrn.getEntityType(), parentNodeUrn1.toString());
final EntitySpec resourceSpec1 = new EntitySpec(parentNodeUrn.getEntityType(), parentNodeUrn1.toString());
mockAuthRequest("MANAGE_ALL_GLOSSARY_CHILDREN", AuthorizationResult.Type.DENY, resourceSpec1);

assertTrue(GlossaryUtils.canManageChildrenEntities(mockContext, parentNodeUrn1, mockClient));
Expand All @@ -226,10 +226,10 @@ public void testCanManageChildrenRecursivelyEntitiesUnauthorizedLevel2() throws
// they do NOT have the MANAGE_GLOSSARIES platform privilege
mockAuthRequest("MANAGE_GLOSSARIES", AuthorizationResult.Type.DENY, null);

final ResourceSpec resourceSpec3 = new ResourceSpec(parentNodeUrn.getEntityType(), parentNodeUrn3.toString());
final EntitySpec resourceSpec3 = new EntitySpec(parentNodeUrn.getEntityType(), parentNodeUrn3.toString());
mockAuthRequest("MANAGE_ALL_GLOSSARY_CHILDREN", AuthorizationResult.Type.DENY, resourceSpec3);

final ResourceSpec resourceSpec2 = new ResourceSpec(parentNodeUrn.getEntityType(), parentNodeUrn2.toString());
final EntitySpec resourceSpec2 = new EntitySpec(parentNodeUrn.getEntityType(), parentNodeUrn2.toString());
mockAuthRequest("MANAGE_ALL_GLOSSARY_CHILDREN", AuthorizationResult.Type.DENY, resourceSpec2);

assertFalse(GlossaryUtils.canManageChildrenEntities(mockContext, parentNodeUrn2, mockClient));
Expand All @@ -241,7 +241,7 @@ public void testCanManageChildrenRecursivelyEntitiesNoLevel2() throws Exception
// they do NOT have the MANAGE_GLOSSARIES platform privilege
mockAuthRequest("MANAGE_GLOSSARIES", AuthorizationResult.Type.DENY, null);

final ResourceSpec resourceSpec3 = new ResourceSpec(parentNodeUrn.getEntityType(), parentNodeUrn3.toString());
final EntitySpec resourceSpec3 = new EntitySpec(parentNodeUrn.getEntityType(), parentNodeUrn3.toString());
mockAuthRequest("MANAGE_ALL_GLOSSARY_CHILDREN", AuthorizationResult.Type.DENY, resourceSpec3);

assertFalse(GlossaryUtils.canManageChildrenEntities(mockContext, parentNodeUrn3, mockClient));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import com.datahub.authentication.Authentication;
import com.datahub.authorization.AuthorizationRequest;
import com.datahub.authorization.AuthorizationResult;
import com.datahub.authorization.ResourceSpec;
import com.datahub.authorization.EntitySpec;
import com.datahub.plugins.auth.authorization.Authorizer;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
Expand Down Expand Up @@ -201,7 +201,7 @@ private QueryContext getMockQueryContext(boolean allowEditEntityQueries) {
TEST_ACTOR_URN.toString(),
PoliciesConfig.EDIT_QUERIES_PRIVILEGE.getType(),
Optional.of(
new ResourceSpec(
new EntitySpec(
TEST_DATASET_URN.getEntityType(),
TEST_DATASET_URN.toString()))
);
Expand All @@ -210,7 +210,7 @@ private QueryContext getMockQueryContext(boolean allowEditEntityQueries) {
TEST_ACTOR_URN.toString(),
PoliciesConfig.EDIT_ENTITY_PRIVILEGE.getType(),
Optional.of(
new ResourceSpec(
new EntitySpec(
TEST_DATASET_URN.getEntityType(),
TEST_DATASET_URN.toString()))
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import com.datahub.authentication.Authentication;
import com.datahub.authorization.AuthorizationRequest;
import com.datahub.authorization.AuthorizationResult;
import com.datahub.authorization.ResourceSpec;
import com.datahub.authorization.EntitySpec;
import com.datahub.plugins.auth.authorization.Authorizer;
import com.google.common.collect.ImmutableList;
import com.linkedin.common.urn.Urn;
Expand Down Expand Up @@ -134,7 +134,7 @@ private QueryContext getMockQueryContext(boolean allowEditEntityQueries) {
DeleteQueryResolverTest.TEST_ACTOR_URN.toString(),
PoliciesConfig.EDIT_QUERIES_PRIVILEGE.getType(),
Optional.of(
new ResourceSpec(
new EntitySpec(
DeleteQueryResolverTest.TEST_DATASET_URN.getEntityType(),
DeleteQueryResolverTest.TEST_DATASET_URN.toString()))
);
Expand All @@ -143,7 +143,7 @@ private QueryContext getMockQueryContext(boolean allowEditEntityQueries) {
TEST_ACTOR_URN.toString(),
PoliciesConfig.EDIT_ENTITY_PRIVILEGE.getType(),
Optional.of(
new ResourceSpec(
new EntitySpec(
TEST_DATASET_URN.getEntityType(),
TEST_DATASET_URN.toString()))
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import com.datahub.authentication.Authentication;
import com.datahub.authorization.AuthorizationRequest;
import com.datahub.authorization.AuthorizationResult;
import com.datahub.authorization.ResourceSpec;
import com.datahub.authorization.EntitySpec;
import com.datahub.plugins.auth.authorization.Authorizer;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
Expand Down Expand Up @@ -206,7 +206,7 @@ private QueryContext getMockQueryContext(boolean allowEditEntityQueries) {
TEST_ACTOR_URN.toString(),
PoliciesConfig.EDIT_QUERIES_PRIVILEGE.getType(),
Optional.of(
new ResourceSpec(
new EntitySpec(
TEST_DATASET_URN.getEntityType(),
TEST_DATASET_URN.toString()))
);
Expand All @@ -215,7 +215,7 @@ private QueryContext getMockQueryContext(boolean allowEditEntityQueries) {
TEST_ACTOR_URN.toString(),
PoliciesConfig.EDIT_ENTITY_PRIVILEGE.getType(),
Optional.of(
new ResourceSpec(
new EntitySpec(
TEST_DATASET_URN.getEntityType(),
TEST_DATASET_URN.toString()))
);
Expand All @@ -224,7 +224,7 @@ private QueryContext getMockQueryContext(boolean allowEditEntityQueries) {
TEST_ACTOR_URN.toString(),
PoliciesConfig.EDIT_QUERIES_PRIVILEGE.getType(),
Optional.of(
new ResourceSpec(
new EntitySpec(
TEST_DATASET_URN_2.getEntityType(),
TEST_DATASET_URN_2.toString()))
);
Expand All @@ -233,7 +233,7 @@ private QueryContext getMockQueryContext(boolean allowEditEntityQueries) {
TEST_ACTOR_URN.toString(),
PoliciesConfig.EDIT_ENTITY_PRIVILEGE.getType(),
Optional.of(
new ResourceSpec(
new EntitySpec(
TEST_DATASET_URN_2.getEntityType(),
TEST_DATASET_URN_2.toString()))
);
Expand Down
Loading
Loading