Skip to content

Commit 711ac49

Browse files
jjoyce0510cClaudeJohn JoyceJohn JoyceJohn Joyce
authored
feat(docs): Adding models + APIs for context base V1 (#15280)
Co-authored-by: cclaude-session <cclaude@users.noreply.github.com> Co-authored-by: John Joyce <john@Mac-9122.lan> Co-authored-by: John Joyce <john@ip-192-168-1-63.us-west-2.compute.internal> Co-authored-by: John Joyce <john@Mac-327.lan> Co-authored-by: John Joyce <john@Johns-MacBook-Pro.local> Co-authored-by: John Joyce <john@ip-192-168-0-210.us-west-2.compute.internal> Co-authored-by: Aseem Bansal <asmbansal2@gmail.com>
1 parent 535db8b commit 711ac49

File tree

79 files changed

+10442
-9
lines changed

Some content is hidden

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

79 files changed

+10442
-9
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ private Constants() {}
3535
public static final String LOGICAL_SCHEMA_FILE = "logical.graphql";
3636
public static final String SETTINGS_SCHEMA_FILE = "settings.graphql";
3737
public static final String FILES_SCHEMA_FILE = "files.graphql";
38+
public static final String DOCUMENTS_SCHEMA_FILE = "documents.graphql";
3839

3940
public static final String QUERY_SCHEMA_FILE = "query.graphql";
4041
public static final String TEMPLATE_SCHEMA_FILE = "template.graphql";

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

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@
301301
import com.linkedin.datahub.graphql.types.incident.IncidentType;
302302
import com.linkedin.datahub.graphql.types.ingestion.ExecutionRequestType;
303303
import com.linkedin.datahub.graphql.types.ingestion.IngestionSourceType;
304+
import com.linkedin.datahub.graphql.types.knowledge.DocumentType;
304305
import com.linkedin.datahub.graphql.types.mlmodel.MLFeatureTableType;
305306
import com.linkedin.datahub.graphql.types.mlmodel.MLFeatureType;
306307
import com.linkedin.datahub.graphql.types.mlmodel.MLModelGroupType;
@@ -341,6 +342,7 @@
341342
import com.linkedin.metadata.service.BusinessAttributeService;
342343
import com.linkedin.metadata.service.DataHubFileService;
343344
import com.linkedin.metadata.service.DataProductService;
345+
import com.linkedin.metadata.service.DocumentService;
344346
import com.linkedin.metadata.service.ERModelRelationshipService;
345347
import com.linkedin.metadata.service.FormService;
346348
import com.linkedin.metadata.service.LineageService;
@@ -424,6 +426,7 @@ public class GmsGraphQLEngine {
424426
private final RestrictedService restrictedService;
425427
private ConnectionService connectionService;
426428
private AssertionService assertionService;
429+
private final DocumentService documentService;
427430
private final EntityVersioningService entityVersioningService;
428431
private final ApplicationService applicationService;
429432
private final PageTemplateService pageTemplateService;
@@ -470,6 +473,7 @@ public class GmsGraphQLEngine {
470473
private final DataHubConnectionType connectionType;
471474
private final ContainerType containerType;
472475
private final DomainType domainType;
476+
private final DocumentType documentType;
473477
private final NotebookType notebookType;
474478
private final AssertionType assertionType;
475479
private final VersionedDatasetType versionedDatasetType;
@@ -574,6 +578,7 @@ public GmsGraphQLEngine(final GmsGraphQLEngineArgs args) {
574578
this.restrictedService = args.restrictedService;
575579
this.connectionService = args.connectionService;
576580
this.assertionService = args.assertionService;
581+
this.documentService = args.documentService;
577582
this.entityVersioningService = args.entityVersioningService;
578583

579584
this.businessAttributeService = args.businessAttributeService;
@@ -613,6 +618,7 @@ public GmsGraphQLEngine(final GmsGraphQLEngineArgs args) {
613618
this.connectionType = new DataHubConnectionType(entityClient, secretService);
614619
this.containerType = new ContainerType(entityClient);
615620
this.domainType = new DomainType(entityClient);
621+
this.documentType = new DocumentType(entityClient);
616622
this.notebookType = new NotebookType(entityClient);
617623
this.assertionType = new AssertionType(entityClient);
618624
this.versionedDatasetType = new VersionedDatasetType(entityClient);
@@ -672,6 +678,7 @@ public GmsGraphQLEngine(final GmsGraphQLEngineArgs args) {
672678
containerType,
673679
notebookType,
674680
domainType,
681+
documentType,
675682
assertionType,
676683
versionedDatasetType,
677684
dataPlatformInstanceType,
@@ -775,6 +782,7 @@ public void configureRuntimeWiring(final RuntimeWiring.Builder builder) {
775782
configureOrganisationRoleResolvers(builder);
776783
configureGlossaryNodeResolvers(builder);
777784
configureDomainResolvers(builder);
785+
configureDocumentResolvers(builder);
778786
configureDataProductResolvers(builder);
779787
configureApplicationResolvers(builder);
780788
configureAssertionResolvers(builder);
@@ -873,7 +881,8 @@ public GraphQLEngine.Builder builder() {
873881
.addSchema(fileBasedSchema(MODULE_SCHEMA_FILE))
874882
.addSchema(fileBasedSchema(PATCH_SCHEMA_FILE))
875883
.addSchema(fileBasedSchema(SETTINGS_SCHEMA_FILE))
876-
.addSchema(fileBasedSchema(FILES_SCHEMA_FILE));
884+
.addSchema(fileBasedSchema(FILES_SCHEMA_FILE))
885+
.addSchema(fileBasedSchema(DOCUMENTS_SCHEMA_FILE));
877886

878887
for (GmsGraphQLPlugin plugin : this.graphQLPlugins) {
879888
List<String> pluginSchemaFiles = plugin.getSchemaFiles();
@@ -2956,6 +2965,20 @@ private void configureDomainResolvers(final RuntimeWiring.Builder builder) {
29562965
.getUrn())));
29572966
}
29582967

2968+
private void configureDocumentResolvers(final RuntimeWiring.Builder builder) {
2969+
// Delegate Knowledge Article wiring to consolidated resolver class
2970+
new com.linkedin.datahub.graphql.resolvers.knowledge.DocumentResolvers(
2971+
this.documentService,
2972+
entityTypes,
2973+
documentType,
2974+
entityClient,
2975+
this.entityService,
2976+
this.graphClient,
2977+
entityRegistry,
2978+
this.timelineService)
2979+
.configureResolvers(builder);
2980+
}
2981+
29592982
private void configureFormResolvers(final RuntimeWiring.Builder builder) {
29602983
builder.type(
29612984
"FormAssociation",

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import com.linkedin.metadata.service.BusinessAttributeService;
2828
import com.linkedin.metadata.service.DataHubFileService;
2929
import com.linkedin.metadata.service.DataProductService;
30+
import com.linkedin.metadata.service.DocumentService;
3031
import com.linkedin.metadata.service.ERModelRelationshipService;
3132
import com.linkedin.metadata.service.FormService;
3233
import com.linkedin.metadata.service.LineageService;
@@ -94,6 +95,7 @@ public class GmsGraphQLEngineArgs {
9495
ChromeExtensionConfiguration chromeExtensionConfiguration;
9596
ConnectionService connectionService;
9697
AssertionService assertionService;
98+
DocumentService documentService;
9799
EntityVersioningService entityVersioningService;
98100
ApplicationService applicationService;
99101
PageTemplateService pageTemplateService;

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/authorization/AuthorizationUtils.java

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,86 @@ public static boolean canManageHomePageTemplates(@Nonnull QueryContext context)
373373
context.getOperationContext(), PoliciesConfig.MANAGE_HOME_PAGE_TEMPLATES_PRIVILEGE);
374374
}
375375

376+
/**
377+
* Returns true if the current user is able to create Knowledge Articles. This is true if the user
378+
* has the 'Create Entity' privilege for Knowledge Articles or 'Manage Knowledge Articles'
379+
* platform privilege.
380+
*/
381+
public static boolean canCreateDocument(@Nonnull QueryContext context) {
382+
final DisjunctivePrivilegeGroup orPrivilegeGroups =
383+
new DisjunctivePrivilegeGroup(
384+
ImmutableList.of(
385+
new ConjunctivePrivilegeGroup(
386+
ImmutableList.of(PoliciesConfig.MANAGE_DOCUMENTS_PRIVILEGE.getType()))));
387+
388+
return AuthUtil.isAuthorized(context.getOperationContext(), orPrivilegeGroups, null);
389+
}
390+
391+
/**
392+
* Returns true if the current user is able to edit a specific Document. This is true if the user
393+
* has the 'Edit Entity Docs' or 'Edit Entity' metadata privilege on the document, or the 'Manage
394+
* Documents' platform privilege.
395+
*/
396+
public static boolean canEditDocument(@Nonnull Urn documentUrn, @Nonnull QueryContext context) {
397+
final DisjunctivePrivilegeGroup orPrivilegeGroups =
398+
new DisjunctivePrivilegeGroup(
399+
ImmutableList.of(
400+
new ConjunctivePrivilegeGroup(
401+
ImmutableList.of(PoliciesConfig.EDIT_ENTITY_PRIVILEGE.getType())),
402+
new ConjunctivePrivilegeGroup(
403+
ImmutableList.of(PoliciesConfig.MANAGE_DOCUMENTS_PRIVILEGE.getType()))));
404+
405+
return isAuthorized(
406+
context, documentUrn.getEntityType(), documentUrn.toString(), orPrivilegeGroups);
407+
}
408+
409+
/**
410+
* Returns true if the current user is able to read a specific Document. This is true if the user
411+
* has the 'Get Entity' metadata privilege on the document or the 'Manage Documents' platform
412+
* privilege.
413+
*/
414+
public static boolean canGetDocument(@Nonnull Urn documentUrn, @Nonnull QueryContext context) {
415+
final DisjunctivePrivilegeGroup orPrivilegeGroups =
416+
new DisjunctivePrivilegeGroup(
417+
ImmutableList.of(
418+
new ConjunctivePrivilegeGroup(
419+
ImmutableList.of(PoliciesConfig.VIEW_ENTITY_PAGE_PRIVILEGE.getType())),
420+
new ConjunctivePrivilegeGroup(
421+
ImmutableList.of(PoliciesConfig.MANAGE_DOCUMENTS_PRIVILEGE.getType()))));
422+
423+
return isAuthorized(
424+
context, documentUrn.getEntityType(), documentUrn.toString(), orPrivilegeGroups);
425+
}
426+
427+
/**
428+
* Returns true if the current user is able to delete a specific Document. This is true if the
429+
* user has the delete entity authorization on the document or the 'Manage Documents' platform
430+
* privilege.
431+
*/
432+
public static boolean canDeleteDocument(@Nonnull Urn documentUrn, @Nonnull QueryContext context) {
433+
// Check if user can delete entity using standard delete authorization
434+
if (AuthUtil.isAuthorizedEntityUrns(
435+
context.getOperationContext(), DELETE, List.of(documentUrn))) {
436+
return true;
437+
}
438+
439+
// Fallback to document-specific management privilege
440+
final DisjunctivePrivilegeGroup orPrivilegeGroups =
441+
new DisjunctivePrivilegeGroup(
442+
ImmutableList.of(
443+
new ConjunctivePrivilegeGroup(
444+
ImmutableList.of(PoliciesConfig.MANAGE_DOCUMENTS_PRIVILEGE.getType()))));
445+
446+
return isAuthorized(
447+
context, documentUrn.getEntityType(), documentUrn.toString(), orPrivilegeGroups);
448+
}
449+
450+
/** Returns true if the current user has the platform-level 'Manage Documents' privilege. */
451+
public static boolean canManageDocuments(@Nonnull QueryContext context) {
452+
return AuthUtil.isAuthorized(
453+
context.getOperationContext(), PoliciesConfig.MANAGE_DOCUMENTS_PRIVILEGE);
454+
}
455+
376456
public static boolean isAuthorized(
377457
@Nonnull QueryContext context,
378458
@Nonnull String resourceType,

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ public CompletableFuture<AuthenticatedUser> get(DataFetchingEnvironment environm
8080
platformPrivileges.setViewTests(canViewTests(context));
8181
platformPrivileges.setManageTests(canManageTests(context));
8282
platformPrivileges.setManageGlossaries(canManageGlossaries(context));
83+
platformPrivileges.setManageDocuments(AuthorizationUtils.canManageDocuments(context));
8384
platformPrivileges.setManageUserCredentials(canManageUserCredentials(context));
8485
platformPrivileges.setCreateDomains(AuthorizationUtils.canCreateDomains(context));
8586
platformPrivileges.setCreateTags(AuthorizationUtils.canCreateTags(context));

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/config/AppConfigResolver.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ public CompletableFuture<AppConfig> get(final DataFetchingEnvironment environmen
278278
.setAssetSummaryPageV1(_featureFlags.isAssetSummaryPageV1())
279279
.setDatasetSummaryPageV1(_featureFlags.isDatasetSummaryPageV1())
280280
.setDocumentationFileUploadV1(isDocumentationFileUploadV1Enabled())
281+
.setContextDocumentsEnabled(_featureFlags.isContextDocumentsEnabled())
281282
.build();
282283

283284
appConfig.setFeatureFlags(featureFlagsConfig);

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/entity/EntityPrivilegesResolver.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ public CompletableFuture<EntityPrivileges> get(DataFetchingEnvironment environme
6464
return getDashboardPrivileges(urn, context);
6565
case Constants.DATA_JOB_ENTITY_NAME:
6666
return getDataJobPrivileges(urn, context);
67+
case Constants.DOCUMENT_ENTITY_NAME:
68+
return getDocumentPrivileges(urn, context);
6769
default:
6870
log.warn(
6971
"Tried to get entity privileges for entity type {}. Adding common privileges only.",
@@ -161,6 +163,14 @@ private EntityPrivileges getDataJobPrivileges(Urn urn, QueryContext context) {
161163
return result;
162164
}
163165

166+
private EntityPrivileges getDocumentPrivileges(Urn urn, QueryContext context) {
167+
final EntityPrivileges result = new EntityPrivileges();
168+
addCommonPrivileges(result, urn, context);
169+
// Document-specific: canManageEntity includes ability to delete/move documents
170+
result.setCanManageEntity(AuthorizationUtils.canEditDocument(urn, context));
171+
return result;
172+
}
173+
164174
private void addCommonPrivileges(
165175
@Nonnull EntityPrivileges result, @Nonnull Urn urn, @Nonnull QueryContext context) {
166176
result.setCanEditLineage(canEditEntityLineage(urn, context));

0 commit comments

Comments
 (0)