Commit 8fe3edd2 by Madhan Neethiraj

ATLAS-3622: added authorization for add/remove of labels, update of namespace attributes

parent 9b89a3fd
...@@ -28,45 +28,53 @@ public class AtlasEntityAccessRequest extends AtlasAccessRequest { ...@@ -28,45 +28,53 @@ public class AtlasEntityAccessRequest extends AtlasAccessRequest {
private final AtlasEntityHeader entity; private final AtlasEntityHeader entity;
private final String entityId; private final String entityId;
private final AtlasClassification classification; private final AtlasClassification classification;
private final String label;
private final String namespaceName;
private final String attributeName; private final String attributeName;
private final AtlasTypeRegistry typeRegistry; private final AtlasTypeRegistry typeRegistry;
private final Set<String> entityClassifications; private final Set<String> entityClassifications;
public AtlasEntityAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action) { public AtlasEntityAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action) {
this(typeRegistry, action, null, null, null, null, null); this(typeRegistry, action, null, null, null, null, null, null, null);
} }
public AtlasEntityAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, AtlasEntityHeader entity) { public AtlasEntityAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, AtlasEntityHeader entity) {
this(typeRegistry, action, entity, null, null, null, null); this(typeRegistry, action, entity, null, null, null, null, null, null);
} }
public AtlasEntityAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, AtlasEntityHeader entity, AtlasClassification classification) { public AtlasEntityAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, AtlasEntityHeader entity, AtlasClassification classification) {
this(typeRegistry, action, entity, classification, null, null, null); this(typeRegistry, action, entity, classification, null, null, null, null, null);
} }
public AtlasEntityAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, AtlasEntityHeader entity, String attributeName) { public AtlasEntityAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, AtlasEntityHeader entity, String attributeName) {
this(typeRegistry, action, entity, null, attributeName, null, null); this(typeRegistry, action, entity, null, attributeName, null, null, null, null);
} }
public AtlasEntityAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, AtlasEntityHeader entity, String userName, Set<String> userGroups) { public AtlasEntityAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, AtlasEntityHeader entity, String userName, Set<String> userGroups) {
this(typeRegistry, action, entity, null, null, userName, userGroups); this(typeRegistry, action, entity, null, null, null, null, userName, userGroups);
} }
public AtlasEntityAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, AtlasEntityHeader entity, AtlasClassification classification, String userName, Set<String> userGroups) { public AtlasEntityAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, AtlasEntityHeader entity, AtlasClassification classification, String userName, Set<String> userGroups) {
this(typeRegistry, action, entity, classification, null, userName, userGroups); this(typeRegistry, action, entity, classification, null, null, null, userName, userGroups);
} }
public AtlasEntityAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, AtlasEntityHeader entity, String attributeName, String userName, Set<String> userGroups) { public AtlasEntityAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, AtlasEntityHeader entity, String attributeName, String userName, Set<String> userGroups) {
this(typeRegistry, action, entity, null, attributeName, userName, userGroups); this(typeRegistry, action, entity, null, attributeName, null, null, userName, userGroups);
} }
public AtlasEntityAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, AtlasEntityHeader entity, AtlasClassification classification, String attributeName, String userName, Set<String> userGroups) { public AtlasEntityAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, AtlasEntityHeader entity, AtlasClassification classification, String attributeName, String userName, Set<String> userGroups) {
this(typeRegistry, action, entity, classification, attributeName, null, null, userName, userGroups);
}
public AtlasEntityAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, AtlasEntityHeader entity, AtlasClassification classification, String attributeName, String label, String namespaceName, String userName, Set<String> userGroups) {
super(action, userName, userGroups); super(action, userName, userGroups);
this.entity = entity; this.entity = entity;
this.entityId = super.getEntityId(entity, typeRegistry); this.entityId = super.getEntityId(entity, typeRegistry);
this.classification = classification; this.classification = classification;
this.label = label;
this.namespaceName = namespaceName;
this.attributeName = attributeName; this.attributeName = attributeName;
this.typeRegistry = typeRegistry; this.typeRegistry = typeRegistry;
this.entityClassifications = super.getClassificationNames(entity); this.entityClassifications = super.getClassificationNames(entity);
...@@ -84,6 +92,14 @@ public class AtlasEntityAccessRequest extends AtlasAccessRequest { ...@@ -84,6 +92,14 @@ public class AtlasEntityAccessRequest extends AtlasAccessRequest {
return classification; return classification;
} }
public String getLabel() {
return label;
}
public String getNamespaceName() {
return namespaceName;
}
public String getAttributeName() { public String getAttributeName() {
return attributeName; return attributeName;
} }
...@@ -106,11 +122,80 @@ public class AtlasEntityAccessRequest extends AtlasAccessRequest { ...@@ -106,11 +122,80 @@ public class AtlasEntityAccessRequest extends AtlasAccessRequest {
@Override @Override
public String toString() { public String toString() {
return "AtlasEntityAccessRequest[entity=" + entity + ", classification=" + classification + ", attributeName=" + attributeName + return "AtlasEntityAccessRequest[entity=" + entity + ", classification=" + classification + ", label=" + label + ", namespaceName=" + namespaceName + ", attributeName=" + attributeName +
", action=" + getAction() + ", accessTime=" + getAccessTime() + ", user=" + getUser() + ", action=" + getAction() + ", accessTime=" + getAccessTime() + ", user=" + getUser() +
", userGroups=" + getUserGroups() + ", clientIPAddress=" + getClientIPAddress() + ", userGroups=" + getUserGroups() + ", clientIPAddress=" + getClientIPAddress() +
", forwardedAddresses=" + getForwardedAddresses() + ", remoteIPAddress=" + getRemoteIPAddress() + "]"; ", forwardedAddresses=" + getForwardedAddresses() + ", remoteIPAddress=" + getRemoteIPAddress() + "]";
} }
public static class AtlasEntityAccessRequestBuilder {
private final AtlasTypeRegistry typeRegistry;
private final AtlasPrivilege action;
private String userName;
private Set<String> userGroups;
private AtlasEntityHeader entity;
private AtlasClassification classification;
private String label;
private String namespaceName;
private String attributeName;
public AtlasEntityAccessRequestBuilder(AtlasTypeRegistry typeRegistry, AtlasPrivilege action) {
this.typeRegistry = typeRegistry;
this.action = action;
}
public AtlasEntityAccessRequestBuilder(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, AtlasEntityHeader entity) {
this.typeRegistry = typeRegistry;
this.action = action;
this.entity = entity;
}
public AtlasEntityAccessRequestBuilder setUserName(String userName) {
this.userName = userName;
return this;
}
public AtlasEntityAccessRequestBuilder setUserGroups(Set<String> userGroups) {
this.userGroups = userGroups;
return this;
}
public AtlasEntityAccessRequestBuilder setEntity(AtlasEntityHeader entity) {
this.entity = entity;
return this;
}
public AtlasEntityAccessRequestBuilder setClassification(AtlasClassification classification) {
this.classification = classification;
return this;
}
public AtlasEntityAccessRequestBuilder setLabel(String label) {
this.label = label;
return this;
}
public AtlasEntityAccessRequestBuilder setNamespaceName(String namespaceName) {
this.namespaceName = namespaceName;
return this;
}
public AtlasEntityAccessRequestBuilder setAttributeName(String attributeName) {
this.attributeName = attributeName;
return this;
}
public AtlasEntityAccessRequest build() {
return new AtlasEntityAccessRequest(typeRegistry, action, entity, classification, attributeName, label, namespaceName, userName, userGroups);
}
}
} }
...@@ -37,7 +37,12 @@ public enum AtlasPrivilege { ...@@ -37,7 +37,12 @@ public enum AtlasPrivilege {
RELATIONSHIP_ADD("add-relationship"), RELATIONSHIP_ADD("add-relationship"),
RELATIONSHIP_UPDATE("update-relationship"), RELATIONSHIP_UPDATE("update-relationship"),
RELATIONSHIP_REMOVE("remove-relationship"), RELATIONSHIP_REMOVE("remove-relationship"),
ADMIN_PURGE("admin-purge");
ADMIN_PURGE("admin-purge"),
ENTITY_ADD_LABEL("entity-add-label"),
ENTITY_REMOVE_LABEL("entity-remove-label"),
ENTITY_UPDATE_NAMESPACE("entity-update-namespace");
private final String type; private final String type;
......
...@@ -238,8 +238,9 @@ public final class AtlasSimpleAuthorizer implements AtlasAuthorizer { ...@@ -238,8 +238,9 @@ public final class AtlasSimpleAuthorizer implements AtlasAuthorizer {
if (permissions != null) { if (permissions != null) {
for (AtlasEntityPermission permission : permissions) { for (AtlasEntityPermission permission : permissions) {
// match entity-type/entity-id/attribute // match entity-type/entity-id/lable/namespace/attribute
if (isMatchAny(entityTypes, permission.getEntityTypes()) && isMatch(entityId, permission.getEntityIds()) && isMatch(attribute, permission.getAttributes())) { if (isMatchAny(entityTypes, permission.getEntityTypes()) && isMatch(entityId, permission.getEntityIds()) && isMatch(attribute, permission.getAttributes())
&& isLabelMatch(request, permission) && isNamespaceMatch(request, permission)) {
// match permission/classification // match permission/classification
if (!hasEntityAccess) { if (!hasEntityAccess) {
if (isMatch(action, permission.getPrivileges()) && isMatch(classification, permission.getClassifications())) { if (isMatch(action, permission.getPrivileges()) && isMatch(classification, permission.getClassifications())) {
...@@ -458,6 +459,14 @@ public final class AtlasSimpleAuthorizer implements AtlasAuthorizer { ...@@ -458,6 +459,14 @@ public final class AtlasSimpleAuthorizer implements AtlasAuthorizer {
} }
} }
} }
private boolean isLabelMatch(AtlasEntityAccessRequest request, AtlasEntityPermission permission) {
return (AtlasPrivilege.ENTITY_ADD_LABEL.equals(request.getAction()) || AtlasPrivilege.ENTITY_REMOVE_LABEL.equals(request.getAction())) ? isMatch(request.getLabel(), permission.getLabels()) : true;
}
private boolean isNamespaceMatch(AtlasEntityAccessRequest request, AtlasEntityPermission permission) {
return AtlasPrivilege.ENTITY_UPDATE_NAMESPACE.equals(request.getAction()) ? isMatch(request.getNamespaceName(), permission.getNamespaces()) : true;
}
} }
...@@ -209,16 +209,24 @@ public class AtlasSimpleAuthzPolicy implements Serializable { ...@@ -209,16 +209,24 @@ public class AtlasSimpleAuthzPolicy implements Serializable {
private List<String> entityTypes; // name of entity-type, wildcards supported private List<String> entityTypes; // name of entity-type, wildcards supported
private List<String> entityIds; // value of entity-unique attribute, wildcards supported private List<String> entityIds; // value of entity-unique attribute, wildcards supported
private List<String> classifications; // name of classification-type, wildcards supported private List<String> classifications; // name of classification-type, wildcards supported
private List<String> labels; // labels, wildcards supported
private List<String> namespaces; // name of namespace-type, wildcards supported
private List<String> attributes; // name of entity-attribute, wildcards supported private List<String> attributes; // name of entity-attribute, wildcards supported
public AtlasEntityPermission() { public AtlasEntityPermission() {
} }
public AtlasEntityPermission(List<String> privileges, List<String> entityTypes, List<String> entityIds, List<String> classifications, List<String> attributes) { public AtlasEntityPermission(List<String> privileges, List<String> entityTypes, List<String> entityIds, List<String> classifications, List<String> attributes) {
this(privileges, entityTypes, entityIds, classifications, attributes, null, null);
}
public AtlasEntityPermission(List<String> privileges, List<String> entityTypes, List<String> entityIds, List<String> classifications, List<String> labels, List<String> namespaces, List<String> attributes) {
this.privileges = privileges; this.privileges = privileges;
this.entityTypes = entityTypes; this.entityTypes = entityTypes;
this.entityIds = entityIds; this.entityIds = entityIds;
this.classifications = classifications; this.classifications = classifications;
this.labels = labels;
this.namespaces = namespaces;
this.attributes = attributes; this.attributes = attributes;
} }
...@@ -254,6 +262,22 @@ public class AtlasSimpleAuthzPolicy implements Serializable { ...@@ -254,6 +262,22 @@ public class AtlasSimpleAuthzPolicy implements Serializable {
this.classifications = classifications; this.classifications = classifications;
} }
public List<String> getLabels() {
return labels;
}
public void setLabels(List<String> labels) {
this.namespaces = labels;
}
public List<String> getNamespaces() {
return namespaces;
}
public void setNamespaces(List<String> namespaces) {
this.namespaces = namespaces;
}
public List<String> getAttributes() { public List<String> getAttributes() {
return attributes; return attributes;
} }
......
...@@ -18,7 +18,9 @@ ...@@ -18,7 +18,9 @@
"privileges": [ ".*" ], "privileges": [ ".*" ],
"entityTypes": [ ".*" ], "entityTypes": [ ".*" ],
"entityIds": [ ".*" ], "entityIds": [ ".*" ],
"classifications": [ ".*" ] "classifications": [ ".*" ],
"labels": [ ".*" ],
"namespaces": [ ".*" ]
} }
], ],
"relationshipPermissions": [ "relationshipPermissions": [
...@@ -41,7 +43,9 @@ ...@@ -41,7 +43,9 @@
"privileges": [ "entity-read", "entity-read-classification" ], "privileges": [ "entity-read", "entity-read-classification" ],
"entityTypes": [ ".*" ], "entityTypes": [ ".*" ],
"entityIds": [ ".*" ], "entityIds": [ ".*" ],
"classifications": [ ".*" ] "classifications": [ ".*" ],
"labels": [ ".*" ],
"namespaces": [ ".*" ]
} }
] ]
}, },
...@@ -49,10 +53,12 @@ ...@@ -49,10 +53,12 @@
"DATA_STEWARD": { "DATA_STEWARD": {
"entityPermissions": [ "entityPermissions": [
{ {
"privileges": [ "entity-read", "entity-create", "entity-update", "entity-read-classification", "entity-add-classification", "entity-update-classification", "entity-remove-classification" ], "privileges": [ "entity-read", "entity-create", "entity-update", "entity-read-classification", "entity-add-classification", "entity-update-classification", "entity-remove-classification", "entity-add-label", "entity-remove-label", "entity-update-namespace" ],
"entityTypes": [ ".*" ], "entityTypes": [ ".*" ],
"entityIds": [ ".*" ], "entityIds": [ ".*" ],
"classifications": [ ".*" ] "classifications": [ ".*" ],
"labels": [ ".*" ],
"namespaces": [ ".*" ]
} }
], ],
"relationshipPermissions": [ "relationshipPermissions": [
......
...@@ -29,6 +29,10 @@ import java.util.Collections; ...@@ -29,6 +29,10 @@ import java.util.Collections;
public class AtlasSimpleAuthorizerTest { public class AtlasSimpleAuthorizerTest {
private static Logger LOG = LoggerFactory.getLogger(AtlasSimpleAuthorizerTest.class); private static Logger LOG = LoggerFactory.getLogger(AtlasSimpleAuthorizerTest.class);
private static final String USER_DATA_SCIENTIST = "dataScientist1";
private static final String USER_DATA_STEWARD = "dataSteward1";
private String originalConf; private String originalConf;
private AtlasAuthorizer authorizer; private AtlasAuthorizer authorizer;
...@@ -104,4 +108,67 @@ public class AtlasSimpleAuthorizerTest { ...@@ -104,4 +108,67 @@ public class AtlasSimpleAuthorizerTest {
AssertJUnit.fail(); AssertJUnit.fail();
} }
} }
@Test(enabled = true)
public void testLabels() {
try {
AtlasEntityAccessRequest request = new AtlasEntityAccessRequest(null, AtlasPrivilege.ENTITY_ADD_LABEL);
request.setUser(USER_DATA_SCIENTIST, Collections.emptySet());
boolean isAccessAllowed = authorizer.isAccessAllowed(request);
AssertJUnit.assertEquals("user " + USER_DATA_SCIENTIST + " shouldn't be allowed to add label", false, isAccessAllowed);
request.setUser(USER_DATA_STEWARD, Collections.emptySet());
isAccessAllowed = authorizer.isAccessAllowed(request);
AssertJUnit.assertEquals("user " + USER_DATA_STEWARD + " should be allowed to add label", true, isAccessAllowed);
request = new AtlasEntityAccessRequest(null, AtlasPrivilege.ENTITY_REMOVE_LABEL);
request.setUser(USER_DATA_SCIENTIST, Collections.emptySet());
isAccessAllowed = authorizer.isAccessAllowed(request);
AssertJUnit.assertEquals("user " + USER_DATA_SCIENTIST + " shouldn't be allowed to remove label", false, isAccessAllowed);
request.setUser(USER_DATA_STEWARD, Collections.emptySet());
isAccessAllowed = authorizer.isAccessAllowed(request);
AssertJUnit.assertEquals("user " + USER_DATA_STEWARD + " should be allowed to remove label", true, isAccessAllowed);
} catch (AtlasAuthorizationException e) {
LOG.error("Exception in AtlasSimpleAuthorizerTest", e);
AssertJUnit.fail();
}
}
@Test(enabled = true)
public void testNamespaces() {
try {
AtlasEntityAccessRequest request = new AtlasEntityAccessRequest(null, AtlasPrivilege.ENTITY_UPDATE_NAMESPACE);
request.setUser(USER_DATA_SCIENTIST, Collections.emptySet());
boolean isAccessAllowed = authorizer.isAccessAllowed(request);
AssertJUnit.assertEquals("user " + USER_DATA_SCIENTIST + " shouldn't be allowed to update namespace", false, isAccessAllowed);
request.setUser(USER_DATA_STEWARD, Collections.emptySet());
isAccessAllowed = authorizer.isAccessAllowed(request);
AssertJUnit.assertEquals("user " + USER_DATA_STEWARD + " should be allowed to update namespace", true, isAccessAllowed);
} catch (AtlasAuthorizationException e) {
LOG.error("Exception in AtlasSimpleAuthorizerTest", e);
AssertJUnit.fail();
}
}
} }
...@@ -43,7 +43,9 @@ ...@@ -43,7 +43,9 @@
"privileges": [ "entity-read", "entity-read-classification" ], "privileges": [ "entity-read", "entity-read-classification" ],
"entityTypes": [ ".*" ], "entityTypes": [ ".*" ],
"entityIds": [ ".*" ], "entityIds": [ ".*" ],
"classifications": [ ".*" ] "classifications": [ ".*" ],
"labels": [ ".*" ],
"namespaces": [ ".*" ]
} }
] ]
}, },
...@@ -51,10 +53,12 @@ ...@@ -51,10 +53,12 @@
"DATA_STEWARD": { "DATA_STEWARD": {
"entityPermissions": [ "entityPermissions": [
{ {
"privileges": [ "entity-read", "entity-create", "entity-update", "entity-read-classification", "entity-add-classification", "entity-update-classification", "entity-remove-classification" ], "privileges": [ "entity-read", "entity-create", "entity-update", "entity-read-classification", "entity-add-classification", "entity-update-classification", "entity-remove-classification", "entity-add-label", "entity-remove-label", "entity-update-namespace" ],
"entityTypes": [ ".*" ], "entityTypes": [ ".*" ],
"entityIds": [ ".*" ], "entityIds": [ ".*" ],
"classifications": [ ".*" ] "classifications": [ ".*" ],
"labels": [ ".*" ],
"namespaces": [ ".*" ]
} }
] ]
} }
...@@ -62,7 +66,9 @@ ...@@ -62,7 +66,9 @@
"userRoles": { "userRoles": {
"admin": [ "ROLE_ADMIN" ], "admin": [ "ROLE_ADMIN" ],
"rangertagsync": [ "DATA_SCIENTIST" ] "rangertagsync": [ "DATA_SCIENTIST" ],
"dataScientist1": [ "DATA_SCIENTIST"],
"dataSteward1": [ "DATA_STEWARD"]
}, },
"groupRoles": { "groupRoles": {
......
...@@ -25,6 +25,7 @@ import org.apache.atlas.annotation.GraphTransaction; ...@@ -25,6 +25,7 @@ import org.apache.atlas.annotation.GraphTransaction;
import org.apache.atlas.authorize.AtlasAdminAccessRequest; import org.apache.atlas.authorize.AtlasAdminAccessRequest;
import org.apache.atlas.authorize.AtlasAuthorizationUtils; import org.apache.atlas.authorize.AtlasAuthorizationUtils;
import org.apache.atlas.authorize.AtlasEntityAccessRequest; import org.apache.atlas.authorize.AtlasEntityAccessRequest;
import org.apache.atlas.authorize.AtlasEntityAccessRequest.AtlasEntityAccessRequestBuilder;
import org.apache.atlas.authorize.AtlasPrivilege; import org.apache.atlas.authorize.AtlasPrivilege;
import org.apache.atlas.exception.AtlasBaseException; import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.TypeCategory; import org.apache.atlas.model.TypeCategory;
...@@ -66,6 +67,7 @@ import javax.inject.Inject; ...@@ -66,6 +67,7 @@ import javax.inject.Inject;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
...@@ -834,14 +836,44 @@ public class AtlasEntityStoreV2 implements AtlasEntityStore { ...@@ -834,14 +836,44 @@ public class AtlasEntityStoreV2 implements AtlasEntityStore {
throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "guid is null/empty"); throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "guid is null/empty");
} }
if (MapUtils.isEmpty(entityNamespaces)) {
throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "entityNamespaces is null/empty");
}
AtlasVertex entityVertex = AtlasGraphUtilsV2.findByGuid(guid); AtlasVertex entityVertex = AtlasGraphUtilsV2.findByGuid(guid);
if (entityVertex == null) { if (entityVertex == null) {
throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guid); throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guid);
} }
String typeName = getTypeName(entityVertex); String typeName = getTypeName(entityVertex);
AtlasEntityType entityType = typeRegistry.getEntityTypeByName(typeName); AtlasEntityType entityType = typeRegistry.getEntityTypeByName(typeName);
AtlasEntityHeader entityHeader = entityRetriever.toAtlasEntityHeaderWithClassifications(entityVertex);
Map<String, Map<String, Object>> currNamespaces = entityRetriever.getEntityNamespaces(entityVertex);
Set<String> updatedNsNames = new HashSet<>();
for (String nsName : entityType.getNamespaceAttributes().keySet()) {
Map<String, Object> nsAttrs = entityNamespaces.get(nsName);
Map<String, Object> currNsAttrs = currNamespaces != null ? currNamespaces.get(nsName) : null;
if (nsAttrs == null && !isOverwrite) {
continue;
} else if (MapUtils.isEmpty(nsAttrs) && MapUtils.isEmpty(currNsAttrs)) { // no change
continue;
} else if (Objects.equals(nsAttrs, currNsAttrs)) { // no change
continue;
}
updatedNsNames.add(nsName);
}
AtlasEntityAccessRequestBuilder requestBuilder = new AtlasEntityAccessRequestBuilder(typeRegistry, AtlasPrivilege.ENTITY_UPDATE_NAMESPACE, entityHeader);
for (String nsName : updatedNsNames) {
requestBuilder.setNamespaceName(nsName);
AtlasAuthorizationUtils.verifyAccess(requestBuilder.build(), "add/update namespace: guid=", guid, ", namespace=", nsName);
}
validateNamespaceAttributes(entityVertex, entityType, entityNamespaces, isOverwrite); validateNamespaceAttributes(entityVertex, entityType, entityNamespaces, isOverwrite);
...@@ -867,14 +899,27 @@ public class AtlasEntityStoreV2 implements AtlasEntityStore { ...@@ -867,14 +899,27 @@ public class AtlasEntityStoreV2 implements AtlasEntityStore {
throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "guid is null/empty"); throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "guid is null/empty");
} }
if (MapUtils.isEmpty(entityNamespaces)) {
throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "entityNamespaces is null/empty");
}
AtlasVertex entityVertex = AtlasGraphUtilsV2.findByGuid(guid); AtlasVertex entityVertex = AtlasGraphUtilsV2.findByGuid(guid);
if (entityVertex == null) { if (entityVertex == null) {
throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guid); throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guid);
} }
String typeName = getTypeName(entityVertex); String typeName = getTypeName(entityVertex);
AtlasEntityType entityType = typeRegistry.getEntityTypeByName(typeName); AtlasEntityType entityType = typeRegistry.getEntityTypeByName(typeName);
AtlasEntityHeader entityHeader = entityRetriever.toAtlasEntityHeaderWithClassifications(entityVertex);
AtlasEntityAccessRequestBuilder requestBuilder = new AtlasEntityAccessRequestBuilder(typeRegistry, AtlasPrivilege.ENTITY_UPDATE_NAMESPACE, entityHeader);
for (String nsName : entityNamespaces.keySet()) {
requestBuilder.setNamespaceName(nsName);
AtlasAuthorizationUtils.verifyAccess(requestBuilder.build(), "remove namespace: guid=", guid, ", namespace=", nsName);
}
entityGraphMapper.removeNamespaceAttributes(entityVertex, entityType, entityNamespaces); entityGraphMapper.removeNamespaceAttributes(entityVertex, entityType, entityNamespaces);
...@@ -902,6 +947,39 @@ public class AtlasEntityStoreV2 implements AtlasEntityStore { ...@@ -902,6 +947,39 @@ public class AtlasEntityStoreV2 implements AtlasEntityStore {
validateLabels(labels); validateLabels(labels);
AtlasEntityHeader entityHeader = entityRetriever.toAtlasEntityHeaderWithClassifications(entityVertex);
Set<String> addedLabels = Collections.emptySet();
Set<String> removedLabels = Collections.emptySet();
if (CollectionUtils.isEmpty(entityHeader.getLabels())) {
addedLabels = labels;
} else if (CollectionUtils.isEmpty(labels)) {
removedLabels = entityHeader.getLabels();
} else {
addedLabels = new HashSet<String>(CollectionUtils.subtract(labels, entityHeader.getLabels()));
removedLabels = new HashSet<String>(CollectionUtils.subtract(entityHeader.getLabels(), labels));
}
if (addedLabels != null) {
AtlasEntityAccessRequestBuilder requestBuilder = new AtlasEntityAccessRequestBuilder(typeRegistry, AtlasPrivilege.ENTITY_ADD_LABEL, entityHeader);
for (String label : addedLabels) {
requestBuilder.setLabel(label);
AtlasAuthorizationUtils.verifyAccess(requestBuilder.build(), "add label: guid=", guid, ", label=", label);
}
}
if (removedLabels != null) {
AtlasEntityAccessRequestBuilder requestBuilder = new AtlasEntityAccessRequestBuilder(typeRegistry, AtlasPrivilege.ENTITY_REMOVE_LABEL, entityHeader);
for (String label : removedLabels) {
requestBuilder.setLabel(label);
AtlasAuthorizationUtils.verifyAccess(requestBuilder.build(), "remove label: guid=", guid, ", label=", label);
}
}
entityGraphMapper.setLabels(entityVertex, labels); entityGraphMapper.setLabels(entityVertex, labels);
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
...@@ -920,12 +998,25 @@ public class AtlasEntityStoreV2 implements AtlasEntityStore { ...@@ -920,12 +998,25 @@ public class AtlasEntityStoreV2 implements AtlasEntityStore {
throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "guid is null/empty"); throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "guid is null/empty");
} }
if (CollectionUtils.isEmpty(labels)) {
throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "labels is null/empty");
}
AtlasVertex entityVertex = AtlasGraphUtilsV2.findByGuid(guid); AtlasVertex entityVertex = AtlasGraphUtilsV2.findByGuid(guid);
if (entityVertex == null) { if (entityVertex == null) {
throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guid); throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guid);
} }
AtlasEntityHeader entityHeader = entityRetriever.toAtlasEntityHeaderWithClassifications(entityVertex);
AtlasEntityAccessRequestBuilder requestBuilder = new AtlasEntityAccessRequestBuilder(typeRegistry, AtlasPrivilege.ENTITY_REMOVE_LABEL, entityHeader);
for (String label : labels) {
requestBuilder.setLabel(label);
AtlasAuthorizationUtils.verifyAccess(requestBuilder.build(), "remove label: guid=", guid, ", label=", label);
}
validateLabels(labels); validateLabels(labels);
entityGraphMapper.removeLabels(entityVertex, labels); entityGraphMapper.removeLabels(entityVertex, labels);
...@@ -946,12 +1037,25 @@ public class AtlasEntityStoreV2 implements AtlasEntityStore { ...@@ -946,12 +1037,25 @@ public class AtlasEntityStoreV2 implements AtlasEntityStore {
throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "guid is null/empty"); throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "guid is null/empty");
} }
if (CollectionUtils.isEmpty(labels)) {
throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "labels is null/empty");
}
AtlasVertex entityVertex = AtlasGraphUtilsV2.findByGuid(guid); AtlasVertex entityVertex = AtlasGraphUtilsV2.findByGuid(guid);
if (entityVertex == null) { if (entityVertex == null) {
throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guid); throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guid);
} }
AtlasEntityHeader entityHeader = entityRetriever.toAtlasEntityHeaderWithClassifications(entityVertex);
AtlasEntityAccessRequestBuilder requestBuilder = new AtlasEntityAccessRequestBuilder(typeRegistry, AtlasPrivilege.ENTITY_ADD_LABEL, entityHeader);
for (String label : labels) {
requestBuilder.setLabel(label);
AtlasAuthorizationUtils.verifyAccess(requestBuilder.build(), "add/update label: guid=", guid, ", label=", label);
}
validateLabels(labels); validateLabels(labels);
entityGraphMapper.addLabels(entityVertex, labels); entityGraphMapper.addLabels(entityVertex, labels);
......
...@@ -353,7 +353,7 @@ public class EntityGraphMapper { ...@@ -353,7 +353,7 @@ public class EntityGraphMapper {
removedLabels = null; removedLabels = null;
} else if (CollectionUtils.isEmpty(labels)) { } else if (CollectionUtils.isEmpty(labels)) {
addedLabels = null; addedLabels = null;
removedLabels = labels; removedLabels = currentLabels;
} else { } else {
addedLabels = new HashSet<String>(CollectionUtils.subtract(labels, currentLabels)); addedLabels = new HashSet<String>(CollectionUtils.subtract(labels, currentLabels));
removedLabels = new HashSet<String>(CollectionUtils.subtract(currentLabels, labels)); removedLabels = new HashSet<String>(CollectionUtils.subtract(currentLabels, labels));
......
...@@ -221,6 +221,41 @@ public class EntityGraphRetriever { ...@@ -221,6 +221,41 @@ public class EntityGraphRetriever {
return ret; return ret;
} }
public Map<String, Map<String, Object>> getEntityNamespaces(AtlasVertex entityVertex) throws AtlasBaseException {
Map<String, Map<String, Object>> ret = null;
String entityTypeName = getTypeName(entityVertex);
AtlasEntityType entityType = typeRegistry.getEntityTypeByName(entityTypeName);
Map<String, Map<String, AtlasNamespaceAttribute>> entityTypeNamespaces = entityType != null ? entityType.getNamespaceAttributes() : null;
if (MapUtils.isNotEmpty(entityTypeNamespaces)) {
for (Map.Entry<String, Map<String, AtlasNamespaceAttribute>> entry : entityTypeNamespaces.entrySet()) {
String nsName = entry.getKey();
Map<String, AtlasNamespaceAttribute> nsAttributes = entry.getValue();
Map<String, Object> entityNsAttrs = null;
for (AtlasNamespaceAttribute nsAttribute : nsAttributes.values()) {
Object nsAttrValue = mapVertexToAttribute(entityVertex, nsAttribute, null, false, false);
if (nsAttrValue != null) {
if (ret == null) {
ret = new HashMap<>();
}
if (entityNsAttrs == null) {
entityNsAttrs = new HashMap<>();
ret.put(nsName, entityNsAttrs);
}
entityNsAttrs.put(nsAttribute.getName(), nsAttrValue);
}
}
}
}
return ret;
}
public Object getEntityAttribute(AtlasVertex entityVertex, AtlasAttribute attribute) { public Object getEntityAttribute(AtlasVertex entityVertex, AtlasAttribute attribute) {
Object ret = null; Object ret = null;
...@@ -770,23 +805,7 @@ public class EntityGraphRetriever { ...@@ -770,23 +805,7 @@ public class EntityGraphRetriever {
} }
private void mapNamespaceAttributes(AtlasVertex entityVertex, AtlasEntity entity) throws AtlasBaseException { private void mapNamespaceAttributes(AtlasVertex entityVertex, AtlasEntity entity) throws AtlasBaseException {
AtlasEntityType entityType = typeRegistry.getEntityTypeByName(entity.getTypeName()); entity.setNamespaceAttributes(getEntityNamespaces(entityVertex));
Map<String, Map<String, AtlasNamespaceAttribute>> entityTypeNamespaces = entityType != null ? entityType.getNamespaceAttributes() : null;
if (MapUtils.isNotEmpty(entityTypeNamespaces)) {
for (Map.Entry<String, Map<String, AtlasNamespaceAttribute>> entry : entityTypeNamespaces.entrySet()) {
String nsName = entry.getKey();
Map<String, AtlasNamespaceAttribute> nsAttributes = entry.getValue();
for (AtlasNamespaceAttribute nsAttribute : nsAttributes.values()) {
Object nsAttrValue = mapVertexToAttribute(entityVertex, nsAttribute, null, false, false);
if (nsAttrValue != null) {
entity.setNamespaceAttribute(nsName, nsAttribute.getName(), nsAttrValue);
}
}
}
}
} }
public List<AtlasClassification> getAllClassifications(AtlasVertex entityVertex) throws AtlasBaseException { public List<AtlasClassification> getAllClassifications(AtlasVertex entityVertex) throws AtlasBaseException {
......
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