Commit 5332f2e5 by Madhan Neethiraj

ATLAS-2826: fix for failure in authorizing save-search operation.

Also, skipping add-relationship authorization if either end has legacy attribute - since this would be covered in authorization of entity-update
parent 24830e6b
......@@ -21,18 +21,23 @@ import org.apache.atlas.model.instance.AtlasClassification;
import org.apache.atlas.model.instance.AtlasEntityHeader;
import org.apache.atlas.type.AtlasClassificationType;
import org.apache.atlas.type.AtlasEntityType;
import org.apache.atlas.type.AtlasStructType.AtlasAttribute;
import org.apache.atlas.type.AtlasTypeRegistry;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class AtlasAccessRequest {
private static Logger LOG = LoggerFactory.getLogger(AtlasAccessRequest.class);
private static final String DEFAULT_ENTITY_ID_ATTRIBUTE = "qualifiedName";
private final AtlasPrivilege action;
private final Date accessTime;
private String user = null;
......@@ -118,17 +123,31 @@ public class AtlasAccessRequest {
}
public String getEntityId(AtlasEntityHeader entity) {
final String ret;
return getEntityId(entity, null);
}
if (entity == null) {
ret = null;
} else {
String qualifiedName = (String) entity.getAttribute("qualifiedName");
public String getEntityId(AtlasEntityHeader entity, AtlasTypeRegistry typeRegistry) {
Object ret = null;
if (entity != null) {
AtlasEntityType entityType = typeRegistry == null ? null : typeRegistry.getEntityTypeByName(entity.getTypeName());
Map<String, AtlasAttribute> uniqAttributes = entityType == null ? null : entityType.getUniqAttributes();
ret = qualifiedName;
if (MapUtils.isEmpty(uniqAttributes)) {
ret = entity.getAttribute(DEFAULT_ENTITY_ID_ATTRIBUTE);
} else {
for (AtlasAttribute uniqAttribute : uniqAttributes.values()) {
ret = entity.getAttribute(uniqAttribute.getName());
if (ret != null) {
break;
}
}
}
}
return ret;
return ret == null ? "" : ret.toString();
}
public Set<String> getClassificationNames(AtlasEntityHeader entity) {
......
......@@ -65,7 +65,7 @@ public class AtlasEntityAccessRequest extends AtlasAccessRequest {
super(action, userName, userGroups);
this.entity = entity;
this.entityId = super.getEntityId(entity);
this.entityId = super.getEntityId(entity, typeRegistry);
this.classification = classification;
this.attributeName = attributeName;
this.typeRegistry = typeRegistry;
......@@ -106,7 +106,7 @@ public class AtlasEntityAccessRequest extends AtlasAccessRequest {
@Override
public String toString() {
return "AtlasEntityAccessRequest[entity=" + entity + ", classification=" + classification + ", attributeName" + attributeName +
return "AtlasEntityAccessRequest[entity=" + entity + ", classification=" + classification + ", attributeName=" + attributeName +
", action=" + getAction() + ", accessTime=" + getAccessTime() + ", user=" + getUser() +
", userGroups=" + getUserGroups() + ", clientIPAddress=" + getClientIPAddress() + "]";
}
......
......@@ -21,7 +21,6 @@ package org.apache.atlas.authorize;
import org.apache.atlas.model.instance.AtlasEntityHeader;
import org.apache.atlas.type.AtlasTypeRegistry;
import java.util.Date;
import java.util.Set;
public class AtlasRelationshipAccessRequest extends AtlasAccessRequest {
......@@ -32,11 +31,11 @@ public class AtlasRelationshipAccessRequest extends AtlasAccessRequest {
public AtlasRelationshipAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, String relationshipType, AtlasEntityHeader end1Entity, AtlasEntityHeader end2Entity) {
this(typeRegistry, action, relationshipType, end1Entity, end2Entity, null, null, null,null);
this(typeRegistry, action, relationshipType, end1Entity, end2Entity, null, null);
}
public AtlasRelationshipAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, String relationshipType, AtlasEntityHeader end1Entity, AtlasEntityHeader end2Entity, String user, Set<String> userGroups, Date accessTime, String clientIPAddress) {
super(action, user, userGroups, accessTime, clientIPAddress);
public AtlasRelationshipAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, String relationshipType, AtlasEntityHeader end1Entity, AtlasEntityHeader end2Entity, String user, Set<String> userGroups) {
super(action, user, userGroups);
this.typeRegistry = typeRegistry;
this.relationshipType = relationshipType;
......@@ -66,7 +65,7 @@ public class AtlasRelationshipAccessRequest extends AtlasAccessRequest {
}
public String getEnd1EntityId() {
return super.getEntityId(end1Entity);
return super.getEntityId(end1Entity, typeRegistry);
}
public Set<String> getEnd2EntityTypeAndAllSuperTypes() {
......@@ -78,10 +77,17 @@ public class AtlasRelationshipAccessRequest extends AtlasAccessRequest {
}
public String getEnd2EntityId() {
return super.getEntityId(end2Entity);
return super.getEntityId(end2Entity, typeRegistry);
}
public Set<String> getClassificationTypeAndAllSuperTypes(String classificationName) {
return super.getClassificationTypeAndAllSuperTypes(classificationName, typeRegistry);
}
@Override
public String toString() {
return "AtlasRelationshipAccessRequest[relationshipType=" + relationshipType + ", end1Entity=" + end1Entity + ", end2Entity=" + end2Entity +
", action=" + getAction() + ", accessTime=" + getAccessTime() + ", user=" + getUser() +
", userGroups=" + getUserGroups() + ", clientIPAddress=" + getClientIPAddress() + "]";
}
}
......@@ -77,14 +77,14 @@ public class AtlasEntityType extends AtlasStructType {
public AtlasEntityType(AtlasEntityDef entityDef) {
super(entityDef);
this.entityDef = entityDef;
this.entityDef = entityDef;
this.typeQryStr = AtlasAttribute.escapeIndexQueryValue(Collections.singleton(getTypeName()));
}
public AtlasEntityType(AtlasEntityDef entityDef, AtlasTypeRegistry typeRegistry) throws AtlasBaseException {
super(entityDef);
this.entityDef = entityDef;
this.entityDef = entityDef;
this.typeQryStr = AtlasAttribute.escapeIndexQueryValue(Collections.singleton(getTypeName()));
resolveReferences(typeRegistry);
......@@ -114,14 +114,14 @@ public class AtlasEntityType extends AtlasStructType {
}
}
this.superTypes = Collections.unmodifiableList(s);
this.allSuperTypes = Collections.unmodifiableSet(allS);
this.allAttributes = Collections.unmodifiableMap(allA);
this.uniqAttributes = getUniqueAttributes(this.allAttributes);
this.subTypes = new HashSet<>(); // this will be populated in resolveReferencesPhase2()
this.allSubTypes = new HashSet<>(); // this will be populated in resolveReferencesPhase2()
this.typeAndAllSubTypes = new HashSet<>(); // this will be populated in resolveReferencesPhase2()
this.relationshipAttributes = new HashMap<>(); // this will be populated in resolveReferencesPhase3()
this.superTypes = Collections.unmodifiableList(s);
this.allSuperTypes = Collections.unmodifiableSet(allS);
this.allAttributes = Collections.unmodifiableMap(allA);
this.uniqAttributes = getUniqueAttributes(this.allAttributes);
this.subTypes = new HashSet<>(); // this will be populated in resolveReferencesPhase2()
this.allSubTypes = new HashSet<>(); // this will be populated in resolveReferencesPhase2()
this.typeAndAllSubTypes = new HashSet<>(); // this will be populated in resolveReferencesPhase2()
this.relationshipAttributes = new HashMap<>(); // this will be populated in resolveReferencesPhase3()
this.relationshipAttributesType = new HashMap<>(); // this will be populated in resolveReferencesPhase3()
this.typeAndAllSubTypes.add(this.getTypeName());
......
......@@ -46,25 +46,32 @@ public class AtlasRelationshipType extends AtlasStructType {
private static final Logger LOG = LoggerFactory.getLogger(AtlasRelationshipType.class);
private final AtlasRelationshipDef relationshipDef;
private final boolean hasLegacyAttributeEnd;
private AtlasEntityType end1Type;
private AtlasEntityType end2Type;
public AtlasRelationshipType(AtlasRelationshipDef relationshipDef) {
super(relationshipDef);
this.relationshipDef = relationshipDef;
AtlasRelationshipEndDef end1Def = relationshipDef != null ? relationshipDef.getEndDef1() : null;
AtlasRelationshipEndDef end2Def = relationshipDef != null ? relationshipDef.getEndDef2() : null;
this.relationshipDef = relationshipDef;
this.hasLegacyAttributeEnd = (end1Def != null && end1Def.getIsLegacyAttribute()) || (end2Def != null && end2Def.getIsLegacyAttribute());
}
public AtlasRelationshipType(AtlasRelationshipDef relationshipDef, AtlasTypeRegistry typeRegistry) throws AtlasBaseException {
super(relationshipDef);
this.relationshipDef = relationshipDef;
this(relationshipDef);
resolveReferences(typeRegistry);
}
public AtlasRelationshipDef getRelationshipDef() { return relationshipDef; }
public boolean hasLegacyAttributeEnd() {
return this.hasLegacyAttributeEnd;
}
@Override
void resolveReferences(AtlasTypeRegistry typeRegistry) throws AtlasBaseException {
super.resolveReferences(typeRegistry);
......
......@@ -331,29 +331,30 @@ public class AtlasRelationshipStoreV2 implements AtlasRelationshipStore {
try {
ret = getRelationshipEdge(end1Vertex, end2Vertex, relationship.getTypeName());
if (ret != null) {
throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIP_ALREADY_EXISTS, relationship.getTypeName(),
AtlasGraphUtilsV2.getIdFromVertex(end1Vertex), AtlasGraphUtilsV2.getIdFromVertex(end2Vertex));
}
if (ret == null) {
AtlasRelationshipType relationType = typeRegistry.getRelationshipTypeByName(relationship.getTypeName());
if (!relationType.hasLegacyAttributeEnd()) { // skip authorization for legacy attributes, as these would be covered as entity-update
AtlasEntityHeader end1Entity = entityRetriever.toAtlasEntityHeaderWithClassifications(end1Vertex);
AtlasEntityHeader end2Entity = entityRetriever.toAtlasEntityHeaderWithClassifications(end2Vertex);
AtlasAuthorizationUtils.verifyAccess(new AtlasRelationshipAccessRequest(typeRegistry, AtlasPrivilege.RELATIONSHIP_ADD, relationship.getTypeName(), end1Entity , end2Entity ));
ret = createRelationshipEdge(end1Vertex, end2Vertex, relationship);
AtlasAuthorizationUtils.verifyAccess(new AtlasRelationshipAccessRequest(typeRegistry, AtlasPrivilege.RELATIONSHIP_ADD, relationship.getTypeName(), end1Entity, end2Entity));
}
AtlasRelationshipType relationType = typeRegistry.getRelationshipTypeByName(relationship.getTypeName());
ret = createRelationshipEdge(end1Vertex, end2Vertex, relationship);
if (MapUtils.isNotEmpty(relationType.getAllAttributes())) {
for (AtlasAttribute attr : relationType.getAllAttributes().values()) {
String attrName = attr.getName();
String attrVertexProperty = attr.getVertexPropertyName();
Object attrValue = relationship.getAttribute(attrName);
if (MapUtils.isNotEmpty(relationType.getAllAttributes())) {
for (AtlasAttribute attr : relationType.getAllAttributes().values()) {
String attrName = attr.getName();
String attrVertexProperty = attr.getVertexPropertyName();
Object attrValue = relationship.getAttribute(attrName);
AtlasGraphUtilsV2.setProperty(ret, attrVertexProperty, attrValue);
}
AtlasGraphUtilsV2.setProperty(ret, attrVertexProperty, attrValue);
}
} else {
throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIP_ALREADY_EXISTS, relationship.getTypeName(),
AtlasGraphUtilsV2.getIdFromVertex(end1Vertex), AtlasGraphUtilsV2.getIdFromVertex(end2Vertex));
}
} catch (RepositoryException e) {
throw new AtlasBaseException(AtlasErrorCode.INTERNAL_ERROR, e);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment