Commit da967ea8 by nixonrodrigues Committed by Madhan Neethiraj

ATLAS-2809: updated authorization model to authorize add/update/remove of relationships

parent d5ecfee5
......@@ -17,10 +17,17 @@
*/
package org.apache.atlas.authorize;
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.AtlasTypeRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
public class AtlasAccessRequest {
......@@ -78,6 +85,68 @@ public class AtlasAccessRequest {
this.clientIPAddress = clientIPAddress;
}
public Set<String> getEntityTypeAndAllSuperTypes(String entityType, AtlasTypeRegistry typeRegistry) {
final Set<String> ret;
if (entityType == null) {
ret = Collections.emptySet();
} else if (typeRegistry == null) {
ret = Collections.singleton(entityType);
} else {
AtlasEntityType entType = typeRegistry.getEntityTypeByName(entityType);
ret = entType != null ? entType.getTypeAndAllSuperTypes() : Collections.singleton(entityType);
}
return ret;
}
public Set<String> getClassificationTypeAndAllSuperTypes(String classificationName, AtlasTypeRegistry typeRegistry) {
final Set<String> ret;
if (classificationName == null) {
ret = Collections.emptySet();
} else if (typeRegistry == null) {
ret = Collections.singleton(classificationName);
} else {
AtlasClassificationType classificationType = typeRegistry.getClassificationTypeByName(classificationName);
return classificationType != null ? classificationType.getTypeAndAllSuperTypes() : Collections.singleton(classificationName);
}
return ret;
}
public String getEntityId(AtlasEntityHeader entity) {
final String ret;
if (entity == null) {
ret = null;
} else {
String qualifiedName = (String) entity.getAttribute("qualifiedName");
ret = qualifiedName;
}
return ret;
}
public Set<String> getClassificationNames(AtlasEntityHeader entity) {
final Set<String> ret;
if (entity == null || entity.getClassifications() == null) {
ret = Collections.emptySet();
} else {
ret = new HashSet<>();
for (AtlasClassification classify : entity.getClassifications()) {
ret.add(classify.getTypeName());
}
}
return ret;
}
@Override
public String toString() {
return "AtlasAccessRequest[action=" + action + ", accessTime=" + accessTime + ", user=" + user +
......
......@@ -62,6 +62,13 @@ public class AtlasAuthorizationUtils {
}
}
public static void verifyAccess(AtlasRelationshipAccessRequest request, Object... errorMsgParams) throws AtlasBaseException {
if (!isAccessAllowed(request)) {
String message = (errorMsgParams != null && errorMsgParams.length > 0) ? StringUtils.join(errorMsgParams) : "";
throw new AtlasBaseException(AtlasErrorCode.UNAUTHORIZED_ACCESS, request.getUser(), message);
}
}
public static void scrubSearchResults(AtlasSearchResultScrubRequest request) throws AtlasBaseException {
String userName = getCurrentUserName();
......@@ -142,6 +149,27 @@ public class AtlasAuthorizationUtils {
return ret;
}
public static boolean isAccessAllowed(AtlasRelationshipAccessRequest request) {
boolean ret = false;
String userName = getCurrentUserName();
if (StringUtils.isNotEmpty(userName)) {
try {
AtlasAuthorizer authorizer = AtlasAuthorizerFactory.getAtlasAuthorizer();
request.setUser(getCurrentUserName(), getCurrentUserGroups());
request.setClientIPAddress(RequestContext.get().getClientIPAddress());
ret = authorizer.isAccessAllowed(request);
} catch (AtlasAuthorizationException e) {
LOG.error("Unable to obtain AtlasAuthorizer", e);
}
} else {
ret = true;
}
return ret;
}
public static String getRequestIpAddress(HttpServletRequest httpServletRequest) {
String ret = "";
......@@ -156,6 +184,8 @@ public class AtlasAuthorizationUtils {
return ret;
}
public static String getCurrentUserName() {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
......
......@@ -48,8 +48,6 @@ public interface AtlasAuthorizer {
*/
boolean isAccessAllowed(AtlasEntityAccessRequest request) throws AtlasAuthorizationException;
/**
* authorize operations on a type
* @param request
......@@ -58,6 +56,16 @@ public interface AtlasAuthorizer {
*/
boolean isAccessAllowed(AtlasTypeAccessRequest request) throws AtlasAuthorizationException;
/**
* authorize relationship type
* @param request
* @return
* @throws AtlasAuthorizationException
*/
default
boolean isAccessAllowed(AtlasRelationshipAccessRequest request) throws AtlasAuthorizationException {
return true;
}
/**
* scrub search-results to handle entities for which the user doesn't have access
......
......@@ -19,13 +19,9 @@ package org.apache.atlas.authorize;
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.AtlasTypeRegistry;
import org.apache.commons.lang.StringUtils;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
public class AtlasEntityAccessRequest extends AtlasAccessRequest {
......@@ -68,21 +64,12 @@ public class AtlasEntityAccessRequest extends AtlasAccessRequest {
public AtlasEntityAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, AtlasEntityHeader entity, AtlasClassification classification, String attributeName, String userName, Set<String> userGroups) {
super(action, userName, userGroups);
this.entity = entity;
this.entityId = entity != null ? (String) entity.getAttribute("qualifiedName") : null;
this.classification = classification;
this.attributeName = attributeName;
this.typeRegistry = typeRegistry;
if (entity == null || entity.getClassifications() == null) {
this.entityClassifications = Collections.emptySet();
} else {
this.entityClassifications = new HashSet<>();
for (AtlasClassification classify : entity.getClassifications()) {
this.entityClassifications.add(classify.getTypeName());
}
}
this.entity = entity;
this.entityId = super.getEntityId(entity);
this.classification = classification;
this.attributeName = attributeName;
this.typeRegistry = typeRegistry;
this.entityClassifications = super.getClassificationNames(entity);
}
public AtlasEntityHeader getEntity() {
......@@ -110,29 +97,11 @@ public class AtlasEntityAccessRequest extends AtlasAccessRequest {
}
public Set<String> getEntityTypeAndAllSuperTypes() {
final Set<String> ret;
if (entity == null) {
ret = Collections.emptySet();
} else if (typeRegistry == null) {
ret = Collections.singleton(entity.getTypeName());
} else {
AtlasEntityType entityType = typeRegistry.getEntityTypeByName(entity.getTypeName());
ret = entityType != null ? entityType.getTypeAndAllSuperTypes() : Collections.singleton(entity.getTypeName());
}
return ret;
return super.getEntityTypeAndAllSuperTypes(entity == null ? null : entity.getTypeName(), typeRegistry);
}
public Set<String> getClassificationTypeAndAllSuperTypes(String classificationName) {
if (typeRegistry != null && classificationName != null) {
AtlasClassificationType classificationType = typeRegistry.getClassificationTypeByName(classificationName);
return classificationType == null ? Collections.emptySet() : classificationType.getTypeAndAllSuperTypes();
}
return Collections.emptySet();
return super.getClassificationTypeAndAllSuperTypes(classificationName, typeRegistry);
}
@Override
......
......@@ -45,6 +45,11 @@ public class AtlasNoneAuthorizer implements AtlasAuthorizer {
return true;
}
@Override
public boolean isAccessAllowed(AtlasRelationshipAccessRequest request) throws AtlasAuthorizationException {
return true;
}
public void scrubSearchResults(AtlasSearchResultScrubRequest request) throws AtlasAuthorizationException {
}
......
......@@ -32,7 +32,11 @@ public enum AtlasPrivilege {
ENTITY_REMOVE_CLASSIFICATION("entity-remove-classification"),
ADMIN_EXPORT("admin-export"),
ADMIN_IMPORT("admin-import");
ADMIN_IMPORT("admin-import"),
RELATIONSHIP_ADD("add-relationship"),
RELATIONSHIP_UPDATE("update-relationship"),
RELATIONSHIP_REMOVE("remove-relationship");
private final String type;
......
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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 {
private final AtlasTypeRegistry typeRegistry;
private final String relationshipType ;
private final AtlasEntityHeader end1Entity;
private final AtlasEntityHeader end2Entity;
public AtlasRelationshipAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, String relationshipType, AtlasEntityHeader end1Entity, AtlasEntityHeader end2Entity) {
this(typeRegistry, action, relationshipType, end1Entity, end2Entity, null, null, 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);
this.typeRegistry = typeRegistry;
this.relationshipType = relationshipType;
this.end1Entity = end1Entity;
this.end2Entity = end2Entity;
}
public AtlasEntityHeader getEnd1Entity() {
return end1Entity;
}
public AtlasEntityHeader getEnd2Entity() {
return end2Entity;
}
public String getRelationshipType() {
return relationshipType;
}
public Set<String> getEnd1EntityTypeAndAllSuperTypes() {
return super.getEntityTypeAndAllSuperTypes(end1Entity == null ? null : end1Entity.getTypeName(), typeRegistry);
}
public Set<String> getEnd1EntityClassifications() {
return super.getClassificationNames(end1Entity);
}
public String getEnd1EntityId() {
return super.getEntityId(end1Entity);
}
public Set<String> getEnd2EntityTypeAndAllSuperTypes() {
return super.getEntityTypeAndAllSuperTypes(end2Entity == null ? null : end2Entity.getTypeName(), typeRegistry);
}
public Set<String> getEnd2EntityClassifications() {
return super.getClassificationNames(end2Entity);
}
public String getEnd2EntityId() {
return super.getEntityId(end2Entity);
}
public Set<String> getClassificationTypeAndAllSuperTypes(String classificationName) {
return super.getClassificationTypeAndAllSuperTypes(classificationName, typeRegistry);
}
}
......@@ -27,13 +27,7 @@ import java.util.Set;
import org.apache.atlas.ApplicationProperties;
import org.apache.atlas.AtlasException;
import org.apache.atlas.authorize.AtlasAdminAccessRequest;
import org.apache.atlas.authorize.AtlasAuthorizer;
import org.apache.atlas.authorize.AtlasAuthorizationException;
import org.apache.atlas.authorize.AtlasEntityAccessRequest;
import org.apache.atlas.authorize.AtlasPrivilege;
import org.apache.atlas.authorize.AtlasSearchResultScrubRequest;
import org.apache.atlas.authorize.AtlasTypeAccessRequest;
import org.apache.atlas.authorize.*;
import org.apache.atlas.authorize.simple.AtlasSimpleAuthzPolicy.*;
import org.apache.atlas.model.discovery.AtlasSearchResult;
import org.apache.atlas.model.discovery.AtlasSearchResult.AtlasFullTextResult;
......@@ -164,6 +158,66 @@ public final class AtlasSimpleAuthorizer implements AtlasAuthorizer {
}
@Override
public boolean isAccessAllowed(AtlasRelationshipAccessRequest request) throws AtlasAuthorizationException {
final Set<String> roles = getRoles(request.getUser(), request.getUserGroups());
final String relationShipType = request.getRelationshipType();
final Set<String> end1EntityTypeAndSuperTypes = request.getEnd1EntityTypeAndAllSuperTypes();
final Set<String> end1Classifications = new HashSet<>(request.getEnd1EntityClassifications());
final String end1EntityId = request.getEnd1EntityId();
final Set<String> end2EntityTypeAndSuperTypes = request.getEnd2EntityTypeAndAllSuperTypes();
final Set<String> end2Classifications = new HashSet<>(request.getEnd2EntityClassifications());
final String end2EntityId = request.getEnd2EntityId();
final String action = request.getAction() != null ? request.getAction().getType() : null;
boolean hasEnd1EntityAccess = false;
boolean hasEnd2EntityAccess = false;
for (String role : roles) {
final List<AtlasRelationshipPermission> permissions = getRelationshipPermissionsForRole(role);
if (permissions == null) {
continue;
}
for (AtlasRelationshipPermission permission : permissions) {
if (isMatch(relationShipType, permission.getRelationshipTypes()) && isMatch(action, permission.getPrivileges())) {
//End1 permission check
if (!hasEnd1EntityAccess) {
if (isMatchAny(end1EntityTypeAndSuperTypes, permission.getEnd1EntityType()) && isMatch(end1EntityId, permission.getEnd1EntityId())) {
for (Iterator<String> iter = end1Classifications.iterator(); iter.hasNext();) {
String entityClassification = iter.next();
if (isMatchAny(request.getClassificationTypeAndAllSuperTypes(entityClassification), permission.getEnd1EntityClassification())) {
iter.remove();
}
}
hasEnd1EntityAccess = CollectionUtils.isEmpty(end1Classifications);
}
}
//End2 permission chech
if (!hasEnd2EntityAccess) {
if (isMatchAny(end2EntityTypeAndSuperTypes, permission.getEnd2EntityType()) && isMatch(end2EntityId, permission.getEnd2EntityId())) {
for (Iterator<String> iter = end2Classifications.iterator(); iter.hasNext();) {
String entityClassification = iter.next();
if (isMatchAny(request.getClassificationTypeAndAllSuperTypes(entityClassification), permission.getEnd2EntityClassification())) {
iter.remove();
}
}
hasEnd2EntityAccess = CollectionUtils.isEmpty(end2Classifications);
}
}
}
}
}
return hasEnd1EntityAccess && hasEnd2EntityAccess;
}
@Override
public boolean isAccessAllowed(AtlasEntityAccessRequest request) throws AtlasAuthorizationException {
if (LOG.isDebugEnabled()) {
LOG.debug("==> SimpleAtlasAuthorizer.isAccessAllowed({})", request);
......@@ -324,6 +378,19 @@ public final class AtlasSimpleAuthorizer implements AtlasAuthorizer {
return ret;
}
private List<AtlasRelationshipPermission> getRelationshipPermissionsForRole(String roleName) {
List<AtlasRelationshipPermission> ret = null;
if (authzPolicy != null && roleName != null) {
AtlasAuthzRole role = authzPolicy.getRoles().get(roleName);
ret = role != null ? role.getRelationshipPermissions() : null;
}
return ret;
}
private boolean isMatch(String value, List<String> patterns) {
boolean ret = false;
......
......@@ -76,17 +76,19 @@ public class AtlasSimpleAuthzPolicy implements Serializable {
public static class AtlasAuthzRole implements Serializable {
private static final long serialVersionUID = 1L;
private List<AtlasAdminPermission> adminPermissions;
private List<AtlasEntityPermission> entityPermissions;
private List<AtlasTypePermission> typePermissions;
private List<AtlasAdminPermission> adminPermissions;
private List<AtlasTypePermission> typePermissions;
private List<AtlasEntityPermission> entityPermissions;
private List<AtlasRelationshipPermission> relationshipPermissions;
public AtlasAuthzRole() {
}
public AtlasAuthzRole(List<AtlasAdminPermission> adminPermissions, List<AtlasEntityPermission> entityPermissions, List<AtlasTypePermission> typePermissions) {
this.adminPermissions = adminPermissions;
this.entityPermissions = entityPermissions;
this.typePermissions = typePermissions;
public AtlasAuthzRole(List<AtlasAdminPermission> adminPermissions, List<AtlasTypePermission> typePermissions, List<AtlasEntityPermission> entityPermissions, List<AtlasRelationshipPermission> relationshipPermissions) {
this.adminPermissions = adminPermissions;
this.typePermissions = typePermissions;
this.entityPermissions = entityPermissions;
this.relationshipPermissions = relationshipPermissions;
}
public List<AtlasAdminPermission> getAdminPermissions() {
......@@ -97,6 +99,14 @@ public class AtlasSimpleAuthzPolicy implements Serializable {
this.adminPermissions = adminPermissions;
}
public List<AtlasTypePermission> getTypePermissions() {
return typePermissions;
}
public void setTypePermissions(List<AtlasTypePermission> typePermissions) {
this.typePermissions = typePermissions;
}
public List<AtlasEntityPermission> getEntityPermissions() {
return entityPermissions;
}
......@@ -105,13 +115,14 @@ public class AtlasSimpleAuthzPolicy implements Serializable {
this.entityPermissions = entityPermissions;
}
public List<AtlasTypePermission> getTypePermissions() {
return typePermissions;
public List<AtlasRelationshipPermission> getRelationshipPermissions() {
return relationshipPermissions;
}
public void setTypePermissions(List<AtlasTypePermission> typePermissions) {
this.typePermissions = typePermissions;
public void setRelationshipPermissions(List<AtlasRelationshipPermission> relationshipPermissions) {
this.relationshipPermissions = relationshipPermissions;
}
}
@JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, fieldVisibility=NONE)
......@@ -252,4 +263,101 @@ public class AtlasSimpleAuthzPolicy implements Serializable {
}
}
@JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, fieldVisibility=NONE)
@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown=true)
@XmlRootElement
@XmlAccessorType(XmlAccessType.PROPERTY)
public static class AtlasRelationshipPermission implements Serializable {
private static final long serialVersionUID = 1L;
private List<String> privileges; // name of AtlasPrivilege enum, wildcards supported
private List<String> relationshipTypes; // name of relationship-type, wildcards supported
private List<String> end1EntityType; // name of end1 entity-type, wildcards supported
private List<String> end1EntityId; // value of end1 entity-unique attribute, wildcards supported
private List<String> end1EntityClassification; // name of end1 classification-type, wildcards supported
private List<String> end2EntityType; // name of end2 entity-type, wildcards supported
private List<String> end2EntityId; // value of end2 entity-unique attribute, wildcards supported
private List<String> end2EntityClassification; // name of end2 classification-type, wildcards supported
public AtlasRelationshipPermission() {
}
public AtlasRelationshipPermission(List<String> privileges, List<String> relationshipTypes, List<String> end1Entitytype, List<String> end1EntityId, List<String> end1EntityClassification, List<String> end2EntityType, List<String> end2EntityId, List<String> end2EntityClassification) {
this.privileges = privileges;
this.relationshipTypes = relationshipTypes;
this.end1EntityType = end1Entitytype;
this.end1EntityId = end1EntityId;
this.end1EntityClassification = end1EntityClassification;
this.end2EntityType = end2EntityType;
this.end2EntityId = end2EntityId;
this.end2EntityClassification = end2EntityClassification;
}
public List<String> getPrivileges() {
return privileges;
}
public void setPrivileges(List<String> privileges) {
this.privileges = privileges;
}
public List<String> getRelationshipTypes() {
return relationshipTypes;
}
public void setRelationshipTypes(List<String> relationshipTypes) {
this.relationshipTypes = relationshipTypes;
}
public List<String> getEnd1EntityType() {
return end1EntityType;
}
public void setEnd1EntityType(List<String> end1EntityType) {
this.end1EntityType = end1EntityType;
}
public List<String> getEnd1EntityId() {
return end1EntityId;
}
public void setEnd1EntityId(List<String> end1EntityId) {
this.end1EntityId = end1EntityId;
}
public List<String> getEnd1EntityClassification() {
return end1EntityClassification;
}
public void setEnd1EntityClassification(List<String> end1EntityClassification) {
this.end1EntityClassification = end1EntityClassification;
}
public List<String> getEnd2EntityType() {
return end2EntityType;
}
public void setEnd2EntityType(List<String> end2EntityType) {
this.end2EntityType = end2EntityType;
}
public List<String> getEnd2EntityId() {
return end2EntityId;
}
public void setEnd2EntityId(List<String> end2EntityId) {
this.end2EntityId = end2EntityId;
}
public List<String> getEnd2EntityClassification() {
return end2EntityClassification;
}
public void setEnd2EntityClassification(List<String> end2EntityClassification) {
this.end2EntityClassification = end2EntityClassification;
}
}
}
......@@ -6,7 +6,13 @@
"privileges": [ ".*" ]
}
],
"typePermissions": [
{
"privileges": [ ".*" ],
"typeCategories": [ ".*" ],
"typeNames": [ ".*" ]
}
],
"entityPermissions": [
{
"privileges": [ ".*" ],
......@@ -15,12 +21,16 @@
"classifications": [ ".*" ]
}
],
"typePermissions": [
"relationshipPermissions": [
{
"privileges": [ ".*" ],
"typeCategories": [ ".*" ],
"typeNames": [ ".*" ]
"privileges": [ ".*" ],
"relationshipTypes": [ ".*" ],
"end1EntityType": [ ".*" ],
"end1EntityId": [ ".*" ],
"end1EntityClassification": [ ".*" ],
"end2EntityType": [ ".*" ],
"end2EntityId": [ ".*" ],
"end2EntityClassification": [ ".*" ]
}
]
},
......@@ -44,6 +54,18 @@
"entityIds": [ ".*" ],
"classifications": [ ".*" ]
}
],
"relationshipPermissions": [
{
"privileges": [ "add-relationship", "update-relationship", "remove-relationship" ],
"relationshipTypes": [ ".*" ],
"end1EntityType": [ ".*" ],
"end1EntityId": [ ".*" ],
"end1EntityClassification": [ ".*" ],
"end2EntityType": [ ".*" ],
"end2EntityId": [ ".*" ],
"end2EntityClassification": [ ".*" ]
}
]
}
},
......
......@@ -22,6 +22,18 @@
"typeCategories": [ ".*" ],
"typeNames": [ ".*" ]
}
],
"relationshipPermissions": [
{
"privileges": [ ".*" ],
"relationshipTypes": [ ".*" ],
"endOneEntityType": [ ".*" ],
"endOneEntityId": [ ".*" ],
"endOneEntityClassification": [ ".*" ],
"endTwoEntityType": [ ".*" ],
"endTwoEntityId": [ ".*" ],
"endTwoEntityClassification": [ ".*" ]
}
]
},
......
......@@ -6,7 +6,13 @@
"privileges": [ ".*" ]
}
],
"typePermissions": [
{
"privileges": [ ".*" ],
"typeCategories": [ ".*" ],
"typeNames": [ ".*" ]
}
],
"entityPermissions": [
{
"privileges": [ ".*" ],
......@@ -15,12 +21,16 @@
"classifications": [ ".*" ]
}
],
"typePermissions": [
"relationshipPermissions": [
{
"privileges": [ ".*" ],
"typeCategories": [ ".*" ],
"typeNames": [ ".*" ]
"relationshipTypes": [ ".*" ],
"endOneEntityType": [ ".*" ],
"endOneEntityId": [ ".*" ],
"endOneEntityClassification": [ ".*" ],
"endTwoEntityType": [ ".*" ],
"endTwoEntityId": [ ".*" ],
"endTwoEntityClassification": [ ".*" ]
}
]
},
......@@ -44,6 +54,18 @@
"entityIds": [ ".*" ],
"classifications": [ ".*" ]
}
],
"relationshipPermissions": [
{
"privileges": [ "add-relationship", "update-relationship", "remove-relationship" ],
"relationshipTypes": [ ".*" ],
"end1EntityType": [ ".*" ],
"end1EntityId": [ ".*" ],
"end1EntityClassification": [ ".*" ],
"end2EntityType": [ ".*" ],
"end2EntityId": [ ".*" ],
"end2EntityClassification": [ ".*" ]
}
]
}
},
......
......@@ -20,10 +20,14 @@ package org.apache.atlas.repository.store.graph.v2;
import org.apache.atlas.AtlasErrorCode;
import org.apache.atlas.annotation.GraphTransaction;
import org.apache.atlas.authorize.AtlasAuthorizationUtils;
import org.apache.atlas.authorize.AtlasPrivilege;
import org.apache.atlas.authorize.AtlasRelationshipAccessRequest;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.TypeCategory;
import org.apache.atlas.model.instance.AtlasClassification;
import org.apache.atlas.model.instance.AtlasEntity.Status;
import org.apache.atlas.model.instance.AtlasEntityHeader;
import org.apache.atlas.model.instance.AtlasObjectId;
import org.apache.atlas.model.instance.AtlasRelationship;
import org.apache.atlas.model.instance.AtlasRelationship.AtlasRelationshipWithExtInfo;
......@@ -183,7 +187,6 @@ public class AtlasRelationshipStoreV2 implements AtlasRelationshipStore {
}
}
validateRelationship(end1Vertex, end2Vertex, edgeType, relationship.getAttributes());
AtlasRelationship ret = updateRelationship(edge, relationship);
......@@ -251,6 +254,7 @@ public class AtlasRelationshipStoreV2 implements AtlasRelationshipStore {
AtlasEdge edge = graphHelper.getEdgeForGUID(guid);
if (edge == null) {
throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIP_GUID_NOT_FOUND, guid);
}
......@@ -259,6 +263,13 @@ public class AtlasRelationshipStoreV2 implements AtlasRelationshipStore {
throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIP_ALREADY_DELETED, guid);
}
String relationShipType = GraphHelper.getTypeName(edge);
AtlasEntityHeader end1Entity = entityRetriever.toAtlasEntityHeaderWithClassifications(edge.getOutVertex());
AtlasEntityHeader end2Entity = entityRetriever.toAtlasEntityHeaderWithClassifications(edge.getInVertex());
AtlasAuthorizationUtils.verifyAccess(new AtlasRelationshipAccessRequest(typeRegistry,AtlasPrivilege.RELATIONSHIP_REMOVE, relationShipType, end1Entity, end2Entity ));
deleteHandler.deleteRelationships(Collections.singleton(edge), forceDelete);
// notify entities for added/removed classification propagation
......@@ -320,7 +331,13 @@ public class AtlasRelationshipStoreV2 implements AtlasRelationshipStore {
try {
ret = getRelationshipEdge(end1Vertex, end2Vertex, relationship.getTypeName());
if (ret == null) {
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);
AtlasRelationshipType relationType = typeRegistry.getRelationshipTypeByName(relationship.getTypeName());
......@@ -347,6 +364,12 @@ public class AtlasRelationshipStoreV2 implements AtlasRelationshipStore {
private AtlasRelationship updateRelationship(AtlasEdge relationshipEdge, AtlasRelationship relationship) throws AtlasBaseException {
AtlasRelationshipType relationType = typeRegistry.getRelationshipTypeByName(relationship.getTypeName());
AtlasVertex end1Vertex = relationshipEdge.getOutVertex();
AtlasVertex end2Vertex = relationshipEdge.getInVertex();
AtlasEntityHeader end1Entity = entityRetriever.toAtlasEntityHeaderWithClassifications(end1Vertex);
AtlasEntityHeader end2Entity = entityRetriever.toAtlasEntityHeaderWithClassifications(end2Vertex);
AtlasAuthorizationUtils.verifyAccess(new AtlasRelationshipAccessRequest(typeRegistry, AtlasPrivilege.RELATIONSHIP_UPDATE, relationship.getTypeName(), end1Entity, end2Entity));
updateTagPropagations(relationshipEdge, relationship);
......
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