You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sentry.apache.org by gq...@apache.org on 2015/05/12 09:06:54 UTC
incubator-sentry git commit: SENTRY-612: Sqoop2 integration with
sentry (Guoquan Shen, reviewed by Prasad Mujumdar)
Repository: incubator-sentry
Updated Branches:
refs/heads/master 6498ce90d -> 357d83fbc
SENTRY-612: Sqoop2 integration with sentry (Guoquan Shen, reviewed by Prasad Mujumdar)
Project: http://git-wip-us.apache.org/repos/asf/incubator-sentry/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-sentry/commit/357d83fb
Tree: http://git-wip-us.apache.org/repos/asf/incubator-sentry/tree/357d83fb
Diff: http://git-wip-us.apache.org/repos/asf/incubator-sentry/diff/357d83fb
Branch: refs/heads/master
Commit: 357d83fbc619ba14bb63a6dce0200c5560e18376
Parents: 6498ce9
Author: Guoquan Shen <gu...@intel.com>
Authored: Tue May 12 14:43:06 2015 +0800
Committer: Guoquan Shen <gu...@intel.com>
Committed: Tue May 12 14:43:06 2015 +0800
----------------------------------------------------------------------
pom.xml | 26 ++
sentry-binding/pom.xml | 1 +
sentry-binding/sentry-binding-sqoop/pom.xml | 80 ++++
.../org/apache/sentry/sqoop/PrincipalDesc.java | 50 +++
.../apache/sentry/sqoop/SentrySqoopError.java | 32 ++
.../sqoop/authz/SentryAccessController.java | 192 +++++++++
.../sqoop/authz/SentryAuthorizationHander.java | 117 ++++++
.../authz/SentryAuthorizationValidator.java | 63 +++
.../sentry/sqoop/binding/SqoopAuthBinding.java | 393 +++++++++++++++++++
.../binding/SqoopAuthBindingSingleton.java | 96 +++++
.../sqoop/binding/SqoopProviderBackend.java | 44 +++
.../apache/sentry/sqoop/conf/SqoopAuthConf.java | 75 ++++
.../sqoop/MockAuthenticationProvider.java | 32 ++
.../sqoop/TestSentryAuthorizationHander.java | 74 ++++
.../apache/sentry/sqoop/TestSqoopAuthConf.java | 62 +++
.../test/resources/no-configure-sentry-site.xml | 22 ++
.../src/test/resources/sentry-site.xml | 38 ++
.../src/test/resources/test-authz-provider.ini | 40 ++
sentry-dist/pom.xml | 4 +
.../provider/common/AuthorizationComponent.java | 1 +
sentry-provider/sentry-provider-db/pom.xml | 4 +
.../generic/SentryGenericProviderBackend.java | 153 ++++++++
.../persistent/PrivilegeOperatePersistence.java | 2 +
.../thrift/SentryGenericPolicyProcessor.java | 9 +
24 files changed, 1610 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 863f70c..8bcf1d0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -94,6 +94,7 @@ limitations under the License.
<objenesis.version>1.2</objenesis.version>
<cglib.version>2.2</cglib.version>
<commons-pool2.version>2.2</commons-pool2.version>
+ <sqoop.version>1.99.6</sqoop.version>
</properties>
<dependencyManagement>
@@ -371,6 +372,11 @@ limitations under the License.
</dependency>
<dependency>
<groupId>org.apache.sentry</groupId>
+ <artifactId>sentry-binding-sqoop</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sentry</groupId>
<artifactId>sentry-provider-common</artifactId>
<version>${project.version}</version>
</dependency>
@@ -531,6 +537,26 @@ limitations under the License.
<artifactId>commons-pool2</artifactId>
<version>${commons-pool2.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.sqoop</groupId>
+ <artifactId>sqoop-common</artifactId>
+ <version>${sqoop.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sqoop</groupId>
+ <artifactId>sqoop-security</artifactId>
+ <version>${sqoop.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sqoop</groupId>
+ <artifactId>sqoop-server</artifactId>
+ <version>${sqoop.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sqoop</groupId>
+ <artifactId>test</artifactId>
+ <version>${sqoop.version}</version>
+ </dependency>
</dependencies>
</dependencyManagement>
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-binding/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-binding/pom.xml b/sentry-binding/pom.xml
index b903ab3..8e0256c 100644
--- a/sentry-binding/pom.xml
+++ b/sentry-binding/pom.xml
@@ -32,6 +32,7 @@ limitations under the License.
<modules>
<module>sentry-binding-hive</module>
<module>sentry-binding-solr</module>
+ <module>sentry-binding-sqoop</module>
</modules>
</project>
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-binding/sentry-binding-sqoop/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/pom.xml b/sentry-binding/sentry-binding-sqoop/pom.xml
new file mode 100644
index 0000000..2d25d21
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/pom.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.sentry</groupId>
+ <artifactId>sentry-binding</artifactId>
+ <version>1.6.0-incubating-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>sentry-binding-sqoop</artifactId>
+ <name>Sentry Binding for Sqoop</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sentry</groupId>
+ <artifactId>sentry-core-common</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sentry</groupId>
+ <artifactId>sentry-core-model-sqoop</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sentry</groupId>
+ <artifactId>sentry-provider-common</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sentry</groupId>
+ <artifactId>sentry-provider-file</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sentry</groupId>
+ <artifactId>sentry-provider-db</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sentry</groupId>
+ <artifactId>sentry-policy-common</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sentry</groupId>
+ <artifactId>sentry-policy-sqoop</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-common</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sqoop</groupId>
+ <artifactId>sqoop-common</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sqoop</groupId>
+ <artifactId>sqoop-security</artifactId>
+ </dependency>
+ </dependencies>
+
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/PrincipalDesc.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/PrincipalDesc.java b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/PrincipalDesc.java
new file mode 100644
index 0000000..cc9096c
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/PrincipalDesc.java
@@ -0,0 +1,50 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sentry.sqoop;
+
+public class PrincipalDesc {
+ public static enum PrincipalType {
+ USER,
+ ROLE,
+ GROUP;
+ }
+
+ private String name;
+ private PrincipalType type;
+
+ public PrincipalDesc(String name, String type) {
+ this.name = name;
+ this.type = fromStr(type);
+ }
+
+ private PrincipalType fromStr(String str) {
+ return Enum.valueOf(PrincipalType.class, str.toUpperCase());
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public PrincipalType getType() {
+ return type;
+ }
+
+ public static PrincipalDesc fromStr(String name, String type) {
+ return new PrincipalDesc(name, type);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/SentrySqoopError.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/SentrySqoopError.java b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/SentrySqoopError.java
new file mode 100644
index 0000000..b86c59f
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/SentrySqoopError.java
@@ -0,0 +1,32 @@
+/*
+ * 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.sqoop;
+
+public class SentrySqoopError {
+ public static final String SHOW_GRANT_NOT_SUPPORTED_FOR_PRINCIPAL =
+ "Sentry does only support show roles on group, not supported on ";
+ public static final String AUTHORIZE_CHECK_NOT_SUPPORT_FOR_PRINCIPAL =
+ "Sentry does only support authorization check on user principal, not supported on ";
+ public static final String SHOW_PRIVILEGE_NOT_SUPPORTED_FOR_PRINCIPAL =
+ "Sentry does only support show privilege on role, not supported on ";
+ public static final String GRANT_REVOKE_PRIVILEGE_NOT_SUPPORT_FOR_PRINCIPAL =
+ "Sentry does only support grant/revoke privilege to/from role, not supported on ";
+ public static final String GRANT_REVOKE_ROLE_NOT_SUPPORT_FOR_PRINCIPAL =
+ "Sentry does only support grant/revoke role to/from group, not supported on ";
+ public static final String NOT_IMPLEMENT_YET =
+ "Sentry does not implement yet ";
+}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/authz/SentryAccessController.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/authz/SentryAccessController.java b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/authz/SentryAccessController.java
new file mode 100644
index 0000000..7762f61
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/authz/SentryAccessController.java
@@ -0,0 +1,192 @@
+/*
+ * 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.sqoop.authz;
+
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.apache.sentry.core.common.Subject;
+import org.apache.sentry.sqoop.PrincipalDesc;
+import org.apache.sentry.sqoop.PrincipalDesc.PrincipalType;
+import org.apache.sentry.sqoop.SentrySqoopError;
+import org.apache.sentry.sqoop.binding.SqoopAuthBinding;
+import org.apache.sentry.sqoop.binding.SqoopAuthBindingSingleton;
+import org.apache.sqoop.common.SqoopException;
+import org.apache.sqoop.model.MPrincipal;
+import org.apache.sqoop.model.MPrivilege;
+import org.apache.sqoop.model.MResource;
+import org.apache.sqoop.model.MRole;
+import org.apache.sqoop.security.AuthorizationAccessController;
+import org.apache.sqoop.security.SecurityError;
+
+public class SentryAccessController extends AuthorizationAccessController {
+ private static final Logger LOG = Logger.getLogger(SentryAccessController.class);
+ private final SqoopAuthBinding binding;
+
+ public SentryAccessController() throws Exception {
+ this.binding = SqoopAuthBindingSingleton.getInstance().getAuthBinding();
+ }
+
+ private Subject getSubject() {
+ return new Subject(SentryAuthorizationHander.getAuthenticator().getUserName());
+ }
+
+ @Override
+ public void createRole(MRole role) throws SqoopException {
+ binding.createRole(getSubject(), role.getName());
+ }
+
+ @Override
+ public void dropRole(MRole role) throws SqoopException {
+ binding.dropRole(getSubject(), role.getName());
+ }
+
+ @Override
+ public List<MRole> getAllRoles() throws SqoopException {
+ return binding.listAllRoles(getSubject());
+ }
+
+ @Override
+ public List<MPrincipal> getPrincipalsByRole(MRole role) throws SqoopException {
+ /**
+ * Sentry does not implement this function yet
+ */
+ throw new SqoopException(SecurityError.AUTH_0014, SentrySqoopError.NOT_IMPLEMENT_YET);
+ }
+
+ @Override
+ public List<MPrivilege> getPrivilegesByPrincipal(MPrincipal principal,
+ MResource resource) throws SqoopException {
+ /**
+ * Sentry Only supports get privilege by role
+ */
+ PrincipalDesc principalDesc = PrincipalDesc.fromStr(principal.getName(), principal.getType());
+ if (principalDesc.getType() != PrincipalType.ROLE) {
+ throw new SqoopException(SecurityError.AUTH_0014,
+ SentrySqoopError.SHOW_PRIVILEGE_NOT_SUPPORTED_FOR_PRINCIPAL
+ + principalDesc.getType().name());
+ }
+ return binding.listPrivilegeByRole(getSubject(), principalDesc.getName(), resource);
+ }
+
+ @Override
+ public List<MRole> getRolesByPrincipal(MPrincipal principal) throws SqoopException {
+ /**
+ * Sentry Only supports get privilege by role
+ */
+ PrincipalDesc principalDesc = PrincipalDesc.fromStr(principal.getName(), principal.getType());
+ if (principalDesc.getType() != PrincipalType.GROUP) {
+ throw new SqoopException(SecurityError.AUTH_0014,
+ SentrySqoopError.SHOW_GRANT_NOT_SUPPORTED_FOR_PRINCIPAL
+ + principalDesc.getType().name());
+ }
+ return binding.listRolesByGroup(getSubject(), principalDesc.getName());
+ }
+
+ @Override
+ public void grantPrivileges(List<MPrincipal> principals, List<MPrivilege> privileges)
+ throws SqoopException {
+ for (MPrincipal principal : principals) {
+ PrincipalDesc principalDesc = PrincipalDesc.fromStr(principal.getName(), principal.getType());
+ if (principalDesc.getType() != PrincipalType.ROLE) {
+ throw new SqoopException(SecurityError.AUTH_0014,
+ SentrySqoopError.GRANT_REVOKE_PRIVILEGE_NOT_SUPPORT_FOR_PRINCIPAL
+ + principalDesc.getType().name());
+ }
+
+ for (MPrivilege privilege : privileges) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Going to grant privilege : " + privilege +
+ " to principal: " + principal);
+ }
+ binding.grantPrivilege(getSubject(), principal.getName(), privilege);
+ }
+ }
+ }
+
+ @Override
+ public void grantRole(List<MPrincipal> principals, List<MRole> roles)
+ throws SqoopException {
+ for (MPrincipal principal : principals) {
+ PrincipalDesc principalDesc = PrincipalDesc.fromStr(principal.getName(), principal.getType());
+ if (principalDesc.getType() != PrincipalType.GROUP) {
+ throw new SqoopException(SecurityError.AUTH_0014,
+ SentrySqoopError.GRANT_REVOKE_ROLE_NOT_SUPPORT_FOR_PRINCIPAL
+ + principalDesc.getType().name());
+ }
+ for (MRole role : roles) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Going to grant role : " + role.getName() +
+ " to principal: " + principal);
+ }
+ binding.grantGroupToRole(getSubject(), principal.getName(), role);
+ }
+ }
+ }
+
+ @Override
+ public void removeResource(MResource resource) throws SqoopException {
+ binding.dropPrivilege(getSubject(), resource);
+ }
+
+ @Override
+ public void revokePrivileges(List<MPrincipal> principals, List<MPrivilege> privileges)
+ throws SqoopException {
+ for (MPrincipal principal : principals) {
+ PrincipalDesc principalDesc = PrincipalDesc.fromStr(principal.getName(), principal.getType());
+ if (principalDesc.getType() != PrincipalType.ROLE) {
+ throw new SqoopException(SecurityError.AUTH_0014,
+ SentrySqoopError.GRANT_REVOKE_PRIVILEGE_NOT_SUPPORT_FOR_PRINCIPAL
+ + principalDesc.getType().name());
+ }
+
+ for (MPrivilege privilege : privileges) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Going to revoke privilege : " + privilege +
+ " from principal: " + principal);
+ }
+ binding.revokePrivilege(getSubject(), principal.getName(), privilege);
+ }
+ }
+ }
+
+ @Override
+ public void revokeRole(List<MPrincipal> principals, List<MRole> roles)
+ throws SqoopException {
+ for (MPrincipal principal : principals) {
+ PrincipalDesc principalDesc = PrincipalDesc.fromStr(principal.getName(), principal.getType());
+ if (principalDesc.getType() != PrincipalType.GROUP) {
+ throw new SqoopException(SecurityError.AUTH_0014,
+ SentrySqoopError.GRANT_REVOKE_ROLE_NOT_SUPPORT_FOR_PRINCIPAL
+ + principalDesc.getType().name());
+ }
+ for (MRole role : roles) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Going to revoke role : " + role.getName() +
+ " from principal: " + principal);
+ }
+ binding.revokeGroupfromRole(getSubject(), principal.getName(), role);
+ }
+ }
+ }
+
+ @Override
+ public void updateResource(MResource srcResource, MResource dstResource)
+ throws SqoopException {
+ binding.renamePrivilege(getSubject(), srcResource, dstResource);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/authz/SentryAuthorizationHander.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/authz/SentryAuthorizationHander.java b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/authz/SentryAuthorizationHander.java
new file mode 100644
index 0000000..93bf3f3
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/authz/SentryAuthorizationHander.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sentry.sqoop.authz;
+
+import java.util.List;
+
+import org.apache.sqoop.common.SqoopException;
+import org.apache.sqoop.model.MPrincipal;
+import org.apache.sqoop.model.MPrivilege;
+import org.apache.sqoop.model.MResource;
+import org.apache.sqoop.model.MRole;
+import org.apache.sqoop.security.AuthenticationProvider;
+import org.apache.sqoop.security.authorization.DefaultAuthorizationHandler;
+
+public class SentryAuthorizationHander extends DefaultAuthorizationHandler {
+ private static AuthenticationProvider authenticator;
+
+ public static AuthenticationProvider getAuthenticator() {
+ if (authenticator == null) {
+ throw new RuntimeException("authenticator can't be null");
+ }
+ return authenticator;
+ }
+ @Override
+ public void doInitialize(AuthenticationProvider authenticationProvider, String serverName)
+ throws ClassNotFoundException, IllegalAccessException,
+ InstantiationException {
+ super.doInitialize(authenticationProvider, serverName);
+ authenticator = authenticationProvider;
+ }
+
+ @Override
+ public void checkPrivileges(MPrincipal principal, List<MPrivilege> privileges)
+ throws SqoopException {
+ authorizationValidator.checkPrivileges(principal, privileges);
+ }
+
+ @Override
+ public void createRole(MRole role) throws SqoopException {
+ authorizationAccessController.createRole(role);
+ }
+
+ @Override
+ public void dropRole(MRole role) throws SqoopException {
+ authorizationAccessController.dropRole(role);
+ }
+
+ @Override
+ public List<MRole> getAllRoles() throws SqoopException {
+ return authorizationAccessController.getAllRoles();
+ }
+
+ @Override
+ public List<MPrincipal> getPrincipalsByRole(MRole role) throws SqoopException {
+ return authorizationAccessController.getPrincipalsByRole(role);
+ }
+
+ @Override
+ public List<MPrivilege> getPrivilegesByPrincipal(MPrincipal principal,
+ MResource resource) throws SqoopException {
+ return authorizationAccessController.getPrivilegesByPrincipal(principal, resource);
+ }
+
+ @Override
+ public List<MRole> getRolesByPrincipal(MPrincipal principal) throws SqoopException {
+ return authorizationAccessController.getRolesByPrincipal(principal);
+ }
+
+ @Override
+ public void grantPrivileges(List<MPrincipal> principals, List<MPrivilege> privileges)
+ throws SqoopException {
+ authorizationAccessController.grantPrivileges(principals, privileges);
+ }
+
+ @Override
+ public void grantRole(List<MPrincipal> principals, List<MRole> roles)
+ throws SqoopException {
+ authorizationAccessController.grantRole(principals, roles);
+ }
+
+ @Override
+ public void removeResource(MResource resource) throws SqoopException {
+ authorizationAccessController.removeResource(resource);
+ }
+
+ @Override
+ public void revokePrivileges(List<MPrincipal> principals, List<MPrivilege> privileges)
+ throws SqoopException {
+ authorizationAccessController.revokePrivileges(principals, privileges);
+ }
+
+ @Override
+ public void revokeRole(List<MPrincipal> principals, List<MRole> roles)
+ throws SqoopException {
+ authorizationAccessController.revokeRole(principals, roles);
+ }
+
+ @Override
+ public void updateResource(MResource srcResource, MResource dstResource)
+ throws SqoopException {
+ authorizationAccessController.updateResource(srcResource, dstResource);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/authz/SentryAuthorizationValidator.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/authz/SentryAuthorizationValidator.java b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/authz/SentryAuthorizationValidator.java
new file mode 100644
index 0000000..5f96767
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/authz/SentryAuthorizationValidator.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.sqoop.authz;
+
+import java.util.List;
+
+import org.apache.sentry.core.common.Subject;
+import org.apache.sentry.sqoop.PrincipalDesc;
+import org.apache.sentry.sqoop.PrincipalDesc.PrincipalType;
+import org.apache.sentry.sqoop.SentrySqoopError;
+import org.apache.sentry.sqoop.binding.SqoopAuthBinding;
+import org.apache.sentry.sqoop.binding.SqoopAuthBindingSingleton;
+import org.apache.sqoop.common.SqoopException;
+import org.apache.sqoop.model.MPrincipal;
+import org.apache.sqoop.model.MPrivilege;
+import org.apache.sqoop.security.AuthorizationValidator;
+import org.apache.sqoop.security.SecurityError;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SentryAuthorizationValidator extends AuthorizationValidator {
+ private static final Logger LOG = LoggerFactory.getLogger(SentryAuthorizationValidator.class);
+ private final SqoopAuthBinding binding;
+
+ public SentryAuthorizationValidator() throws Exception {
+ this.binding = SqoopAuthBindingSingleton.getInstance().getAuthBinding();
+ }
+
+ @Override
+ public void checkPrivileges(MPrincipal principal, List<MPrivilege> privileges) throws SqoopException {
+ if ((privileges == null) || privileges.isEmpty()) {
+ return;
+ }
+ PrincipalDesc principalDesc = new PrincipalDesc(principal.getName(), principal.getType());
+ if (principalDesc.getType() != PrincipalType.USER) {
+ throw new SqoopException(SecurityError.AUTH_0014,SentrySqoopError.AUTHORIZE_CHECK_NOT_SUPPORT_FOR_PRINCIPAL);
+ }
+ for (MPrivilege privilege : privileges) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Going to authorize check on privilege : " + privilege +
+ " for principal: " + principal);
+ }
+ if (!binding.authorize(new Subject(principalDesc.getName()), privilege)) {
+ throw new SqoopException(SecurityError.AUTH_0014, "User " + principalDesc.getName() +
+ " does not have privileges for : " + privilege.toString());
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/binding/SqoopAuthBinding.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/binding/SqoopAuthBinding.java b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/binding/SqoopAuthBinding.java
new file mode 100644
index 0000000..86b157c
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/binding/SqoopAuthBinding.java
@@ -0,0 +1,393 @@
+/*
+ * 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.sqoop.binding;
+
+import java.lang.reflect.Constructor;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.sentry.SentryUserException;
+import org.apache.sentry.core.common.ActiveRoleSet;
+import org.apache.sentry.core.common.Authorizable;
+import org.apache.sentry.core.common.Subject;
+import org.apache.sentry.core.model.sqoop.Server;
+import org.apache.sentry.core.model.sqoop.SqoopActionConstant;
+import org.apache.sentry.core.model.sqoop.SqoopActionFactory;
+import org.apache.sentry.policy.common.PolicyEngine;
+import org.apache.sentry.provider.common.AuthorizationComponent;
+import org.apache.sentry.provider.common.AuthorizationProvider;
+import org.apache.sentry.provider.common.ProviderBackend;
+import org.apache.sentry.provider.db.generic.service.thrift.SentryGenericServiceClient;
+import org.apache.sentry.provider.db.generic.service.thrift.TAuthorizable;
+import org.apache.sentry.provider.db.generic.service.thrift.TSentryGrantOption;
+import org.apache.sentry.provider.db.generic.service.thrift.TSentryPrivilege;
+import org.apache.sentry.provider.db.generic.service.thrift.TSentryRole;
+import org.apache.sentry.sqoop.conf.SqoopAuthConf.AuthzConfVars;
+import org.apache.sqoop.common.SqoopException;
+import org.apache.sqoop.model.MPrivilege;
+import org.apache.sqoop.model.MResource;
+import org.apache.sqoop.model.MRole;
+import org.apache.sqoop.security.SecurityError;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
+public class SqoopAuthBinding {
+ private static final Logger LOG = LoggerFactory.getLogger(SqoopAuthBinding.class);
+ private static final String COMPONENT_TYPE = AuthorizationComponent.SQOOP;
+
+ private final Configuration authConf;
+ private final AuthorizationProvider authProvider;
+ private final Server sqoopServer;
+ private ProviderBackend providerBackend;
+
+ private final SqoopActionFactory actionFactory = new SqoopActionFactory();
+
+ public SqoopAuthBinding(Configuration authConf, String serverName) throws Exception {
+ this.authConf = authConf;
+ this.authConf.set(AuthzConfVars.AUTHZ_SERVER_NAME.getVar(), serverName);
+ this.sqoopServer = new Server(serverName);
+ this.authProvider = createAuthProvider();
+ }
+
+ /**
+ * Instantiate the configured authz provider
+ * @return {@link AuthorizationProvider}
+ */
+ private AuthorizationProvider createAuthProvider() throws Exception {
+ /**
+ * get the authProvider class, policyEngine class, providerBackend class and resources from the sqoopAuthConf config
+ */
+ String authProviderName = authConf.get(AuthzConfVars.AUTHZ_PROVIDER.getVar(),AuthzConfVars.AUTHZ_PROVIDER.getDefault());
+ String resourceName = authConf.get(AuthzConfVars.AUTHZ_PROVIDER_RESOURCE.getVar(), AuthzConfVars.AUTHZ_PROVIDER_RESOURCE.getDefault());
+ String providerBackendName = authConf.get(AuthzConfVars.AUTHZ_PROVIDER_BACKEND.getVar(), AuthzConfVars.AUTHZ_PROVIDER_BACKEND.getDefault());
+ String policyEngineName = authConf.get(AuthzConfVars.AUTHZ_POLICY_ENGINE.getVar(), AuthzConfVars.AUTHZ_POLICY_ENGINE.getDefault());
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Using authorization provider " + authProviderName +
+ " with resource " + resourceName + ", policy engine "
+ + policyEngineName + ", provider backend " + providerBackendName);
+ }
+
+ //Instantiate the configured providerBackend
+ Constructor<?> providerBackendConstructor =
+ Class.forName(providerBackendName).getDeclaredConstructor(Configuration.class, String.class);
+ providerBackendConstructor.setAccessible(true);
+ providerBackend =
+ (ProviderBackend) providerBackendConstructor.newInstance(new Object[] {authConf, resourceName});
+
+ //Instantiate the configured policyEngine
+ Constructor<?> policyConstructor =
+ Class.forName(policyEngineName).getDeclaredConstructor(String.class, ProviderBackend.class);
+ policyConstructor.setAccessible(true);
+ PolicyEngine policyEngine =
+ (PolicyEngine) policyConstructor.newInstance(new Object[] {sqoopServer.getName(), providerBackend});
+
+ //Instantiate the configured authProvider
+ Constructor<?> constrctor =
+ Class.forName(authProviderName).getDeclaredConstructor(Configuration.class, String.class, PolicyEngine.class);
+ constrctor.setAccessible(true);
+ return (AuthorizationProvider) constrctor.newInstance(new Object[] {authConf, resourceName, policyEngine});
+ }
+
+ /**
+ * Authorize access to a Sqoop privilege
+ * @param subject
+ * @param authorizable
+ * @param action
+ * @return true or false
+ */
+ public boolean authorize(Subject subject, MPrivilege privilege) {
+ List<Authorizable> authorizables = toAuthorizable(privilege.getResource());
+ if (!hasServerInclude(authorizables)) {
+ authorizables.add(0, sqoopServer);
+ }
+ return authProvider.hasAccess(subject,
+ authorizables,
+ Sets.newHashSet(actionFactory.getActionByName(privilege.getAction())), ActiveRoleSet.ALL);
+ }
+
+ public boolean hasServerInclude(List<Authorizable> authorizables) {
+ for (Authorizable authorizable : authorizables) {
+ if (authorizable.getTypeName().equalsIgnoreCase(sqoopServer.getTypeName())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * The Sentry-296(generate client for connection pooling) has already finished development and reviewed by now. When it
+ * was committed to master, the getClient method was needed to refactor using the connection pool
+ */
+ private SentryGenericServiceClient getClient() throws Exception {
+ return new SentryGenericServiceClient(authConf);
+ }
+
+ public void createRole(final Subject subject, final String role) throws SqoopException {
+ execute(new Command<Void>() {
+ @Override
+ public Void run(SentryGenericServiceClient client) throws Exception {
+ client.createRole(subject.getName(), role, COMPONENT_TYPE);
+ return null;
+ }
+ });
+ }
+
+ public void dropRole(final Subject subject, final String role) throws SqoopException {
+ execute(new Command<Void>() {
+ @Override
+ public Void run(SentryGenericServiceClient client) throws Exception {
+ client.dropRole(subject.getName(), role, COMPONENT_TYPE);
+ return null;
+ }
+ });
+ }
+
+ public List<MRole> listAllRoles(final Subject subject) throws SqoopException {
+ Set<TSentryRole> tSentryRoles = execute(new Command<Set<TSentryRole>>() {
+ @Override
+ public Set<TSentryRole> run(SentryGenericServiceClient client)
+ throws Exception {
+ return client.listAllRoles(subject.getName(), COMPONENT_TYPE);
+ }
+ });
+
+ List<MRole> roles = Lists.newArrayList();
+ for (TSentryRole tRole : tSentryRoles) {
+ roles.add(new MRole(tRole.getRoleName()));
+ }
+ return roles;
+ }
+
+ public List<MRole> listRolesByGroup(final Subject subject, final String groupName) throws SqoopException {
+ Set<TSentryRole> tSentryRoles = execute(new Command<Set<TSentryRole>>() {
+ @Override
+ public Set<TSentryRole> run(SentryGenericServiceClient client)
+ throws Exception {
+ return client.listRolesByGroupName(subject.getName(), groupName, COMPONENT_TYPE);
+ }
+ });
+
+ List<MRole> roles = Lists.newArrayList();
+ for (TSentryRole tSentryRole : tSentryRoles) {
+ roles.add(new MRole(tSentryRole.getRoleName()));
+ }
+ return roles;
+ }
+
+ public List<MPrivilege> listPrivilegeByRole(final Subject subject, final String role, final MResource resource) throws SqoopException {
+ Set<TSentryPrivilege> tSentryPrivileges = execute(new Command<Set<TSentryPrivilege>>() {
+ @Override
+ public Set<TSentryPrivilege> run(SentryGenericServiceClient client)
+ throws Exception {
+ if (resource == null) {
+ return client.listPrivilegesByRoleName(subject.getName(), role, COMPONENT_TYPE, sqoopServer.getName());
+ } else if (resource.getType().equalsIgnoreCase(MResource.TYPE.SERVER.name())) {
+ return client.listPrivilegesByRoleName(subject.getName(), role, COMPONENT_TYPE, resource.getName());
+ } else {
+ return client.listPrivilegesByRoleName(subject.getName(), role, COMPONENT_TYPE, sqoopServer.getName(), toAuthorizable(resource));
+ }
+ }
+ });
+
+ List<MPrivilege> privileges = Lists.newArrayList();
+ for (TSentryPrivilege tSentryPrivilege : tSentryPrivileges) {
+ privileges.add(toSqoopPrivilege(tSentryPrivilege));
+ }
+ return privileges;
+ }
+
+ public void grantPrivilege(final Subject subject, final String role, final MPrivilege privilege) throws SqoopException {
+ execute(new Command<Void>() {
+ @Override
+ public Void run(SentryGenericServiceClient client) throws Exception {
+ client.grantPrivilege(subject.getName(), role, COMPONENT_TYPE, toTSentryPrivilege(privilege));
+ return null;
+ }
+ });
+ }
+
+ public void revokePrivilege(final Subject subject, final String role, final MPrivilege privilege) throws SqoopException {
+ execute(new Command<Void>() {
+ @Override
+ public Void run(SentryGenericServiceClient client) throws Exception {
+ client.revokePrivilege(subject.getName(), role, COMPONENT_TYPE, toTSentryPrivilege(privilege));
+ return null;
+ }
+ });
+ }
+
+ public void grantGroupToRole(final Subject subject, final String group, final MRole role) throws SqoopException {
+ execute(new Command<Void>() {
+ @Override
+ public Void run(SentryGenericServiceClient client) throws Exception {
+ client.addRoleToGroups(subject.getName(), role.getName(), COMPONENT_TYPE, Sets.newHashSet(group));
+ return null;
+ }
+ });
+ }
+
+ public void revokeGroupfromRole(final Subject subject, final String group, final MRole role) throws SqoopException {
+ execute(new Command<Void>() {
+ @Override
+ public Void run(SentryGenericServiceClient client) throws Exception {
+ client.deleteRoleToGroups(subject.getName(), role.getName(), COMPONENT_TYPE, Sets.newHashSet(group));
+ return null;
+ }
+ });
+ }
+
+ public void renamePrivilege(final Subject subject, final MResource srcResource, final MResource dstResource) throws SqoopException {
+ execute(new Command<Void>() {
+ @Override
+ public Void run(SentryGenericServiceClient client) throws Exception {
+ client.renamePrivilege(subject.getName(), COMPONENT_TYPE, sqoopServer.getName(),
+ toAuthorizable(srcResource), toAuthorizable(dstResource));
+ return null;
+ }
+ });
+ }
+
+ public void dropPrivilege(final Subject subject, final MResource resource) throws SqoopException {
+ execute(new Command<Void>() {
+ @Override
+ public Void run(SentryGenericServiceClient client) throws Exception {
+ TSentryPrivilege privilege = new TSentryPrivilege();
+ privilege.setComponent(COMPONENT_TYPE);
+ privilege.setServiceName(sqoopServer.getName());
+ privilege.setAuthorizables(toTSentryAuthorizable(resource));
+ privilege.setAction(SqoopActionConstant.ALL);
+ client.dropPrivilege(subject.getName(), COMPONENT_TYPE, privilege);
+ return null;
+ }
+ });
+ }
+
+ private MPrivilege toSqoopPrivilege(TSentryPrivilege tPrivilege) {
+ //construct a sqoop resource
+ boolean grantOption = false;
+ if (tPrivilege.getGrantOption() == TSentryGrantOption.TRUE) {
+ grantOption = true;
+ }
+ //construct a sqoop privilege
+ return new MPrivilege(
+ toSqoopResource(tPrivilege.getAuthorizables()),
+ tPrivilege.getAction().equalsIgnoreCase(SqoopActionConstant.ALL) ? SqoopActionConstant.ALL_NAME
+ : tPrivilege.getAction(), grantOption);
+ }
+
+ private MResource toSqoopResource(List<TAuthorizable> authorizables) {
+ if ((authorizables == null) || authorizables.isEmpty()) {
+ //server resource
+ return new MResource(sqoopServer.getName(), MResource.TYPE.SERVER);
+ } else {
+ //currently Sqoop only has one-level hierarchy authorizable resource
+ return new MResource(authorizables.get(0).getName(), authorizables.get(0).getType());
+ }
+ }
+
+ /**
+ * construct a Sentry privilege to call by the thrift API
+ * @param privilege
+ * @return {@link TSentryPrivilege}
+ */
+ private TSentryPrivilege toTSentryPrivilege(MPrivilege privilege) {
+ TSentryPrivilege tSentryPrivilege = new TSentryPrivilege();
+ tSentryPrivilege.setComponent(COMPONENT_TYPE);
+ tSentryPrivilege.setServiceName(sqoopServer.getName());
+ tSentryPrivilege.setAction(privilege.getAction().equalsIgnoreCase(
+ SqoopActionConstant.ALL_NAME) ? SqoopActionConstant.ALL : privilege
+ .getAction());
+ if (privilege.isWith_grant_option()) {
+ tSentryPrivilege.setGrantOption(TSentryGrantOption.TRUE);
+ } else {
+ tSentryPrivilege.setGrantOption(TSentryGrantOption.FALSE);
+ }
+ tSentryPrivilege.setAuthorizables(toTSentryAuthorizable(privilege.getResource()));
+ return tSentryPrivilege;
+ }
+
+
+ private List<TAuthorizable> toTSentryAuthorizable(MResource resource) {
+ List<TAuthorizable> tAuthorizables = Lists.newArrayList();
+ /**
+ * Currently Sqoop supports grant privileges on server object, but the server name must be equaled the configuration
+ * of org.apache.sqoop.security.authorization.server_name in the Sqoop.properties.
+ */
+ if (resource.getType().equalsIgnoreCase(MResource.TYPE.SERVER.name())) {
+ if (!resource.getName().equalsIgnoreCase(sqoopServer.getName())) {
+ throw new IllegalArgumentException( resource.getName() + " must be equal to " + sqoopServer.getName() + "\n" +
+ " Currently Sqoop supports grant/revoke privileges on server object, but the server name must be equal to the configuration " +
+ "of org.apache.sqoop.security.authorization.server_name in the Sqoop.properties");
+ }
+ } else {
+ tAuthorizables.add(new TAuthorizable(resource.getType(), resource.getName()));
+ }
+ return tAuthorizables;
+ }
+
+ private List<Authorizable> toAuthorizable(final MResource resource) {
+ List<Authorizable> authorizables = Lists.newArrayList();
+ if (resource == null) {
+ return authorizables;
+ }
+ authorizables.add(new Authorizable() {
+ @Override
+ public String getTypeName() {
+ return resource.getType();
+ }
+
+ @Override
+ public String getName() {
+ return resource.getName();
+ }
+ });
+ return authorizables;
+ }
+
+ /**
+ * A Command is a closure used to pass a block of code from individual
+ * functions to execute, which centralizes connection error
+ * handling. Command is parameterized on the return type of the function.
+ */
+ private static interface Command<T> {
+ T run(SentryGenericServiceClient client) throws Exception;
+ }
+
+ private <T> T execute(Command<T> cmd) throws SqoopException {
+ SentryGenericServiceClient client = null;
+ try {
+ client = getClient();
+ return cmd.run(client);
+ } catch (SentryUserException ex) {
+ String msg = "Unable to excute command on sentry server: " + ex.getMessage();
+ LOG.error(msg, ex);
+ throw new SqoopException(SecurityError.AUTH_0014, msg, ex);
+ } catch (Exception ex) {
+ String msg = "Unable to obtain client:" + ex.getMessage();
+ LOG.error(msg, ex);
+ throw new SqoopException(SecurityError.AUTH_0014, msg, ex);
+ } finally {
+ if (client != null) {
+ client.close();
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/binding/SqoopAuthBindingSingleton.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/binding/SqoopAuthBindingSingleton.java b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/binding/SqoopAuthBindingSingleton.java
new file mode 100644
index 0000000..bdd60a4
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/binding/SqoopAuthBindingSingleton.java
@@ -0,0 +1,96 @@
+/*
+ * 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.sqoop.binding;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.sentry.sqoop.conf.SqoopAuthConf;
+import org.apache.sentry.sqoop.conf.SqoopAuthConf.AuthzConfVars;
+import org.apache.sqoop.core.SqoopConfiguration;
+import org.apache.sqoop.security.SecurityConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Strings;
+
+public class SqoopAuthBindingSingleton {
+ private static Logger log = LoggerFactory.getLogger(SqoopAuthBindingSingleton.class);
+ private static SqoopAuthBindingSingleton instance = null;
+
+ private SqoopAuthBinding binding;
+
+ private SqoopAuthBindingSingleton() {
+ SqoopAuthBinding tmpBinding = null;
+ try {
+ String serverName = SqoopConfiguration.getInstance().getContext().getString(SecurityConstants.SERVER_NAME);
+ if (Strings.isNullOrEmpty(serverName)) {
+ throw new IllegalArgumentException(SecurityConstants.SERVER_NAME + " can't be null or empty");
+ }
+ SqoopAuthConf conf = loadAuthzConf();
+ validateSentrySqoopConfig(conf);
+ tmpBinding = new SqoopAuthBinding(conf, serverName.trim());
+ log.info("SqoopAuthBinding created successfully");
+ } catch (Exception ex) {
+ log.error("Unable to create SqoopAuthBinding", ex);
+ throw new RuntimeException("Unable to create SqoopAuthBinding: " + ex.getMessage(), ex);
+ }
+ binding = tmpBinding;
+ }
+
+ private SqoopAuthConf loadAuthzConf() {
+ String sentry_site = SqoopConfiguration.getInstance().getContext()
+ .getString(SqoopAuthConf.SENTRY_SQOOP_SITE_URL);
+ if (Strings.isNullOrEmpty(sentry_site)) {
+ throw new IllegalArgumentException("Configuration key " + SqoopAuthConf.SENTRY_SQOOP_SITE_URL
+ + " value '" + sentry_site + "' is invalid.");
+ }
+
+ SqoopAuthConf sqoopAuthConf = null;
+ try {
+ sqoopAuthConf = new SqoopAuthConf(new URL(sentry_site));
+ } catch (MalformedURLException e) {
+ throw new IllegalArgumentException("Configuration key " + SqoopAuthConf.SENTRY_SQOOP_SITE_URL
+ + " specifies a malformed URL '" + sentry_site + "'", e);
+ }
+ return sqoopAuthConf;
+ }
+
+ private void validateSentrySqoopConfig(SqoopAuthConf conf) {
+ boolean isTestingMode = Boolean.parseBoolean(conf.get(AuthzConfVars.AUTHZ_TESTING_MODE.getVar(),
+ AuthzConfVars.AUTHZ_TESTING_MODE.getDefault()));
+ String authentication = SqoopConfiguration.getInstance().getContext()
+ .getString(SecurityConstants.AUTHENTICATION_TYPE, SecurityConstants.TYPE.SIMPLE.name());
+ String kerberos = SecurityConstants.TYPE.KERBEROS.name();
+ if(!isTestingMode && !kerberos.equalsIgnoreCase(authentication)) {
+ throw new IllegalArgumentException(SecurityConstants.AUTHENTICATION_TYPE + "can't be set simple mode in non-testing mode");
+ }
+ }
+
+ public static SqoopAuthBindingSingleton getInstance() {
+ if (instance != null) {
+ return instance;
+ }
+ instance = new SqoopAuthBindingSingleton();
+ return instance;
+ }
+
+ public SqoopAuthBinding getAuthBinding() {
+ return binding;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/binding/SqoopProviderBackend.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/binding/SqoopProviderBackend.java b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/binding/SqoopProviderBackend.java
new file mode 100644
index 0000000..cadc2f5
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/binding/SqoopProviderBackend.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sentry.sqoop.binding;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.sentry.core.model.sqoop.Server;
+import org.apache.sentry.provider.common.AuthorizationComponent;
+import org.apache.sentry.provider.db.generic.SentryGenericProviderBackend;
+import org.apache.sentry.sqoop.conf.SqoopAuthConf.AuthzConfVars;
+
+public class SqoopProviderBackend extends SentryGenericProviderBackend {
+ private Server sqoopServer;
+ public SqoopProviderBackend(Configuration conf, String resourcePath) throws Exception {
+ super(conf);
+ sqoopServer = new Server(conf.get(AuthzConfVars.AUTHZ_SERVER_NAME.getVar()));
+ }
+ @Override
+ public String getComponentType() {
+ return AuthorizationComponent.SQOOP;
+ }
+
+ /**
+ * SqoopProviderBackend use the name of Sqoop Server as the identifier to
+ * distinguish itself from multiple Sqoop Servers
+ */
+ @Override
+ public String getComponentIdentifier() {
+ return sqoopServer.getName();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/conf/SqoopAuthConf.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/conf/SqoopAuthConf.java b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/conf/SqoopAuthConf.java
new file mode 100644
index 0000000..fcf7860
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/conf/SqoopAuthConf.java
@@ -0,0 +1,75 @@
+/*
+ * 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.sqoop.conf;
+
+import java.net.URL;
+import org.apache.hadoop.conf.Configuration;
+
+public class SqoopAuthConf extends Configuration {
+ /**
+ * Configuration key used in sqoop.properties to point at sentry-site.xml
+ */
+ public static final String SENTRY_SQOOP_SITE_URL = "sentry.sqoop.site.url";
+ /**
+ * Config setting definitions
+ */
+ public static enum AuthzConfVars {
+ AUTHZ_PROVIDER("sentry.sqoop.provider","org.apache.sentry.provider.common.HadoopGroupResourceAuthorizationProvider"),
+ AUTHZ_PROVIDER_RESOURCE("sentry.sqoop.provider.resource", ""),
+ AUTHZ_PROVIDER_BACKEND("sentry.sqoop.provider.backend","org.apache.sentry.provider.file.SimpleFileProviderBackend"),
+ AUTHZ_POLICY_ENGINE("sentry.sqoop.policy.engine","org.apache.sentry.policy.sqoop.SimpleSqoopPolicyEngine"),
+ AUTHZ_SERVER_NAME("sentry.sqoop.name", ""),
+ AUTHZ_TESTING_MODE("sentry.sqoop.testing.mode", "false");
+
+ private final String varName;
+ private final String defaultVal;
+
+ AuthzConfVars(String varName, String defaultVal) {
+ this.varName = varName;
+ this.defaultVal = defaultVal;
+ }
+
+ public String getVar() {
+ return varName;
+ }
+
+ public String getDefault() {
+ return defaultVal;
+ }
+
+ public static String getDefault(String varName) {
+ for (AuthzConfVars oneVar : AuthzConfVars.values()) {
+ if (oneVar.getVar().equalsIgnoreCase(varName)) {
+ return oneVar.getDefault();
+ }
+ }
+ return null;
+ }
+ }
+
+ public static final String AUTHZ_SITE_FILE = "sentry-site.xml";
+
+ public SqoopAuthConf(URL sqoopAuthzSiteURL) {
+ super(true);
+ addResource(sqoopAuthzSiteURL);
+ }
+
+ @Override
+ public String get(String varName) {
+ return get(varName, AuthzConfVars.getDefault(varName));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/sqoop/MockAuthenticationProvider.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/sqoop/MockAuthenticationProvider.java b/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/sqoop/MockAuthenticationProvider.java
new file mode 100644
index 0000000..0cd9fc6
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/sqoop/MockAuthenticationProvider.java
@@ -0,0 +1,32 @@
+/*
+ * 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.sqoop;
+
+import org.apache.sqoop.security.AuthenticationProvider;
+
+public class MockAuthenticationProvider extends AuthenticationProvider {
+
+ @Override
+ public String[] getGroupNames() {
+ return new String[]{""};
+ }
+
+ @Override
+ public String getUserName() {
+ return "";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/sqoop/TestSentryAuthorizationHander.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/sqoop/TestSentryAuthorizationHander.java b/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/sqoop/TestSentryAuthorizationHander.java
new file mode 100644
index 0000000..7efc0a2
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/sqoop/TestSentryAuthorizationHander.java
@@ -0,0 +1,74 @@
+/*
+ * 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.sqoop;
+
+import static junit.framework.Assert.fail;
+
+import java.io.File;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.sentry.provider.file.PolicyFiles;
+import org.apache.sentry.sqoop.conf.SqoopAuthConf;
+import org.apache.sentry.sqoop.conf.SqoopAuthConf.AuthzConfVars;
+import org.apache.sqoop.security.SecurityFactory;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.io.Files;
+import com.google.common.io.Resources;
+
+public class TestSentryAuthorizationHander {
+ private static final String RESOURCE_PATH = "test-authz-provider.ini";
+ private SqoopAuthConf authzConf;
+ private File baseDir;
+
+ @Before
+ public void setup() throws Exception {
+ baseDir = Files.createTempDir();
+ PolicyFiles.copyToDir(baseDir, RESOURCE_PATH);
+ authzConf = new SqoopAuthConf(Resources.getResource("sentry-site.xml"));
+ authzConf.set(AuthzConfVars.AUTHZ_PROVIDER_RESOURCE.getVar(), new File(baseDir, RESOURCE_PATH).getPath());
+ }
+
+ @After
+ public void teardown() {
+ if(baseDir != null) {
+ FileUtils.deleteQuietly(baseDir);
+ }
+ }
+
+ /**
+ * Test that incorrect specification of classes for
+ * AUTHZ_ACCESS_CONTROLLER and AUTHZ_ACCESS_VALIDATOR
+ * correctly throw ClassNotFoundExceptions
+ */
+ @Test
+ public void testClassNotFound() throws Exception {
+ try {
+ SecurityFactory.getAuthorizationAccessController("org.apache.sentry.sqoop.authz.BogusSentryAccessController");
+ fail("Exception should have been thrown");
+ } catch (Exception ex) {
+ }
+
+ try {
+ SecurityFactory.getAuthorizationValidator("org.apache.sentry.sqoop.authz.BogusSentryAuthorizationValidator");
+ fail("Exception should have been thrown");
+ } catch (Exception ex) {
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/sqoop/TestSqoopAuthConf.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/sqoop/TestSqoopAuthConf.java b/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/sqoop/TestSqoopAuthConf.java
new file mode 100644
index 0000000..e4991e1
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/sqoop/TestSqoopAuthConf.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sentry.sqoop;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.sentry.sqoop.conf.SqoopAuthConf;
+import org.apache.sentry.sqoop.conf.SqoopAuthConf.AuthzConfVars;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.google.common.io.Resources;
+
+public class TestSqoopAuthConf {
+ private static SqoopAuthConf authAllConf;
+ private static SqoopAuthConf authNoConf;
+ private static List<AuthzConfVars> currentProps;
+
+ @BeforeClass
+ public static void setup() throws Exception {
+ authAllConf = new SqoopAuthConf(Resources.getResource("sentry-site.xml"));
+ authNoConf = new SqoopAuthConf(Resources.getResource("no-configure-sentry-site.xml"));
+ currentProps = Arrays.asList(new AuthzConfVars[]{
+ AuthzConfVars.AUTHZ_PROVIDER, AuthzConfVars.AUTHZ_PROVIDER_BACKEND,
+ AuthzConfVars.AUTHZ_POLICY_ENGINE, AuthzConfVars.AUTHZ_PROVIDER_RESOURCE
+ });
+ }
+
+ @Test
+ public void testPropertiesHaveConfigured() {
+ Assert.assertEquals("org.apache.sentry.provider.common.HadoopGroupResourceAuthorizationProvider",
+ authAllConf.get(AuthzConfVars.AUTHZ_PROVIDER.getVar()));
+ Assert.assertEquals("classpath:test-authz-provider.ini",
+ authAllConf.get(AuthzConfVars.AUTHZ_PROVIDER_RESOURCE.getVar()));
+ Assert.assertEquals("org.apache.sentry.policy.sqoop.SimpleSqoopPolicyEngine",
+ authAllConf.get(AuthzConfVars.AUTHZ_POLICY_ENGINE.getVar()));
+ Assert.assertEquals("true", authAllConf.get(AuthzConfVars.AUTHZ_TESTING_MODE.getVar()));
+ }
+
+ @Test
+ public void testPropertiesNoConfigured() {
+ for (AuthzConfVars currentVar : currentProps) {
+ Assert.assertEquals(currentVar.getDefault(), authNoConf.get(currentVar.getVar()));
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-binding/sentry-binding-sqoop/src/test/resources/no-configure-sentry-site.xml
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/test/resources/no-configure-sentry-site.xml b/sentry-binding/sentry-binding-sqoop/src/test/resources/no-configure-sentry-site.xml
new file mode 100644
index 0000000..f642712
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/test/resources/no-configure-sentry-site.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<!--
+ 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.
+-->
+
+<configuration>
+</configuration>
+
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-binding/sentry-binding-sqoop/src/test/resources/sentry-site.xml
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/test/resources/sentry-site.xml b/sentry-binding/sentry-binding-sqoop/src/test/resources/sentry-site.xml
new file mode 100644
index 0000000..2c98980
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/test/resources/sentry-site.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<!--
+ 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.
+-->
+
+<configuration>
+ <property>
+ <name>sentry.sqoop.provider</name>
+ <value>org.apache.sentry.provider.common.HadoopGroupResourceAuthorizationProvider</value>
+ </property>
+ <property>
+ <name>sentry.sqoop.provider.resource</name>
+ <value>classpath:test-authz-provider.ini</value>
+ </property>
+ <property>
+ <name>sentry.sqoop.policy.engine</name>
+ <value>org.apache.sentry.policy.sqoop.SimpleSqoopPolicyEngine</value>
+ </property>
+ <property>
+ <name>sentry.sqoop.testing.mode</name>
+ <value>true</value>
+ </property>
+</configuration>
+
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-binding/sentry-binding-sqoop/src/test/resources/test-authz-provider.ini
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/test/resources/test-authz-provider.ini b/sentry-binding/sentry-binding-sqoop/src/test/resources/test-authz-provider.ini
new file mode 100644
index 0000000..dc11b4b
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/test/resources/test-authz-provider.ini
@@ -0,0 +1,40 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+[groups]
+developer = jdbc_connector_role, hdfs_connector_role,kafka_connector_role,kite_connector_role,\
+ jobs_analyst_role,links_analyst_role
+analyst = jobs_analyst_role,links_analyst_role
+connectors_operator = jdbc_connector_role, hdfs_connector_role,kafka_connector_role,kite_connector_role
+jobs_analyst = jobs_analyst_role
+job1_2_operator = job1_role,job2_role
+links_analyst = links_analyst_role
+link1_2_operator = link1_role,link2_role
+admin = admin_role
+
+[roles]
+admin_role = server=server1->action=*
+jdbc_connector_role = server=server1->connector=generic-jdbc-connector->action=read
+hdfs_connector_role = server=server1->connector=hdfs-connector->action=read
+kafka_connector_role = server=server1->connector=kafka-connector->action=read
+kite_connector_role = server=server1->connector=kite-connector->action=read
+jobs_analyst_role = server=server1->job=*->action=*
+job1_role = server=server1->job=job1->action=read
+job2_role = server=server1->job=job2->action=read
+links_analyst_role = server=server1->link=*->action=*
+link1_role = server=server1->link=link1->action=read
+link2_role = server=server1->link=link2->action=read
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-dist/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-dist/pom.xml b/sentry-dist/pom.xml
index 51e05a5..cde21c0 100644
--- a/sentry-dist/pom.xml
+++ b/sentry-dist/pom.xml
@@ -56,6 +56,10 @@ limitations under the License.
</dependency>
<dependency>
<groupId>org.apache.sentry</groupId>
+ <artifactId>sentry-binding-sqoop</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sentry</groupId>
<artifactId>solr-sentry-handlers</artifactId>
</dependency>
<dependency>
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/AuthorizationComponent.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/AuthorizationComponent.java b/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/AuthorizationComponent.java
index def3486..6409015 100644
--- a/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/AuthorizationComponent.java
+++ b/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/AuthorizationComponent.java
@@ -21,4 +21,5 @@ package org.apache.sentry.provider.common;
*/
public class AuthorizationComponent{
public static final String Search = "solr";
+ public static final String SQOOP = "sqoop";
}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-provider/sentry-provider-db/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/pom.xml b/sentry-provider/sentry-provider-db/pom.xml
index 7dd40b8..9c4618f 100644
--- a/sentry-provider/sentry-provider-db/pom.xml
+++ b/sentry-provider/sentry-provider-db/pom.xml
@@ -88,6 +88,10 @@ limitations under the License.
</dependency>
<dependency>
<groupId>org.apache.sentry</groupId>
+ <artifactId>sentry-core-model-sqoop</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sentry</groupId>
<artifactId>sentry-provider-common</artifactId>
</dependency>
<dependency>
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/SentryGenericProviderBackend.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/SentryGenericProviderBackend.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/SentryGenericProviderBackend.java
new file mode 100644
index 0000000..11ffde2
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/SentryGenericProviderBackend.java
@@ -0,0 +1,153 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sentry.provider.db.generic;
+
+import java.util.Arrays;
+import java.util.Set;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.sentry.SentryUserException;
+import org.apache.sentry.core.common.ActiveRoleSet;
+import org.apache.sentry.core.common.Authorizable;
+import org.apache.sentry.core.common.SentryConfigurationException;
+import org.apache.sentry.provider.common.ProviderBackend;
+import org.apache.sentry.provider.common.ProviderBackendContext;
+import org.apache.sentry.provider.db.generic.service.thrift.SentryGenericServiceClient;
+import org.apache.sentry.provider.db.generic.service.thrift.TSentryRole;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+
+/**
+ * This class used when any component such as Hive, Solr or Sqoop want to integration with the Sentry service
+ */
+public abstract class SentryGenericProviderBackend implements ProviderBackend {
+ private static final Logger LOGGER = LoggerFactory.getLogger(SentryGenericProviderBackend.class);
+ private final Configuration conf;
+ private volatile boolean initialized = false;
+
+ public SentryGenericProviderBackend(Configuration conf) throws Exception {
+ this.conf = conf;
+ }
+
+ @Override
+ public void initialize(ProviderBackendContext context) {
+ if (initialized) {
+ throw new IllegalStateException("SentryGenericProviderBackend has already been initialized, cannot be initialized twice");
+ }
+ this.initialized = true;
+ }
+
+ /**
+ * The Sentry-296(generate client for connection pooling) has already finished development and reviewed by now. When it
+ * was committed to master, the getClient method was needed to refactor using the connection pool
+ */
+ private SentryGenericServiceClient getClient() throws Exception {
+ return new SentryGenericServiceClient(conf);
+ }
+
+ @Override
+ public ImmutableSet<String> getPrivileges(Set<String> groups,
+ ActiveRoleSet roleSet, Authorizable... authorizableHierarchy) {
+ if (!initialized) {
+ throw new IllegalStateException("SentryGenericProviderBackend has not been properly initialized");
+ }
+ SentryGenericServiceClient client = null;
+ try {
+ client = getClient();
+ return ImmutableSet.copyOf(client.listPrivilegesForProvider(
+ getComponentType(), getComponentIdentifier(), roleSet, groups,
+ Arrays.asList(authorizableHierarchy)));
+ } catch (SentryUserException e) {
+ String msg = "Unable to obtain privileges from server: " + e.getMessage();
+ LOGGER.error(msg, e);
+ } catch (Exception e) {
+ String msg = "Unable to obtain client:" + e.getMessage();
+ LOGGER.error(msg, e);
+ } finally {
+ if (client != null) {
+ client.close();
+ }
+ }
+ return ImmutableSet.of();
+ }
+
+ @Override
+ public ImmutableSet<String> getRoles(Set<String> groups, ActiveRoleSet roleSet) {
+ if (!initialized) {
+ throw new IllegalStateException("SentryGenericProviderBackend has not been properly initialized");
+ }
+ SentryGenericServiceClient client = null;
+ try {
+ Set<TSentryRole> tRoles = Sets.newHashSet();
+ client = getClient();
+ //get the roles according to group
+ String requestor = UserGroupInformation.getCurrentUser().getShortUserName();
+ for (String group : groups) {
+ tRoles.addAll(client.listRolesByGroupName(requestor, group, getComponentType()));
+ }
+ Set<String> roles = Sets.newHashSet();
+ for (TSentryRole tRole : tRoles) {
+ roles.add(tRole.getRoleName());
+ }
+ return ImmutableSet.copyOf(roleSet.isAll() ? roles : Sets.intersection(roles, roleSet.getRoles()));
+ } catch (SentryUserException e) {
+ String msg = "Unable to obtain roles from server: " + e.getMessage();
+ LOGGER.error(msg, e);
+ } catch (Exception e) {
+ String msg = "Unable to obtain client:" + e.getMessage();
+ LOGGER.error(msg, e);
+ } finally {
+ if (client != null) {
+ client.close();
+ }
+ }
+ return ImmutableSet.of();
+ }
+
+ /**
+ * SentryGenericProviderBackend does nothing in the validatePolicy()
+ */
+ @Override
+ public void validatePolicy(boolean strictValidation)
+ throws SentryConfigurationException {
+ if (!initialized) {
+ throw new IllegalStateException("SentryGenericProviderBackend has not been properly initialized");
+ }
+ }
+
+ @Override
+ public void close() {
+ }
+
+ /**
+ * Get the component type for the Generic Provider backend, such as Hive,Solr or Sqoop
+ */
+ public abstract String getComponentType();
+
+ /**
+ * When the providerBackend want to get privileges from the Sentry service.
+ * The component identifier is very important to Sentry service. Take the component type is Hive for example,
+ * when there are multiple HiveServers implemented role-based authorization via Sentry. Each HiveServer must uses a
+ * identifier to distinguish itself from multiple HiveServers.
+ */
+ public abstract String getComponentIdentifier();
+}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/persistent/PrivilegeOperatePersistence.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/persistent/PrivilegeOperatePersistence.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/persistent/PrivilegeOperatePersistence.java
index daeefdf..98b22b0 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/persistent/PrivilegeOperatePersistence.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/persistent/PrivilegeOperatePersistence.java
@@ -32,6 +32,7 @@ import org.apache.sentry.core.common.Authorizable;
import org.apache.sentry.core.common.BitFieldAction;
import org.apache.sentry.core.common.BitFieldActionFactory;
import org.apache.sentry.core.model.search.SearchActionFactory;
+import org.apache.sentry.core.model.sqoop.SqoopActionFactory;
import org.apache.sentry.provider.db.generic.service.persistent.PrivilegeObject.Builder;
import org.apache.sentry.provider.db.service.model.MSentryGMPrivilege;
import org.apache.sentry.provider.db.service.model.MSentryPrivilege;
@@ -50,6 +51,7 @@ public class PrivilegeOperatePersistence {
private static final Map<String, BitFieldActionFactory> actionFactories = Maps.newHashMap();
static{
actionFactories.put("solr", new SearchActionFactory());
+ actionFactories.put("sqoop", new SqoopActionFactory());
}
public boolean checkPrivilegeOption(Set<MSentryRole> roles, PrivilegeObject privilege, PersistenceManager pm) {
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericPolicyProcessor.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericPolicyProcessor.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericPolicyProcessor.java
index d6600a0..62f36b4 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericPolicyProcessor.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericPolicyProcessor.java
@@ -29,6 +29,7 @@ import org.apache.hadoop.conf.Configuration;
import org.apache.sentry.SentryUserException;
import org.apache.sentry.core.common.Authorizable;
import org.apache.sentry.core.model.db.AccessConstants;
+import org.apache.sentry.provider.common.AuthorizationComponent;
import org.apache.sentry.provider.db.SentryAccessDeniedException;
import org.apache.sentry.provider.db.SentryAlreadyExistsException;
import org.apache.sentry.provider.db.SentryInvalidInputException;
@@ -255,6 +256,9 @@ public class SentryGenericPolicyProcessor implements SentryGenericPolicyService.
Set<String> permissions = Sets.newHashSet();
for (PrivilegeObject privilege : privileges) {
List<String> hierarchy = Lists.newArrayList();
+ if (hasComponentServerPrivilege(privilege.getComponent())) {
+ hierarchy.add(KV_JOINER.join("server", privilege.getService()));
+ }
for (Authorizable authorizable : privilege.getAuthorizables()) {
hierarchy.add(KV_JOINER.join(authorizable.getTypeName(),authorizable.getName()));
}
@@ -264,6 +268,11 @@ public class SentryGenericPolicyProcessor implements SentryGenericPolicyService.
return permissions;
}
+ private boolean hasComponentServerPrivilege(String component) {
+ //judge the component whether has the server privilege, for example: sqoop has the privilege on the server
+ return AuthorizationComponent.SQOOP.equalsIgnoreCase(component);
+ }
+
@Override
public TCreateSentryRoleResponse create_sentry_role(
final TCreateSentryRoleRequest request) throws TException {