This is an automated email from the ASF dual-hosted git repository.
madhan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/atlas.git
The following commit(s) were added to refs/heads/master by this push:
new 8fe3edd ATLAS-3622: added authorization for add/remove of labels,
update of namespace attributes
8fe3edd is described below
commit 8fe3edd2a7d480408ec3d43762cfb43887d5fa19
Author: Madhan Neethiraj <[email protected]>
AuthorDate: Sun Feb 16 17:15:34 2020 -0800
ATLAS-3622: added authorization for add/remove of labels, update of
namespace attributes
---
.../atlas/authorize/AtlasEntityAccessRequest.java | 101 +++++++++++++++++--
.../org/apache/atlas/authorize/AtlasPrivilege.java | 7 +-
.../authorize/simple/AtlasSimpleAuthorizer.java | 13 ++-
.../authorize/simple/AtlasSimpleAuthzPolicy.java | 24 +++++
.../main/resources/atlas-simple-authz-policy.json | 14 ++-
.../simple/AtlasSimpleAuthorizerTest.java | 67 ++++++++++++
.../test/resources/atlas-simple-authz-policy.json | 14 ++-
.../store/graph/v2/AtlasEntityStoreV2.java | 112 ++++++++++++++++++++-
.../store/graph/v2/EntityGraphMapper.java | 2 +-
.../store/graph/v2/EntityGraphRetriever.java | 53 ++++++----
10 files changed, 366 insertions(+), 41 deletions(-)
diff --git
a/authorization/src/main/java/org/apache/atlas/authorize/AtlasEntityAccessRequest.java
b/authorization/src/main/java/org/apache/atlas/authorize/AtlasEntityAccessRequest.java
index 951e5c9..f2e4838 100644
---
a/authorization/src/main/java/org/apache/atlas/authorize/AtlasEntityAccessRequest.java
+++
b/authorization/src/main/java/org/apache/atlas/authorize/AtlasEntityAccessRequest.java
@@ -28,45 +28,53 @@ public class AtlasEntityAccessRequest extends
AtlasAccessRequest {
private final AtlasEntityHeader entity;
private final String entityId;
private final AtlasClassification classification;
+ private final String label;
+ private final String namespaceName;
private final String attributeName;
private final AtlasTypeRegistry typeRegistry;
private final Set<String> entityClassifications;
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) {
- 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) {
- 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) {
- 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) {
- 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) {
- 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) {
- 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) {
+ 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);
this.entity = entity;
this.entityId = super.getEntityId(entity, typeRegistry);
this.classification = classification;
+ this.label = label;
+ this.namespaceName = namespaceName;
this.attributeName = attributeName;
this.typeRegistry = typeRegistry;
this.entityClassifications = super.getClassificationNames(entity);
@@ -84,6 +92,14 @@ public class AtlasEntityAccessRequest extends
AtlasAccessRequest {
return classification;
}
+ public String getLabel() {
+ return label;
+ }
+
+ public String getNamespaceName() {
+ return namespaceName;
+ }
+
public String getAttributeName() {
return attributeName;
}
@@ -106,11 +122,80 @@ public class AtlasEntityAccessRequest extends
AtlasAccessRequest {
@Override
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() +
", userGroups=" + getUserGroups() + ", clientIPAddress=" +
getClientIPAddress() +
", 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);
+ }
+ }
}
diff --git
a/authorization/src/main/java/org/apache/atlas/authorize/AtlasPrivilege.java
b/authorization/src/main/java/org/apache/atlas/authorize/AtlasPrivilege.java
index 38b68fa..7d81e22 100644
--- a/authorization/src/main/java/org/apache/atlas/authorize/AtlasPrivilege.java
+++ b/authorization/src/main/java/org/apache/atlas/authorize/AtlasPrivilege.java
@@ -37,7 +37,12 @@ public enum AtlasPrivilege {
RELATIONSHIP_ADD("add-relationship"),
RELATIONSHIP_UPDATE("update-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;
diff --git
a/authorization/src/main/java/org/apache/atlas/authorize/simple/AtlasSimpleAuthorizer.java
b/authorization/src/main/java/org/apache/atlas/authorize/simple/AtlasSimpleAuthorizer.java
index e210958..5f0c7b2 100644
---
a/authorization/src/main/java/org/apache/atlas/authorize/simple/AtlasSimpleAuthorizer.java
+++
b/authorization/src/main/java/org/apache/atlas/authorize/simple/AtlasSimpleAuthorizer.java
@@ -238,8 +238,9 @@ public final class AtlasSimpleAuthorizer implements
AtlasAuthorizer {
if (permissions != null) {
for (AtlasEntityPermission permission : permissions) {
- // match entity-type/entity-id/attribute
- if (isMatchAny(entityTypes, permission.getEntityTypes())
&& isMatch(entityId, permission.getEntityIds()) && isMatch(attribute,
permission.getAttributes())) {
+ // match entity-type/entity-id/lable/namespace/attribute
+ if (isMatchAny(entityTypes, permission.getEntityTypes())
&& isMatch(entityId, permission.getEntityIds()) && isMatch(attribute,
permission.getAttributes())
+ && isLabelMatch(request, permission) &&
isNamespaceMatch(request, permission)) {
// match permission/classification
if (!hasEntityAccess) {
if (isMatch(action, permission.getPrivileges()) &&
isMatch(classification, permission.getClassifications())) {
@@ -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;
+ }
}
diff --git
a/authorization/src/main/java/org/apache/atlas/authorize/simple/AtlasSimpleAuthzPolicy.java
b/authorization/src/main/java/org/apache/atlas/authorize/simple/AtlasSimpleAuthzPolicy.java
index 485d4e8..899e386 100644
---
a/authorization/src/main/java/org/apache/atlas/authorize/simple/AtlasSimpleAuthzPolicy.java
+++
b/authorization/src/main/java/org/apache/atlas/authorize/simple/AtlasSimpleAuthzPolicy.java
@@ -209,16 +209,24 @@ public class AtlasSimpleAuthzPolicy implements
Serializable {
private List<String> entityTypes; // name of entity-type,
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> labels; // labels, wildcards supported
+ private List<String> namespaces; // name of namespace-type,
wildcards supported
private List<String> attributes; // name of entity-attribute,
wildcards supported
public AtlasEntityPermission() {
}
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.entityTypes = entityTypes;
this.entityIds = entityIds;
this.classifications = classifications;
+ this.labels = labels;
+ this.namespaces = namespaces;
this.attributes = attributes;
}
@@ -254,6 +262,22 @@ public class AtlasSimpleAuthzPolicy implements
Serializable {
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() {
return attributes;
}
diff --git a/authorization/src/main/resources/atlas-simple-authz-policy.json
b/authorization/src/main/resources/atlas-simple-authz-policy.json
index 0a5f0fa..bd08a6f 100644
--- a/authorization/src/main/resources/atlas-simple-authz-policy.json
+++ b/authorization/src/main/resources/atlas-simple-authz-policy.json
@@ -18,7 +18,9 @@
"privileges": [ ".*" ],
"entityTypes": [ ".*" ],
"entityIds": [ ".*" ],
- "classifications": [ ".*" ]
+ "classifications": [ ".*" ],
+ "labels": [ ".*" ],
+ "namespaces": [ ".*" ]
}
],
"relationshipPermissions": [
@@ -41,7 +43,9 @@
"privileges": [ "entity-read", "entity-read-classification" ],
"entityTypes": [ ".*" ],
"entityIds": [ ".*" ],
- "classifications": [ ".*" ]
+ "classifications": [ ".*" ],
+ "labels": [ ".*" ],
+ "namespaces": [ ".*" ]
}
]
},
@@ -49,10 +53,12 @@
"DATA_STEWARD": {
"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": [ ".*" ],
"entityIds": [ ".*" ],
- "classifications": [ ".*" ]
+ "classifications": [ ".*" ],
+ "labels": [ ".*" ],
+ "namespaces": [ ".*" ]
}
],
"relationshipPermissions": [
diff --git
a/authorization/src/test/java/org/apache/atlas/authorize/simple/AtlasSimpleAuthorizerTest.java
b/authorization/src/test/java/org/apache/atlas/authorize/simple/AtlasSimpleAuthorizerTest.java
index 16c8c8c..e585e93 100644
---
a/authorization/src/test/java/org/apache/atlas/authorize/simple/AtlasSimpleAuthorizerTest.java
+++
b/authorization/src/test/java/org/apache/atlas/authorize/simple/AtlasSimpleAuthorizerTest.java
@@ -29,6 +29,10 @@ import java.util.Collections;
public class AtlasSimpleAuthorizerTest {
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 AtlasAuthorizer authorizer;
@@ -104,4 +108,67 @@ public class AtlasSimpleAuthorizerTest {
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();
+ }
+ }
}
diff --git a/authorization/src/test/resources/atlas-simple-authz-policy.json
b/authorization/src/test/resources/atlas-simple-authz-policy.json
index 5743de1..379d42b 100644
--- a/authorization/src/test/resources/atlas-simple-authz-policy.json
+++ b/authorization/src/test/resources/atlas-simple-authz-policy.json
@@ -43,7 +43,9 @@
"privileges": [ "entity-read", "entity-read-classification" ],
"entityTypes": [ ".*" ],
"entityIds": [ ".*" ],
- "classifications": [ ".*" ]
+ "classifications": [ ".*" ],
+ "labels": [ ".*" ],
+ "namespaces": [ ".*" ]
}
]
},
@@ -51,10 +53,12 @@
"DATA_STEWARD": {
"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": [ ".*" ],
"entityIds": [ ".*" ],
- "classifications": [ ".*" ]
+ "classifications": [ ".*" ],
+ "labels": [ ".*" ],
+ "namespaces": [ ".*" ]
}
]
}
@@ -62,7 +66,9 @@
"userRoles": {
"admin": [ "ROLE_ADMIN" ],
- "rangertagsync": [ "DATA_SCIENTIST" ]
+ "rangertagsync": [ "DATA_SCIENTIST" ],
+ "dataScientist1": [ "DATA_SCIENTIST"],
+ "dataSteward1": [ "DATA_STEWARD"]
},
"groupRoles": {
diff --git
a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2.java
b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2.java
index c536f3b..30f5e5a 100644
---
a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2.java
+++
b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2.java
@@ -25,6 +25,7 @@ import org.apache.atlas.annotation.GraphTransaction;
import org.apache.atlas.authorize.AtlasAdminAccessRequest;
import org.apache.atlas.authorize.AtlasAuthorizationUtils;
import org.apache.atlas.authorize.AtlasEntityAccessRequest;
+import
org.apache.atlas.authorize.AtlasEntityAccessRequest.AtlasEntityAccessRequestBuilder;
import org.apache.atlas.authorize.AtlasPrivilege;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.TypeCategory;
@@ -66,6 +67,7 @@ import javax.inject.Inject;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -834,14 +836,44 @@ public class AtlasEntityStoreV2 implements
AtlasEntityStore {
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);
if (entityVertex == null) {
throw new
AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guid);
}
- String typeName = getTypeName(entityVertex);
- AtlasEntityType entityType =
typeRegistry.getEntityTypeByName(typeName);
+ String typeName =
getTypeName(entityVertex);
+ 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);
@@ -867,14 +899,27 @@ public class AtlasEntityStoreV2 implements
AtlasEntityStore {
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);
if (entityVertex == null) {
throw new
AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guid);
}
- String typeName = getTypeName(entityVertex);
- AtlasEntityType entityType =
typeRegistry.getEntityTypeByName(typeName);
+ String typeName =
getTypeName(entityVertex);
+ 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);
@@ -902,6 +947,39 @@ public class AtlasEntityStoreV2 implements
AtlasEntityStore {
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);
if (LOG.isDebugEnabled()) {
@@ -920,12 +998,25 @@ public class AtlasEntityStoreV2 implements
AtlasEntityStore {
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);
if (entityVertex == null) {
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);
entityGraphMapper.removeLabels(entityVertex, labels);
@@ -946,12 +1037,25 @@ public class AtlasEntityStoreV2 implements
AtlasEntityStore {
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);
if (entityVertex == null) {
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);
entityGraphMapper.addLabels(entityVertex, labels);
diff --git
a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java
b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java
index 7461931..2f3aad0 100644
---
a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java
+++
b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java
@@ -353,7 +353,7 @@ public class EntityGraphMapper {
removedLabels = null;
} else if (CollectionUtils.isEmpty(labels)) {
addedLabels = null;
- removedLabels = labels;
+ removedLabels = currentLabels;
} else {
addedLabels = new
HashSet<String>(CollectionUtils.subtract(labels, currentLabels));
removedLabels = new
HashSet<String>(CollectionUtils.subtract(currentLabels, labels));
diff --git
a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphRetriever.java
b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphRetriever.java
index 3c22d9a..7533ebc 100644
---
a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphRetriever.java
+++
b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphRetriever.java
@@ -221,6 +221,41 @@ public class EntityGraphRetriever {
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) {
Object ret = null;
@@ -770,23 +805,7 @@ public class EntityGraphRetriever {
}
private void mapNamespaceAttributes(AtlasVertex entityVertex, AtlasEntity
entity) throws AtlasBaseException {
- AtlasEntityType entityType
= typeRegistry.getEntityTypeByName(entity.getTypeName());
- 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);
- }
- }
- }
- }
+ entity.setNamespaceAttributes(getEntityNamespaces(entityVertex));
}
public List<AtlasClassification> getAllClassifications(AtlasVertex
entityVertex) throws AtlasBaseException {