Skip to content

Commit

Permalink
Merge branch 'master' into beta
Browse files Browse the repository at this point in the history
  • Loading branch information
sumandas0 committed Jan 16, 2025
2 parents 556e9ce + 92718c4 commit 8b5f266
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 120 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -374,4 +374,13 @@ EntityMutationResponse deleteByUniqueAttributes(List<AtlasObjectId> objectIds)
void unlinkBusinessPolicy(String policyId, Set<String> unlinkGuids) throws AtlasBaseException;

void moveBusinessPolicies(Set<String> policyId, String assetId, String type) throws AtlasBaseException;

/**
*
* @param entities
* @throws AtlasBaseException
*
* For evaluations of policies
*/
List<AtlasEvaluatePolicyResponse> evaluatePolicies(List<AtlasEvaluatePolicyRequest> entities) throws AtlasBaseException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -512,32 +512,25 @@ public List<AtlasVertex> addTagPropagation(AtlasVertex classificationVertex, Lis

public void authorizeRemoveRelation(AtlasEdge edge) throws AtlasBaseException {
AtlasPerfMetrics.MetricRecorder metric = RequestContext.get().startMetricRecord("authoriseRemoveRelation");
if(isRequestFromWF()){
RequestContext.get().setAuthorisedRemoveRelation(true);
}
AtlasEntityHeader end1Entity, end2Entity;
String relationShipType = getTypeName(edge);
AtlasRelationshipDef relationshipDef = typeRegistry.getRelationshipDefByName(relationShipType);
if (relationshipDef == null) {
return;
}

end1Entity = entityRetriever.toAtlasEntityHeaderWithClassifications(edge.getOutVertex());
end2Entity = entityRetriever.toAtlasEntityHeaderWithClassifications(edge.getInVertex());
if(!RequestContext.get().isAuthorisedRemoveRelation()) {
if (isRequestFromWorkFlow()) {
RequestContext.get().setAuthorisedRemoveRelation(true);
}
AtlasEntityHeader end1Entity, end2Entity;
String relationShipType = getTypeName(edge);
AtlasRelationshipDef relationshipDef = typeRegistry.getRelationshipDefByName(relationShipType);
if (relationshipDef == null) {
return;
}

AtlasAuthorizationUtils.verifyAccess(new AtlasRelationshipAccessRequest(typeRegistry, AtlasPrivilege.RELATIONSHIP_REMOVE, relationShipType, end1Entity, end2Entity ));
end1Entity = entityRetriever.toAtlasEntityHeaderWithClassifications(edge.getOutVertex());
end2Entity = entityRetriever.toAtlasEntityHeaderWithClassifications(edge.getInVertex());

AtlasAuthorizationUtils.verifyAccess(new AtlasRelationshipAccessRequest(typeRegistry, AtlasPrivilege.RELATIONSHIP_REMOVE, relationShipType, end1Entity, end2Entity));
}
RequestContext.get().endMetricRecord(metric);
}

private boolean isRequestFromWF() {
String workflowID = RequestContext.get().getRequestContextHeaders().getOrDefault("x-atlan-agent-workflow-id", "");
boolean ret = !workflowID.isEmpty();
if(ret){
LOG.info("Authorised one time request for workflow with id : {} ", workflowID);
}
return ret;
}

public Map<AtlasVertex, List<AtlasVertex>> removeTagPropagation(AtlasEdge edge) throws AtlasBaseException {
AtlasPerfMetrics.MetricRecorder metric = RequestContext.get().startMetricRecord("removeTagPropagationEdge");
Expand Down Expand Up @@ -1605,6 +1598,14 @@ public void resetHasLineageOnInputOutputDelete(Collection<AtlasEdge> removedEdge
}
RequestContext.get().endMetricRecord(metricRecorder);
}
private boolean isRequestFromWorkFlow() {
String workflowID = RequestContext.get().getRequestContextHeaders().getOrDefault("x-atlan-agent-workflow-id", "");
boolean isWorkFlowRequest = !workflowID.isEmpty();
if(isWorkFlowRequest){
LOG.info("Authorised one time request for workflow with id : {} ", workflowID);
}
return isWorkFlowRequest;
}

private String getLabel(String guid, String label){
return guid + ":" + label;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,8 @@ protected void deleteEdge(AtlasEdge edge, boolean force) throws AtlasBaseExcepti
LOG.debug("==> SoftDeleteHandlerV1.deleteEdge({}, {})", GraphHelper.string(edge), force);
}
boolean isRelationshipEdge = isRelationshipEdge(edge);
if(!RequestContext.get().isAuthorisedRemoveRelation()) {
authorizeRemoveRelation(edge);
}
authorizeRemoveRelation(edge);


if (DEFERRED_ACTION_ENABLED && RequestContext.get().getCurrentTask() == null) {
if (CollectionUtils.isNotEmpty(getPropagatableClassifications(edge))) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,13 @@
import javax.inject.Inject;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

import static java.lang.Boolean.FALSE;
import static org.apache.atlas.AtlasConfiguration.STORE_DIFFERENTIAL_AUDITS;
import static org.apache.atlas.AtlasErrorCode.BAD_REQUEST;
import static org.apache.atlas.authorize.AtlasPrivilege.*;
import static org.apache.atlas.bulkimport.BulkImportResponse.ImportStatus.FAILED;
import static org.apache.atlas.model.instance.AtlasEntity.Status.ACTIVE;
import static org.apache.atlas.model.instance.EntityMutations.EntityOperation.*;
Expand Down Expand Up @@ -763,6 +766,114 @@ public EntityMutationResponse deleteByUniqueAttributes(AtlasEntityType entityTyp
return ret;
}

private AtlasEntityHeader getAtlasEntityHeader(String entityGuid, String entityId, String entityType) throws AtlasBaseException {
// Metric logs
AtlasPerfMetrics.MetricRecorder metric = RequestContext.get().startMetricRecord("getAtlasEntityHeader");
AtlasEntityHeader entityHeader = null;
String cacheKey = generateCacheKey(entityGuid, entityId, entityType);
entityHeader = RequestContext.get().getCachedEntityHeader(cacheKey);
if(Objects.nonNull(entityHeader)){
return entityHeader;
}
if (StringUtils.isNotEmpty(entityGuid)) {
AtlasEntityWithExtInfo ret = getByIdWithoutAuthorization(entityGuid);
entityHeader = new AtlasEntityHeader(ret.getEntity());
} else if (StringUtils.isNotEmpty(entityId) && StringUtils.isNotEmpty(entityType)) {
try {
entityHeader = getAtlasEntityHeaderWithoutAuthorization(null, entityId, entityType);
} catch (AtlasBaseException abe) {
if (abe.getAtlasErrorCode() == AtlasErrorCode.INSTANCE_BY_UNIQUE_ATTRIBUTE_NOT_FOUND) {
Map<String, Object> attributes = new HashMap<>();
attributes.put(QUALIFIED_NAME, entityId);
entityHeader = new AtlasEntityHeader(entityType, attributes);
}
}
} else {
throw new AtlasBaseException(BAD_REQUEST, "requires entityGuid or typeName and qualifiedName for entity authorization");
}
RequestContext.get().setEntityHeaderCache(cacheKey, entityHeader);
RequestContext.get().endMetricRecord(metric);
return entityHeader;
}

@Override
public List<AtlasEvaluatePolicyResponse> evaluatePolicies(List<AtlasEvaluatePolicyRequest> entities) throws AtlasBaseException {
List<AtlasEvaluatePolicyResponse> response = new ArrayList<>();
HashMap<String, AtlasEntityHeader> atlasEntityHeaderCache = new HashMap<>();
for (AtlasEvaluatePolicyRequest entity : entities) {
String action = entity.getAction();

if (action == null) {
throw new AtlasBaseException(BAD_REQUEST, "action is null");
}
AtlasEntityHeader entityHeader = null;

if (ENTITY_READ.name().equals(action) || ENTITY_CREATE.name().equals(action) || ENTITY_UPDATE.name().equals(action)
|| ENTITY_DELETE.name().equals(action) || ENTITY_UPDATE_BUSINESS_METADATA.name().equals(action)) {

try {
entityHeader = getAtlasEntityHeader(entity.getEntityGuid(), entity.getEntityId(), entity.getTypeName());
AtlasEntityAccessRequest.AtlasEntityAccessRequestBuilder requestBuilder = new AtlasEntityAccessRequest.AtlasEntityAccessRequestBuilder(typeRegistry, AtlasPrivilege.valueOf(entity.getAction()), entityHeader);
if (entity.getBusinessMetadata() != null) {
requestBuilder.setBusinessMetadata(entity.getBusinessMetadata());
}

AtlasEntityAccessRequest entityAccessRequest = requestBuilder.build();

AtlasAuthorizationUtils.verifyAccess(entityAccessRequest, entity.getAction() + "guid=" + entity.getEntityGuid());
response.add(new AtlasEvaluatePolicyResponse(entity.getTypeName(), entity.getEntityGuid(), entity.getAction(), entity.getEntityId(), true, null , entity.getBusinessMetadata()));
} catch (AtlasBaseException e) {
AtlasErrorCode code = e.getAtlasErrorCode();
String errorCode = code.getErrorCode();
response.add(new AtlasEvaluatePolicyResponse(entity.getTypeName(), entity.getEntityGuid(), entity.getAction(), entity.getEntityId(), false, errorCode, entity.getBusinessMetadata()));
}

} else if (ENTITY_REMOVE_CLASSIFICATION.name().equals(action) || ENTITY_ADD_CLASSIFICATION.name().equals(action) || ENTITY_UPDATE_CLASSIFICATION.name().equals(action)) {

if (entity.getClassification() == null) {
throw new AtlasBaseException(BAD_REQUEST, "classification needed for " + action + " authorization");
}
try {
entityHeader = getAtlasEntityHeader(entity.getEntityGuid(), entity.getEntityId(), entity.getTypeName());

AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.valueOf(entity.getAction()), entityHeader, new AtlasClassification(entity.getClassification())));
response.add(new AtlasEvaluatePolicyResponse(entity.getTypeName(), entity.getEntityGuid(), entity.getAction(), entity.getEntityId(), entity.getClassification(), true, null));

} catch (AtlasBaseException e) {
AtlasErrorCode code = e.getAtlasErrorCode();
String errorCode = code.getErrorCode();
response.add(new AtlasEvaluatePolicyResponse(entity.getTypeName(), entity.getEntityGuid(), entity.getAction(), entity.getEntityId(), entity.getClassification(), false, errorCode));
}

} else if (RELATIONSHIP_ADD.name().equals(action) || RELATIONSHIP_REMOVE.name().equals(action) || RELATIONSHIP_UPDATE.name().equals(action)) {

if (entity.getRelationShipTypeName() == null) {
throw new AtlasBaseException(BAD_REQUEST, "RelationShip TypeName needed for " + action + " authorization");
}

try {
AtlasEntityHeader end1Entity = getAtlasEntityHeader(entity.getEntityGuidEnd1(), entity.getEntityIdEnd1(), entity.getEntityTypeEnd1());

AtlasEntityHeader end2Entity = getAtlasEntityHeader(entity.getEntityGuidEnd2(), entity.getEntityIdEnd2(), entity.getEntityTypeEnd2());

AtlasAuthorizationUtils.verifyAccess(new AtlasRelationshipAccessRequest(typeRegistry, AtlasPrivilege.valueOf(action), entity.getRelationShipTypeName(), end1Entity, end2Entity));
response.add(new AtlasEvaluatePolicyResponse(action, entity.getRelationShipTypeName(), entity.getEntityTypeEnd1(), entity.getEntityGuidEnd1(), entity.getEntityIdEnd1(), entity.getEntityTypeEnd2(), entity.getEntityGuidEnd2(), entity.getEntityIdEnd2(), true, null));
} catch (AtlasBaseException e) {
AtlasErrorCode code = e.getAtlasErrorCode();
String errorCode = code.getErrorCode();
response.add(new AtlasEvaluatePolicyResponse(action, entity.getRelationShipTypeName(), entity.getEntityTypeEnd1(), entity.getEntityGuidEnd1(), entity.getEntityIdEnd1(), entity.getEntityTypeEnd2(), entity.getEntityGuidEnd2(), entity.getEntityIdEnd2(), false, errorCode));
}
}
}
return response;
}

