sentry-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From br...@apache.org
Subject git commit: SENTRY-42 - Create sentry-provider-policy-search module - RoleValidators, Permissions, Authorizables (Gregory Chanan via Brock Noland)
Date Thu, 10 Oct 2013 04:13:19 GMT
Updated Branches:
  refs/heads/master 224aa8c8b -> ed7b7539f


SENTRY-42 - Create sentry-provider-policy-search module - RoleValidators, Permissions, Authorizables
(Gregory Chanan via Brock Noland)


Project: http://git-wip-us.apache.org/repos/asf/incubator-sentry/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-sentry/commit/ed7b7539
Tree: http://git-wip-us.apache.org/repos/asf/incubator-sentry/tree/ed7b7539
Diff: http://git-wip-us.apache.org/repos/asf/incubator-sentry/diff/ed7b7539

Branch: refs/heads/master
Commit: ed7b7539f1fc8f18784a4a5b6222e73253f57769
Parents: 224aa8c
Author: Brock Noland <brock@apache.org>
Authored: Wed Oct 9 23:13:10 2013 -0500
Committer: Brock Noland <brock@apache.org>
Committed: Wed Oct 9 23:13:10 2013 -0500

----------------------------------------------------------------------
 pom.xml                                         |   5 +
 sentry-dist/pom.xml                             |   4 +
 sentry-dist/src/main/assembly/src.xml           |   1 +
 sentry-provider/pom.xml                         |   1 +
 .../sentry-provider-policy-search/pom.xml       |  66 ++++++
 .../search/AbstractSearchRoleValidator.java     |  50 +++++
 .../search/CollectionRequiredInRole.java        |  44 ++++
 .../search/SearchModelAuthorizables.java        |  48 +++++
 .../search/SearchWildcardPermission.java        | 152 ++++++++++++++
 .../search/TestCollectionRequiredInRole.java    |  62 ++++++
 .../search/TestSearchModelAuthorizables.java    |  60 ++++++
 .../search/TestSearchWildcardPermission.java    | 206 +++++++++++++++++++
 12 files changed, 699 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/ed7b7539/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index d266e26..9b73a21 100644
--- a/pom.xml
+++ b/pom.xml
@@ -257,6 +257,11 @@ limitations under the License.
       </dependency>
       <dependency>
         <groupId>org.apache.sentry</groupId>
