This is an automated email from the ASF dual-hosted git repository.
madhan pushed a commit to branch branch-2.0
in repository https://gitbox.apache.org/repos/asf/atlas.git
The following commit(s) were added to refs/heads/branch-2.0 by this push:
new bc770b4 ATLAS-3898: authorization updates to require TYPE_READ
permission for type-def read
bc770b4 is described below
commit bc770b4a20b43f32cea8d64740a8ee5408db8755
Author: nixonrodrigues <[email protected]>
AuthorDate: Thu Aug 13 18:07:13 2020 +0530
ATLAS-3898: authorization updates to require TYPE_READ permission for
type-def read
Signed-off-by: Madhan Neethiraj <[email protected]>
---
.../atlas/authorize/AtlasAuthorizationUtils.java | 22 ++++++++
.../apache/atlas/authorize/AtlasAuthorizer.java | 4 ++
.../org/apache/atlas/authorize/AtlasPrivilege.java | 4 +-
.../authorize/AtlasTypesDefFilterRequest.java | 50 +++++++++++++++++
.../authorize/simple/AtlasSimpleAuthorizer.java | 62 ++++++++++++++++++++++
.../store/graph/AtlasTypeDefGraphStore.java | 37 +++++++++++++
6 files changed, 178 insertions(+), 1 deletion(-)
diff --git
a/authorization/src/main/java/org/apache/atlas/authorize/AtlasAuthorizationUtils.java
b/authorization/src/main/java/org/apache/atlas/authorize/AtlasAuthorizationUtils.java
index 460b454..b1a3eb5 100644
---
a/authorization/src/main/java/org/apache/atlas/authorize/AtlasAuthorizationUtils.java
+++
b/authorization/src/main/java/org/apache/atlas/authorize/AtlasAuthorizationUtils.java
@@ -199,6 +199,28 @@ public class AtlasAuthorizationUtils {
return ret;
}
+ public static void filterTypesDef(AtlasTypesDefFilterRequest request) {
+ MetricRecorder metric =
RequestContext.get().startMetricRecord("filterTypesDef");
+ String userName = getCurrentUserName();
+
+ if (StringUtils.isNotEmpty(userName) &&
!RequestContext.get().isImportInProgress()) {
+ try {
+ AtlasAuthorizer authorizer =
AtlasAuthorizerFactory.getAtlasAuthorizer();
+
+ request.setUser(getCurrentUserName(), getCurrentUserGroups());
+
request.setClientIPAddress(RequestContext.get().getClientIPAddress());
+
request.setForwardedAddresses(RequestContext.get().getForwardedAddresses());
+
request.setRemoteIPAddress(RequestContext.get().getClientIPAddress());
+
+ authorizer.filterTypesDef(request);
+ } catch (AtlasAuthorizationException e) {
+ LOG.error("Unable to obtain AtlasAuthorizer", e);
+ }
+ }
+
+ RequestContext.get().endMetricRecord(metric);
+ }
+
public static List<String>
getForwardedAddressesFromRequest(HttpServletRequest httpServletRequest){
String ipAddress = httpServletRequest.getHeader("X-FORWARDED-FOR");
String[] forwardedAddresses = null ;
diff --git
a/authorization/src/main/java/org/apache/atlas/authorize/AtlasAuthorizer.java
b/authorization/src/main/java/org/apache/atlas/authorize/AtlasAuthorizer.java
index 95d69e6..21b8cf9 100644
---
a/authorization/src/main/java/org/apache/atlas/authorize/AtlasAuthorizer.java
+++
b/authorization/src/main/java/org/apache/atlas/authorize/AtlasAuthorizer.java
@@ -101,4 +101,8 @@ public interface AtlasAuthorizer {
entity.getMeaningNames().clear();
}
}
+
+ default
+ void filterTypesDef(AtlasTypesDefFilterRequest request) throws
AtlasAuthorizationException {
+ }
}
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 7287b3d..9dbcd32 100644
--- a/authorization/src/main/java/org/apache/atlas/authorize/AtlasPrivilege.java
+++ b/authorization/src/main/java/org/apache/atlas/authorize/AtlasPrivilege.java
@@ -42,7 +42,9 @@ public enum AtlasPrivilege {
ENTITY_ADD_LABEL("entity-add-label"),
ENTITY_REMOVE_LABEL("entity-remove-label"),
- ENTITY_UPDATE_BUSINESS_METADATA("entity-update-business-metadata");
+ ENTITY_UPDATE_BUSINESS_METADATA("entity-update-business-metadata"),
+
+ TYPE_READ("type-read");
private final String type;
diff --git
a/authorization/src/main/java/org/apache/atlas/authorize/AtlasTypesDefFilterRequest.java
b/authorization/src/main/java/org/apache/atlas/authorize/AtlasTypesDefFilterRequest.java
new file mode 100644
index 0000000..a2dc11f
--- /dev/null
+++
b/authorization/src/main/java/org/apache/atlas/authorize/AtlasTypesDefFilterRequest.java
@@ -0,0 +1,50 @@
+/**
+ * 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.typedef.AtlasTypesDef;
+
+import java.util.Set;
+
+public class AtlasTypesDefFilterRequest extends AtlasAccessRequest {
+ private final AtlasTypesDef typesDef;
+
+
+ public AtlasTypesDefFilterRequest(AtlasTypesDef typesDef) {
+ super(AtlasPrivilege.TYPE_READ);
+
+ this.typesDef = typesDef;
+ }
+
+ public AtlasTypesDefFilterRequest(AtlasTypesDef typesDef, String userName,
Set<String> usergroups) {
+ super(AtlasPrivilege.TYPE_READ, userName, usergroups);
+
+ this.typesDef = typesDef;
+ }
+
+ public AtlasTypesDef getTypesDef() {
+ return typesDef;
+ }
+
+ @Override
+ public String toString() {
+ return "AtlasTypesDefFilterRequest[typesDef=" + typesDef + ", action="
+ getAction() + ", accessTime=" + getAccessTime() +
+ ", user=" + getUser() + ", userGroups=" + getUserGroups() + ",
clientIPAddress=" + getClientIPAddress() +
+ ", forwardedAddresses=" + getForwardedAddresses() + ",
remoteIPAddress=" + getRemoteIPAddress() + "]";
+ }
+}
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 7349916..5636438 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
@@ -23,6 +23,7 @@ import java.io.InputStream;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+import java.util.ListIterator;
import java.util.Set;
import org.apache.atlas.ApplicationProperties;
@@ -32,6 +33,8 @@ import
org.apache.atlas.authorize.simple.AtlasSimpleAuthzPolicy.*;
import org.apache.atlas.model.discovery.AtlasSearchResult;
import org.apache.atlas.model.discovery.AtlasSearchResult.AtlasFullTextResult;
import org.apache.atlas.model.instance.AtlasEntityHeader;
+import org.apache.atlas.model.typedef.AtlasBaseTypeDef;
+import org.apache.atlas.model.typedef.AtlasTypesDef;
import org.apache.atlas.utils.AtlasJson;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
@@ -39,6 +42,11 @@ import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import static org.apache.atlas.authorize.AtlasPrivilege.TYPE_CREATE;
+import static org.apache.atlas.authorize.AtlasPrivilege.TYPE_DELETE;
+import static org.apache.atlas.authorize.AtlasPrivilege.TYPE_READ;
+import static org.apache.atlas.authorize.AtlasPrivilege.TYPE_UPDATE;
+
public final class AtlasSimpleAuthorizer implements AtlasAuthorizer {
private static final Logger LOG =
LoggerFactory.getLogger(AtlasSimpleAuthorizer.class);
@@ -61,6 +69,8 @@ public final class AtlasSimpleAuthorizer implements
AtlasAuthorizer {
inputStream =
ApplicationProperties.getFileAsInputStream(ApplicationProperties.get(),
"atlas.authorizer.simple.authz.policy.file", "atlas-simple-authz-policy.json");
authzPolicy = AtlasJson.fromJson(inputStream,
AtlasSimpleAuthzPolicy.class);
+
+ addImpliedTypeReadPrivilege(authzPolicy);
} catch (IOException | AtlasException e) {
LOG.error("SimpleAtlasAuthorizer.init(): initialization failed",
e);
@@ -313,6 +323,18 @@ public final class AtlasSimpleAuthorizer implements
AtlasAuthorizer {
}
}
+ @Override
+ public void filterTypesDef(AtlasTypesDefFilterRequest request) throws
AtlasAuthorizationException {
+ AtlasTypesDef typesDef = request.getTypesDef();
+
+ filterTypes(request, typesDef.getEnumDefs());
+ filterTypes(request, typesDef.getStructDefs());
+ filterTypes(request, typesDef.getEntityDefs());
+ filterTypes(request, typesDef.getClassificationDefs());
+ filterTypes(request, typesDef.getRelationshipDefs());
+ filterTypes(request, typesDef.getBusinessMetadataDefs());
+ }
+
private Set<String> getRoles(String userName, Set<String> userGroups) {
Set<String> ret = new HashSet<>();
@@ -467,6 +489,46 @@ public final class AtlasSimpleAuthorizer implements
AtlasAuthorizer {
private boolean isBusinessMetadataMatch(AtlasEntityAccessRequest request,
AtlasEntityPermission permission) {
return
AtlasPrivilege.ENTITY_UPDATE_BUSINESS_METADATA.equals(request.getAction()) ?
isMatch(request.getBusinessMetadata(), permission.getBusinessMetadata()) : true;
}
+
+ private void filterTypes(AtlasAccessRequest request, List<? extends
AtlasBaseTypeDef> typeDefs)throws AtlasAuthorizationException {
+ if (typeDefs != null) {
+ for (ListIterator<? extends AtlasBaseTypeDef> iter =
typeDefs.listIterator(); iter.hasNext();) {
+ AtlasBaseTypeDef typeDef = iter.next();
+ AtlasTypeAccessRequest typeRequest = new
AtlasTypeAccessRequest(request.getAction(), typeDef, request.getUser(),
request.getUserGroups());
+
+ typeRequest.setClientIPAddress(request.getClientIPAddress());
+
typeRequest.setForwardedAddresses(request.getForwardedAddresses());
+ typeRequest.setRemoteIPAddress(request.getRemoteIPAddress());
+
+ if (!isAccessAllowed(typeRequest)) {
+ iter.remove();
+ }
+ }
+ }
+ }
+
+ // add TYPE_READ privilege, if at least one of the following is granted:
TYPE_CREATE, TYPE_UPDATE, TYPE_DELETE
+ private void addImpliedTypeReadPrivilege(AtlasSimpleAuthzPolicy policy) {
+ if (policy != null && policy.getRoles() != null) {
+ for (AtlasAuthzRole role : policy.getRoles().values()) {
+ if (role.getTypePermissions() == null) {
+ continue;
+ }
+
+ for (AtlasTypePermission permission :
role.getTypePermissions()) {
+ List<String> privileges = permission.getPrivileges();
+
+ if (CollectionUtils.isEmpty(privileges) ||
privileges.contains(TYPE_READ.name())) {
+ continue;
+ }
+
+ if (privileges.contains(TYPE_CREATE.name()) ||
privileges.contains(TYPE_UPDATE.name()) ||
privileges.contains(TYPE_DELETE.name())) {
+ privileges.add(TYPE_READ.name());
+ }
+ }
+ }
+ }
+ }
}
diff --git
a/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasTypeDefGraphStore.java
b/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasTypeDefGraphStore.java
index 79f5270..0b1317a 100644
---
a/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasTypeDefGraphStore.java
+++
b/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasTypeDefGraphStore.java
@@ -20,6 +20,10 @@ package org.apache.atlas.repository.store.graph;
import org.apache.atlas.AtlasErrorCode;
import org.apache.atlas.GraphTransactionInterceptor;
import org.apache.atlas.annotation.GraphTransaction;
+import org.apache.atlas.authorize.AtlasAuthorizationUtils;
+import org.apache.atlas.authorize.AtlasPrivilege;
+import org.apache.atlas.authorize.AtlasTypeAccessRequest;
+import org.apache.atlas.authorize.AtlasTypesDefFilterRequest;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.listener.ChangedTypeDefs;
import org.apache.atlas.listener.TypeDefChangeListener;
@@ -120,6 +124,9 @@ public abstract class AtlasTypeDefGraphStore implements
AtlasTypeDefStore {
if (ret == null) {
throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_NOT_FOUND,
name);
}
+
+ AtlasAuthorizationUtils.verifyAccess(new
AtlasTypeAccessRequest(AtlasPrivilege.TYPE_READ, ret), "read type ", name);
+
return ret;
}
@@ -129,6 +136,9 @@ public abstract class AtlasTypeDefGraphStore implements
AtlasTypeDefStore {
if (ret == null) {
throw new AtlasBaseException(AtlasErrorCode.TYPE_GUID_NOT_FOUND,
guid);
}
+
+ AtlasAuthorizationUtils.verifyAccess(new
AtlasTypeAccessRequest(AtlasPrivilege.TYPE_READ, ret), "read type ",
ret.getName());
+
return ret;
}
@@ -160,6 +170,8 @@ public abstract class AtlasTypeDefGraphStore implements
AtlasTypeDefStore {
throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_NOT_FOUND,
name);
}
+ AtlasAuthorizationUtils.verifyAccess(new
AtlasTypeAccessRequest(AtlasPrivilege.TYPE_READ, ret), "read type ", name);
+
return ret;
}
@@ -171,6 +183,8 @@ public abstract class AtlasTypeDefGraphStore implements
AtlasTypeDefStore {
throw new AtlasBaseException(AtlasErrorCode.TYPE_GUID_NOT_FOUND,
guid);
}
+ AtlasAuthorizationUtils.verifyAccess(new
AtlasTypeAccessRequest(AtlasPrivilege.TYPE_READ, ret), "read type ",
ret.getName());
+
return ret;
}
@@ -182,6 +196,8 @@ public abstract class AtlasTypeDefGraphStore implements
AtlasTypeDefStore {
throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_NOT_FOUND,
name);
}
+ AtlasAuthorizationUtils.verifyAccess(new
AtlasTypeAccessRequest(AtlasPrivilege.TYPE_READ, ret), "read type ", name);
+
return ret;
}
@@ -193,6 +209,8 @@ public abstract class AtlasTypeDefGraphStore implements
AtlasTypeDefStore {
throw new AtlasBaseException(AtlasErrorCode.TYPE_GUID_NOT_FOUND,
guid);
}
+ AtlasAuthorizationUtils.verifyAccess(new
AtlasTypeAccessRequest(AtlasPrivilege.TYPE_READ, ret), "read type ",
ret.getName());
+
return ret;
}
@@ -204,6 +222,8 @@ public abstract class AtlasTypeDefGraphStore implements
AtlasTypeDefStore {
throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_NOT_FOUND,
name);
}
+ AtlasAuthorizationUtils.verifyAccess(new
AtlasTypeAccessRequest(AtlasPrivilege.TYPE_READ, ret), "read type ", name);
+
return ret;
}
@@ -215,6 +235,8 @@ public abstract class AtlasTypeDefGraphStore implements
AtlasTypeDefStore {
throw new AtlasBaseException(AtlasErrorCode.TYPE_GUID_NOT_FOUND,
guid);
}
+ AtlasAuthorizationUtils.verifyAccess(new
AtlasTypeAccessRequest(AtlasPrivilege.TYPE_READ, ret), "read type ",
ret.getName());
+
return ret;
}
@@ -250,6 +272,8 @@ public abstract class AtlasTypeDefGraphStore implements
AtlasTypeDefStore {
}
}
+ AtlasAuthorizationUtils.verifyAccess(new
AtlasTypeAccessRequest(AtlasPrivilege.TYPE_READ, ret), "read type ", name);
+
return ret;
}
@@ -261,6 +285,8 @@ public abstract class AtlasTypeDefGraphStore implements
AtlasTypeDefStore {
throw new AtlasBaseException(AtlasErrorCode.TYPE_GUID_NOT_FOUND,
guid);
}
+ AtlasAuthorizationUtils.verifyAccess(new
AtlasTypeAccessRequest(AtlasPrivilege.TYPE_READ, ret), "read type ",
ret.getName());
+
return ret;
}
@@ -298,6 +324,8 @@ public abstract class AtlasTypeDefGraphStore implements
AtlasTypeDefStore {
}
}
+ AtlasAuthorizationUtils.verifyAccess(new
AtlasTypeAccessRequest(AtlasPrivilege.TYPE_READ, ret), "read type ", name);
+
return ret;
}
@@ -309,6 +337,8 @@ public abstract class AtlasTypeDefGraphStore implements
AtlasTypeDefStore {
throw new AtlasBaseException(AtlasErrorCode.TYPE_GUID_NOT_FOUND,
guid);
}
+ AtlasAuthorizationUtils.verifyAccess(new
AtlasTypeAccessRequest(AtlasPrivilege.TYPE_READ, ret), "read type ",
ret.getName());
+
return ret;
}
@@ -722,6 +752,8 @@ public abstract class AtlasTypeDefGraphStore implements
AtlasTypeDefStore {
}
}
+ AtlasAuthorizationUtils.filterTypesDef(new
AtlasTypesDefFilterRequest(typesDef));
+
return typesDef;
}
@@ -771,6 +803,11 @@ public abstract class AtlasTypeDefGraphStore implements
AtlasTypeDefStore {
default:
throw new AtlasBaseException(AtlasErrorCode.SYSTEM_TYPE,
type.getTypeCategory().name());
}
+
+ if (ret != null) {
+ AtlasAuthorizationUtils.verifyAccess(new
AtlasTypeAccessRequest(AtlasPrivilege.TYPE_READ, ret), "read type ",
ret.getName());
+ }
+
return ret;
}