private String generateCacheKey(String guid, String id, String typeName) {
return (guid != null ? guid : "") + "|" + (id != null ? id : "") + "|" + (typeName != null ? typeName : "");
}



@Override
@GraphTransaction
public EntityMutationResponse deleteByUniqueAttributes(List<AtlasObjectId> objectIds) throws AtlasBaseException {
Expand Down
21 changes: 15 additions & 6 deletions server-api/src/main/java/org/apache/atlas/RequestContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public class RequestContext {
private final Set<String> deletedEdgesIds = new HashSet<>();
private final Set<String> processGuidIds = new HashSet<>();

private Map<String, String> evaluateEntityHeaderCache = null;
private final AtlasPerfMetrics metrics = isMetricsEnabled ? new AtlasPerfMetrics() : null;
private final List<AtlasPerfMetrics.Metric> applicationMetrics = new ArrayList<>();
private List<EntityGuidPair> entityGuidInRequest = null;
Expand Down Expand Up @@ -596,17 +597,17 @@ public void cacheDifferentialEntity(AtlasEntity entity) {
}
}

public void setEntityHeaderCache(AtlasEntityHeader headerCache){
if(headerCache != null && headerCache.getGuid() != null){
entityHeaderCache.put(headerCache.getGuid(), headerCache);
public void setEntityHeaderCache(String cacheKey, AtlasEntityHeader headerCache){
if(headerCache != null && StringUtils.isNotEmpty(cacheKey)){
entityHeaderCache.put(cacheKey, headerCache);
}
}

public AtlasEntityHeader getCachedEntityHeader(String guid){
if(guid == null){
public AtlasEntityHeader getCachedEntityHeader(String cacheKey){
if(cacheKey == null){
return null;
}
return entityHeaderCache.get(guid);
return entityHeaderCache.getOrDefault(cacheKey,null);
}

public AtlasEntity getDifferentialEntity(String guid) {
Expand Down Expand Up @@ -781,6 +782,14 @@ public void setClientOrigin(String clientOrigin) {
this.clientOrigin = StringUtils.isEmpty(clientOrigin) ? "other" :clientOrigin;
}

public Map<String, String> getEvaluateEntityHeaderCache() {
return evaluateEntityHeaderCache;
}

public void setEvaluateEntityHeaderCache(Map<String, String> evaluateEntityHeaderCache) {
this.evaluateEntityHeaderCache = evaluateEntityHeaderCache;
}

public class EntityGuidPair {
private final Object entity;
private final String guid;
Expand Down
Loading

0 comments on commit 8b5f266

Please sign in to comment.