You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by yh...@apache.org on 2016/05/09 17:09:33 UTC
[2/2] incubator-atlas git commit: ATLAS-497 Simple Authorization
(saqeeb.s via yhemanth)
ATLAS-497 Simple Authorization (saqeeb.s via yhemanth)
Project: http://git-wip-us.apache.org/repos/asf/incubator-atlas/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-atlas/commit/a963e980
Tree: http://git-wip-us.apache.org/repos/asf/incubator-atlas/tree/a963e980
Diff: http://git-wip-us.apache.org/repos/asf/incubator-atlas/diff/a963e980
Branch: refs/heads/master
Commit: a963e9806c7dd85b50d6957ec915233865c6216b
Parents: 34f51a2
Author: Hemanth Yamijala <hy...@hortonworks.com>
Authored: Mon May 9 22:39:11 2016 +0530
Committer: Hemanth Yamijala <hy...@hortonworks.com>
Committed: Mon May 9 22:39:11 2016 +0530
----------------------------------------------------------------------
distro/src/conf/atlas-application.properties | 3 +
distro/src/conf/policy-store.txt | 9 +
pom.xml | 1 +
release-log.txt | 1 +
.../atlas/authorize/AtlasAccessRequest.java | 117 ++++++
.../atlas/authorize/AtlasAccessorTypes.java | 22 ++
.../atlas/authorize/AtlasActionTypes.java | 22 ++
.../authorize/AtlasAuthorizationException.java | 40 ++
.../authorize/AtlasAuthorizationUtils.java | 132 +++++++
.../apache/atlas/authorize/AtlasAuthorizer.java | 43 +++
.../atlas/authorize/AtlasResourceTypes.java | 23 ++
.../org/apache/atlas/authorize/PolicyDef.java | 67 ++++
.../apache/atlas/authorize/PolicyParser.java | 238 ++++++++++++
.../org/apache/atlas/authorize/PolicyUtil.java | 164 ++++++++
.../atlas/authorize/SimpleAtlasAuthorizer.java | 380 +++++++++++++++++++
.../org/apache/atlas/util/FileReaderUtil.java | 56 +++
.../web/filters/AtlasAuthorizationFilter.java | 166 ++++++++
webapp/src/main/resources/spring-security.xml | 3 +
.../atlas/authorize/PolicyParserTest.java | 167 ++++++++
.../apache/atlas/authorize/PolicyUtilTest.java | 95 +++++
.../authorize/SimpleAtlasAuthorizerTest.java | 185 +++++++++
.../web/security/FileAuthenticationTest.java | 17 +-
22 files changed, 1947 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/a963e980/distro/src/conf/atlas-application.properties
----------------------------------------------------------------------
diff --git a/distro/src/conf/atlas-application.properties b/distro/src/conf/atlas-application.properties
index 290105f..119865d 100755
--- a/distro/src/conf/atlas-application.properties
+++ b/distro/src/conf/atlas-application.properties
@@ -124,3 +124,6 @@ atlas.login.method=FILE
### File path of users-credentials
atlas.login.credentials.file=${sys:atlas.home}/conf/users-credentials.properties
+#########POLICY FILE PATH #########
+atlas.auth.policy.file=${sys:atlas.home}/conf/policy-store.txt
+
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/a963e980/distro/src/conf/policy-store.txt
----------------------------------------------------------------------
diff --git a/distro/src/conf/policy-store.txt b/distro/src/conf/policy-store.txt
new file mode 100644
index 0000000..b072b49
--- /dev/null
+++ b/distro/src/conf/policy-store.txt
@@ -0,0 +1,9 @@
+##Policy Format
+##r-READ, w-WRITE, u-UPDATE, d-DELETE
+##Policy_Name;;User_Name1:Operations_Allowed,User_Name2:Operations_Allowed;;Group_Name1:Operations_Allowed,Group_Name2:Operations_Allowed;;Resource_Type1:Resource_Name,Resource_Type2:Resource_Name
+##
+adminPolicy;;admin:rwud;;ROLE_ADMIN:rwud;;type:*,entity:*,operation:*
+typeReadPolicy;;nixon:rw;;;;type:*,entity:*
+classReadPolicy;;saqeeb:r;;;;type:*,entity:*
+dataScientistPolicy;;;;DATA_SCIENTIST:r;;type:*,entity:*
+dataStewardPolicy;;;;DATA_STEWARD:rwu;;type:*,entity:*
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/a963e980/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 7b872c3..0606d80 100755
--- a/pom.xml
+++ b/pom.xml
@@ -1668,6 +1668,7 @@
<!-- atlas data directory creates when tests are run from IDE -->
<exclude>**/atlas.data/**</exclude>
<exclude>**/${sys:atlas.data}/**</exclude>
+ <exclude>**/policy-store.txt</exclude>
</excludes>
</configuration>
<executions>
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/a963e980/release-log.txt
----------------------------------------------------------------------
diff --git a/release-log.txt b/release-log.txt
index 4bacdfb..1afc1ed 100644
--- a/release-log.txt
+++ b/release-log.txt
@@ -3,6 +3,7 @@ Apache Atlas Release Notes
--trunk - unreleased
INCOMPATIBLE CHANGES:
+ATLAS-497 Simple Authorization (saqeeb.s via yhemanth)
ATLAS-661 REST API Authentication (nixonrodrigues via yhemanth)
ATLAS-672 UI: Make dashboard v2 the default UI implementation (bergenholtz via yhemanth)
ATLAS-532 Change Data types of all timestamps in Hive model(currently long)(sumasai via yhemanth)
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/a963e980/webapp/src/main/java/org/apache/atlas/authorize/AtlasAccessRequest.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/authorize/AtlasAccessRequest.java b/webapp/src/main/java/org/apache/atlas/authorize/AtlasAccessRequest.java
new file mode 100644
index 0000000..5db9646
--- /dev/null
+++ b/webapp/src/main/java/org/apache/atlas/authorize/AtlasAccessRequest.java
@@ -0,0 +1,117 @@
+/**
+ * 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 java.util.Date;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class AtlasAccessRequest {
+
+ private static Logger LOG = LoggerFactory.getLogger(AtlasAccessRequest.class);
+ private static boolean isDebugEnabled = LOG.isDebugEnabled();
+ private List<AtlasResourceTypes> resourceType = null;
+ private String resource = null;
+ private AtlasActionTypes action = null;
+ private String user = null;
+ private List<String> userGroups = null;
+ private Date accessTime = null;
+ private String clientIPAddress = null;
+
+ public AtlasAccessRequest(List<AtlasResourceTypes> resourceType, String resource, AtlasActionTypes action,
+ String user, List<String> userGroups) {
+ if (isDebugEnabled) {
+ LOG.debug("<== AtlasAccessRequestImpl-- Initializing AtlasAccessRequest");
+ }
+ setResource(resource);
+ setAction(action);
+ setUser(user);
+ setUserGroups(userGroups);
+ setResourceType(resourceType);
+
+ // set remaining fields to default value
+ setAccessTime(null);
+ setClientIPAddress(null);
+ }
+
+ public List<AtlasResourceTypes> getResourceTypes() {
+ return resourceType;
+ }
+
+ public void setResourceType(List<AtlasResourceTypes> resourceType) {
+ this.resourceType = resourceType;
+ }
+
+ public String getResource() {
+ return resource;
+ }
+
+ public void setResource(String resource) {
+ this.resource = resource;
+ }
+
+ public AtlasActionTypes getAction() {
+ return action;
+ }
+
+ public void setAction(AtlasActionTypes action) {
+ this.action = action;
+ }
+
+ public String getUser() {
+ return user;
+ }
+
+ public void setUser(String user) {
+ this.user = user;
+ }
+
+ public void setUserGroups(List<String> userGroups) {
+ this.userGroups = userGroups;
+ }
+
+ public List<String> getUserGroups() {
+ return userGroups;
+ }
+
+ public Date getAccessTime() {
+ return accessTime;
+ }
+
+ public void setAccessTime(Date accessTime) {
+ this.accessTime = accessTime;
+ }
+
+ public String getClientIPAddress() {
+ return clientIPAddress;
+ }
+
+ public void setClientIPAddress(String clientIPAddress) {
+ this.clientIPAddress = clientIPAddress;
+ }
+
+ @Override
+ public String toString() {
+ return "AtlasAccessRequest [resourceType=" + resourceType + ", resource=" + resource + ", action=" + action
+ + ", user=" + user + ", userGroups=" + userGroups + ", accessTime=" + accessTime + ", clientIPAddress="
+ + clientIPAddress + "]";
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/a963e980/webapp/src/main/java/org/apache/atlas/authorize/AtlasAccessorTypes.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/authorize/AtlasAccessorTypes.java b/webapp/src/main/java/org/apache/atlas/authorize/AtlasAccessorTypes.java
new file mode 100644
index 0000000..5f3827a
--- /dev/null
+++ b/webapp/src/main/java/org/apache/atlas/authorize/AtlasAccessorTypes.java
@@ -0,0 +1,22 @@
+/**
+ * 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;
+
+public enum AtlasAccessorTypes {
+ USER, GROUP;
+}
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/a963e980/webapp/src/main/java/org/apache/atlas/authorize/AtlasActionTypes.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/authorize/AtlasActionTypes.java b/webapp/src/main/java/org/apache/atlas/authorize/AtlasActionTypes.java
new file mode 100644
index 0000000..13c8b53
--- /dev/null
+++ b/webapp/src/main/java/org/apache/atlas/authorize/AtlasActionTypes.java
@@ -0,0 +1,22 @@
+/**
+ * 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;
+
+public enum AtlasActionTypes {
+ READ, WRITE, UPDATE, DELETE;
+}
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/a963e980/webapp/src/main/java/org/apache/atlas/authorize/AtlasAuthorizationException.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/authorize/AtlasAuthorizationException.java b/webapp/src/main/java/org/apache/atlas/authorize/AtlasAuthorizationException.java
new file mode 100644
index 0000000..676c9f9
--- /dev/null
+++ b/webapp/src/main/java/org/apache/atlas/authorize/AtlasAuthorizationException.java
@@ -0,0 +1,40 @@
+/**
+ * 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;
+
+public class AtlasAuthorizationException extends Exception {
+ private static final long serialVersionUID = 1L;
+
+ public AtlasAuthorizationException() {
+
+ }
+
+ public AtlasAuthorizationException(String message) {
+ super(message);
+ }
+
+ public AtlasAuthorizationException(String message, Throwable exception) {
+ super(message, exception);
+ }
+
+ public AtlasAuthorizationException(String message, Throwable exception, boolean enableSuppression,
+ boolean writableStackTrace) {
+ super(message, exception, enableSuppression, writableStackTrace);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/a963e980/webapp/src/main/java/org/apache/atlas/authorize/AtlasAuthorizationUtils.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/authorize/AtlasAuthorizationUtils.java b/webapp/src/main/java/org/apache/atlas/authorize/AtlasAuthorizationUtils.java
new file mode 100644
index 0000000..211ee7f
--- /dev/null
+++ b/webapp/src/main/java/org/apache/atlas/authorize/AtlasAuthorizationUtils.java
@@ -0,0 +1,132 @@
+/**
+ * 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 java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.List;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.atlas.AtlasClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Strings;
+
+public class AtlasAuthorizationUtils {
+ private static final Logger LOG = LoggerFactory.getLogger(AtlasAuthorizationUtils.class);
+ private static boolean isDebugEnabled = LOG.isDebugEnabled();
+ private static final String BASE_URL = "/" + AtlasClient.BASE_URI;
+
+ public static String parse(String fullPath, String subPath) {
+ String api = null;
+ if (!Strings.isNullOrEmpty(fullPath)) {
+ api = fullPath.substring(subPath.length(), fullPath.length());
+
+ }
+ if (isDebugEnabled) {
+ LOG.debug("Extracted " + api + " from path : " + fullPath);
+ }
+ return api;
+ }
+
+ public static String getApi(String u) {
+ if (isDebugEnabled) {
+ LOG.debug("getApi <=== from " + u);
+ }
+ if (u.startsWith(BASE_URL)) {
+ u = parse(u, BASE_URL);
+ }
+ String[] split = u.split("/");
+ return split[0];
+ }
+
+ public static AtlasActionTypes getAtlasAction(String method) {
+ AtlasActionTypes action = null;
+
+ switch (method.toUpperCase()) {
+ case "POST":
+ action = AtlasActionTypes.WRITE;
+ break;
+ case "GET":
+ action = AtlasActionTypes.READ;
+ break;
+ case "PUT":
+ action = AtlasActionTypes.UPDATE;
+ break;
+ case "DELETE":
+ action = AtlasActionTypes.DELETE;
+ break;
+ default:
+ if (isDebugEnabled) {
+ LOG.debug("Invalid HTTP method in request : " + method + " this is serious!!!");
+ }
+ break;
+ }
+
+ if (isDebugEnabled) {
+ LOG.debug("==> AtlasAuthorizationFilter getAtlasAction HTTP Method " + method + " mapped to AtlasAction : "
+ + action);
+ }
+ return action;
+ }
+
+ public static List<AtlasResourceTypes> getAtlasResourceType(String contextPath) throws ServletException {
+ List<AtlasResourceTypes> resourceTypes = new ArrayList<AtlasResourceTypes>();
+ if (isDebugEnabled) {
+ LOG.debug("getAtlasResourceType <=== for " + contextPath);
+ }
+ String api = getApi(contextPath);
+
+ if (api.startsWith("types")) {
+ resourceTypes.add(AtlasResourceTypes.TYPE);
+ } else if ((api.startsWith("discovery") && api.contains("gremlin")) || api.startsWith("admin")
+ || api.startsWith("graph")) {
+ resourceTypes.add(AtlasResourceTypes.OPERATION);
+ } else if ((api.startsWith("entities") && contextPath.contains("traits")) || api.startsWith("discovery")) {
+ resourceTypes.add(AtlasResourceTypes.ENTITY);
+ resourceTypes.add(AtlasResourceTypes.TYPE);
+ } else if (api.startsWith("entities") || api.startsWith("lineage")) {
+ resourceTypes.add(AtlasResourceTypes.ENTITY);
+ } else {
+ LOG.error("Unable to find Atlas Resource corresponding to : " + api);
+ throw new ServletException("Unable to find Atlas Resource corresponding to : " + api);
+ }
+
+ if (isDebugEnabled) {
+ LOG.debug("Returning AtlasResources " + resourceTypes + " for api " + api);
+ }
+ return resourceTypes;
+ }
+
+ /*
+ * This implementation will be changed for Resource level Authorization.
+ */
+ public static String getAtlasResource(HttpServletRequest requeset, AtlasActionTypes action) {
+ if (isDebugEnabled) {
+ LOG.debug("getAtlasResource <=== "
+ + "This implementation will be changed for Resource level Authorization.");
+ }
+ return "*";
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/a963e980/webapp/src/main/java/org/apache/atlas/authorize/AtlasAuthorizer.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/authorize/AtlasAuthorizer.java b/webapp/src/main/java/org/apache/atlas/authorize/AtlasAuthorizer.java
new file mode 100644
index 0000000..7c93c7a
--- /dev/null
+++ b/webapp/src/main/java/org/apache/atlas/authorize/AtlasAuthorizer.java
@@ -0,0 +1,43 @@
+/**
+ * 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;
+
+
+public interface AtlasAuthorizer {
+ /**
+ * This method will load the policy file and would initialize the required data-structures.
+ */
+ public void init();
+
+ /**
+ * This method is responsible to perform the actual authorization for every REST API call. It will check the if the
+ * user:u can perform action:a on resource:r.
+ *
+ * @param request
+ * @return
+ */
+ public boolean isAccessAllowed(AtlasAccessRequest request) throws AtlasAuthorizationException;
+
+ /**
+ * This method is responsible to perform the cleanup and release activities. It must be called when you are done
+ * with the Authorization activity and once it's called a restart would be required. Try to invoke this while
+ * destroying the context.
+ */
+ public void cleanUp();
+}
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/a963e980/webapp/src/main/java/org/apache/atlas/authorize/AtlasResourceTypes.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/authorize/AtlasResourceTypes.java b/webapp/src/main/java/org/apache/atlas/authorize/AtlasResourceTypes.java
new file mode 100644
index 0000000..8ce3f4c
--- /dev/null
+++ b/webapp/src/main/java/org/apache/atlas/authorize/AtlasResourceTypes.java
@@ -0,0 +1,23 @@
+/**
+ * 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;
+
+public enum AtlasResourceTypes {
+ ENTITY, TYPE, OPERATION;
+}
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/a963e980/webapp/src/main/java/org/apache/atlas/authorize/PolicyDef.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/authorize/PolicyDef.java b/webapp/src/main/java/org/apache/atlas/authorize/PolicyDef.java
new file mode 100644
index 0000000..0ee39df
--- /dev/null
+++ b/webapp/src/main/java/org/apache/atlas/authorize/PolicyDef.java
@@ -0,0 +1,67 @@
+/** 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 java.util.List;
+import java.util.Map;
+
+public class PolicyDef {
+
+ private String policyName;
+ private Map<String, List<AtlasActionTypes>> users;
+ private Map<String, List<AtlasActionTypes>> groups;
+ private Map<AtlasResourceTypes, List<String>> resources;
+
+ public String getPolicyName() {
+ return policyName;
+ }
+
+ public void setPolicyName(String policyName) {
+ this.policyName = policyName;
+ }
+
+ public Map<String, List<AtlasActionTypes>> getUsers() {
+ return users;
+ }
+
+ public void setUsers(Map<String, List<AtlasActionTypes>> users) {
+ this.users = users;
+ }
+
+ public Map<String, List<AtlasActionTypes>> getGroups() {
+ return groups;
+ }
+
+ public void setGroups(Map<String, List<AtlasActionTypes>> groups) {
+ this.groups = groups;
+ }
+
+ public Map<AtlasResourceTypes, List<String>> getResources() {
+ return resources;
+ }
+
+ public void setResources(Map<AtlasResourceTypes, List<String>> resources) {
+ this.resources = resources;
+ }
+
+ @Override
+ public String toString() {
+ return "PolicyDef [policyName=" + policyName + ", users=" + users + ", groups=" + groups + ", resources="
+ + resources + "]";
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/a963e980/webapp/src/main/java/org/apache/atlas/authorize/PolicyParser.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/authorize/PolicyParser.java b/webapp/src/main/java/org/apache/atlas/authorize/PolicyParser.java
new file mode 100644
index 0000000..51a6dc2
--- /dev/null
+++ b/webapp/src/main/java/org/apache/atlas/authorize/PolicyParser.java
@@ -0,0 +1,238 @@
+/**
+ * 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 java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PolicyParser {
+
+ private static Logger LOG = LoggerFactory.getLogger(PolicyParser.class);
+ private static boolean isDebugEnabled = LOG.isDebugEnabled();
+ public static final int POLICYNAME = 0;
+
+ public static final int USER_INDEX = 1;
+ public static final int USERNAME = 0;
+ public static final int USER_AUTHORITIES = 1;
+
+ public static final int GROUP_INDEX = 2;
+ public static final int GROUPNAME = 0;
+ public static final int GROUP_AUTHORITIES = 1;
+
+ public static final int RESOURCE_INDEX = 3;
+ public static final int RESOURCE_TYPE = 0;
+ public static final int RESOURCE_NAME = 1;
+
+ private List<AtlasActionTypes> getListOfAutorities(String auth) {
+ if (isDebugEnabled) {
+ LOG.debug("<== PolicyParser getListOfAutorities");
+ }
+ List<AtlasActionTypes> authorities = new ArrayList<AtlasActionTypes>();
+
+ for (int i = 0; i < auth.length(); i++) {
+ char access = auth.toLowerCase().charAt(i);
+ switch (access) {
+ case 'r':
+ authorities.add(AtlasActionTypes.READ);
+ break;
+ case 'w':
+ authorities.add(AtlasActionTypes.WRITE);
+ break;
+ case 'u':
+ authorities.add(AtlasActionTypes.UPDATE);
+ break;
+ case 'd':
+ authorities.add(AtlasActionTypes.DELETE);
+ break;
+
+ default:
+ if (LOG.isErrorEnabled()) {
+ LOG.error("Invalid Action");
+ }
+ break;
+ }
+ }
+ if (isDebugEnabled) {
+ LOG.debug("==> PolicyParser getListOfAutorities");
+ }
+ return authorities;
+ }
+
+ public List<PolicyDef> parsePolicies(List<String> policies) {
+ if (isDebugEnabled) {
+ LOG.debug("<== PolicyParser parsePolicies");
+ }
+ List<PolicyDef> policyDefs = new ArrayList<PolicyDef>();
+ for (String policy : policies) {
+ PolicyDef policyDef = parsePolicy(policy);
+ policyDefs.add(policyDef);
+ }
+ if (isDebugEnabled) {
+ LOG.debug("==> PolicyParser parsePolicies");
+ LOG.debug(policyDefs.toString());
+ }
+ return policyDefs;
+ }
+
+ private PolicyDef parsePolicy(String data) {
+ if (isDebugEnabled) {
+ LOG.debug("<== PolicyParser parsePolicy");
+ }
+ PolicyDef def = new PolicyDef();
+ String[] props = data.split(";;");
+ def.setPolicyName(props[POLICYNAME]);
+ parseUsers(props[USER_INDEX], def);
+ parseGroups(props[GROUP_INDEX], def);
+ parseResources(props[RESOURCE_INDEX], def);
+ if (isDebugEnabled) {
+ LOG.debug("policy successfully parsed!!!");
+ LOG.debug("==> PolicyParser parsePolicy");
+ }
+ return def;
+ }
+
+ private boolean validateEntity(String entity) {
+ if (isDebugEnabled) {
+ LOG.debug("<== PolicyParser validateEntity");
+ }
+ boolean isValidEntity = Pattern.matches("(.+:.+)+", entity);
+ boolean isEmpty = entity.isEmpty();
+ if (isValidEntity == false || isEmpty == true) {
+ if (isDebugEnabled) {
+ LOG.debug("group/user/resource not properly define in Policy");
+ LOG.debug("==> PolicyParser validateEntity");
+ }
+ return false;
+ } else {
+ if (isDebugEnabled) {
+ LOG.debug("==> PolicyParser validateEntity");
+ }
+ return true;
+ }
+
+ }
+
+ private void parseUsers(String usersDef, PolicyDef def) {
+ if (isDebugEnabled) {
+ LOG.debug("<== PolicyParser parseUsers");
+ }
+ String[] users = usersDef.split(",");
+ String[] userAndRole = null;
+ Map<String, List<AtlasActionTypes>> usersMap = new HashMap<String, List<AtlasActionTypes>>();
+ if (validateEntity(usersDef)) {
+ for (String user : users) {
+ if (!Pattern.matches("(.+:.+)+", user)) {
+ continue;
+ }
+ userAndRole = user.split(":");
+ if (def.getUsers() != null) {
+ usersMap = def.getUsers();
+ }
+ List<AtlasActionTypes> userAutorities = usersMap.get(userAndRole[USERNAME]);
+ if (userAutorities == null) {
+
+ userAutorities = new ArrayList<AtlasActionTypes>();
+ }
+ userAutorities = getListOfAutorities(userAndRole[USER_AUTHORITIES]);
+ usersMap.put(userAndRole[USERNAME], userAutorities);
+ def.setUsers(usersMap);
+ }
+
+ } else {
+ def.setUsers(usersMap);
+ }
+ if (isDebugEnabled) {
+ LOG.debug("==> PolicyParser parseUsers");
+ }
+ }
+
+ private void parseGroups(String groupsDef, PolicyDef def) {
+ if (isDebugEnabled) {
+ LOG.debug("<== PolicyParser parseGroups");
+ }
+ String[] groups = groupsDef.split("\\,");
+ String[] groupAndRole = null;
+ Map<String, List<AtlasActionTypes>> groupsMap = new HashMap<String, List<AtlasActionTypes>>();
+ if (validateEntity(groupsDef.trim())) {
+ for (String group : groups) {
+ if (!Pattern.matches("(.+:.+)+", group)) {
+ continue;
+ }
+ groupAndRole = group.split("[:]");
+ if (def.getGroups() != null) {
+ groupsMap = def.getGroups();
+ }
+ List<AtlasActionTypes> groupAutorities = groupsMap.get(groupAndRole[GROUPNAME]);
+ if (groupAutorities == null) {
+ groupAutorities = new ArrayList<AtlasActionTypes>();
+ }
+ groupAutorities = getListOfAutorities(groupAndRole[GROUP_AUTHORITIES]);
+ groupsMap.put(groupAndRole[GROUPNAME], groupAutorities);
+ def.setGroups(groupsMap);
+ }
+
+ } else {
+ def.setGroups(groupsMap);
+ }
+ if (isDebugEnabled) {
+ LOG.debug("==> PolicyParser parseGroups");
+ }
+
+ }
+
+ private void parseResources(String resourceDef, PolicyDef def) {
+ if (isDebugEnabled) {
+ LOG.debug("<== PolicyParser parseResources");
+ }
+ String[] resources = resourceDef.split(",");
+ String[] resourceTypeAndName = null;
+ Map<AtlasResourceTypes, List<String>> resourcesMap = new HashMap<AtlasResourceTypes, List<String>>();
+ if (validateEntity(resourceDef)) {
+ for (String resource : resources) {
+ if (!Pattern.matches("(.+:.+)+", resource)) {
+ continue;
+ }
+ resourceTypeAndName = resource.split("[:]");
+ if (def.getResources() != null) {
+ resourcesMap = def.getResources();
+ }
+ AtlasResourceTypes resourceType =
+ AtlasResourceTypes.valueOf(resourceTypeAndName[RESOURCE_TYPE].toUpperCase());
+ List<String> resourceList = resourcesMap.get(resourceType);
+ if (resourceList == null) {
+ resourceList = new ArrayList<String>();
+ }
+ resourceList.add(resourceTypeAndName[RESOURCE_NAME]);
+ resourcesMap.put(resourceType, resourceList);
+ def.setResources(resourcesMap);
+ }
+ } else {
+ def.setResources(resourcesMap);
+ }
+ if (isDebugEnabled) {
+ LOG.debug("==> PolicyParser parseResources");
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/a963e980/webapp/src/main/java/org/apache/atlas/authorize/PolicyUtil.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/authorize/PolicyUtil.java b/webapp/src/main/java/org/apache/atlas/authorize/PolicyUtil.java
new file mode 100644
index 0000000..a565f96
--- /dev/null
+++ b/webapp/src/main/java/org/apache/atlas/authorize/PolicyUtil.java
@@ -0,0 +1,164 @@
+/** 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 java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PolicyUtil {
+
+ private static Logger LOG = LoggerFactory.getLogger(PolicyUtil.class);
+ private static boolean isDebugEnabled = LOG.isDebugEnabled();
+ private Map<String, Map<AtlasResourceTypes, List<String>>> userReadMap;
+ private Map<String, Map<AtlasResourceTypes, List<String>>> userWriteMap;
+ private Map<String, Map<AtlasResourceTypes, List<String>>> userUpdateMap;
+ private Map<String, Map<AtlasResourceTypes, List<String>>> userDeleteMap;
+
+ private Map<String, Map<AtlasResourceTypes, List<String>>> groupReadMap;
+ private Map<String, Map<AtlasResourceTypes, List<String>>> groupWriteMap;
+ private Map<String, Map<AtlasResourceTypes, List<String>>> groupUpdateMap;
+ private Map<String, Map<AtlasResourceTypes, List<String>>> groupDeleteMap;
+
+ /**
+ * @return the userReadMap
+ */
+ public Map<String, Map<AtlasResourceTypes, List<String>>> getUserReadMap() {
+ return userReadMap;
+ }
+
+ /**
+ * @return the userWriteMap
+ */
+ public Map<String, Map<AtlasResourceTypes, List<String>>> getUserWriteMap() {
+ return userWriteMap;
+ }
+
+ /**
+ * @return the userUpdateMap
+ */
+ public Map<String, Map<AtlasResourceTypes, List<String>>> getUserUpdateMap() {
+ return userUpdateMap;
+ }
+
+ /**
+ * @return the userDeleteMap
+ */
+ public Map<String, Map<AtlasResourceTypes, List<String>>> getUserDeleteMap() {
+ return userDeleteMap;
+ }
+
+ /**
+ * @return the groupReadMap
+ */
+ public Map<String, Map<AtlasResourceTypes, List<String>>> getGroupReadMap() {
+ return groupReadMap;
+ }
+
+ /**
+ * @return the groupWriteMap
+ */
+ public Map<String, Map<AtlasResourceTypes, List<String>>> getGroupWriteMap() {
+ return groupWriteMap;
+ }
+
+ /**
+ * @return the groupUpdateMap
+ */
+ public Map<String, Map<AtlasResourceTypes, List<String>>> getGroupUpdateMap() {
+ return groupUpdateMap;
+ }
+
+ /**
+ * @return the groupDeleteMap
+ */
+ public Map<String, Map<AtlasResourceTypes, List<String>>> getGroupDeleteMap() {
+ return groupDeleteMap;
+ }
+
+ public Map<String, Map<AtlasResourceTypes, List<String>>> createPermissionMap(List<PolicyDef> policyDefList,
+ AtlasActionTypes permissionType, AtlasAccessorTypes principalType) {
+ if (isDebugEnabled) {
+ LOG.debug("<== PolicyUtil createPermissionMap");
+ LOG.debug("Creating Permission Map for :: " + permissionType + " & " + principalType);
+ }
+ Map<String, Map<AtlasResourceTypes, List<String>>> userReadMap =
+ new HashMap<String, Map<AtlasResourceTypes, List<String>>>();
+
+ // Iterate over the list of policies to create map
+ for (PolicyDef policyDef : policyDefList) {
+ LOG.info("Processing policy def : " + policyDef);
+ Map<String, List<AtlasActionTypes>> principalMap =
+ principalType.equals(AtlasAccessorTypes.USER) ? policyDef.getUsers() : policyDef.getGroups();
+ // For every policy extract the resource list and populate the user map
+ for (Entry<String, List<AtlasActionTypes>> e : principalMap.entrySet()) {
+ // Check if the user has passed permission type like READ
+ if (!e.getValue().contains(permissionType)) {
+ continue;
+ }
+ // See if the current user is already added to map
+ String username = e.getKey();
+ Map<AtlasResourceTypes, List<String>> userResourceList = userReadMap.get(username);
+
+ // If its not added then create a new resource list
+ if (userResourceList == null) {
+ if (isDebugEnabled) {
+ LOG.debug("Resource list not found for " + username + ", creating it");
+ }
+ userResourceList = new HashMap<AtlasResourceTypes, List<String>>();
+ }
+ /*
+ * Iterate over resources from the current policy def and update the resource list for the current user
+ */
+ for (Entry<AtlasResourceTypes, List<String>> resourceTypeMap : policyDef.getResources().entrySet()) {
+ // For the current resourceType in the policyDef, get the
+ // current list of resources already added
+ AtlasResourceTypes type = resourceTypeMap.getKey();
+ List<String> resourceList = userResourceList.get(type);
+
+ if (resourceList == null) {
+ // if the resource list was not added for this type then
+ // create and add all the resources in this policy
+ resourceList = new ArrayList<String>();
+ resourceList.addAll(resourceTypeMap.getValue());
+ } else {
+ // if the resource list is present then merge both the
+ // list
+ resourceList.removeAll(resourceTypeMap.getValue());
+ resourceList.addAll(resourceTypeMap.getValue());
+ }
+
+ userResourceList.put(type, resourceList);
+ }
+ userReadMap.put(username, userResourceList);
+ LOG.info("userReadMap=====>>>>>> " + userReadMap);
+ }
+ }
+ if (isDebugEnabled) {
+ LOG.debug("Returning Map for " + principalType + " :: " + userReadMap);
+ LOG.debug("==> PolicyUtil createPermissionMap");
+ }
+ return userReadMap;
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/a963e980/webapp/src/main/java/org/apache/atlas/authorize/SimpleAtlasAuthorizer.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/authorize/SimpleAtlasAuthorizer.java b/webapp/src/main/java/org/apache/atlas/authorize/SimpleAtlasAuthorizer.java
new file mode 100644
index 0000000..2a32e4e
--- /dev/null
+++ b/webapp/src/main/java/org/apache/atlas/authorize/SimpleAtlasAuthorizer.java
@@ -0,0 +1,380 @@
+/**
+ * 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 java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.atlas.ApplicationProperties;
+import org.apache.atlas.AtlasException;
+import org.apache.atlas.util.FileReaderUtil;
+import org.apache.atlas.util.PropertiesUtil;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.io.IOCase;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.annotations.VisibleForTesting;
+
+public final class SimpleAtlasAuthorizer implements AtlasAuthorizer {
+ private static final Logger LOG = LoggerFactory.getLogger(SimpleAtlasAuthorizer.class);
+ private boolean isDebugEnabled = LOG.isDebugEnabled();
+
+ private final static String WILDCARD_ASTERISK = "*";
+ private final static String WILDCARDS = "*?";
+ private boolean optIgnoreCase = false;
+
+ private Map<String, Map<AtlasResourceTypes, List<String>>> userReadMap = null;
+ private Map<String, Map<AtlasResourceTypes, List<String>>> userWriteMap = null;
+ private Map<String, Map<AtlasResourceTypes, List<String>>> userUpdateMap = null;
+ private Map<String, Map<AtlasResourceTypes, List<String>>> userDeleteMap = null;
+ private Map<String, Map<AtlasResourceTypes, List<String>>> groupReadMap = null;
+ private Map<String, Map<AtlasResourceTypes, List<String>>> groupWriteMap = null;
+ private Map<String, Map<AtlasResourceTypes, List<String>>> groupUpdateMap = null;
+ private Map<String, Map<AtlasResourceTypes, List<String>>> groupDeleteMap = null;
+ private static AtlasAuthorizer defaultAuthorizer = new SimpleAtlasAuthorizer();
+
+ private SimpleAtlasAuthorizer() {
+ }
+
+ public static AtlasAuthorizer getInstance() {
+ return defaultAuthorizer;
+ }
+
+ @Override
+ public void init() {
+ if (isDebugEnabled) {
+ LOG.debug("<== SimpleAtlasAuthorizer init");
+ }
+ try {
+
+ PolicyUtil util = new PolicyUtil();
+ PolicyParser parser = new PolicyParser();
+ optIgnoreCase = Boolean.valueOf(PropertiesUtil.getProperty("optIgnoreCase", "false"));
+
+ if (isDebugEnabled) {
+ LOG.debug("Read from PropertiesUtil --> optIgnoreCase :: " + optIgnoreCase);
+ }
+
+ Configuration configuration = ApplicationProperties.get();
+ String policyStorePath = configuration.getString("atlas.auth.policy.file");
+
+ if (isDebugEnabled) {
+ LOG.debug("Loading Apache Atlas policies from : " + policyStorePath);
+ }
+
+ List<String> policies = FileReaderUtil.readFile(policyStorePath);
+ List<PolicyDef> policyDef = parser.parsePolicies(policies);
+
+ userReadMap = util.createPermissionMap(policyDef, AtlasActionTypes.READ, AtlasAccessorTypes.USER);
+ userWriteMap = util.createPermissionMap(policyDef, AtlasActionTypes.WRITE, AtlasAccessorTypes.USER);
+ userUpdateMap = util.createPermissionMap(policyDef, AtlasActionTypes.UPDATE, AtlasAccessorTypes.USER);
+ userDeleteMap = util.createPermissionMap(policyDef, AtlasActionTypes.DELETE, AtlasAccessorTypes.USER);
+
+ groupReadMap = util.createPermissionMap(policyDef, AtlasActionTypes.READ, AtlasAccessorTypes.GROUP);
+ groupWriteMap = util.createPermissionMap(policyDef, AtlasActionTypes.WRITE, AtlasAccessorTypes.GROUP);
+ groupUpdateMap = util.createPermissionMap(policyDef, AtlasActionTypes.UPDATE, AtlasAccessorTypes.GROUP);
+ groupDeleteMap = util.createPermissionMap(policyDef, AtlasActionTypes.DELETE, AtlasAccessorTypes.GROUP);
+
+ if (isDebugEnabled) {
+ LOG.debug("\n\nUserReadMap :: " + userReadMap + "\nGroupReadMap :: " + groupReadMap);
+ LOG.debug("\n\nUserWriteMap :: " + userWriteMap + "\nGroupWriteMap :: " + groupWriteMap);
+ LOG.debug("\n\nUserUpdateMap :: " + userUpdateMap + "\nGroupUpdateMap :: " + groupUpdateMap);
+ LOG.debug("\n\nUserDeleteMap :: " + userDeleteMap + "\nGroupDeleteMap :: " + groupDeleteMap);
+ }
+
+ } catch (IOException | AtlasException e) {
+ if (LOG.isErrorEnabled()) {
+ LOG.error("SimpleAtlasAuthorizer could not be initialized properly due to : ", e);
+ }
+ }
+ }
+
+ @Override
+ public boolean isAccessAllowed(AtlasAccessRequest request) throws AtlasAuthorizationException {
+ if (isDebugEnabled) {
+ LOG.debug("<== SimpleAtlasAuthorizer isAccessAllowed");
+ LOG.debug("isAccessAllowd(" + request + ")");
+ }
+ String user = request.getUser();
+ List<String> groups = request.getUserGroups();
+ AtlasActionTypes action = request.getAction();
+ String resource = request.getResource();
+ List<AtlasResourceTypes> resourceTypes = request.getResourceTypes();
+ if (isDebugEnabled)
+ LOG.debug("Checking for :: \nUser :: " + user + "\nGroups :: " + groups + "\nAction :: " + action
+ + "\nResource :: " + resource);
+
+ boolean isAccessAllowed = false;
+ boolean isUser = user == null ? false : true;
+ boolean isGroup = groups == null ? false : true;
+
+ if ((!isUser && !isGroup) || action == null || resource == null) {
+ if (isDebugEnabled) {
+ LOG.debug("Please check the formation AtlasAccessRequest.");
+ }
+ return isAccessAllowed;
+ } else {
+ if (isDebugEnabled) {
+ LOG.debug("checkAccess for Operation :: " + action + " on Resource " + resourceTypes + ":" + resource);
+ }
+ switch (action) {
+ case READ:
+ isAccessAllowed = checkAccess(user, resourceTypes, resource, userReadMap);
+ isAccessAllowed =
+ isAccessAllowed == false ? checkAccessForGroups(groups, resourceTypes, resource, groupReadMap)
+ : isAccessAllowed;
+ break;
+ case WRITE:
+ isAccessAllowed = checkAccess(user, resourceTypes, resource, userWriteMap);
+ isAccessAllowed =
+ isAccessAllowed == false ? checkAccessForGroups(groups, resourceTypes, resource, groupWriteMap)
+ : isAccessAllowed;
+ break;
+ case UPDATE:
+ isAccessAllowed = checkAccess(user, resourceTypes, resource, userUpdateMap);
+ isAccessAllowed =
+ isAccessAllowed == false
+ ? checkAccessForGroups(groups, resourceTypes, resource, groupUpdateMap) : isAccessAllowed;
+ break;
+ case DELETE:
+ isAccessAllowed = checkAccess(user, resourceTypes, resource, userDeleteMap);
+ isAccessAllowed =
+ isAccessAllowed == false
+ ? checkAccessForGroups(groups, resourceTypes, resource, groupDeleteMap) : isAccessAllowed;
+ break;
+ default:
+ if (isDebugEnabled) {
+ LOG.debug("Invalid Action " + action);
+ LOG.debug("Raising an exception!!!");
+ }
+ throw new AtlasAuthorizationException("Invalid Exception :: " + action);
+ }
+ }
+
+ if (isDebugEnabled) {
+ LOG.debug("==> +SimpleAtlasAuthorizer isAccessAllowed = " + isAccessAllowed);
+ }
+
+ return isAccessAllowed;
+ }
+
+ private boolean checkAccess(String accessor, List<AtlasResourceTypes> resourceTypes, String resource,
+ Map<String, Map<AtlasResourceTypes, List<String>>> map) {
+ if (isDebugEnabled) {
+ LOG.debug("<== SimpleAtlasAuthorizer checkAccess");
+ LOG.debug("Now checking access for accessor : " + accessor + "\nResource Types : " + resourceTypes
+ + "\nResource : " + resource + "\nMap : " + map);
+ }
+ boolean result = true;
+ Map<AtlasResourceTypes, List<String>> rescMap = map.get(accessor);
+ if (rescMap != null) {
+ for (AtlasResourceTypes resourceType : resourceTypes) {
+ List<String> accessList = rescMap.get(resourceType);
+ if (isDebugEnabled) {
+ LOG.debug("\nChecking for resource : " + resource + " in list : " + accessList + "\n");
+ }
+ if (accessList != null) {
+ result = result && isMatch(resource, accessList);
+ } else {
+ result = false;
+ }
+ }
+ } else {
+ result = false;
+ if (isDebugEnabled)
+ LOG.debug("Key " + accessor + " missing. Returning with result : " + result);
+ }
+
+ if (isDebugEnabled) {
+ LOG.debug("Check for " + accessor + " :: " + result);
+ LOG.debug("==> SimpleAtlasAuthorizer checkAccess");
+ }
+ return result;
+ }
+
+ private boolean checkAccessForGroups(List<String> groups, List<AtlasResourceTypes> resourceType, String resource,
+ Map<String, Map<AtlasResourceTypes, List<String>>> map) {
+ boolean isAccessAllowed = false;
+ if (isDebugEnabled) {
+ LOG.debug("<== SimpleAtlasAuthorizer checkAccessForGroups");
+ }
+
+ for (String group : groups) {
+ isAccessAllowed = checkAccess(group, resourceType, resource, map);
+ if (isAccessAllowed) {
+ break;
+ }
+ }
+
+ if (isDebugEnabled) {
+ LOG.debug("==> SimpleAtlasAuthorizer checkAccessForGroups");
+ }
+ return isAccessAllowed;
+ }
+
+ private boolean resourceMatchHelper(List<String> policyResource) {
+ boolean isMatchAny = false;
+ if (isDebugEnabled) {
+ LOG.debug("<== SimpleAtlasAuthorizer resourceMatchHelper");
+ }
+
+ boolean optWildCard = true;
+
+ List<String> policyValues = new ArrayList<String>();
+
+ if (policyResource != null) {
+ boolean isWildCardPresent = !optWildCard;
+ for (String policyValue : policyResource) {
+ if (StringUtils.isEmpty(policyValue)) {
+ continue;
+ }
+ if (StringUtils.containsOnly(policyValue, WILDCARD_ASTERISK)) {
+ isMatchAny = true;
+ } else if (!isWildCardPresent && StringUtils.containsAny(policyValue, WILDCARDS)) {
+ isWildCardPresent = true;
+ }
+ policyValues.add(policyValue);
+ }
+ optWildCard = optWildCard && isWildCardPresent;
+ } else {
+ isMatchAny = false;
+ }
+
+ if (isDebugEnabled) {
+ LOG.debug("==> SimpleAtlasAuthorizer resourceMatchHelper");
+ }
+ return isMatchAny;
+ }
+
+ private boolean isMatch(String resource, List<String> policyValues) {
+ if (isDebugEnabled) {
+ LOG.debug("<== SimpleAtlasAuthorizer isMatch");
+ }
+ boolean isMatchAny = resourceMatchHelper(policyValues);
+ boolean isMatch = false;
+ boolean allValuesRequested = isAllValuesRequested(resource);
+
+ if (allValuesRequested || isMatchAny) {
+ isMatch = isMatchAny;
+ } else {
+ for (String policyValue : policyValues) {
+ if (policyValue.contains("*")) {
+ isMatch =
+ optIgnoreCase ? FilenameUtils.wildcardMatch(resource, policyValue, IOCase.INSENSITIVE)
+ : FilenameUtils.wildcardMatch(resource, policyValue, IOCase.SENSITIVE);
+ } else {
+ isMatch =
+ optIgnoreCase ? StringUtils.equalsIgnoreCase(resource, policyValue) : StringUtils.equals(
+ resource, policyValue);
+ }
+ if (isMatch) {
+ break;
+ }
+ }
+ }
+
+ if (isMatch == false) {
+
+ if (isDebugEnabled) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("[");
+ for (String policyValue : policyValues) {
+ sb.append(policyValue);
+ sb.append(" ");
+ }
+ sb.append("]");
+
+ LOG.debug("AtlasDefaultResourceMatcher.isMatch returns FALSE, (resource=" + resource
+ + ", policyValues=" + sb.toString() + ")");
+ }
+
+ }
+
+ if (isDebugEnabled) {
+ LOG.debug("==> SimpleAtlasAuthorizer isMatch(" + resource + "): " + isMatch);
+ }
+
+ return isMatch;
+ }
+
+ private boolean isAllValuesRequested(String resource) {
+ boolean result = StringUtils.isEmpty(resource) || WILDCARD_ASTERISK.equals(resource);
+ return result;
+ }
+
+ @Override
+ public void cleanUp() {
+ if (isDebugEnabled) {
+ LOG.debug("<== +SimpleAtlasAuthorizer cleanUp");
+ }
+ userReadMap = null;
+ userWriteMap = null;
+ userUpdateMap = null;
+ userDeleteMap = null;
+ groupReadMap = null;
+ groupWriteMap = null;
+ groupUpdateMap = null;
+ groupDeleteMap = null;
+ if (isDebugEnabled) {
+ LOG.debug("==> +SimpleAtlasAuthorizer cleanUp");
+ }
+ }
+
+ /*
+ * NOTE :: This method is added for setting the maps for testing purpose.
+ */
+ @VisibleForTesting
+ public void setResourcesForTesting(Map<String, Map<AtlasResourceTypes, List<String>>> userMap,
+ Map<String, Map<AtlasResourceTypes, List<String>>> groupMap, AtlasActionTypes actionTypes) {
+
+ switch (actionTypes) {
+ case READ:
+ this.userReadMap = userMap;
+ this.groupReadMap = groupMap;
+ break;
+
+ case WRITE:
+
+ this.userWriteMap = userMap;
+ this.groupWriteMap = groupMap;
+ break;
+ case UPDATE:
+
+ this.userUpdateMap = userMap;
+ this.groupUpdateMap = groupMap;
+ break;
+ case DELETE:
+
+ this.userDeleteMap = userMap;
+ this.groupDeleteMap = groupMap;
+ break;
+
+ default:
+ if (isDebugEnabled) {
+ LOG.debug("No such action available");
+ }
+ break;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/a963e980/webapp/src/main/java/org/apache/atlas/util/FileReaderUtil.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/util/FileReaderUtil.java b/webapp/src/main/java/org/apache/atlas/util/FileReaderUtil.java
new file mode 100644
index 0000000..22eaff9
--- /dev/null
+++ b/webapp/src/main/java/org/apache/atlas/util/FileReaderUtil.java
@@ -0,0 +1,56 @@
+/**
+ * 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.util;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import org.apache.log4j.Logger;
+
+public class FileReaderUtil {
+ private static Logger LOG = Logger.getLogger(FileReaderUtil.class);
+ private static boolean isDebugEnabled = LOG.isDebugEnabled();
+
+ public static List<String> readFile(String path) throws IOException {
+ if (isDebugEnabled) {
+ LOG.debug("<== FileReaderUtil readFile");
+ }
+ LOG.info("reading the file" + path);
+ BufferedReader br = new BufferedReader(new FileReader(path));
+ List<String> list = new ArrayList<String>();
+ String line = null;
+ while ((line = br.readLine()) != null) {
+ if ((!line.startsWith("##")) && Pattern.matches(".+;;.*;;.*;;.+", line))
+ list.add(line);
+ }
+
+ if (isDebugEnabled) {
+ LOG.debug("==> FileReaderUtil readFile");
+ LOG.debug("Policies read :: " + list);
+ }
+ if (br != null) {
+ br.close();
+ }
+ return list;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/a963e980/webapp/src/main/java/org/apache/atlas/web/filters/AtlasAuthorizationFilter.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/filters/AtlasAuthorizationFilter.java b/webapp/src/main/java/org/apache/atlas/web/filters/AtlasAuthorizationFilter.java
new file mode 100644
index 0000000..13fc7da
--- /dev/null
+++ b/webapp/src/main/java/org/apache/atlas/web/filters/AtlasAuthorizationFilter.java
@@ -0,0 +1,166 @@
+/*
+ * 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.web.filters;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.atlas.AtlasClient;
+import org.apache.atlas.AtlasException;
+import org.apache.atlas.authorize.AtlasAccessRequest;
+import org.apache.atlas.authorize.AtlasActionTypes;
+import org.apache.atlas.authorize.AtlasAuthorizationException;
+import org.apache.atlas.authorize.AtlasAuthorizer;
+import org.apache.atlas.authorize.AtlasResourceTypes;
+import org.apache.atlas.authorize.SimpleAtlasAuthorizer;
+import org.json.simple.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.web.filter.GenericFilterBean;
+import static org.apache.atlas.authorize.AtlasAuthorizationUtils.*;
+
+import com.google.common.base.Strings;
+
+public class AtlasAuthorizationFilter extends GenericFilterBean {
+
+ private static final Logger LOG = LoggerFactory.getLogger(AtlasAuthorizationFilter.class);
+ private static boolean isDebugEnabled = LOG.isDebugEnabled();
+ private AtlasAuthorizer authorizer = SimpleAtlasAuthorizer.getInstance();
+
+ private final String BASE_URL = "/" + AtlasClient.BASE_URI;
+
+ public AtlasAuthorizationFilter() {
+ if (isDebugEnabled) {
+ LOG.debug("<== AtlasAuthorizationFilter() -- " + "Now initializing the Apache Atlas Authorizer!!!");
+ }
+ authorizer.init();
+ }
+
+ @Override
+ public void destroy() {
+ if (isDebugEnabled) {
+ LOG.debug("<== AtlasAuthorizationFilter destroy");
+ }
+ authorizer.cleanUp();
+ super.destroy();
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException,
+ ServletException {
+ if (isDebugEnabled) {
+ LOG.debug("==> AuthorizationFilter.doFilter");
+ }
+
+ HttpServletRequest request = (HttpServletRequest) req;
+ String pathInfo = request.getServletPath();
+ if (pathInfo.startsWith(BASE_URL)) {
+ if (isDebugEnabled) {
+ LOG.debug(pathInfo + " is a valid REST API request!!!");
+ }
+
+ AtlasActionTypes action = getAtlasAction(request.getMethod());
+ String userName = null;
+ List<String> groups = new ArrayList<String>();
+ StringBuilder sb = new StringBuilder();
+
+ Authentication auth = SecurityContextHolder.getContext().getAuthentication();
+
+ if (auth != null) {
+ userName = String.valueOf(auth.getPrincipal());
+ Collection<? extends GrantedAuthority> authorities = auth.getAuthorities();
+ for (GrantedAuthority c : authorities) {
+ groups.add(c.getAuthority());
+ }
+ sb.append("============================\n");
+ sb.append("UserName ==>> " + userName + "\nGroups ==>> " + groups);
+ } else {
+ if (LOG.isErrorEnabled()) {
+ LOG.error("Cannot obtain Security Context : " + auth);
+ }
+ throw new ServletException("Cannot obtain Security Context : " + auth);
+ }
+
+ sb.append("\n" + "URL :: " + request.getRequestURL() + " Action :: " + action);
+ sb.append("\nrequest.getServletPath() :: " + pathInfo);
+ sb.append("\n============================\n");
+
+ if (isDebugEnabled) {
+ LOG.debug(sb.toString());
+ }
+ sb = null;
+ List<AtlasResourceTypes> atlasResourceType = getAtlasResourceType(pathInfo);
+ String resource = getAtlasResource(request, action);
+ AtlasAccessRequest atlasRequest =
+ new AtlasAccessRequest(atlasResourceType, resource, action, userName, groups);
+ boolean accessAllowed = false;
+ try {
+ accessAllowed = authorizer.isAccessAllowed(atlasRequest);
+ } catch (AtlasAuthorizationException e) {
+ if (LOG.isErrorEnabled()) {
+ LOG.error("Access Restricted. Could not process the request due to : " + e);
+ }
+ }
+ if (isDebugEnabled) {
+ LOG.debug("Authorizer result :: " + accessAllowed);
+ }
+ if (accessAllowed) {
+ if (isDebugEnabled) {
+ LOG.debug("Access is allowed so forwarding the request!!!");
+ }
+ chain.doFilter(req, res);
+ } else {
+ JSONObject json = new JSONObject();
+ json.put("AuthorizationError", "Sorry you are not authorized for " + action.name() + " on "
+ + atlasResourceType + " : " + resource);
+ HttpServletResponse response = (HttpServletResponse) res;
+ response.setContentType("application/json");
+ response.setStatus(HttpServletResponse.SC_FORBIDDEN);
+
+ response.sendError(HttpServletResponse.SC_FORBIDDEN, json.toString());
+ if (isDebugEnabled) {
+ LOG.debug("Sorry you are not authorized for " + action.name() + " on " + atlasResourceType + " : "
+ + resource);
+ LOG.debug("Returning 403 since the access is blocked update!!!!");
+ }
+ return;
+ }
+
+ } else {
+ if (isDebugEnabled) {
+ LOG.debug("Ignoring request " + pathInfo);
+ }
+ chain.doFilter(req, res);
+ }
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/a963e980/webapp/src/main/resources/spring-security.xml
----------------------------------------------------------------------
diff --git a/webapp/src/main/resources/spring-security.xml b/webapp/src/main/resources/spring-security.xml
index d90b9d6..4590eef 100644
--- a/webapp/src/main/resources/spring-security.xml
+++ b/webapp/src/main/resources/spring-security.xml
@@ -49,6 +49,7 @@
<security:logout logout-success-url="/login.jsp" delete-cookies="JSESSIONID"
logout-url="/logout.html" />
<http-basic />
+ <security:custom-filter position="LAST" ref="atlasAuthorizationFilter"/>
</security:http>
<beans:bean id="formAuthenticationEntryPoint"
@@ -86,4 +87,6 @@
pre-post-annotations="enabled" />
<context:component-scan base-package="org.apache.atlas.web" />
+
+ <beans:bean id = "atlasAuthorizationFilter" class="org.apache.atlas.web.filters.AtlasAuthorizationFilter"/>
</beans:beans>
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/a963e980/webapp/src/test/java/org/apache/atlas/authorize/PolicyParserTest.java
----------------------------------------------------------------------
diff --git a/webapp/src/test/java/org/apache/atlas/authorize/PolicyParserTest.java b/webapp/src/test/java/org/apache/atlas/authorize/PolicyParserTest.java
new file mode 100644
index 0000000..507d4c6
--- /dev/null
+++ b/webapp/src/test/java/org/apache/atlas/authorize/PolicyParserTest.java
@@ -0,0 +1,167 @@
+/*
+ * 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 static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.testng.annotations.Test;
+
+public class PolicyParserTest {
+
+ @Test
+ public void testParsePoliciesWithAllProperties() {
+ List<String> policies = new ArrayList<String>();
+ policies.add("hivePolicy;;usr1:r,usr2:rw;;grp1:rwu,grp2:u;;entity:*abc,operation:*xyz,type:PII");
+ /* Creating group data */
+ Map<String, List<AtlasActionTypes>> groupMap = new HashMap<String, List<AtlasActionTypes>>();
+ List<AtlasActionTypes> accessList1 = new ArrayList<AtlasActionTypes>();
+ accessList1.add(AtlasActionTypes.READ);
+ accessList1.add(AtlasActionTypes.WRITE);
+ accessList1.add(AtlasActionTypes.UPDATE);
+
+ groupMap.put("grp1", accessList1);
+ List<AtlasActionTypes> accessList2 = new ArrayList<AtlasActionTypes>();
+ accessList2.add(AtlasActionTypes.UPDATE);
+ groupMap.put("grp2", accessList2);
+
+ /* Creating user data */
+ Map<String, List<AtlasActionTypes>> usersMap = new HashMap<String, List<AtlasActionTypes>>();
+ List<AtlasActionTypes> usr1AccessList = new ArrayList<AtlasActionTypes>();
+ usr1AccessList.add(AtlasActionTypes.READ);
+ usersMap.put("usr1", usr1AccessList);
+
+ List<AtlasActionTypes> usr2AccessList = new ArrayList<AtlasActionTypes>();
+ usr2AccessList.add(AtlasActionTypes.READ);
+ usr2AccessList.add(AtlasActionTypes.WRITE);
+ usersMap.put("usr2", usr2AccessList);
+
+ /* Creating resources data */
+ Map<AtlasResourceTypes, List<String>> resourceMap = new HashMap<AtlasResourceTypes, List<String>>();
+ List<String> resource1List = new ArrayList<String>();
+ resource1List.add("*abc");
+ resourceMap.put(AtlasResourceTypes.ENTITY, resource1List);
+
+ List<String> resource2List = new ArrayList<String>();
+ resource2List.add("*xyz");
+ resourceMap.put(AtlasResourceTypes.OPERATION, resource2List);
+
+ List<String> resource3List = new ArrayList<String>();
+ resource3List.add("PII");
+ resourceMap.put(AtlasResourceTypes.TYPE, resource3List);
+
+ List<PolicyDef> policyDefs = new PolicyParser().parsePolicies(policies);
+ for (PolicyDef def : policyDefs) {
+
+ assertEquals(def.getPolicyName(), "hivePolicy");
+ assertEquals(def.getGroups(), groupMap);
+ assertEquals(def.getUsers(), usersMap);
+ assertEquals(def.getResources(), resourceMap);
+
+ }
+
+ }
+
+ @Test
+ public void testParsePoliciesWithOutUserProperties() {
+ List<String> policies = new ArrayList<String>();
+ policies.add("hivePolicy;;;;grp1:rwu,grp2:u;;entity:*abc,operation:*xyz,type:PII");
+ // Creating group data
+ Map<String, List<AtlasActionTypes>> groupMap = new HashMap<String, List<AtlasActionTypes>>();
+ List<AtlasActionTypes> accessList1 = new ArrayList<AtlasActionTypes>();
+ accessList1.add(AtlasActionTypes.READ);
+ accessList1.add(AtlasActionTypes.WRITE);
+ accessList1.add(AtlasActionTypes.UPDATE);
+
+ groupMap.put("grp1", accessList1);
+ List<AtlasActionTypes> accessList2 = new ArrayList<AtlasActionTypes>();
+ accessList2.add(AtlasActionTypes.UPDATE);
+ groupMap.put("grp2", accessList2);
+
+ // Creating user data
+ Map<String, List<AtlasActionTypes>> usersMap = new HashMap<String, List<AtlasActionTypes>>();
+
+ // Creating resources data
+ Map<AtlasResourceTypes, List<String>> resourceMap = new HashMap<AtlasResourceTypes, List<String>>();
+ List<String> resource1List = new ArrayList<String>();
+ resource1List.add("*abc");
+ resourceMap.put(AtlasResourceTypes.ENTITY, resource1List);
+
+ List<String> resource2List = new ArrayList<String>();
+ resource2List.add("*xyz");
+ resourceMap.put(AtlasResourceTypes.OPERATION, resource2List);
+
+ List<String> resource3List = new ArrayList<String>();
+ resource3List.add("PII");
+ resourceMap.put(AtlasResourceTypes.TYPE, resource3List);
+
+ List<PolicyDef> policyDefs = new PolicyParser().parsePolicies(policies);
+ for (PolicyDef def : policyDefs) {
+
+ assertEquals(def.getPolicyName(), "hivePolicy");
+ assertEquals(def.getGroups(), groupMap);
+ assertEquals(def.getUsers(), usersMap);
+ assertEquals(def.getResources(), resourceMap);
+
+ }
+
+ }
+
+ @Test
+ public void testParsePoliciesWithOutGroupProperties() {
+ List<String> policies = new ArrayList<String>();
+ policies.add("hivePolicy;;usr1:r,usr2:rw;;;;entity:*abc,operation:*xyz,type:PII");
+ // Creating group data
+ Map<String, List<AtlasActionTypes>> groupMap = new HashMap<String, List<AtlasActionTypes>>();
+
+ // Creating user data
+ Map<String, List<AtlasActionTypes>> usersMap = new HashMap<String, List<AtlasActionTypes>>();
+ List<AtlasActionTypes> usr1AccessList = new ArrayList<AtlasActionTypes>();
+ usr1AccessList.add(AtlasActionTypes.READ);
+ usersMap.put("usr1", usr1AccessList);
+
+ List<AtlasActionTypes> usr2AccessList = new ArrayList<AtlasActionTypes>();
+ usr2AccessList.add(AtlasActionTypes.READ);
+ usr2AccessList.add(AtlasActionTypes.WRITE);
+ usersMap.put("usr2", usr2AccessList);
+
+ // Creating resources data
+ Map<AtlasResourceTypes, List<String>> resourceMap = new HashMap<AtlasResourceTypes, List<String>>();
+ List<String> resource1List = new ArrayList<String>();
+ resource1List.add("*abc");
+ resourceMap.put(AtlasResourceTypes.ENTITY, resource1List);
+
+ List<String> resource2List = new ArrayList<String>();
+ resource2List.add("*xyz");
+ resourceMap.put(AtlasResourceTypes.OPERATION, resource2List);
+
+ List<String> resource3List = new ArrayList<String>();
+ resource3List.add("PII");
+ resourceMap.put(AtlasResourceTypes.TYPE, resource3List);
+
+ List<PolicyDef> policyDefs = new PolicyParser().parsePolicies(policies);
+ for (PolicyDef def : policyDefs) {
+ assertEquals(def.getPolicyName(), "hivePolicy");
+ assertEquals(def.getGroups(), groupMap);
+ assertEquals(def.getUsers(), usersMap);
+ assertEquals(def.getResources(), resourceMap);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/a963e980/webapp/src/test/java/org/apache/atlas/authorize/PolicyUtilTest.java
----------------------------------------------------------------------
diff --git a/webapp/src/test/java/org/apache/atlas/authorize/PolicyUtilTest.java b/webapp/src/test/java/org/apache/atlas/authorize/PolicyUtilTest.java
new file mode 100644
index 0000000..59e88c9
--- /dev/null
+++ b/webapp/src/test/java/org/apache/atlas/authorize/PolicyUtilTest.java
@@ -0,0 +1,95 @@
+/*
+ * 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 static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.testng.annotations.Test;
+
+public class PolicyUtilTest {
+
+ @Test
+ public void testCreatePermissionMap() {
+
+ HashMap<AtlasResourceTypes, List<String>> resourceMap = new HashMap<AtlasResourceTypes, List<String>>();
+ List<String> resource1List = new ArrayList<String>();
+ resource1List.add("*abc");
+ resourceMap.put(AtlasResourceTypes.ENTITY, resource1List);
+
+ List<String> resource2List = new ArrayList<String>();
+ resource2List.add("*xyz");
+ resourceMap.put(AtlasResourceTypes.OPERATION, resource2List);
+
+ List<String> resource3List = new ArrayList<String>();
+ resource3List.add("PII");
+ resourceMap.put(AtlasResourceTypes.TYPE, resource3List);
+
+ Map<String, HashMap<AtlasResourceTypes, List<String>>> permissionMap =
+ new HashMap<String, HashMap<AtlasResourceTypes, List<String>>>();
+ permissionMap.put("grp1", resourceMap);
+
+ List<String> policies = new ArrayList<String>();
+ policies.add("hivePolicy;;usr1:r,usr2:rw;;grp1:rwu,grp2:u;;entity:*abc,operation:*xyz,type:PII");
+ List<PolicyDef> policyDefList = new PolicyParser().parsePolicies(policies);
+
+ Map<String, Map<AtlasResourceTypes, List<String>>> createdPermissionMap =
+ new PolicyUtil().createPermissionMap(policyDefList, AtlasActionTypes.READ, AtlasAccessorTypes.GROUP);
+
+ assertEquals(permissionMap, createdPermissionMap);
+
+ }
+
+ @Test
+ public void testMergeCreatePermissionMap() {
+
+ HashMap<AtlasResourceTypes, List<String>> resourceMap = new HashMap<AtlasResourceTypes, List<String>>();
+ List<String> resource1List = new ArrayList<String>();
+ resource1List.add("*abc");
+ resourceMap.put(AtlasResourceTypes.ENTITY, resource1List);
+
+ List<String> resource2List = new ArrayList<String>();
+ resource2List.add("*x");
+ resource2List.add("*xyz");
+ resourceMap.put(AtlasResourceTypes.OPERATION, resource2List);
+
+ List<String> resource3List = new ArrayList<String>();
+ resource3List.add("PII");
+ resourceMap.put(AtlasResourceTypes.TYPE, resource3List);
+
+ Map<String, HashMap<AtlasResourceTypes, List<String>>> permissionMap =
+ new HashMap<String, HashMap<AtlasResourceTypes, List<String>>>();
+ permissionMap.put("grp1", resourceMap);
+
+ List<String> policies = new ArrayList<String>();
+ policies.add("hivePolicys;;;;grp1:rwu;;entity:*abc,operation:*xyz,operation:*x");
+ policies.add("hivePolicy;;;;grp1:rwu;;entity:*abc,operation:*xyz");
+ policies.add("hivePolicy;;usr1:r,usr2:rw;;grp1:rwu;;entity:*abc,operation:*xyz");
+ policies.add("hivePolicy;;usr1:r,usr2:rw;;grp1:rwu,grp2:u;;entity:*abc,operation:*xyz,type:PII");
+ List<PolicyDef> policyDefList = new PolicyParser().parsePolicies(policies);
+
+ Map<String, Map<AtlasResourceTypes, List<String>>> createdPermissionMap =
+ new PolicyUtil().createPermissionMap(policyDefList, AtlasActionTypes.READ, AtlasAccessorTypes.GROUP);
+
+ assertEquals(permissionMap, createdPermissionMap);
+
+ }
+}