You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sentry.apache.org by co...@apache.org on 2016/04/22 08:28:27 UTC
[07/13] sentry git commit: SENTRY-999: Refactor the sentry to
integrate with external components quickly (Colin Ma, reviewed by Dapeng Sun)
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/HivePrivilegeModel.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/HivePrivilegeModel.java b/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/HivePrivilegeModel.java
new file mode 100644
index 0000000..231acca
--- /dev/null
+++ b/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/HivePrivilegeModel.java
@@ -0,0 +1,68 @@
+/*
+ * 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.core.model.db;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.sentry.core.common.BitFieldActionFactory;
+import org.apache.sentry.core.common.ImplyMethodType;
+import org.apache.sentry.core.common.Model;
+import org.apache.sentry.core.common.validator.PrivilegeValidator;
+import org.apache.sentry.core.model.db.validator.DatabaseMustMatch;
+import org.apache.sentry.core.model.db.validator.DatabaseRequiredInPrivilege;
+import org.apache.sentry.core.model.db.validator.ServerNameMustMatch;
+import org.apache.sentry.core.model.db.validator.ServersAllIsInvalid;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.apache.sentry.core.model.db.DBModelAuthorizable.AuthorizableType;
+
+public class HivePrivilegeModel implements Model {
+ private Map<String, ImplyMethodType> implyMethodMap;
+ private BitFieldActionFactory bitFieldActionFactory;
+ private static HivePrivilegeModel hivePrivilegeModel = new HivePrivilegeModel();
+
+ private HivePrivilegeModel() {
+ implyMethodMap = new HashMap<String, ImplyMethodType>();
+ bitFieldActionFactory = new HiveActionFactory();
+
+ implyMethodMap.put(AuthorizableType.Server.name().toLowerCase(), ImplyMethodType.STRING);
+ implyMethodMap.put(AuthorizableType.Db.name().toLowerCase(), ImplyMethodType.STRING);
+ implyMethodMap.put(AuthorizableType.Table.name().toLowerCase(), ImplyMethodType.STRING);
+ implyMethodMap.put(AuthorizableType.Column.name().toLowerCase(), ImplyMethodType.STRING);
+ implyMethodMap.put(AuthorizableType.URI.name().toLowerCase(), ImplyMethodType.URL);
+ }
+
+ @Override
+ public Map<String, ImplyMethodType> getImplyMethodMap() {
+ return implyMethodMap;
+ }
+
+ @Override
+ public BitFieldActionFactory getBitFieldActionFactory() {
+ return bitFieldActionFactory;
+ }
+
+ public static HivePrivilegeModel getInstance() {
+ return hivePrivilegeModel;
+ }
+
+ public ImmutableList<PrivilegeValidator> getPrivilegeValidators(String serverName) {
+ return ImmutableList.<PrivilegeValidator>of(new ServersAllIsInvalid(), new DatabaseMustMatch(),
+ new DatabaseRequiredInPrivilege(), new ServerNameMustMatch(serverName));
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/AbstractDBPrivilegeValidator.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/AbstractDBPrivilegeValidator.java b/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/AbstractDBPrivilegeValidator.java
new file mode 100644
index 0000000..fa28716
--- /dev/null
+++ b/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/AbstractDBPrivilegeValidator.java
@@ -0,0 +1,51 @@
+/*
+ * 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.core.model.db.validator;
+
+import static org.apache.sentry.core.common.utils.SentryConstants.AUTHORIZABLE_SPLITTER;
+import static org.apache.sentry.core.common.utils.SentryConstants.PRIVILEGE_PREFIX;
+
+import java.util.List;
+
+import org.apache.sentry.core.model.db.DBModelAuthorizable;
+import org.apache.sentry.core.common.validator.PrivilegeValidator;
+import org.apache.sentry.core.model.db.DBModelAuthorizables;
+import org.apache.shiro.config.ConfigurationException;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Lists;
+
+public abstract class AbstractDBPrivilegeValidator implements PrivilegeValidator {
+
+ @VisibleForTesting
+ public static Iterable<DBModelAuthorizable> parsePrivilege(String string) {
+ List<DBModelAuthorizable> 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)) {
+ DBModelAuthorizable authorizable = DBModelAuthorizables.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/sentry/blob/d94e900a/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/DatabaseMustMatch.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/DatabaseMustMatch.java b/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/DatabaseMustMatch.java
new file mode 100644
index 0000000..4276667
--- /dev/null
+++ b/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/DatabaseMustMatch.java
@@ -0,0 +1,46 @@
+/*
+ * 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.core.model.db.validator;
+
+import org.apache.sentry.core.model.db.DBModelAuthorizable;
+import org.apache.sentry.core.model.db.Database;
+import org.apache.sentry.core.common.validator.PrivilegeValidatorContext;
+import org.apache.shiro.config.ConfigurationException;
+
+public class DatabaseMustMatch extends AbstractDBPrivilegeValidator {
+
+ @Override
+ public void validate(PrivilegeValidatorContext context) throws ConfigurationException {
+ String database = context.getDatabase();
+ String privilege = context.getPrivilege();
+ /*
+ * Rule only applies to rules in per database policy file
+ */
+ if(database != null) {
+ Iterable<DBModelAuthorizable> authorizables = parsePrivilege(privilege);
+ for(DBModelAuthorizable authorizable : authorizables) {
+ if(authorizable instanceof Database &&
+ !database.equalsIgnoreCase(authorizable.getName())) {
+ String msg = "Privilege " + privilege + " references db " +
+ authorizable.getName() + ", but is only allowed to reference "
+ + database;
+ throw new ConfigurationException(msg);
+ }
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/DatabaseRequiredInPrivilege.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/DatabaseRequiredInPrivilege.java b/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/DatabaseRequiredInPrivilege.java
new file mode 100644
index 0000000..fed3038
--- /dev/null
+++ b/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/DatabaseRequiredInPrivilege.java
@@ -0,0 +1,72 @@
+/*
+ * 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.core.model.db.validator;
+
+import org.apache.sentry.core.common.utils.SentryConstants;
+import org.apache.sentry.core.model.db.AccessURI;
+import org.apache.sentry.core.model.db.DBModelAuthorizable;
+import org.apache.sentry.core.model.db.Database;
+import org.apache.sentry.core.common.validator.PrivilegeValidatorContext;
+import org.apache.shiro.config.ConfigurationException;
+
+public class DatabaseRequiredInPrivilege extends AbstractDBPrivilegeValidator {
+
+ @Override
+ public void validate(PrivilegeValidatorContext context) throws ConfigurationException {
+ String database = context.getDatabase();
+ String privilege = context.getPrivilege();
+ /*
+ * Rule only applies to rules in per database policy file
+ */
+ if(database != null) {
+ Iterable<DBModelAuthorizable> authorizables = parsePrivilege(privilege);
+ /*
+ * Each permission in a non-global file must have a database
+ * object except for URIs.
+ *
+ * We allow URIs to be specified in the per DB policy file for
+ * ease of mangeability. URIs will contain to remain server scope
+ * objects.
+ */
+ boolean foundDatabaseInAuthorizables = false;
+ boolean foundURIInAuthorizables = false;
+ boolean allowURIInAuthorizables = false;
+
+ if ("true".equalsIgnoreCase(
+ System.getProperty(SentryConstants.ACCESS_ALLOW_URI_PER_DB_POLICYFILE))) {
+ allowURIInAuthorizables = true;
+ }
+
+ for(DBModelAuthorizable authorizable : authorizables) {
+ if(authorizable instanceof Database) {
+ foundDatabaseInAuthorizables = true;
+ }
+ if (authorizable instanceof AccessURI) {
+ if (foundDatabaseInAuthorizables) {
+ String msg = "URI object is specified at DB scope in " + privilege;
+ throw new ConfigurationException(msg);
+ }
+ foundURIInAuthorizables = true;
+ }
+ }
+ if(!foundDatabaseInAuthorizables && !(foundURIInAuthorizables && allowURIInAuthorizables)) {
+ String msg = "Missing database object in " + privilege;
+ throw new ConfigurationException(msg);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/ServerNameMustMatch.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/ServerNameMustMatch.java b/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/ServerNameMustMatch.java
new file mode 100644
index 0000000..c79a8bf
--- /dev/null
+++ b/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/ServerNameMustMatch.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.sentry.core.model.db.validator;
+
+import org.apache.sentry.core.model.db.DBModelAuthorizable;
+import org.apache.sentry.core.model.db.Server;
+import org.apache.sentry.core.common.validator.PrivilegeValidatorContext;
+import org.apache.shiro.config.ConfigurationException;
+
+public class ServerNameMustMatch extends AbstractDBPrivilegeValidator {
+
+ private final String serverName;
+ public ServerNameMustMatch(String serverName) {
+ this.serverName = serverName;
+ }
+ @Override
+ public void validate(PrivilegeValidatorContext context) throws ConfigurationException {
+ String privilege = context.getPrivilege();
+ Iterable<DBModelAuthorizable> authorizables = parsePrivilege(privilege);
+ for(DBModelAuthorizable authorizable : authorizables) {
+ if(authorizable instanceof Server && !serverName.equalsIgnoreCase(authorizable.getName())) {
+ String msg = "Server name " + authorizable.getName() + " in "
+ + privilege + " is invalid. Expected " + serverName;
+ throw new ConfigurationException(msg);
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/ServersAllIsInvalid.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/ServersAllIsInvalid.java b/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/ServersAllIsInvalid.java
new file mode 100644
index 0000000..e3f5a3a
--- /dev/null
+++ b/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/ServersAllIsInvalid.java
@@ -0,0 +1,39 @@
+/*
+ * 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.core.model.db.validator;
+
+import org.apache.sentry.core.model.db.DBModelAuthorizable;
+import org.apache.sentry.core.model.db.Server;
+import org.apache.sentry.core.common.validator.PrivilegeValidatorContext;
+import org.apache.shiro.config.ConfigurationException;
+
+public class ServersAllIsInvalid extends AbstractDBPrivilegeValidator {
+
+ @Override
+ public void validate(PrivilegeValidatorContext context) throws ConfigurationException {
+ String privilege = context.getPrivilege();
+ Iterable<DBModelAuthorizable> authorizables = parsePrivilege(privilege);
+ for(DBModelAuthorizable authorizable : authorizables) {
+ if(authorizable instanceof Server &&
+ authorizable.getName().equals(Server.ALL.getName())) {
+ String msg = "Invalid value for " + authorizable.getAuthzType() + " in " + privilege;
+ throw new ConfigurationException(msg);
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-indexer/src/main/java/org/apache/sentry/core/model/indexer/IndexerModelAuthorizables.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-indexer/src/main/java/org/apache/sentry/core/model/indexer/IndexerModelAuthorizables.java b/sentry-core/sentry-core-model-indexer/src/main/java/org/apache/sentry/core/model/indexer/IndexerModelAuthorizables.java
new file mode 100644
index 0000000..d15e911
--- /dev/null
+++ b/sentry-core/sentry-core-model-indexer/src/main/java/org/apache/sentry/core/model/indexer/IndexerModelAuthorizables.java
@@ -0,0 +1,46 @@
+/*
+ * 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.core.model.indexer;
+
+import org.apache.sentry.core.model.indexer.IndexerModelAuthorizable.AuthorizableType;
+import org.apache.sentry.core.common.utils.KeyValue;
+
+public class IndexerModelAuthorizables {
+
+ public static IndexerModelAuthorizable 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 IndexerModelAuthorizable from(String s) {
+ return from(new KeyValue(s));
+ }
+
+ private static IndexerModelAuthorizable from(AuthorizableType type, String name) {
+ switch (type) {
+ case Indexer:
+ return new Indexer(name);
+ default:
+ return null;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-indexer/src/main/java/org/apache/sentry/core/model/indexer/IndexerPrivilegeModel.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-indexer/src/main/java/org/apache/sentry/core/model/indexer/IndexerPrivilegeModel.java b/sentry-core/sentry-core-model-indexer/src/main/java/org/apache/sentry/core/model/indexer/IndexerPrivilegeModel.java
new file mode 100644
index 0000000..6951513
--- /dev/null
+++ b/sentry-core/sentry-core-model-indexer/src/main/java/org/apache/sentry/core/model/indexer/IndexerPrivilegeModel.java
@@ -0,0 +1,59 @@
+/*
+ * 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.core.model.indexer;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.sentry.core.common.BitFieldActionFactory;
+import org.apache.sentry.core.common.ImplyMethodType;
+import org.apache.sentry.core.common.Model;
+import org.apache.sentry.core.common.validator.PrivilegeValidator;
+import org.apache.sentry.core.model.indexer.validator.IndexerRequiredInPrivilege;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class IndexerPrivilegeModel implements Model {
+
+ private Map<String, ImplyMethodType> implyMethodMap;
+ private BitFieldActionFactory bitFieldActionFactory;
+ private static IndexerPrivilegeModel indexerPrivilegeModel = new IndexerPrivilegeModel();;
+
+ private IndexerPrivilegeModel() {
+ implyMethodMap = new HashMap<String, ImplyMethodType>();
+ bitFieldActionFactory = new IndexerActionFactory();
+
+ implyMethodMap.put(IndexerModelAuthorizable.AuthorizableType.Indexer.name().toLowerCase(), ImplyMethodType.STRING);
+ }
+
+ @Override
+ public Map<String, ImplyMethodType> getImplyMethodMap() {
+ return implyMethodMap;
+ }
+
+ @Override
+ public BitFieldActionFactory getBitFieldActionFactory() {
+ return bitFieldActionFactory;
+ }
+
+ public static IndexerPrivilegeModel getInstance() {
+ return indexerPrivilegeModel;
+ }
+
+ public ImmutableList<PrivilegeValidator> getPrivilegeValidators() {
+ return ImmutableList.<PrivilegeValidator>of(new IndexerRequiredInPrivilege());
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-indexer/src/main/java/org/apache/sentry/core/model/indexer/validator/AbstractIndexerPrivilegeValidator.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-indexer/src/main/java/org/apache/sentry/core/model/indexer/validator/AbstractIndexerPrivilegeValidator.java b/sentry-core/sentry-core-model-indexer/src/main/java/org/apache/sentry/core/model/indexer/validator/AbstractIndexerPrivilegeValidator.java
new file mode 100644
index 0000000..c73fc3c
--- /dev/null
+++ b/sentry-core/sentry-core-model-indexer/src/main/java/org/apache/sentry/core/model/indexer/validator/AbstractIndexerPrivilegeValidator.java
@@ -0,0 +1,51 @@
+/*
+ * 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.core.model.indexer.validator;
+
+import static org.apache.sentry.core.common.utils.SentryConstants.AUTHORIZABLE_SPLITTER;
+import static org.apache.sentry.core.common.utils.SentryConstants.PRIVILEGE_PREFIX;
+
+import java.util.List;
+
+import org.apache.sentry.core.model.indexer.IndexerModelAuthorizable;
+import org.apache.sentry.core.common.validator.PrivilegeValidator;
+import org.apache.sentry.core.model.indexer.IndexerModelAuthorizables;
+import org.apache.shiro.config.ConfigurationException;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Lists;
+
+public abstract class AbstractIndexerPrivilegeValidator implements PrivilegeValidator {
+
+ @VisibleForTesting
+ public static Iterable<IndexerModelAuthorizable> parsePrivilege(String string) {
+ List<IndexerModelAuthorizable> result = Lists.newArrayList();
+ for(String section : AUTHORIZABLE_SPLITTER.split(string)) {
+ // XXX this ugly hack is because action is not an authorizable
+ if(!section.toLowerCase().startsWith(PRIVILEGE_PREFIX)) {
+ IndexerModelAuthorizable authorizable = IndexerModelAuthorizables.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/sentry/blob/d94e900a/sentry-core/sentry-core-model-indexer/src/main/java/org/apache/sentry/core/model/indexer/validator/IndexerRequiredInPrivilege.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-indexer/src/main/java/org/apache/sentry/core/model/indexer/validator/IndexerRequiredInPrivilege.java b/sentry-core/sentry-core-model-indexer/src/main/java/org/apache/sentry/core/model/indexer/validator/IndexerRequiredInPrivilege.java
new file mode 100644
index 0000000..82bc25d
--- /dev/null
+++ b/sentry-core/sentry-core-model-indexer/src/main/java/org/apache/sentry/core/model/indexer/validator/IndexerRequiredInPrivilege.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.sentry.core.model.indexer.validator;
+
+import org.apache.sentry.core.common.SentryConfigurationException;
+import org.apache.sentry.core.model.indexer.Indexer;
+import org.apache.sentry.core.model.indexer.IndexerModelAuthorizable;
+import org.apache.sentry.core.common.validator.PrivilegeValidatorContext;
+
+public class IndexerRequiredInPrivilege extends AbstractIndexerPrivilegeValidator {
+
+ @Override
+ public void validate(PrivilegeValidatorContext context) throws SentryConfigurationException {
+ String privilege = context.getPrivilege();
+ Iterable<IndexerModelAuthorizable> authorizables = parsePrivilege(privilege);
+ boolean foundIndexerInAuthorizables = false;
+
+ for(IndexerModelAuthorizable authorizable : authorizables) {
+ if(authorizable instanceof Indexer) {
+ foundIndexerInAuthorizables = true;
+ break;
+ }
+ }
+ if(!foundIndexerInAuthorizables) {
+ String msg = "Missing indexer object in " + privilege;
+ throw new SentryConfigurationException(msg);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-kafka/src/main/java/org/apache/sentry/core/model/kafka/KafkaActionFactory.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-kafka/src/main/java/org/apache/sentry/core/model/kafka/KafkaActionFactory.java b/sentry-core/sentry-core-model-kafka/src/main/java/org/apache/sentry/core/model/kafka/KafkaActionFactory.java
index fc3bf7a..a1fec1f 100644
--- a/sentry-core/sentry-core-model-kafka/src/main/java/org/apache/sentry/core/model/kafka/KafkaActionFactory.java
+++ b/sentry-core/sentry-core-model-kafka/src/main/java/org/apache/sentry/core/model/kafka/KafkaActionFactory.java
@@ -52,9 +52,9 @@ public class KafkaActionFactory extends BitFieldActionFactory {
DELETE(KafkaActionConstant.DELETE, 8),
ALTER(KafkaActionConstant.ALTER, 16),
DESCRIBE(KafkaActionConstant.DESCRIBE, 32),
- CLUSTER_ACTION(KafkaActionConstant.CLUSTER_ACTION, 64),
+ CLUSTERACTION(KafkaActionConstant.CLUSTER_ACTION, 64),
ALL(KafkaActionConstant.ALL, READ.getCode() | WRITE.getCode() | CREATE.getCode()
- | DELETE.getCode() | ALTER.getCode()| DESCRIBE.getCode() | CLUSTER_ACTION.getCode());
+ | DELETE.getCode() | ALTER.getCode()| DESCRIBE.getCode() | CLUSTERACTION.getCode());
private String name;
private int code;
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-kafka/src/main/java/org/apache/sentry/core/model/kafka/KafkaModelAuthorizables.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-kafka/src/main/java/org/apache/sentry/core/model/kafka/KafkaModelAuthorizables.java b/sentry-core/sentry-core-model-kafka/src/main/java/org/apache/sentry/core/model/kafka/KafkaModelAuthorizables.java
new file mode 100644
index 0000000..45a1148
--- /dev/null
+++ b/sentry-core/sentry-core-model-kafka/src/main/java/org/apache/sentry/core/model/kafka/KafkaModelAuthorizables.java
@@ -0,0 +1,57 @@
+/*
+ * 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.core.model.kafka;
+
+import org.apache.sentry.core.common.utils.KeyValue;
+import org.apache.sentry.core.model.kafka.KafkaAuthorizable.AuthorizableType;
+import org.apache.shiro.config.ConfigurationException;
+
+public class KafkaModelAuthorizables {
+ public static KafkaAuthorizable from(KeyValue keyValue) throws ConfigurationException {
+ String prefix = keyValue.getKey().toLowerCase();
+ String name = keyValue.getValue();
+ for (AuthorizableType type : AuthorizableType.values()) {
+ if (prefix.equalsIgnoreCase(type.name())) {
+ return from(type, name);
+ }
+ }
+ return null;
+ }
+
+ public static KafkaAuthorizable from(String keyValue) throws ConfigurationException {
+ return from(new KeyValue(keyValue));
+ }
+
+ public static KafkaAuthorizable from(AuthorizableType type, String name) throws ConfigurationException {
+ switch (type) {
+ case HOST:
+ return new Host(name);
+ case CLUSTER: {
+ if (!name.equals(Cluster.NAME)) {
+ throw new ConfigurationException("Kafka's cluster resource can only have name " + Cluster.NAME);
+ }
+ return new Cluster();
+ }
+ case TOPIC:
+ return new Topic(name);
+ case CONSUMERGROUP:
+ return new ConsumerGroup(name);
+ default:
+ return null;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-kafka/src/main/java/org/apache/sentry/core/model/kafka/KafkaPrivilegeModel.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-kafka/src/main/java/org/apache/sentry/core/model/kafka/KafkaPrivilegeModel.java b/sentry-core/sentry-core-model-kafka/src/main/java/org/apache/sentry/core/model/kafka/KafkaPrivilegeModel.java
new file mode 100644
index 0000000..74c887e
--- /dev/null
+++ b/sentry-core/sentry-core-model-kafka/src/main/java/org/apache/sentry/core/model/kafka/KafkaPrivilegeModel.java
@@ -0,0 +1,69 @@
+/**
+ * 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.core.model.kafka;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.sentry.core.common.BitFieldActionFactory;
+import org.apache.sentry.core.common.ImplyMethodType;
+import org.apache.sentry.core.common.Model;
+import org.apache.sentry.core.common.validator.PrivilegeValidator;
+import org.apache.sentry.core.model.kafka.validator.KafkaPrivilegeValidator;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class KafkaPrivilegeModel implements Model {
+
+ private Map<String, ImplyMethodType> implyMethodMap;
+ private BitFieldActionFactory bitFieldActionFactory;
+ private static KafkaPrivilegeModel kafkaPrivilegeModel = new KafkaPrivilegeModel();
+
+ private KafkaPrivilegeModel() {
+ implyMethodMap = new HashMap<String, ImplyMethodType>();
+ bitFieldActionFactory = KafkaActionFactory.getInstance();
+
+ implyMethodMap.put(KafkaAuthorizable.AuthorizableType.CLUSTER.name().toLowerCase(),
+ ImplyMethodType.STRING);
+ implyMethodMap.put(KafkaAuthorizable.AuthorizableType.HOST.name().toLowerCase(),
+ ImplyMethodType.STRING);
+ implyMethodMap.put(KafkaAuthorizable.AuthorizableType.TOPIC.name().toLowerCase(),
+ ImplyMethodType.STRING);
+ implyMethodMap.put(KafkaAuthorizable.AuthorizableType.CONSUMERGROUP.name().toLowerCase(),
+ ImplyMethodType.STRING);
+ }
+
+ @Override
+ public Map<String, ImplyMethodType> getImplyMethodMap() {
+ return implyMethodMap;
+ }
+
+ @Override
+ public BitFieldActionFactory getBitFieldActionFactory() {
+ return bitFieldActionFactory;
+ }
+
+ public static KafkaPrivilegeModel getInstance() {
+ return kafkaPrivilegeModel;
+ }
+
+ public ImmutableList<PrivilegeValidator> getPrivilegeValidators() {
+ return ImmutableList.<PrivilegeValidator>of(new KafkaPrivilegeValidator());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-kafka/src/main/java/org/apache/sentry/core/model/kafka/validator/KafkaPrivilegeValidator.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-kafka/src/main/java/org/apache/sentry/core/model/kafka/validator/KafkaPrivilegeValidator.java b/sentry-core/sentry-core-model-kafka/src/main/java/org/apache/sentry/core/model/kafka/validator/KafkaPrivilegeValidator.java
new file mode 100644
index 0000000..5c45865
--- /dev/null
+++ b/sentry-core/sentry-core-model-kafka/src/main/java/org/apache/sentry/core/model/kafka/validator/KafkaPrivilegeValidator.java
@@ -0,0 +1,119 @@
+/*
+ * 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.core.model.kafka.validator;
+
+import static org.apache.sentry.core.common.utils.SentryConstants.AUTHORIZABLE_SPLITTER;
+import static org.apache.sentry.core.common.utils.SentryConstants.PRIVILEGE_PREFIX;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.sentry.core.common.validator.PrivilegeValidator;
+import org.apache.sentry.core.common.validator.PrivilegeValidatorContext;
+import org.apache.sentry.core.model.kafka.KafkaActionFactory;
+import org.apache.sentry.core.model.kafka.KafkaAuthorizable;
+import org.apache.sentry.core.model.kafka.Host;
+import org.apache.sentry.core.model.kafka.KafkaModelAuthorizables;
+import org.apache.shiro.config.ConfigurationException;
+
+import com.google.common.collect.Lists;
+
+/**
+ * Validator for Kafka privileges.
+ * Below are the requirements for a kafka privilege to be valid.
+ * 1. Privilege must start with Host resource.
+ * 2. Privilege must have at most one non Host resource, Cluster or Topic or ConsumerGroup, followed
+ * by Host resource.
+ * 3. Privilege must end with exactly one action.
+ */
+public class KafkaPrivilegeValidator implements PrivilegeValidator {
+
+ public static final String KafkaPrivilegeHelpMsg =
+ "Invalid Kafka privilege." +
+ " Kafka privilege must be of the form host=<HOST>-><RESOURCE>=<RESOURCE_NAME>->action=<ACTION>," +
+ " where <HOST> can be '*' or any valid host name," +
+ " <RESOURCE> can be one of " + Arrays.toString(getKafkaAuthorizablesExceptHost()) +
+ " <RESOURCE_NAME> is name of the resource," +
+ " <ACTION> can be one of " + Arrays.toString(KafkaActionFactory.KafkaActionType.values()) +
+ ".";
+
+ private static KafkaAuthorizable.AuthorizableType[] getKafkaAuthorizablesExceptHost() {
+ final KafkaAuthorizable.AuthorizableType[] authorizableTypes = KafkaAuthorizable.AuthorizableType.values();
+ List<KafkaAuthorizable.AuthorizableType> authorizableTypesWithoutHost = new ArrayList<>(authorizableTypes.length - 1);
+ for (KafkaAuthorizable.AuthorizableType authorizableType: authorizableTypes) {
+ if (!authorizableType.equals(KafkaAuthorizable.AuthorizableType.HOST)) {
+ authorizableTypesWithoutHost.add(authorizableType);
+ }
+ }
+ return authorizableTypesWithoutHost.toArray(new KafkaAuthorizable.AuthorizableType[authorizableTypesWithoutHost.size()]);
+ }
+
+ public KafkaPrivilegeValidator() {
+ }
+
+ @Override
+ public void validate(PrivilegeValidatorContext context) throws ConfigurationException {
+ List<String> splits = Lists.newArrayList();
+ for (String section : AUTHORIZABLE_SPLITTER.split(context.getPrivilege())) {
+ splits.add(section);
+ }
+
+ // Check privilege splits length is 2 or 3
+ if (splits.size() < 2 || splits.size() > 3) {
+ throw new ConfigurationException(KafkaPrivilegeHelpMsg);
+ }
+
+ // Check privilege starts with Host resource
+ if (isAction(splits.get(0))) {
+ throw new ConfigurationException("Kafka privilege can not start with an action.\n" + KafkaPrivilegeHelpMsg);
+ }
+ KafkaAuthorizable hostAuthorizable = KafkaModelAuthorizables.from(splits.get(0));
+ if (hostAuthorizable == null) {
+ throw new ConfigurationException("No Kafka authorizable found for " + splits.get(0) + "\n." + KafkaPrivilegeHelpMsg);
+ }
+ if (!(hostAuthorizable instanceof Host)) {
+ throw new ConfigurationException("Kafka privilege must begin with host authorizable.\n" + KafkaPrivilegeHelpMsg);
+ }
+
+ // Check privilege has at most one non Host resource following Host resource
+ if (splits.size() == 3) {
+ if (isAction(splits.get(1))) {
+ throw new ConfigurationException("Kafka privilege can have action only at the end of privilege.\n" + KafkaPrivilegeHelpMsg);
+ }
+ KafkaAuthorizable authorizable = KafkaModelAuthorizables.from(splits.get(1));
+ if (authorizable == null) {
+ throw new ConfigurationException("No Kafka authorizable found for " + splits.get(1) + "\n." + KafkaPrivilegeHelpMsg);
+ }
+ if (authorizable instanceof Host) {
+ throw new ConfigurationException("Host authorizable can be specified just once in a Kafka privilege.\n" + KafkaPrivilegeHelpMsg);
+ }
+ }
+
+ // Check privilege ends with exactly one valid action
+ if (!isAction(splits.get(splits.size() - 1))) {
+ throw new ConfigurationException("Kafka privilege must end with a valid action.\n" + KafkaPrivilegeHelpMsg);
+ }
+ }
+
+ private boolean isAction(String privilegePart) {
+ final String privilege = privilegePart.toLowerCase();
+ final String action = privilege.replace(PRIVILEGE_PREFIX, "").toLowerCase();
+ return privilege.startsWith(PRIVILEGE_PREFIX) &&
+ KafkaActionFactory.getInstance().getActionByName(action) != null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-search/src/main/java/org/apache/sentry/core/model/search/SearchModelAuthorizables.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-search/src/main/java/org/apache/sentry/core/model/search/SearchModelAuthorizables.java b/sentry-core/sentry-core-model-search/src/main/java/org/apache/sentry/core/model/search/SearchModelAuthorizables.java
new file mode 100644
index 0000000..c3292c7
--- /dev/null
+++ b/sentry-core/sentry-core-model-search/src/main/java/org/apache/sentry/core/model/search/SearchModelAuthorizables.java
@@ -0,0 +1,46 @@
+/*
+ * 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.core.model.search;
+
+import org.apache.sentry.core.model.search.SearchModelAuthorizable.AuthorizableType;
+import org.apache.sentry.core.common.utils.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/sentry/blob/d94e900a/sentry-core/sentry-core-model-search/src/main/java/org/apache/sentry/core/model/search/SearchPrivilegeModel.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-search/src/main/java/org/apache/sentry/core/model/search/SearchPrivilegeModel.java b/sentry-core/sentry-core-model-search/src/main/java/org/apache/sentry/core/model/search/SearchPrivilegeModel.java
new file mode 100644
index 0000000..9429a25
--- /dev/null
+++ b/sentry-core/sentry-core-model-search/src/main/java/org/apache/sentry/core/model/search/SearchPrivilegeModel.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.core.model.search;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.sentry.core.common.BitFieldActionFactory;
+import org.apache.sentry.core.common.ImplyMethodType;
+import org.apache.sentry.core.common.Model;
+import org.apache.sentry.core.common.validator.PrivilegeValidator;
+import org.apache.sentry.core.model.search.validator.CollectionRequiredInPrivilege;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class SearchPrivilegeModel implements Model {
+
+ private Map<String, ImplyMethodType> implyMethodMap;
+ private BitFieldActionFactory bitFieldActionFactory;
+ private static SearchPrivilegeModel searchPrivilegeModel = new SearchPrivilegeModel();
+
+ private SearchPrivilegeModel() {
+ implyMethodMap = new HashMap<String, ImplyMethodType>();
+ bitFieldActionFactory = new SearchActionFactory();
+
+ implyMethodMap.put(SearchModelAuthorizable.AuthorizableType.Collection.name().toLowerCase(), ImplyMethodType.STRING);
+ implyMethodMap.put(SearchModelAuthorizable.AuthorizableType.Field.name().toLowerCase(), ImplyMethodType.STRING);
+ }
+
+ @Override
+ public Map<String, ImplyMethodType> getImplyMethodMap() {
+ return implyMethodMap;
+ }
+
+ @Override
+ public BitFieldActionFactory getBitFieldActionFactory() {
+ return bitFieldActionFactory;
+ }
+
+ public static SearchPrivilegeModel getInstance() {
+ return searchPrivilegeModel;
+ }
+
+ public ImmutableList<PrivilegeValidator> getPrivilegeValidators() {
+ return ImmutableList.<PrivilegeValidator>of(new CollectionRequiredInPrivilege());
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-search/src/main/java/org/apache/sentry/core/model/search/validator/AbstractSearchPrivilegeValidator.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-search/src/main/java/org/apache/sentry/core/model/search/validator/AbstractSearchPrivilegeValidator.java b/sentry-core/sentry-core-model-search/src/main/java/org/apache/sentry/core/model/search/validator/AbstractSearchPrivilegeValidator.java
new file mode 100644
index 0000000..c06131c
--- /dev/null
+++ b/sentry-core/sentry-core-model-search/src/main/java/org/apache/sentry/core/model/search/validator/AbstractSearchPrivilegeValidator.java
@@ -0,0 +1,52 @@
+/*
+ * 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.core.model.search.validator;
+
+import static org.apache.sentry.core.common.utils.SentryConstants.AUTHORIZABLE_SPLITTER;
+import static org.apache.sentry.core.common.utils.SentryConstants.PRIVILEGE_PREFIX;
+
+import java.util.List;
+
+import org.apache.sentry.core.model.search.SearchModelAuthorizable;
+import org.apache.sentry.core.common.validator.PrivilegeValidator;
+import org.apache.sentry.core.model.search.SearchModelAuthorizables;
+import org.apache.shiro.config.ConfigurationException;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Lists;
+
+public abstract class AbstractSearchPrivilegeValidator implements PrivilegeValidator {
+
+ @VisibleForTesting
+ public static Iterable<SearchModelAuthorizable> parsePrivilege(String string) {
+ List<SearchModelAuthorizable> result = Lists.newArrayList();
+ System.err.println("privilege = " + string);
+ for(String section : AUTHORIZABLE_SPLITTER.split(string)) {
+ // XXX this ugly hack is because action is not an authorizable
+ 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/sentry/blob/d94e900a/sentry-core/sentry-core-model-search/src/main/java/org/apache/sentry/core/model/search/validator/CollectionRequiredInPrivilege.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-search/src/main/java/org/apache/sentry/core/model/search/validator/CollectionRequiredInPrivilege.java b/sentry-core/sentry-core-model-search/src/main/java/org/apache/sentry/core/model/search/validator/CollectionRequiredInPrivilege.java
new file mode 100644
index 0000000..17b87df
--- /dev/null
+++ b/sentry-core/sentry-core-model-search/src/main/java/org/apache/sentry/core/model/search/validator/CollectionRequiredInPrivilege.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.sentry.core.model.search.validator;
+
+import org.apache.sentry.core.common.SentryConfigurationException;
+import org.apache.sentry.core.model.search.Collection;
+import org.apache.sentry.core.model.search.SearchModelAuthorizable;
+import org.apache.sentry.core.common.validator.PrivilegeValidatorContext;
+
+public class CollectionRequiredInPrivilege extends AbstractSearchPrivilegeValidator {
+
+ @Override
+ public void validate(PrivilegeValidatorContext context) throws SentryConfigurationException {
+ String privilege = context.getPrivilege();
+ Iterable<SearchModelAuthorizable> authorizables = parsePrivilege(privilege);
+ boolean foundCollectionInAuthorizables = false;
+
+ for(SearchModelAuthorizable authorizable : authorizables) {
+ if(authorizable instanceof Collection) {
+ foundCollectionInAuthorizables = true;
+ break;
+ }
+ }
+ if(!foundCollectionInAuthorizables) {
+ String msg = "Missing collection object in " + privilege;
+ throw new SentryConfigurationException(msg);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-sqoop/src/main/java/org/apache/sentry/core/model/sqoop/SqoopModelAuthorizables.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-sqoop/src/main/java/org/apache/sentry/core/model/sqoop/SqoopModelAuthorizables.java b/sentry-core/sentry-core-model-sqoop/src/main/java/org/apache/sentry/core/model/sqoop/SqoopModelAuthorizables.java
new file mode 100644
index 0000000..11ce7ec
--- /dev/null
+++ b/sentry-core/sentry-core-model-sqoop/src/main/java/org/apache/sentry/core/model/sqoop/SqoopModelAuthorizables.java
@@ -0,0 +1,52 @@
+/*
+ * 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.core.model.sqoop;
+
+import org.apache.sentry.core.model.sqoop.SqoopAuthorizable.AuthorizableType;
+import org.apache.sentry.core.common.utils.KeyValue;
+
+public class SqoopModelAuthorizables {
+ public static SqoopAuthorizable 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 SqoopAuthorizable from(String keyValue) {
+ return from(new KeyValue(keyValue));
+ }
+
+ public static SqoopAuthorizable from(AuthorizableType type, String name) {
+ switch(type) {
+ case SERVER:
+ return new Server(name);
+ case JOB:
+ return new Job(name);
+ case CONNECTOR:
+ return new Connector(name);
+ case LINK:
+ return new Link(name);
+ default:
+ return null;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-sqoop/src/main/java/org/apache/sentry/core/model/sqoop/SqoopPrivilegeModel.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-sqoop/src/main/java/org/apache/sentry/core/model/sqoop/SqoopPrivilegeModel.java b/sentry-core/sentry-core-model-sqoop/src/main/java/org/apache/sentry/core/model/sqoop/SqoopPrivilegeModel.java
new file mode 100644
index 0000000..4bd8f94
--- /dev/null
+++ b/sentry-core/sentry-core-model-sqoop/src/main/java/org/apache/sentry/core/model/sqoop/SqoopPrivilegeModel.java
@@ -0,0 +1,63 @@
+/*
+ * 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.core.model.sqoop;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.sentry.core.common.BitFieldActionFactory;
+import org.apache.sentry.core.common.ImplyMethodType;
+import org.apache.sentry.core.common.Model;
+import org.apache.sentry.core.common.validator.PrivilegeValidator;
+import org.apache.sentry.core.model.sqoop.validator.ServerNameRequiredMatch;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class SqoopPrivilegeModel implements Model {
+
+ private Map<String, ImplyMethodType> implyMethodMap;
+ private BitFieldActionFactory bitFieldActionFactory;
+ private static SqoopPrivilegeModel sqoopPrivilegeModel = new SqoopPrivilegeModel();
+
+ private SqoopPrivilegeModel() {
+ implyMethodMap = new HashMap<String, ImplyMethodType>();
+ bitFieldActionFactory = new SqoopActionFactory();
+
+ implyMethodMap.put(SqoopAuthorizable.AuthorizableType.SERVER.name().toLowerCase(), ImplyMethodType.STRING);
+ implyMethodMap.put(SqoopAuthorizable.AuthorizableType.CONNECTOR.name().toLowerCase(), ImplyMethodType.STRING);
+ implyMethodMap.put(SqoopAuthorizable.AuthorizableType.LINK.name().toLowerCase(), ImplyMethodType.STRING);
+ implyMethodMap.put(SqoopAuthorizable.AuthorizableType.JOB.name().toLowerCase(), ImplyMethodType.STRING);
+ }
+
+ @Override
+ public Map<String, ImplyMethodType> getImplyMethodMap() {
+ return implyMethodMap;
+ }
+
+ @Override
+ public BitFieldActionFactory getBitFieldActionFactory() {
+ return bitFieldActionFactory;
+ }
+
+ public static SqoopPrivilegeModel getInstance() {
+ return sqoopPrivilegeModel;
+ }
+
+ public ImmutableList<PrivilegeValidator> getPrivilegeValidators(String sqoopServerName) {
+ return ImmutableList.<PrivilegeValidator>of(new ServerNameRequiredMatch(sqoopServerName));
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-sqoop/src/main/java/org/apache/sentry/core/model/sqoop/validator/ServerNameRequiredMatch.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-sqoop/src/main/java/org/apache/sentry/core/model/sqoop/validator/ServerNameRequiredMatch.java b/sentry-core/sentry-core-model-sqoop/src/main/java/org/apache/sentry/core/model/sqoop/validator/ServerNameRequiredMatch.java
new file mode 100644
index 0000000..67347bc
--- /dev/null
+++ b/sentry-core/sentry-core-model-sqoop/src/main/java/org/apache/sentry/core/model/sqoop/validator/ServerNameRequiredMatch.java
@@ -0,0 +1,70 @@
+/*
+ * 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.core.model.sqoop.validator;
+
+import static org.apache.sentry.core.common.utils.SentryConstants.AUTHORIZABLE_SPLITTER;
+import static org.apache.sentry.core.common.utils.SentryConstants.PRIVILEGE_PREFIX;
+
+import java.util.List;
+
+import org.apache.sentry.core.model.sqoop.Server;
+import org.apache.sentry.core.model.sqoop.SqoopAuthorizable;
+import org.apache.sentry.core.common.validator.PrivilegeValidatorContext;
+import org.apache.sentry.core.common.validator.PrivilegeValidator;
+import org.apache.sentry.core.model.sqoop.SqoopModelAuthorizables;
+import org.apache.shiro.config.ConfigurationException;
+
+import com.google.common.collect.Lists;
+
+public class ServerNameRequiredMatch implements PrivilegeValidator {
+ private final String sqoopServerName;
+ public ServerNameRequiredMatch(String sqoopServerName) {
+ this.sqoopServerName = sqoopServerName;
+ }
+ @Override
+ public void validate(PrivilegeValidatorContext context)
+ throws ConfigurationException {
+ Iterable<SqoopAuthorizable> authorizables = parsePrivilege(context.getPrivilege());
+ boolean match = false;
+ for (SqoopAuthorizable authorizable : authorizables) {
+ if (authorizable instanceof Server && authorizable.getName().equalsIgnoreCase(sqoopServerName)) {
+ match = true;
+ break;
+ }
+ }
+ if (!match) {
+ String msg = "server=[name] in " + context.getPrivilege()
+ + " is required. The name is expected " + sqoopServerName;
+ throw new ConfigurationException(msg);
+ }
+ }
+
+ private Iterable<SqoopAuthorizable> parsePrivilege(String string) {
+ List<SqoopAuthorizable> result = Lists.newArrayList();
+ for(String section : AUTHORIZABLE_SPLITTER.split(string)) {
+ if(!section.toLowerCase().startsWith(PRIVILEGE_PREFIX)) {
+ SqoopAuthorizable authorizable = SqoopModelAuthorizables.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/sentry/blob/d94e900a/sentry-dist/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-dist/pom.xml b/sentry-dist/pom.xml
index 130de75..80ec9c9 100644
--- a/sentry-dist/pom.xml
+++ b/sentry-dist/pom.xml
@@ -92,24 +92,8 @@ limitations under the License.
</dependency>
<dependency>
<groupId>org.apache.sentry</groupId>
- <artifactId>sentry-policy-db</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.sentry</groupId>
<artifactId>sentry-policy-indexer</artifactId>
</dependency>
- <dependency>
- <groupId>org.apache.sentry</groupId>
- <artifactId>sentry-policy-search</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.sentry</groupId>
- <artifactId>sentry-policy-sqoop</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.sentry</groupId>
- <artifactId>sentry-policy-kafka</artifactId>
- </dependency>
</dependencies>
<profiles>
<profile>
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-policy/pom.xml b/sentry-policy/pom.xml
index 4abcf03..14fe829 100644
--- a/sentry-policy/pom.xml
+++ b/sentry-policy/pom.xml
@@ -31,11 +31,8 @@ limitations under the License.
<modules>
<module>sentry-policy-common</module>
- <module>sentry-policy-db</module>
+ <module>sentry-policy-engine</module>
<module>sentry-policy-indexer</module>
- <module>sentry-policy-search</module>
- <module>sentry-policy-sqoop</module>
- <module>sentry-policy-kafka</module>
</modules>
</project>
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-common/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-common/pom.xml b/sentry-policy/sentry-policy-common/pom.xml
index 1f8c522..57fc9d9 100644
--- a/sentry-policy/sentry-policy-common/pom.xml
+++ b/sentry-policy/sentry-policy-common/pom.xml
@@ -45,6 +45,11 @@ limitations under the License.
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.sentry</groupId>
+ <artifactId>sentry-core-model-db</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/CommonPrivilege.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/CommonPrivilege.java b/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/CommonPrivilege.java
new file mode 100644
index 0000000..dedd908
--- /dev/null
+++ b/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/CommonPrivilege.java
@@ -0,0 +1,176 @@
+/*
+ * 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.policy.common;
+
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import org.apache.sentry.core.common.BitFieldAction;
+import org.apache.sentry.core.common.BitFieldActionFactory;
+import org.apache.sentry.core.common.ImplyMethodType;
+import org.apache.sentry.core.common.Model;
+import org.apache.sentry.core.common.utils.KeyValue;
+import org.apache.sentry.core.common.utils.PathUtils;
+import org.apache.sentry.core.common.utils.SentryConstants;
+
+import java.util.List;
+
+// The class is used to compare the privilege
+public class CommonPrivilege implements Privilege {
+
+ private ImmutableList<KeyValue> parts;
+
+ public CommonPrivilege(String privilegeStr) {
+ privilegeStr = Strings.nullToEmpty(privilegeStr).trim();
+ if (privilegeStr.isEmpty()) {
+ throw new IllegalArgumentException("Privilege string cannot be null or empty.");
+ }
+ List<KeyValue> parts = Lists.newArrayList();
+ for (String authorizable : SentryConstants.AUTHORIZABLE_SPLITTER.trimResults().split(
+ privilegeStr)) {
+ if (authorizable.isEmpty()) {
+ throw new IllegalArgumentException("Privilege '" + privilegeStr + "' has an empty section");
+ }
+ parts.add(new KeyValue(authorizable));
+ }
+ if (parts.isEmpty()) {
+ throw new AssertionError("Should never occur: " + privilegeStr);
+ }
+ this.parts = ImmutableList.copyOf(parts);
+ }
+
+ @Override
+ public boolean implies(Privilege privilege, Model model) {
+ // By default only supports comparisons with other IndexerWildcardPermissions
+ if (!(privilege instanceof CommonPrivilege)) {
+ return false;
+ }
+
+ List<KeyValue> otherParts = ((CommonPrivilege) privilege).getParts();
+ if(parts.equals(otherParts)) {
+ return true;
+ }
+
+ int index = 0;
+ for (KeyValue otherPart : otherParts) {
+ // If this privilege has less parts than the other privilege, everything
+ // after the number of parts contained
+ // in this privilege is automatically implied, so return true
+ if (parts.size() - 1 < index) {
+ return true;
+ } else {
+ KeyValue part = parts.get(index);
+ String policyKey = part.getKey();
+ // are the keys even equal
+ if(!policyKey.equalsIgnoreCase(otherPart.getKey())) {
+ // Support for action inheritance from parent to child
+ if (SentryConstants.PRIVILEGE_NAME.equalsIgnoreCase(policyKey)) {
+ continue;
+ }
+ return false;
+ }
+
+ // do the imply for action
+ if (SentryConstants.PRIVILEGE_NAME.equalsIgnoreCase(policyKey)) {
+ if (!impliesAction(part.getValue(), otherPart.getValue(), model.getBitFieldActionFactory())) {
+ return false;
+ }
+ } else {
+ if (!impliesResource(model.getImplyMethodMap().get(policyKey.toLowerCase()),
+ part.getValue(), otherPart.getValue())) {
+ return false;
+ }
+ }
+
+ index++;
+ }
+ }
+
+ // If this privilege 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 (!SentryConstants.PRIVILEGE_WILDCARD_VALUE.equals(part.getValue())) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ // The method is used for compare the value of resource by the ImplyMethodType.
+ // for Hive, databaseName, tableName, columnName will be compared using String.equal(wildcard support)
+ // url will be compared using PathUtils.impliesURI
+ private boolean impliesResource(ImplyMethodType implyMethodType, String policyValue, String requestValue) {
+ // wildcard support, "*", "+", "all"("+" and "all" are for backward compatibility) are represented as wildcard
+ // if requestValue is wildcard, means privilege request is to match with any value of given resource
+ if (SentryConstants.RESOURCE_WILDCARD_VALUE.equals(policyValue)
+ || SentryConstants.RESOURCE_WILDCARD_VALUE.equals(requestValue)
+ || SentryConstants.RESOURCE_WILDCARD_VALUE_ALL.equalsIgnoreCase(policyValue)
+ || SentryConstants.RESOURCE_WILDCARD_VALUE_ALL.equalsIgnoreCase(requestValue)
+ || SentryConstants.RESOURCE_WILDCARD_VALUE_SOME.equals(requestValue)) {
+ return true;
+ }
+
+ // compare as the url
+ if (ImplyMethodType.URL == implyMethodType) {
+ return PathUtils.impliesURI(policyValue, requestValue);
+ } else if (ImplyMethodType.STRING_CASE_SENSITIVE == implyMethodType) {
+ // compare as the string case sensitive
+ return policyValue.equals(requestValue);
+ }
+ // default: compare as the string case insensitive
+ return policyValue.equalsIgnoreCase(requestValue);
+ }
+
+ // The method is used for compare the action for the privilege model.
+ // for Hive, the action will be select, insert, etc.
+ // for Solr, the action will be update, query, etc.
+ private boolean impliesAction(String policyValue, String requestValue,
+ BitFieldActionFactory bitFieldActionFactory) {
+ BitFieldAction currentAction = bitFieldActionFactory.getActionByName(policyValue);
+ BitFieldAction requestAction = bitFieldActionFactory.getActionByName(requestValue);
+ // the action in privilege is not supported
+ if (currentAction == null || requestAction == null) {
+ return false;
+ }
+ return currentAction.implies(requestAction);
+ }
+
+ @Override
+ public String toString() {
+ return SentryConstants.AUTHORIZABLE_JOINER.join(parts);
+ }
+
+ public List<KeyValue> getParts() {
+ return parts;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof CommonPrivilege) {
+ CommonPrivilege cp = (CommonPrivilege) o;
+ return parts.equals(cp.parts);
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return parts.hashCode();
+ }
+}
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/KeyValue.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/KeyValue.java b/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/KeyValue.java
deleted file mode 100644
index 77e5fdf..0000000
--- a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/KeyValue.java
+++ /dev/null
@@ -1,99 +0,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.
- */
-package org.apache.sentry.policy.common;
-
-import java.util.List;
-
-import com.google.common.collect.Lists;
-
-public class KeyValue {
- private final String key;
- private final String value;
-
- public KeyValue(String keyValue) {
- List<String> kvList = Lists.newArrayList(PolicyConstants.KV_SPLITTER.trimResults().limit(2).split(keyValue));
- if (kvList.size() != 2) {
- throw new IllegalArgumentException("Invalid key value: " + keyValue + " " + kvList);
- }
- key = kvList.get(0);
- value = kvList.get(1);
- if (key.isEmpty()) {
- throw new IllegalArgumentException("Key cannot be empty");
- } else if (value.isEmpty()) {
- throw new IllegalArgumentException("Value cannot be empty");
- }
- }
-
- public KeyValue(String key, String value) {
- super();
- this.key = key;
- this.value = value;
- }
-
- public String getKey() {
- return key;
- }
-
- public String getValue() {
- return value;
- }
-
- @Override
- public String toString() {
- return PolicyConstants.KV_JOINER.join(key, value);
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((key == null) ? 0 : key.hashCode());
- result = prime * result + ((value == null) ? 0 : value.hashCode());
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- KeyValue other = (KeyValue) obj;
- if (key == null) {
- if (other.key != null) {
- return false;
- }
- } else if (!key.equalsIgnoreCase(other.key)) {
- return false;
- }
- if (value == null) {
- if (other.value != null) {
- return false;
- }
- } else if (!value.equalsIgnoreCase(other.value)) {
- return false;
- }
- return true;
- }
-}
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/PolicyConstants.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/PolicyConstants.java b/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/PolicyConstants.java
deleted file mode 100644
index 0bad8c1..0000000
--- a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/PolicyConstants.java
+++ /dev/null
@@ -1,38 +0,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.
- */
-package org.apache.sentry.policy.common;
-
-import com.google.common.base.Joiner;
-import com.google.common.base.Splitter;
-
-public class PolicyConstants {
-
- public static final String ROLE_SEPARATOR = ",";
- public static final String AUTHORIZABLE_SEPARATOR = "->";
- public static final String KV_SEPARATOR = "=";
-
- public static final Splitter ROLE_SPLITTER = Splitter.on(ROLE_SEPARATOR);
- public static final Splitter AUTHORIZABLE_SPLITTER = Splitter.on(AUTHORIZABLE_SEPARATOR);
- public static final Splitter KV_SPLITTER = Splitter.on(KV_SEPARATOR);
- public static final Joiner ROLE_JOINER = Joiner.on(ROLE_SEPARATOR);
- public static final Joiner AUTHORIZABLE_JOINER = Joiner.on(AUTHORIZABLE_SEPARATOR);
- public static final Joiner KV_JOINER = Joiner.on(KV_SEPARATOR);
-
- // TODO change to privilege
- public static final String PRIVILEGE_NAME = "action";
- public static final String PRIVILEGE_PREFIX = (PRIVILEGE_NAME + KV_SEPARATOR).toLowerCase();
-}
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/Privilege.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/Privilege.java b/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/Privilege.java
index 27d5afa..e9f4609 100644
--- a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/Privilege.java
+++ b/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/Privilege.java
@@ -16,6 +16,8 @@
*/
package org.apache.sentry.policy.common;
+import org.apache.sentry.core.common.Model;
+
public interface Privilege {
- boolean implies(Privilege p);
+ boolean implies(Privilege p, Model model);
}
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/PrivilegeValidator.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/PrivilegeValidator.java b/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/PrivilegeValidator.java
deleted file mode 100644
index 36abdd4..0000000
--- a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/PrivilegeValidator.java
+++ /dev/null
@@ -1,24 +0,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.
- */
-package org.apache.sentry.policy.common;
-
-import org.apache.shiro.config.ConfigurationException;
-
-public interface PrivilegeValidator {
-
- void validate(PrivilegeValidatorContext context) throws ConfigurationException;
-}
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/PrivilegeValidatorContext.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/PrivilegeValidatorContext.java b/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/PrivilegeValidatorContext.java
deleted file mode 100644
index 2b7fd1a..0000000
--- a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/PrivilegeValidatorContext.java
+++ /dev/null
@@ -1,38 +0,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.
- */
-package org.apache.sentry.policy.common;
-
-import javax.annotation.Nullable;
-
-public class PrivilegeValidatorContext {
- private final String database;
- private final String privilege;
- public PrivilegeValidatorContext(String privilege) {
- this(null, privilege);
- }
- public PrivilegeValidatorContext(@Nullable String database, String privilege) {
- super();
- this.database = database;
- this.privilege = privilege;
- }
- public @Nullable String getDatabase() {
- return database;
- }
- public String getPrivilege() {
- return privilege;
- }
-}
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-common/src/test/java/org/apache/sentry/policy/common/ModelForTest.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-common/src/test/java/org/apache/sentry/policy/common/ModelForTest.java b/sentry-policy/sentry-policy-common/src/test/java/org/apache/sentry/policy/common/ModelForTest.java
new file mode 100644
index 0000000..6c7ea08
--- /dev/null
+++ b/sentry-policy/sentry-policy-common/src/test/java/org/apache/sentry/policy/common/ModelForTest.java
@@ -0,0 +1,87 @@
+/*
+ * 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.policy.common;
+
+import org.apache.sentry.core.common.*;
+import org.apache.sentry.core.model.db.DBModelAuthorizable;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ModelForTest implements Model {
+
+ private Map<String, ImplyMethodType> implyMethodMap;
+ private BitFieldActionFactory bitFieldActionFactory;
+
+ public ModelForTest() {
+ implyMethodMap = new HashMap<String, ImplyMethodType>();
+ bitFieldActionFactory = new ActionFactoryForTest();
+
+ implyMethodMap.put(DBModelAuthorizable.AuthorizableType.Server.name().toLowerCase(), ImplyMethodType.STRING);
+ implyMethodMap.put(DBModelAuthorizable.AuthorizableType.Db.name().toLowerCase(), ImplyMethodType.STRING);
+ implyMethodMap.put(DBModelAuthorizable.AuthorizableType.Table.name().toLowerCase(), ImplyMethodType.STRING);
+ implyMethodMap.put(DBModelAuthorizable.AuthorizableType.Column.name().toLowerCase(), ImplyMethodType.STRING_CASE_SENSITIVE);
+ implyMethodMap.put(DBModelAuthorizable.AuthorizableType.URI.name().toLowerCase(), ImplyMethodType.URL);
+ }
+
+ public Map<String, ImplyMethodType> getImplyMethodMap() {
+ return implyMethodMap;
+ }
+
+ public BitFieldActionFactory getBitFieldActionFactory() {
+ return bitFieldActionFactory;
+ }
+
+ public static class ActionFactoryForTest extends BitFieldActionFactory {
+ enum ActionType {
+ SELECT("select", 1),
+ INSERT("insert", 2),
+ ALL("all", SELECT.getCode() | INSERT.getCode()),
+ ALL_STAR("*", SELECT.getCode() | INSERT.getCode());
+
+ private String name;
+ private int code;
+
+ ActionType(String name, int code) {
+ this.name = name;
+ this.code = code;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public String getName() {
+ return name;
+ }
+ }
+
+ public List<? extends BitFieldAction> getActionsByCode(int actionCode) {
+ return null;
+ }
+
+ public BitFieldAction getActionByName(String name) {
+ for (ActionType action : ActionType.values()) {
+ if (action.name.equalsIgnoreCase(name)) {
+ return new BitFieldAction(action.getName(), action.getCode());
+ }
+ }
+ return null;
+ }
+ }
+}