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

DQ-22: Data contract PreProcessor #2937

Merged
merged 25 commits into from
Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
27285ad
Add DataContract preprocessor and versioning
bichitra95 Mar 28, 2024
5c53ca1
Refactore contract code and release
bichitra95 Apr 3, 2024
94d98db
Add unknown attributes to DataContract and fix minor bugs
bichitra95 Apr 4, 2024
d64e969
Add attribute hasContract for assets
bichitra95 Apr 4, 2024
6ee00aa
Add validation of data contract spec
bichitra95 Apr 9, 2024
c79dfa0
Fix audit logs for associated asset
bichitra95 Apr 16, 2024
723286a
Update dataset spec structure
bichitra95 Apr 16, 2024
3e6f1b2
Minor bug fix
bichitra95 Apr 16, 2024
f69d6f6
Refactor with new attributes
bichitra95 Apr 22, 2024
3e75d0f
Fix order of attributes in contract and change dataContractVersion to…
bichitra95 Apr 23, 2024
2e30f63
Add bootstrap policy for DataContract CRU
bichitra95 Apr 23, 2024
32104e9
Fix qualifiedName of the contract
bichitra95 Apr 24, 2024
8185bfe
Add asset guid in DataContract asset and minor fixes
bichitra95 Apr 24, 2024
e863c13
Inconsistency in relationship fixed for data contract<>asset
bichitra95 Apr 24, 2024
2971520
Removed maven release for data-contract branch
bichitra95 Apr 24, 2024
4cd524d
Change datasource to data_source in DataContract
bichitra95 Apr 26, 2024
8ed00b3
Merge create and update AuthPolicy for DataContract
bichitra95 Apr 27, 2024
5434342
Update DataContract attributes from public to private and create gett…
bichitra95 Apr 27, 2024
09c500a
Add setter for private attributes and formatted the file
bichitra95 Apr 27, 2024
d78cdc1
Address PR review changes
bichitra95 Apr 28, 2024
9779ffe
Address code review comments
bichitra95 Apr 29, 2024
191b447
Remove redundant code/arguments in contract preprocessor
bichitra95 Apr 30, 2024
9f26e46
Add remove user added relationship to control relationship update
bichitra95 Apr 30, 2024
418a8cf
Ignoring null value fields
bichitra95 Apr 30, 2024
fb0ee62
Upgrade validator version to avoid vulnerability
bichitra95 Apr 30, 2024
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
102 changes: 102 additions & 0 deletions addons/policies/bootstrap_entity_policies.json
Original file line number Diff line number Diff line change
Expand Up @@ -3004,6 +3004,108 @@
"entity-delete"
]
}
},
{
"typeName": "AuthPolicy",
"attributes":
{
"name": "CREATE_DATA_CONTRACT",
"qualifiedName": "CREATE_DATA_CONTRACT",
"policyCategory": "bootstrap",
"policySubCategory": "default",
"policyServiceName": "atlas",
"policyType": "allow",
"policyPriority": 1,
"policyUsers":
[],
"policyGroups":
[],
"policyRoles":
[
"$admin",
"$member",
"$api-token-default-access"
],
"policyResourceCategory": "ENTITY",
"policyResources":
[
"entity-type:DataContract",
"entity-classification:*",
"entity:*"
],
"policyActions":
[
"entity-create"
]
}
},
{
"typeName": "AuthPolicy",
"attributes":
{
"name": "READ_DATA_CONTRACT",
"qualifiedName": "READ_DATA_CONTRACT",
"policyCategory": "bootstrap",
"policySubCategory": "default",
nikhilbonte21 marked this conversation as resolved.
Show resolved Hide resolved
"policyServiceName": "atlas",
"policyType": "allow",
"policyPriority": 1,
"policyUsers":
[],
"policyGroups":
[],
"policyRoles":
[
"$admin",
"$member",
"$api-token-default-access"
],
"policyResourceCategory": "ENTITY",
"policyResources":
[
"entity-type:DataContract",
"entity-classification:*",
"entity:*"
],
"policyActions":
[
"entity-read"
]
}
},
{
"typeName": "AuthPolicy",
"attributes":
{
"name": "UPDATE_DATA_CONTRACT",
"qualifiedName": "UPDATE_DATA_CONTRACT",
"policyCategory": "bootstrap",
"policySubCategory": "default",
"policyServiceName": "atlas",
"policyType": "allow",
"policyPriority": 1,
"policyUsers":
[],
"policyGroups":
[],
"policyRoles":
[
"$admin",
"$member",
"$api-token-default-access"
],
"policyResourceCategory": "ENTITY",
"policyResources":
[
"entity-type:DataContract",
"entity-classification:*",
"entity:*"
],
"policyActions":
[
"entity-update"
]
}
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,11 @@ public final class Constants {
public static final String ASSET_README_EDGE_LABEL = "__Asset.readme";
public static final String ASSET_LINK_EDGE_LABEL = "__Asset.links";

/**
* Contract
*/
public static final String CONTRACT_ENTITY_TYPE = "DataContract";

/**
* Lineage relations.
*/
Expand Down Expand Up @@ -394,7 +399,8 @@ public enum SupportedFileExtensions { XLSX, XLS, CSV }
public static final String ATTR_STARRED_DETAILS_LIST = "starredDetailsList";
public static final String ATTR_ASSET_STARRED_BY = "assetStarredBy";
public static final String ATTR_ASSET_STARRED_AT = "assetStarredAt";

public static final String ATTR_CERTIFICATE_STATUS = "certificateStatus";
public static final String ATTR_CONTRACT = "dataContractJson";
public static final String STRUCT_STARRED_DETAILS = "StarredDetails";

public static final String KEYCLOAK_ROLE_ADMIN = "$admin";
Expand Down
6 changes: 6 additions & 0 deletions repository/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,12 @@
<version>3.0.0-SNAPSHOT</version>
</dependency>

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.3.0.Final</version>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got a CVE of severity medium here! please fix it. Can't let it to be a backlog
image
https://github.com/atlanhq/atlas-metastore/actions/runs/8890490131

Check how difficult it is to fix it.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically dependency review is failing

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image Just bump it to 4.3.2 and we will be fine here

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initially, I tried with the latest version for Java 8 supported https://central.sonatype.com/artifact/org.hibernate.validator/hibernate-validator/6.2.5.Final

This is not working as the repository/gorupId got changed from org.hibernate to org.hibernate.validator which is why the validator is not working (possible issue might be due to conflict in dependency).

I have limited knowledge of how dependency works in Java. If you can help debug further, I am happy to jump on an call and solve this.

</dependency>

</dependencies>

<profiles>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
import org.apache.atlas.repository.store.graph.v1.RestoreHandlerV1;
import org.apache.atlas.repository.store.graph.v2.preprocessor.AuthPolicyPreProcessor;
import org.apache.atlas.repository.store.graph.v2.preprocessor.ConnectionPreProcessor;
import org.apache.atlas.repository.store.graph.v2.preprocessor.contract.ContractPreProcessor;
import org.apache.atlas.repository.store.graph.v2.preprocessor.resource.LinkPreProcessor;
import org.apache.atlas.repository.store.graph.v2.preprocessor.PreProcessor;
import org.apache.atlas.repository.store.graph.v2.preprocessor.accesscontrol.PersonaPreProcessor;
Expand Down Expand Up @@ -694,8 +695,9 @@ public EntityMutationResponse purgeByIds(Set<String> guids) throws AtlasBaseExce
if (CollectionUtils.isEmpty(guids)) {
throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "Guid(s) not specified");
}

AtlasAuthorizationUtils.verifyAccess(new AtlasAdminAccessRequest(AtlasPrivilege.ADMIN_PURGE), "purge entity: guids=", guids);
if (!RequestContext.get().isSkipAuthorizationCheck()) {
AtlasAuthorizationUtils.verifyAccess(new AtlasAdminAccessRequest(AtlasPrivilege.ADMIN_PURGE), "purge entity: guids=", guids);
}
Collection<AtlasVertex> purgeCandidates = new ArrayList<>();

for (String guid : guids) {
Expand Down Expand Up @@ -1835,6 +1837,10 @@ public PreProcessor getPreProcessor(String typeName) {
case README_ENTITY_TYPE:
preProcessor = new ReadmePreProcessor(typeRegistry, entityRetriever);
break;

case CONTRACT_ENTITY_TYPE:
preProcessor = new ContractPreProcessor(graph, typeRegistry, entityRetriever, this, storeDifferentialAudits, discovery);
break;
}

return preProcessor;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package org.apache.atlas.repository.store.graph.v2.preprocessor.contract;

import org.apache.atlas.RequestContext;
import org.apache.atlas.authorize.AtlasAuthorizationUtils;
import org.apache.atlas.authorize.AtlasEntityAccessRequest;
import org.apache.atlas.authorize.AtlasPrivilege;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.TypeCategory;
import org.apache.atlas.model.instance.AtlasEntity;
import org.apache.atlas.model.instance.AtlasEntityHeader;
import org.apache.atlas.repository.graphdb.AtlasGraph;
import org.apache.atlas.repository.graphdb.AtlasVertex;
import org.apache.atlas.repository.store.graph.v2.AtlasGraphUtilsV2;
import org.apache.atlas.repository.store.graph.v2.EntityGraphRetriever;
import org.apache.atlas.repository.store.graph.v2.preprocessor.PreProcessor;
import org.apache.atlas.type.AtlasEntityType;
import org.apache.atlas.type.AtlasTypeRegistry;
import org.apache.atlas.utils.AtlasPerfMetrics;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;

import static org.apache.atlas.AtlasErrorCode.INSTANCE_BY_UNIQUE_ATTRIBUTE_NOT_FOUND;
import static org.apache.atlas.AtlasErrorCode.TYPE_NAME_INVALID;
import static org.apache.atlas.repository.Constants.*;

public abstract class AbstractContractPreProcessor implements PreProcessor {
private static final Logger LOG = LoggerFactory.getLogger(AbstractContractPreProcessor.class);

public final AtlasTypeRegistry typeRegistry;
public final EntityGraphRetriever entityRetriever;
public final AtlasGraph graph;


AbstractContractPreProcessor(AtlasGraph graph, AtlasTypeRegistry typeRegistry,
EntityGraphRetriever entityRetriever) {
this.graph = graph;
this.typeRegistry = typeRegistry;
this.entityRetriever = entityRetriever;
}

void authorizeContractCreateOrUpdate(AtlasEntity contractEntity, AtlasEntity.AtlasEntityWithExtInfo associatedAsset) throws AtlasBaseException {
AtlasPerfMetrics.MetricRecorder metricRecorder = RequestContext.get().startMetricRecord("authorizeContractUpdate");
try {
AtlasEntityHeader entityHeader = new AtlasEntityHeader(associatedAsset.getEntity());

//First authorize entity update access
verifyAssetAccess(entityHeader, AtlasPrivilege.ENTITY_UPDATE, contractEntity, AtlasPrivilege.ENTITY_UPDATE);

} finally {
RequestContext.get().endMetricRecord(metricRecorder);
}
}


private void verifyAssetAccess(AtlasEntityHeader asset, AtlasPrivilege assetPrivilege,
AtlasEntity contract, AtlasPrivilege contractPrivilege) throws AtlasBaseException {
verifyAccess(asset, assetPrivilege);
verifyAccess(contract, contractPrivilege);
}

private void verifyAccess(AtlasEntity entity, AtlasPrivilege privilege) throws AtlasBaseException {
verifyAccess(new AtlasEntityHeader(entity), privilege);
}

private void verifyAccess(AtlasEntityHeader entityHeader, AtlasPrivilege privilege) throws AtlasBaseException {
String errorMessage = privilege.name() + " entity: " + entityHeader.getTypeName();
AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, privilege, entityHeader), errorMessage);
}

AtlasEntity.AtlasEntityWithExtInfo getAssociatedAsset(String datasetQName, String typeName) throws AtlasBaseException {

Map<String, Object> uniqAttributes = new HashMap<>();
uniqAttributes.put(QUALIFIED_NAME, datasetQName);

AtlasEntityType entityType = ensureEntityType(typeName);

AtlasVertex entityVertex = AtlasGraphUtilsV2.getVertexByUniqueAttributes(graph, entityType, uniqAttributes);

EntityGraphRetriever entityRetriever = new EntityGraphRetriever(graph, typeRegistry, true);
nikhilbonte21 marked this conversation as resolved.
Show resolved Hide resolved

AtlasEntity.AtlasEntityWithExtInfo ret = entityRetriever.toAtlasEntityWithExtInfo(entityVertex);

if (ret == null) {
nikhilbonte21 marked this conversation as resolved.
Show resolved Hide resolved
throw new AtlasBaseException(INSTANCE_BY_UNIQUE_ATTRIBUTE_NOT_FOUND, entityType.getTypeName(),
uniqAttributes.toString());
}
return ret;
}

AtlasEntityType ensureEntityType(String typeName) throws AtlasBaseException {
AtlasEntityType ret = typeRegistry.getEntityTypeByName(typeName);

if (ret == null) {
throw new AtlasBaseException(TYPE_NAME_INVALID, TypeCategory.ENTITY.name(), typeName);
}

return ret;
}


}
Loading
Loading