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; + } + } +}