+        <artifactId>sentry-provider-policy-search</artifactId>
+        <version>${project.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.sentry</groupId>
         <artifactId>sentry-dist</artifactId>
         <version>${project.version}</version>
       </dependency>

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/ed7b7539/sentry-dist/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-dist/pom.xml b/sentry-dist/pom.xml
index e9fbdfd..b398ce0 100644
--- a/sentry-dist/pom.xml
+++ b/sentry-dist/pom.xml
@@ -50,6 +50,10 @@ limitations under the License.
       <groupId>org.apache.sentry</groupId>
       <artifactId>sentry-provider-policy-db</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.apache.sentry</groupId>
+      <artifactId>sentry-provider-policy-search</artifactId>
+    </dependency>
   </dependencies>
   <build>
     <plugins>

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/ed7b7539/sentry-dist/src/main/assembly/src.xml
----------------------------------------------------------------------
diff --git a/sentry-dist/src/main/assembly/src.xml b/sentry-dist/src/main/assembly/src.xml
index 2bd52e7..60ec346 100644
--- a/sentry-dist/src/main/assembly/src.xml
+++ b/sentry-dist/src/main/assembly/src.xml
@@ -45,6 +45,7 @@
         <include>org.apache.sentry:sentry-provider</include>
         <include>org.apache.sentry:sentry-provider-file</include>
         <include>org.apache.sentry:sentry-provider-policy-db</include>
+        <include>org.apache.sentry:sentry-provider-policy-search</include>
         <include>org.apache.sentry:sentry-tests</include>
         <include>org.apache.sentry:sentry-tests-hive</include>
         <include>org.apache.sentry:sentry-dist</include>

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/ed7b7539/sentry-provider/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-provider/pom.xml b/sentry-provider/pom.xml
index 0eaabbd..2667312 100644
--- a/sentry-provider/pom.xml
+++ b/sentry-provider/pom.xml
@@ -32,6 +32,7 @@ limitations under the License.
   <modules>
     <module>sentry-provider-file</module>
     <module>sentry-provider-policy-db</module>
+    <module>sentry-provider-policy-search</module>
   </modules>
 
 </project>

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/ed7b7539/sentry-provider/sentry-provider-policy-search/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-policy-search/pom.xml b/sentry-provider/sentry-provider-policy-search/pom.xml
new file mode 100644
index 0000000..5156c2c
--- /dev/null
+++ b/sentry-provider/sentry-provider-policy-search/pom.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0"?>
+<!--
+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.
+-->
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.sentry</groupId>
+    <artifactId>sentry-provider</artifactId>
+    <version>1.3.0-incubating-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>sentry-provider-policy-search</artifactId>
+  <name>Sentry Provider and Policy for Search</name>
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>log4j</groupId>
+      <artifactId>log4j</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.shiro</groupId>
+      <artifactId>shiro-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-log4j12</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.sentry</groupId>
+      <artifactId>sentry-core-model-search</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.sentry</groupId>
+      <artifactId>sentry-provider-file</artifactId>
+    </dependency>
+  </dependencies>
+
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/ed7b7539/sentry-provider/sentry-provider-policy-search/src/main/java/org/apache/sentry/provider/search/AbstractSearchRoleValidator.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-policy-search/src/main/java/org/apache/sentry/provider/search/AbstractSearchRoleValidator.java
b/sentry-provider/sentry-provider-policy-search/src/main/java/org/apache/sentry/provider/search/AbstractSearchRoleValidator.java
new file mode 100644
index 0000000..b0134bd
--- /dev/null
+++ b/sentry-provider/sentry-provider-policy-search/src/main/java/org/apache/sentry/provider/search/AbstractSearchRoleValidator.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.sentry.provider.search;
+
+import static org.apache.sentry.provider.file.PolicyFileConstants.AUTHORIZABLE_SPLITTER;
+import static org.apache.sentry.provider.file.PolicyFileConstants.PRIVILEGE_PREFIX;
+
+import java.util.List;
+
+import org.apache.sentry.provider.file.RoleValidator;
+import org.apache.sentry.core.model.search.SearchModelAuthorizable;
+import org.apache.shiro.config.ConfigurationException;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Lists;
+
+public abstract class AbstractSearchRoleValidator implements RoleValidator {
+
+  @VisibleForTesting
+  public static Iterable<SearchModelAuthorizable> parseRole(String string) {
+    List<SearchModelAuthorizable> result = Lists.newArrayList();
+    for(String section : AUTHORIZABLE_SPLITTER.split(string)) {
+      // XXX this ugly hack is because action is not an authorizeable
+      if(!section.toLowerCase().startsWith(PRIVILEGE_PREFIX)) {
+        SearchModelAuthorizable authorizable = SearchModelAuthorizables.from(section);
+        if(authorizable == null) {
+          String msg = "No authorizable found for " + section;
+          throw new ConfigurationException(msg);
+        }
+        result.add(authorizable);
+      }
+    }
+    return result;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/ed7b7539/sentry-provider/sentry-provider-policy-search/src/main/java/org/apache/sentry/provider/search/CollectionRequiredInRole.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-policy-search/src/main/java/org/apache/sentry/provider/search/CollectionRequiredInRole.java
b/sentry-provider/sentry-provider-policy-search/src/main/java/org/apache/sentry/provider/search/CollectionRequiredInRole.java
new file mode 100644
index 0000000..c803a81
--- /dev/null
+++ b/sentry-provider/sentry-provider-policy-search/src/main/java/org/apache/sentry/provider/search/CollectionRequiredInRole.java
@@ -0,0 +1,44 @@
+/*
+ * 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.sentry.provider.search;
+
+import javax.annotation.Nullable;
+
+import org.apache.sentry.core.model.search.Collection;
+import org.apache.sentry.core.model.search.SearchModelAuthorizable;
+import org.apache.shiro.config.ConfigurationException;
+
+public class CollectionRequiredInRole extends AbstractSearchRoleValidator {
+
+  @Override
+  public void validate(@Nullable String database, String role) throws ConfigurationException
{
+    Iterable<SearchModelAuthorizable> authorizables = parseRole(role);
+    boolean foundCollectionInAuthorizables = false;
+
+    for(SearchModelAuthorizable authorizable : authorizables) {
+      if(authorizable instanceof Collection) {
+        foundCollectionInAuthorizables = true;
+        break;
+      }
+    }
+
+    if(!foundCollectionInAuthorizables) {
+      String msg = "Missing collection object in " + role;
+      throw new ConfigurationException(msg);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/ed7b7539/sentry-provider/sentry-provider-policy-search/src/main/java/org/apache/sentry/provider/search/SearchModelAuthorizables.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-policy-search/src/main/java/org/apache/sentry/provider/search/SearchModelAuthorizables.java
b/sentry-provider/sentry-provider-policy-search/src/main/java/org/apache/sentry/provider/search/SearchModelAuthorizables.java
new file mode 100644
index 0000000..41917a6
--- /dev/null
+++ b/sentry-provider/sentry-provider-policy-search/src/main/java/org/apache/sentry/provider/search/SearchModelAuthorizables.java
@@ -0,0 +1,48 @@
+/*
+ * 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.sentry.provider.search;
+
+import org.apache.sentry.core.model.search.Collection;
+import org.apache.sentry.core.model.search.SearchModelAuthorizable;
+import org.apache.sentry.core.model.search.SearchModelAuthorizable.AuthorizableType;
+import org.apache.sentry.provider.file.KeyValue;
+
+public class SearchModelAuthorizables {
+
+  public static SearchModelAuthorizable from(KeyValue keyValue) {
+    String prefix = keyValue.getKey().toLowerCase();
+    String name = keyValue.getValue().toLowerCase();
+    for(AuthorizableType type : AuthorizableType.values()) {
+      if(prefix.equalsIgnoreCase(type.name())) {
+        return from(type, name);
+      }
+    }
+    return null;
+  }
+  public static SearchModelAuthorizable from(String s) {
+    return from(new KeyValue(s));
+  }
+
+  private static SearchModelAuthorizable from(AuthorizableType type, String name) {
+    switch (type) {
+    case Collection:
+      return new Collection(name);
+    default:
+      return null;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/ed7b7539/sentry-provider/sentry-provider-policy-search/src/main/java/org/apache/sentry/provider/search/SearchWildcardPermission.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-policy-search/src/main/java/org/apache/sentry/provider/search/SearchWildcardPermission.java
b/sentry-provider/sentry-provider-policy-search/src/main/java/org/apache/sentry/provider/search/SearchWildcardPermission.java
new file mode 100644
index 0000000..427ed2b
--- /dev/null
+++ b/sentry-provider/sentry-provider-policy-search/src/main/java/org/apache/sentry/provider/search/SearchWildcardPermission.java
@@ -0,0 +1,152 @@
+/*
+ * 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.
+ */
+
+// copied from apache shiro
+
+package org.apache.sentry.provider.search;
+
+import static org.apache.sentry.provider.file.PolicyFileConstants.AUTHORIZABLE_JOINER;
+import static org.apache.sentry.provider.file.PolicyFileConstants.AUTHORIZABLE_SPLITTER;
+
+import java.io.Serializable;
+import java.util.List;
+
+import org.apache.sentry.core.model.search.SearchConstants;
+import org.apache.sentry.provider.file.KeyValue;
+import org.apache.sentry.provider.file.PermissionFactory;
+import org.apache.sentry.provider.file.PolicyFileConstants;
+import org.apache.shiro.authz.Permission;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+
+public class SearchWildcardPermission implements Permission, Serializable {
+  private static final Logger LOGGER = LoggerFactory
+      .getLogger(SearchWildcardPermission.class);
+  private static final long serialVersionUID = -6785051263922740819L;
+
+  private final ImmutableList<KeyValue> parts;
+
+  public SearchWildcardPermission(String wildcardString) {
+    wildcardString = Strings.nullToEmpty(wildcardString).trim();
+    if (wildcardString.isEmpty()) {
+      throw new IllegalArgumentException("Wildcard string cannot be null or empty.");
+    }
+    List<KeyValue>parts = Lists.newArrayList();
+    for (String authorizable : AUTHORIZABLE_SPLITTER.trimResults().split(wildcardString))
{
+      if (authorizable.isEmpty()) {
+        throw new IllegalArgumentException("Privilege '" + wildcardString + "' has an empty
section");
+      }
+      parts.add(new KeyValue(authorizable));
+    }
+    if (parts.isEmpty()) {
+      throw new AssertionError("Should never occur: " + wildcardString);
+    }
+    this.parts = ImmutableList.copyOf(parts);
+  }
+
+
+  @Override
+  public boolean implies(Permission p) {
+    // By default only supports comparisons with other SearchWildcardPermissions
+    if (!(p instanceof SearchWildcardPermission)) {
+      return false;
+    }
+
+    SearchWildcardPermission wp = (SearchWildcardPermission) p;
+
+    List<KeyValue> otherParts = wp.parts;
+    if(equals(wp)) {
+      return true;
+    }
+    int index = 0;
+    for (KeyValue otherPart : otherParts) {
+      // If this permission has less parts than the other permission, everything
+      // after the number of parts contained
+      // in this permission is automatically implied, so return true
+      if (parts.size() - 1 < index) {
+        return true;
+      } else {
+        KeyValue part = parts.get(index);
+        // are the keys even equal
+        if(!part.getKey().equalsIgnoreCase(otherPart.getKey())) {
+          return false;
+        }
+        if (!impliesKeyValue(part, otherPart)) {
+          return false;
+        }
+        index++;
+      }
+    }
+    // If this permission has more parts than
+    // the other parts, only imply it if
+    // all of the other parts are wildcards
+    for (; index < parts.size(); index++) {
+      KeyValue part = parts.get(index);
+      if (!part.getValue().equals(SearchConstants.ALL)) {
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+  private boolean impliesKeyValue(KeyValue policyPart, KeyValue requestPart) {
+    Preconditions.checkState(policyPart.getKey().equalsIgnoreCase(requestPart.getKey()),
+        "Please report, this method should not be called with two different keys");
+    if(policyPart.getValue().equals(SearchConstants.ALL) || policyPart.equals(requestPart))
{
+      return true;
+    } else if (!PolicyFileConstants.PRIVILEGE_NAME.equalsIgnoreCase(policyPart.getKey())
+        && SearchConstants.ALL.equalsIgnoreCase(requestPart.getValue())) {
+      /* permission request is to match with any object of given type */
+      return true;
+    }
+    return false;
+  }
+
+  @Override
+  public String toString() {
+    return AUTHORIZABLE_JOINER.join(parts);
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (o instanceof SearchWildcardPermission) {
+      SearchWildcardPermission wp = (SearchWildcardPermission) o;
+      return parts.equals(wp.parts);
+    }
+    return false;
+  }
+
+  @Override
+  public int hashCode() {
+    return parts.hashCode();
+  }
+
+  public static class SearchWildcardPermissionFactory implements PermissionFactory {
+    @Override
+    public Permission createPermission(String permission) {
+      return new SearchWildcardPermission(permission);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/ed7b7539/sentry-provider/sentry-provider-policy-search/src/test/java/org/apache/sentry/provider/search/TestCollectionRequiredInRole.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-policy-search/src/test/java/org/apache/sentry/provider/search/TestCollectionRequiredInRole.java
b/sentry-provider/sentry-provider-policy-search/src/test/java/org/apache/sentry/provider/search/TestCollectionRequiredInRole.java
new file mode 100644
index 0000000..0055250
--- /dev/null
+++ b/sentry-provider/sentry-provider-policy-search/src/test/java/org/apache/sentry/provider/search/TestCollectionRequiredInRole.java
@@ -0,0 +1,62 @@
+/*
+ * 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.sentry.provider.search;
+
+import junit.framework.Assert;
+
+import org.apache.shiro.config.ConfigurationException;
+import org.junit.Test;
+
+public class TestCollectionRequiredInRole {
+
+  @Test
+  public void testEmptyRole() throws Exception {
+    CollectionRequiredInRole collRequiredInRole = new CollectionRequiredInRole();
+
+    // check no db
+    try {
+      collRequiredInRole.validate(null,"index=index1");
+      Assert.fail("Expected ConfigurationException");
+    } catch (ConfigurationException e) {
+      ;
+    }
+
+    // check with db
+    try {
+      collRequiredInRole.validate("db1","index=index2");
+      Assert.fail("Expected ConfigurationException");
+    } catch (ConfigurationException e) {
+      ;
+    }
+  }
+
+  @Test
+  public void testCollectionWithoutAction() throws Exception {
+    CollectionRequiredInRole collRequiredInRole = new CollectionRequiredInRole();
+    collRequiredInRole.validate(null,"collection=nodb");
+    collRequiredInRole.validate("db2","collection=db");
+  }
+
+  @Test
+  public void testCollectionWithAction() throws Exception {
+    CollectionRequiredInRole collRequiredInRole = new CollectionRequiredInRole();
+    collRequiredInRole.validate(null,"collection=nodb->action=query");
+    collRequiredInRole.validate("db2","collection=db->action=update");
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/ed7b7539/sentry-provider/sentry-provider-policy-search/src/test/java/org/apache/sentry/provider/search/TestSearchModelAuthorizables.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-policy-search/src/test/java/org/apache/sentry/provider/search/TestSearchModelAuthorizables.java
b/sentry-provider/sentry-provider-policy-search/src/test/java/org/apache/sentry/provider/search/TestSearchModelAuthorizables.java
new file mode 100644
index 0000000..a79d9df
--- /dev/null
+++ b/sentry-provider/sentry-provider-policy-search/src/test/java/org/apache/sentry/provider/search/TestSearchModelAuthorizables.java
@@ -0,0 +1,60 @@
+/*
+ * 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.sentry.provider.search;
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNull;
+
+
+import org.apache.sentry.core.model.search.Collection;
+import org.apache.sentry.provider.search.SearchModelAuthorizables;
+import org.junit.Test;
+
+public class TestSearchModelAuthorizables {
+
+  @Test
+  public void testServer() throws Exception {
+    Collection coll = (Collection)SearchModelAuthorizables.from("CoLleCtiOn=collection1");
+    assertEquals("collection1", coll.getName());
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testNoKV() throws Exception {
+    System.out.println(SearchModelAuthorizables.from("nonsense"));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testTooManyKV() throws Exception {
+    System.out.println(SearchModelAuthorizables.from("k=v1=v2"));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testEmptyKey() throws Exception {
+    System.out.println(SearchModelAuthorizables.from("=v"));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testEmptyValue() throws Exception {
+    System.out.println(SearchModelAuthorizables.from("k="));
+  }
+
+  @Test
+  public void testNotAuthorizable() throws Exception {
+    assertNull(SearchModelAuthorizables.from("k=v"));
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/ed7b7539/sentry-provider/sentry-provider-policy-search/src/test/java/org/apache/sentry/provider/search/TestSearchWildcardPermission.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-policy-search/src/test/java/org/apache/sentry/provider/search/TestSearchWildcardPermission.java
b/sentry-provider/sentry-provider-policy-search/src/test/java/org/apache/sentry/provider/search/TestSearchWildcardPermission.java
new file mode 100644
index 0000000..d43854d
--- /dev/null
+++ b/sentry-provider/sentry-provider-policy-search/src/test/java/org/apache/sentry/provider/search/TestSearchWildcardPermission.java
@@ -0,0 +1,206 @@
+/*
+ * 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.sentry.provider.search;
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+import static org.apache.sentry.provider.file.PolicyFileConstants.AUTHORIZABLE_JOINER;
+import static org.apache.sentry.provider.file.PolicyFileConstants.KV_JOINER;
+import static org.apache.sentry.provider.file.PolicyFileConstants.KV_SEPARATOR;
+
+import org.apache.sentry.core.model.search.SearchConstants;
+import org.apache.sentry.provider.file.KeyValue;
+import org.apache.shiro.authz.Permission;
+import org.junit.Test;
+
+public class TestSearchWildcardPermission {
+
+  private static final String ALL = SearchConstants.ALL;
+
+  @Test
+  public void testSimpleNoAction() throws Exception {
+    Permission collection1 = create(new KeyValue("collection", "coll1"));
+    Permission collection2 = create(new KeyValue("collection", "coll2"));
+    Permission collection1Case = create(new KeyValue("colleCtIon", "coLl1"));
+
+    assertTrue(collection1.implies(collection1));
+    assertTrue(collection2.implies(collection2));
+    assertTrue(collection1.implies(collection1Case));
+    assertTrue(collection1Case.implies(collection1));
+
+    assertFalse(collection1.implies(collection2));
+    assertFalse(collection1Case.implies(collection2));
+    assertFalse(collection2.implies(collection1));
+    assertFalse(collection2.implies(collection1Case));
+  }
+
+  @Test
+  public void testSimpleAction() throws Exception {
+    Permission query =
+      create(new KeyValue("collection", "coll1"), new KeyValue("action", "query"));
+    Permission update =
+      create(new KeyValue("collection", "coll1"), new KeyValue("action", "update"));
+    Permission queryCase =
+      create(new KeyValue("colleCtIon", "coLl1"), new KeyValue("AcTiOn", "QuERy"));
+
+    assertTrue(query.implies(query));
+    assertTrue(update.implies(update));
+    assertTrue(query.implies(queryCase));
+    assertTrue(queryCase.implies(query));
+
+    assertFalse(query.implies(update));
+    assertFalse(queryCase.implies(update));
+    assertFalse(update.implies(query));
+    assertFalse(update.implies(queryCase));
+  }
+
+  @Test
+  public void testRoleShorterThanRequest() throws Exception {
+    Permission collection1 = create(new KeyValue("collection", "coll1"));
+    Permission query =
+      create(new KeyValue("collection", "coll1"), new KeyValue("action", "query"));
+    Permission update =
+      create(new KeyValue("collection", "coll1"), new KeyValue("action", "update"));
+    Permission all =
+      create(new KeyValue("collection", "coll1"), new KeyValue("action", ALL));
+
+    assertTrue(collection1.implies(query));
+    assertTrue(collection1.implies(update));
+    assertTrue(collection1.implies(all));
+
+    assertFalse(query.implies(collection1));
+    assertFalse(update.implies(collection1));
+    assertTrue(all.implies(collection1));
+  }
+
+  @Test
+  public void testCollectionAll() throws Exception {
+    Permission collectionAll = create(new KeyValue("collection", ALL));
+    Permission collection1 = create(new KeyValue("collection", "coll1"));
+    assertTrue(collectionAll.implies(collection1));
+    assertTrue(collection1.implies(collectionAll));
+
+    Permission allUpdate =
+      create(new KeyValue("collection", ALL), new KeyValue("action", "update"));
+    Permission allQuery =
+      create(new KeyValue("collection", ALL), new KeyValue("action", "query"));
+    Permission coll1Update =
+      create(new KeyValue("collection", "coll1"), new KeyValue("action", "update"));
+    Permission coll1Query =
+      create(new KeyValue("collection", "coll1"), new KeyValue("action", "query"));
+    assertTrue(allUpdate.implies(coll1Update));
+    assertTrue(allQuery.implies(coll1Query));
+    assertTrue(coll1Update.implies(allUpdate));
+    assertTrue(coll1Query.implies(allQuery));
+    assertFalse(allUpdate.implies(coll1Query));
+    assertFalse(coll1Update.implies(coll1Query));
+    assertFalse(allQuery.implies(coll1Update));
+    assertFalse(coll1Query.implies(allUpdate));
+    assertFalse(allUpdate.implies(allQuery));
+    assertFalse(allQuery.implies(allUpdate));
+    assertFalse(coll1Update.implies(coll1Query));
+    assertFalse(coll1Query.implies(coll1Update));
+
+    // test different length paths
+    assertTrue(collectionAll.implies(allUpdate));
+    assertTrue(collectionAll.implies(allQuery));
+    assertTrue(collectionAll.implies(coll1Update));
+    assertTrue(collectionAll.implies(coll1Query));
+    assertFalse(allUpdate.implies(collectionAll));
+    assertFalse(allQuery.implies(collectionAll));
+    assertFalse(coll1Update.implies(collectionAll));
+    assertFalse(coll1Query.implies(collectionAll));
+  }
+
+  @Test
+  public void testActionAll() throws Exception {
+    Permission coll1All =
+       create(new KeyValue("collection", "coll1"), new KeyValue("action", ALL));
+    Permission coll1Update =
+      create(new KeyValue("collection", "coll1"), new KeyValue("action", "update"));
+    Permission coll1Query =
+      create(new KeyValue("collection", "coll1"), new KeyValue("action", "query"));
+    assertTrue(coll1All.implies(coll1All));
+    assertTrue(coll1All.implies(coll1Update));
+    assertTrue(coll1All.implies(coll1Query));
+    assertFalse(coll1Update.implies(coll1All));
+    assertFalse(coll1Query.implies(coll1All));
+
+    // test different lengths
+    Permission coll1 =
+       create(new KeyValue("collection", "coll1"));
+    assertTrue(coll1All.implies(coll1));
+    assertTrue(coll1.implies(coll1All));
+  }
+
+  @Test
+  public void testUnexpected() throws Exception {
+    Permission p = new Permission() {
+      @Override
+      public boolean implies(Permission p) {
+        return false;
+      }
+    };
+    Permission collection1 = create(new KeyValue("collection", "coll1"));
+    assertFalse(collection1.implies(null));
+    assertFalse(collection1.implies(p));
+    assertFalse(collection1.equals(null));
+    assertFalse(collection1.equals(p));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testNullString() throws Exception {
+    System.out.println(create((String)null));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testEmptyString() throws Exception {
+    System.out.println(create(""));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testEmptyKey() throws Exception {
+    System.out.println(create(KV_JOINER.join("collection", "")));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testEmptyValue() throws Exception {
+    System.out.println(create(KV_JOINER.join("", "coll1")));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testEmptyPart() throws Exception {
+    System.out.println(create(AUTHORIZABLE_JOINER.
+        join(KV_JOINER.join("collection1", "coll1"), "")));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testOnlySeperators() throws Exception {
+    System.out.println(create(AUTHORIZABLE_JOINER.
+        join(KV_SEPARATOR, KV_SEPARATOR, KV_SEPARATOR)));
+  }
+
+  static SearchWildcardPermission create(KeyValue... keyValues) {
+    return create(AUTHORIZABLE_JOINER.join(keyValues));
+
+  }
+  static SearchWildcardPermission create(String s) {
+    return new SearchWildcardPermission(s);
+  }
+}


Mime
View raw message