You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by bb...@apache.org on 2017/06/09 17:55:17 UTC
[10/11] nifi git commit: NIFI-3653: - Introducing UserGroup and
Policy provider interfaces. - Introducing FileUserGroupProvider and
FileAccessPolicyProvider. - Refactoring FileAuthorizer to utilize the file
based implementations. - Introducing the Standa
http://git-wip-us.apache.org/repos/asf/nifi/blob/4ed7511b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/UserGroupProvider.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/UserGroupProvider.java b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/UserGroupProvider.java
new file mode 100644
index 0000000..a7b7a0b
--- /dev/null
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/UserGroupProvider.java
@@ -0,0 +1,108 @@
+/*
+ * 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.nifi.authorization;
+
+import org.apache.nifi.authorization.exception.AuthorizationAccessException;
+import org.apache.nifi.authorization.exception.AuthorizerCreationException;
+import org.apache.nifi.authorization.exception.AuthorizerDestructionException;
+
+import java.util.Set;
+
+/**
+ * Provides access to Users and Groups.
+ *
+ * NOTE: Extensions will be called often and frequently. Because of this, if the underlying implementation needs to
+ * make remote calls or expensive calculations those should probably be done asynchronously and/or cache the results.
+ *
+ * Additionally, extensions need to be thread safe.
+ */
+public interface UserGroupProvider {
+
+ /**
+ * Retrieves all users. Must be non null
+ *
+ * @return a list of users
+ * @throws AuthorizationAccessException if there was an unexpected error performing the operation
+ */
+ Set<User> getUsers() throws AuthorizationAccessException;
+
+ /**
+ * Retrieves the user with the given identifier.
+ *
+ * @param identifier the id of the user to retrieve
+ * @return the user with the given id, or null if no matching user was found
+ * @throws AuthorizationAccessException if there was an unexpected error performing the operation
+ */
+ User getUser(String identifier) throws AuthorizationAccessException;
+
+ /**
+ * Retrieves the user with the given identity.
+ *
+ * @param identity the identity of the user to retrieve
+ * @return the user with the given identity, or null if no matching user was found
+ * @throws AuthorizationAccessException if there was an unexpected error performing the operation
+ */
+ User getUserByIdentity(String identity) throws AuthorizationAccessException;
+
+ /**
+ * Retrieves all groups. Must be non null
+ *
+ * @return a list of groups
+ * @throws AuthorizationAccessException if there was an unexpected error performing the operation
+ */
+ Set<Group> getGroups() throws AuthorizationAccessException;
+
+ /**
+ * Retrieves a Group by id.
+ *
+ * @param identifier the identifier of the Group to retrieve
+ * @return the Group with the given identifier, or null if no matching group was found
+ * @throws AuthorizationAccessException if there was an unexpected error performing the operation
+ */
+ Group getGroup(String identifier) throws AuthorizationAccessException;
+
+ /**
+ * Gets a user and their groups. Must be non null. If the user is not known the UserAndGroups.getUser() and
+ * UserAndGroups.getGroups() should return null
+ *
+ * @return the UserAndGroups for the specified identity
+ * @throws AuthorizationAccessException if there was an unexpected error performing the operation
+ */
+ UserAndGroups getUserAndGroups(String identity) throws AuthorizationAccessException;
+
+ /**
+ * Called immediately after instance creation for implementers to perform additional setup
+ *
+ * @param initializationContext in which to initialize
+ */
+ void initialize(UserGroupProviderInitializationContext initializationContext) throws AuthorizerCreationException;
+
+ /**
+ * Called to configure the Authorizer.
+ *
+ * @param configurationContext at the time of configuration
+ * @throws AuthorizerCreationException for any issues configuring the provider
+ */
+ void onConfigured(AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException;
+
+ /**
+ * Called immediately before instance destruction for implementers to release resources.
+ *
+ * @throws AuthorizerDestructionException If pre-destruction fails.
+ */
+ void preDestruction() throws AuthorizerDestructionException;
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/4ed7511b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/UserGroupProviderInitializationContext.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/UserGroupProviderInitializationContext.java b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/UserGroupProviderInitializationContext.java
new file mode 100644
index 0000000..d83b4b3
--- /dev/null
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/UserGroupProviderInitializationContext.java
@@ -0,0 +1,37 @@
+/*
+ * 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.nifi.authorization;
+
+/**
+ * Initialization content for UserGroupProviders.
+ */
+public interface UserGroupProviderInitializationContext {
+
+ /**
+ * The identifier of the UserGroupProvider.
+ *
+ * @return The identifier
+ */
+ String getIdentifier();
+
+ /**
+ * The lookup for accessing other configured UserGroupProviders.
+ *
+ * @return The UserGroupProvider lookup
+ */
+ UserGroupProviderLookup getUserGroupProviderLookup();
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/4ed7511b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/UserGroupProviderLookup.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/UserGroupProviderLookup.java b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/UserGroupProviderLookup.java
new file mode 100644
index 0000000..b879374
--- /dev/null
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/UserGroupProviderLookup.java
@@ -0,0 +1,31 @@
+/*
+ * 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.nifi.authorization;
+
+/**
+ *
+ */
+public interface UserGroupProviderLookup {
+
+ /**
+ * Looks up the UserGroupProvider with the specified identifier
+ *
+ * @param identifier The identifier of the UserGroupProvider
+ * @return The UserGroupProvider
+ */
+ UserGroupProvider getUserGroupProvider(String identifier);
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/4ed7511b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/exception/UninheritableAuthorizationsException.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/exception/UninheritableAuthorizationsException.java b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/exception/UninheritableAuthorizationsException.java
new file mode 100644
index 0000000..f75ead8
--- /dev/null
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/exception/UninheritableAuthorizationsException.java
@@ -0,0 +1,28 @@
+/*
+ * 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.nifi.authorization.exception;
+
+/**
+ * Represents the case when the proposed authorizations are not inheritable.
+ */
+public class UninheritableAuthorizationsException extends RuntimeException {
+
+ public UninheritableAuthorizationsException(String message) {
+ super(message);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/4ed7511b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/resource/Authorizable.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/resource/Authorizable.java b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/resource/Authorizable.java
index 3219ac2..cd27e10 100644
--- a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/resource/Authorizable.java
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/resource/Authorizable.java
@@ -84,6 +84,7 @@ public interface Authorizable {
final Resource resource = getResource();
final AuthorizationRequest request = new AuthorizationRequest.Builder()
.identity(user.getIdentity())
+ .groups(user.getGroups())
.anonymous(user.isAnonymous())
.accessAttempt(false)
.action(action)
@@ -188,6 +189,7 @@ public interface Authorizable {
final Resource resource = getResource();
final AuthorizationRequest request = new AuthorizationRequest.Builder()
.identity(user.getIdentity())
+ .groups(user.getGroups())
.anonymous(user.isAnonymous())
.accessAttempt(true)
.action(action)
http://git-wip-us.apache.org/repos/asf/nifi/blob/4ed7511b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/user/NiFiUser.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/user/NiFiUser.java b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/user/NiFiUser.java
index c450bc4..6b8012b 100644
--- a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/user/NiFiUser.java
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/user/NiFiUser.java
@@ -17,6 +17,8 @@
package org.apache.nifi.authorization.user;
+import java.util.Set;
+
/**
* A representation of a NiFi user that has logged into the application
*/
@@ -28,6 +30,11 @@ public interface NiFiUser {
String getIdentity();
/**
+ * @return the groups that this user belongs to if this nifi is configured to load user groups, null otherwise.
+ */
+ Set<String> getGroups();
+
+ /**
* @return the next user in the proxied entities chain, or <code>null</code> if no more users exist in the chain.
*/
NiFiUser getChain();
http://git-wip-us.apache.org/repos/asf/nifi/blob/4ed7511b/nifi-framework-api/src/test/java/org/apache/nifi/authorization/TestAbstractPolicyBasedAuthorizer.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/test/java/org/apache/nifi/authorization/TestAbstractPolicyBasedAuthorizer.java b/nifi-framework-api/src/test/java/org/apache/nifi/authorization/TestAbstractPolicyBasedAuthorizer.java
index cda2ac5..08c8bb3 100644
--- a/nifi-framework-api/src/test/java/org/apache/nifi/authorization/TestAbstractPolicyBasedAuthorizer.java
+++ b/nifi-framework-api/src/test/java/org/apache/nifi/authorization/TestAbstractPolicyBasedAuthorizer.java
@@ -16,7 +16,6 @@
*/
package org.apache.nifi.authorization;
-import org.apache.nifi.authorization.exception.AuthorizerCreationException;
import org.junit.Assert;
import org.junit.Test;
import org.mockito.Mockito;
@@ -251,10 +250,7 @@ public class TestAbstractPolicyBasedAuthorizer {
when(authorizer2.getAccessPolicies()).thenReturn(policies2);
// compare the fingerprints
-
assertEquals(authorizer1.getFingerprint(), authorizer2.getFingerprint());
-
- //System.out.println(authorizer1.getFingerprint());
}
@Test
@@ -332,211 +328,4 @@ public class TestAbstractPolicyBasedAuthorizer {
Assert.assertTrue(fingerprint.length() > 0);
}
- @Test(expected = AuthorizerCreationException.class)
- public void testOnConfiguredWhenPoliciesWithSameResourceAndAction() {
- User user1 = new User.Builder().identifier("user-id-1").identity("user-1").build();
-
- AccessPolicy policy1 = new AccessPolicy.Builder()
- .identifier("policy-id-1")
- .resource("resource1")
- .action(RequestAction.READ)
- .addUser(user1.getIdentifier())
- .build();
-
- AccessPolicy policy2 = new AccessPolicy.Builder()
- .identifier("policy-id-2")
- .resource("resource1")
- .action(RequestAction.READ)
- .addUser(user1.getIdentifier())
- .build();
-
- Set<AccessPolicy> policies = new LinkedHashSet<>();
- policies.add(policy1);
- policies.add(policy2);
-
- Set<User> users = new LinkedHashSet<>();
- users.add(user1);
-
- AuthorizerConfigurationContext context = Mockito.mock(AuthorizerConfigurationContext.class);
- AbstractPolicyBasedAuthorizer authorizer = new MockPolicyBasedAuthorizer(new HashSet<>(), users, policies);
- authorizer.onConfigured(context);
- }
-
- @Test(expected = AuthorizerCreationException.class)
- public void testOnConfiguredWhenUsersWithSameIdentity() {
- User user1 = new User.Builder().identifier("user-id-1").identity("user-1").build();
- User user2 = new User.Builder().identifier("user-id-2").identity("user-1").build();
-
- Set<User> users = new LinkedHashSet<>();
- users.add(user1);
- users.add(user2);
-
- AuthorizerConfigurationContext context = Mockito.mock(AuthorizerConfigurationContext.class);
- AbstractPolicyBasedAuthorizer authorizer = new MockPolicyBasedAuthorizer(new HashSet<>(), users, new HashSet<>());
- authorizer.onConfigured(context);
- }
-
- @Test(expected = AuthorizerCreationException.class)
- public void testOnConfiguredWhenGroupsWithSameName() {
- Group group1 = new Group.Builder().identifier("group-id-1").name("group-1").build();
- Group group2 = new Group.Builder().identifier("group-id-2").name("group-1").build();
-
- Set<Group> groups = new LinkedHashSet<>();
- groups.add(group1);
- groups.add(group2);
-
- AuthorizerConfigurationContext context = Mockito.mock(AuthorizerConfigurationContext.class);
- AbstractPolicyBasedAuthorizer authorizer = new MockPolicyBasedAuthorizer(groups, new HashSet<>(), new HashSet<>());
- authorizer.onConfigured(context);
- }
-
- @Test
- public void testAddPoliciesWithSameResourceAndAction() {
- AuthorizerConfigurationContext context = Mockito.mock(AuthorizerConfigurationContext.class);
- AbstractPolicyBasedAuthorizer authorizer = new MockPolicyBasedAuthorizer();
- authorizer.onConfigured(context);
-
- User user1 = new User.Builder().identifier("user-id-1").identity("user-1").build();
- authorizer.addUser(user1);
-
- AccessPolicy policy1 = new AccessPolicy.Builder()
- .identifier("policy-id-1")
- .resource("resource1")
- .action(RequestAction.READ)
- .addUser(user1.getIdentifier())
- .build();
- authorizer.addAccessPolicy(policy1);
-
- AccessPolicy policy2 = new AccessPolicy.Builder()
- .identifier("policy-id-2")
- .resource("resource1")
- .action(RequestAction.READ)
- .addUser(user1.getIdentifier())
- .build();
-
- try {
- authorizer.addAccessPolicy(policy2);
- Assert.fail("Should have thrown exception");
- } catch (IllegalStateException e) {
-
- }
- }
-
- @Test
- public void testAddUsersWithSameIdentity() {
- AuthorizerConfigurationContext context = Mockito.mock(AuthorizerConfigurationContext.class);
- AbstractPolicyBasedAuthorizer authorizer = new MockPolicyBasedAuthorizer();
- authorizer.onConfigured(context);
-
- User user1 = new User.Builder().identifier("user-id-1").identity("user-1").build();
- authorizer.addUser(user1);
-
- User user2 = new User.Builder().identifier("user-id-2").identity("user-1").build();
-
- try {
- authorizer.addUser(user2);
- Assert.fail("Should have thrown exception");
- } catch (IllegalStateException e) {
-
- }
- }
-
- @Test
- public void testAddGroupsWithSameName() {
- AuthorizerConfigurationContext context = Mockito.mock(AuthorizerConfigurationContext.class);
- AbstractPolicyBasedAuthorizer authorizer = new MockPolicyBasedAuthorizer();
- authorizer.onConfigured(context);
-
- Group group1 = new Group.Builder().identifier("group-id-1").name("group-1").build();
- authorizer.addGroup(group1);
-
- Group group2 = new Group.Builder().identifier("group-id-2").name("group-1").build();
-
- try {
- authorizer.addGroup(group2);
- Assert.fail("Should have thrown exception");
- } catch (IllegalStateException e) {
-
- }
- }
-
- @Test
- public void testAddUsersWithSameIdentityAsGroupName() {
- AuthorizerConfigurationContext context = Mockito.mock(AuthorizerConfigurationContext.class);
- AbstractPolicyBasedAuthorizer authorizer = new MockPolicyBasedAuthorizer();
- authorizer.onConfigured(context);
-
- Group group1 = new Group.Builder().identifier("group-id-1").name("abc").build();
- authorizer.addGroup(group1);
-
- User user = new User.Builder().identifier("user-id-2").identity("abc").build();
-
- try {
- authorizer.addUser(user);
- Assert.fail("Should have thrown exception");
- } catch (IllegalStateException e) {
-
- }
- }
-
- @Test
- public void testAddGroupWithSameNameAsUserIdentity() {
- AuthorizerConfigurationContext context = Mockito.mock(AuthorizerConfigurationContext.class);
- AbstractPolicyBasedAuthorizer authorizer = new MockPolicyBasedAuthorizer();
- authorizer.onConfigured(context);
-
- User user = new User.Builder().identifier("user-id-2").identity("abc").build();
- authorizer.addUser(user);
-
- Group group1 = new Group.Builder().identifier("group-id-1").name("abc").build();
- try {
- authorizer.addGroup(group1);
- Assert.fail("Should have thrown exception");
- } catch (IllegalStateException e) {
-
- }
- }
-
- @Test
- public void testUpdateUserWithSameIdentity() {
- AuthorizerConfigurationContext context = Mockito.mock(AuthorizerConfigurationContext.class);
- AbstractPolicyBasedAuthorizer authorizer = new MockPolicyBasedAuthorizer();
- authorizer.onConfigured(context);
-
- User user1 = new User.Builder().identifier("user-id-1").identity("abc").build();
- authorizer.addUser(user1);
-
- User user2 = new User.Builder().identifier("user-id-2").identity("xyz").build();
- authorizer.addUser(user2);
-
- try {
- User user1Updated = new User.Builder().identifier("user-id-1").identity("xyz").build();
- authorizer.updateUser(user1Updated);
- Assert.fail("Should have thrown exception");
- } catch (IllegalStateException e) {
-
- }
- }
-
- @Test
- public void testUpdateGroupWithSameName() {
- AuthorizerConfigurationContext context = Mockito.mock(AuthorizerConfigurationContext.class);
- AbstractPolicyBasedAuthorizer authorizer = new MockPolicyBasedAuthorizer();
- authorizer.onConfigured(context);
-
- Group group1 = new Group.Builder().identifier("group-id-1").name("abc").build();
- authorizer.addGroup(group1);
-
- Group group2 = new Group.Builder().identifier("group-id-2").name("xyz").build();
- authorizer.addGroup(group2);
-
- try {
- Group group1Updated = new Group.Builder().identifier("group-id-1").name("xyz").build();
- authorizer.updateGroup(group1Updated);
- Assert.fail("Should have thrown exception");
- } catch (IllegalStateException e) {
-
- }
- }
-
}
http://git-wip-us.apache.org/repos/asf/nifi/blob/4ed7511b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/pom.xml
index 1fe42d9..b0a64d9 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/pom.xml
@@ -65,15 +65,27 @@
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
- <artifactId>nifi-framework-core</artifactId>
+ <artifactId>nifi-nar-utils</artifactId>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
- <artifactId>nifi-nar-utils</artifactId>
+ <artifactId>nifi-properties</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-beans</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
- <artifactId>nifi-properties</artifactId>
+ <artifactId>nifi-framework-nar-utils</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.nifi</groupId>
+ <artifactId>nifi-framework-authorization</artifactId>
</dependency>
</dependencies>
http://git-wip-us.apache.org/repos/asf/nifi/blob/4ed7511b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/java/org/apache/nifi/authorization/AccessPolicyProviderFactory.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/java/org/apache/nifi/authorization/AccessPolicyProviderFactory.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/java/org/apache/nifi/authorization/AccessPolicyProviderFactory.java
new file mode 100644
index 0000000..c71c982
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/java/org/apache/nifi/authorization/AccessPolicyProviderFactory.java
@@ -0,0 +1,179 @@
+/*
+ * 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.nifi.authorization;
+
+import org.apache.nifi.authorization.exception.AuthorizationAccessException;
+import org.apache.nifi.authorization.exception.AuthorizerCreationException;
+import org.apache.nifi.authorization.exception.AuthorizerDestructionException;
+import org.apache.nifi.authorization.exception.UninheritableAuthorizationsException;
+import org.apache.nifi.nar.NarCloseable;
+
+import java.util.Set;
+
+public final class AccessPolicyProviderFactory {
+
+ public static AccessPolicyProvider withNarLoader(final AccessPolicyProvider baseAccessPolicyProvider) {
+ if (baseAccessPolicyProvider instanceof ConfigurableAccessPolicyProvider) {
+ final ConfigurableAccessPolicyProvider baseConfigurableAccessPolicyProvider = (ConfigurableAccessPolicyProvider) baseAccessPolicyProvider;
+ return new ConfigurableAccessPolicyProvider() {
+ @Override
+ public AccessPolicy addAccessPolicy(AccessPolicy accessPolicy) throws AuthorizationAccessException {
+ try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+ return baseConfigurableAccessPolicyProvider.addAccessPolicy(accessPolicy);
+ }
+ }
+
+ @Override
+ public AccessPolicy updateAccessPolicy(AccessPolicy accessPolicy) throws AuthorizationAccessException {
+ try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+ return baseConfigurableAccessPolicyProvider.updateAccessPolicy(accessPolicy);
+ }
+ }
+
+ @Override
+ public AccessPolicy deleteAccessPolicy(AccessPolicy accessPolicy) throws AuthorizationAccessException {
+ try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+ return baseConfigurableAccessPolicyProvider.deleteAccessPolicy(accessPolicy);
+ }
+ }
+
+ @Override
+ public Set<AccessPolicy> getAccessPolicies() throws AuthorizationAccessException {
+ try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+ return baseConfigurableAccessPolicyProvider.getAccessPolicies();
+ }
+ }
+
+ @Override
+ public AccessPolicy getAccessPolicy(String identifier) throws AuthorizationAccessException {
+ try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+ return baseConfigurableAccessPolicyProvider.getAccessPolicy(identifier);
+ }
+ }
+
+ @Override
+ public AccessPolicy getAccessPolicy(String resourceIdentifier, RequestAction action) throws AuthorizationAccessException {
+ try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+ return baseConfigurableAccessPolicyProvider.getAccessPolicy(resourceIdentifier, action);
+ }
+ }
+
+ @Override
+ public UserGroupProvider getUserGroupProvider() {
+ try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+ return baseConfigurableAccessPolicyProvider.getUserGroupProvider();
+ }
+ }
+
+ @Override
+ public void inheritFingerprint(String fingerprint) throws AuthorizationAccessException {
+ try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+ baseConfigurableAccessPolicyProvider.inheritFingerprint(fingerprint);
+ }
+ }
+
+ @Override
+ public void checkInheritability(String proposedFingerprint) throws AuthorizationAccessException, UninheritableAuthorizationsException {
+ try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+ baseConfigurableAccessPolicyProvider.checkInheritability(proposedFingerprint);
+ }
+ }
+
+ @Override
+ public String getFingerprint() throws AuthorizationAccessException {
+ try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+ return baseConfigurableAccessPolicyProvider.getFingerprint();
+ }
+ }
+
+ @Override
+ public void initialize(AccessPolicyProviderInitializationContext initializationContext) throws AuthorizerCreationException {
+ try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+ baseConfigurableAccessPolicyProvider.initialize(initializationContext);
+ }
+ }
+
+ @Override
+ public void onConfigured(AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
+ try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+ baseConfigurableAccessPolicyProvider.onConfigured(configurationContext);
+ }
+ }
+
+ @Override
+ public void preDestruction() throws AuthorizerDestructionException {
+ try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+ baseConfigurableAccessPolicyProvider.preDestruction();
+ }
+ }
+ };
+ } else {
+ return new AccessPolicyProvider() {
+ @Override
+ public Set<AccessPolicy> getAccessPolicies() throws AuthorizationAccessException {
+ try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+ return baseAccessPolicyProvider.getAccessPolicies();
+ }
+ }
+
+ @Override
+ public AccessPolicy getAccessPolicy(String identifier) throws AuthorizationAccessException {
+ try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+ return baseAccessPolicyProvider.getAccessPolicy(identifier);
+ }
+ }
+
+ @Override
+ public AccessPolicy getAccessPolicy(String resourceIdentifier, RequestAction action) throws AuthorizationAccessException {
+ try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+ return baseAccessPolicyProvider.getAccessPolicy(resourceIdentifier, action);
+ }
+ }
+
+ @Override
+ public UserGroupProvider getUserGroupProvider() {
+ try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+ return baseAccessPolicyProvider.getUserGroupProvider();
+ }
+ }
+
+ @Override
+ public void initialize(AccessPolicyProviderInitializationContext initializationContext) throws AuthorizerCreationException {
+ try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+ baseAccessPolicyProvider.initialize(initializationContext);
+ }
+ }
+
+ @Override
+ public void onConfigured(AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
+ try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+ baseAccessPolicyProvider.onConfigured(configurationContext);
+ }
+ }
+
+ @Override
+ public void preDestruction() throws AuthorizerDestructionException {
+ try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+ baseAccessPolicyProvider.preDestruction();
+ }
+ }
+ };
+ }
+ }
+
+ private AccessPolicyProviderFactory() {}
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/4ed7511b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/java/org/apache/nifi/authorization/AuthorizerCapabilityDetection.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/java/org/apache/nifi/authorization/AuthorizerCapabilityDetection.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/java/org/apache/nifi/authorization/AuthorizerCapabilityDetection.java
new file mode 100644
index 0000000..59de908
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/java/org/apache/nifi/authorization/AuthorizerCapabilityDetection.java
@@ -0,0 +1,45 @@
+/*
+ * 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.nifi.authorization;
+
+public final class AuthorizerCapabilityDetection {
+
+ public static boolean isManagedAuthorizer(final Authorizer authorizer) {
+ return authorizer instanceof ManagedAuthorizer;
+ }
+
+ public static boolean isConfigurableAccessPolicyProvider(final Authorizer authorizer) {
+ if (!isManagedAuthorizer(authorizer)) {
+ return false;
+ }
+
+ final ManagedAuthorizer managedAuthorizer = (ManagedAuthorizer) authorizer;
+ return managedAuthorizer.getAccessPolicyProvider() instanceof ConfigurableAccessPolicyProvider;
+ }
+
+ public static boolean isConfigurableUserGroupProvider(final Authorizer authorizer) {
+ if (!isManagedAuthorizer(authorizer)) {
+ return false;
+ }
+
+ final ManagedAuthorizer managedAuthorizer = (ManagedAuthorizer) authorizer;
+ final AccessPolicyProvider accessPolicyProvider = managedAuthorizer.getAccessPolicyProvider();
+ return accessPolicyProvider.getUserGroupProvider() instanceof ConfigurableUserGroupProvider;
+ }
+
+ private AuthorizerCapabilityDetection() {}
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/4ed7511b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/java/org/apache/nifi/authorization/AuthorizerFactory.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/java/org/apache/nifi/authorization/AuthorizerFactory.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/java/org/apache/nifi/authorization/AuthorizerFactory.java
new file mode 100644
index 0000000..660b47b
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/java/org/apache/nifi/authorization/AuthorizerFactory.java
@@ -0,0 +1,426 @@
+/*
+ * 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.nifi.authorization;
+
+import org.apache.nifi.authorization.exception.AuthorizationAccessException;
+import org.apache.nifi.authorization.exception.AuthorizerCreationException;
+import org.apache.nifi.authorization.exception.AuthorizerDestructionException;
+import org.apache.nifi.authorization.exception.UninheritableAuthorizationsException;
+import org.apache.nifi.nar.NarCloseable;
+
+import java.util.Set;
+
+public final class AuthorizerFactory {
+
+ /**
+ * Checks if another policy exists with the same resource and action as the given policy.
+ *
+ * @param checkAccessPolicy an access policy being checked
+ * @return true if another access policy exists with the same resource and action, false otherwise
+ */
+ private static boolean policyExists(final AccessPolicyProvider accessPolicyProvider, final AccessPolicy checkAccessPolicy) {
+ for (AccessPolicy accessPolicy : accessPolicyProvider.getAccessPolicies()) {
+ if (!accessPolicy.getIdentifier().equals(checkAccessPolicy.getIdentifier())
+ && accessPolicy.getResource().equals(checkAccessPolicy.getResource())
+ && accessPolicy.getAction().equals(checkAccessPolicy.getAction())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Checks if another user exists with the same identity.
+ *
+ * @param identifier identity of the user
+ * @param identity identity of the user
+ * @return true if another user exists with the same identity, false otherwise
+ */
+ private static boolean tenantExists(final UserGroupProvider userGroupProvider, final String identifier, final String identity) {
+ for (User user : userGroupProvider.getUsers()) {
+ if (!user.getIdentifier().equals(identifier)
+ && user.getIdentity().equals(identity)) {
+ return true;
+ }
+ }
+
+ for (Group group : userGroupProvider.getGroups()) {
+ if (!group.getIdentifier().equals(identifier)
+ && group.getName().equals(identity)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public static Authorizer installIntegrityChecks(final Authorizer baseAuthorizer) {
+ if (baseAuthorizer instanceof ManagedAuthorizer) {
+ final ManagedAuthorizer baseManagedAuthorizer = (ManagedAuthorizer) baseAuthorizer;
+ return new ManagedAuthorizer() {
+ @Override
+ public String getFingerprint() throws AuthorizationAccessException {
+ return baseManagedAuthorizer.getFingerprint();
+ }
+
+ @Override
+ public void inheritFingerprint(String fingerprint) throws AuthorizationAccessException {
+ baseManagedAuthorizer.inheritFingerprint(fingerprint);
+ }
+
+ @Override
+ public void checkInheritability(String proposedFingerprint) throws AuthorizationAccessException, UninheritableAuthorizationsException {
+ baseManagedAuthorizer.checkInheritability(proposedFingerprint);
+ }
+
+ @Override
+ public AccessPolicyProvider getAccessPolicyProvider() {
+ final AccessPolicyProvider baseAccessPolicyProvider = baseManagedAuthorizer.getAccessPolicyProvider();
+ if (baseAccessPolicyProvider instanceof ConfigurableAccessPolicyProvider) {
+ final ConfigurableAccessPolicyProvider baseConfigurableAccessPolicyProvider = (ConfigurableAccessPolicyProvider) baseAccessPolicyProvider;
+ return new ConfigurableAccessPolicyProvider() {
+ @Override
+ public String getFingerprint() throws AuthorizationAccessException {
+ return baseConfigurableAccessPolicyProvider.getFingerprint();
+ }
+
+ @Override
+ public void inheritFingerprint(String fingerprint) throws AuthorizationAccessException {
+ baseConfigurableAccessPolicyProvider.inheritFingerprint(fingerprint);
+ }
+
+ @Override
+ public void checkInheritability(String proposedFingerprint) throws AuthorizationAccessException, UninheritableAuthorizationsException {
+ baseConfigurableAccessPolicyProvider.checkInheritability(proposedFingerprint);
+ }
+
+ @Override
+ public AccessPolicy addAccessPolicy(AccessPolicy accessPolicy) throws AuthorizationAccessException {
+ if (policyExists(baseConfigurableAccessPolicyProvider, accessPolicy)) {
+ throw new IllegalStateException(String.format("Found multiple policies for '%s' with '%s'.", accessPolicy.getResource(), accessPolicy.getAction()));
+ }
+ return baseConfigurableAccessPolicyProvider.addAccessPolicy(accessPolicy);
+ }
+
+ @Override
+ public AccessPolicy updateAccessPolicy(AccessPolicy accessPolicy) throws AuthorizationAccessException {
+ return baseConfigurableAccessPolicyProvider.updateAccessPolicy(accessPolicy);
+ }
+
+ @Override
+ public AccessPolicy deleteAccessPolicy(AccessPolicy accessPolicy) throws AuthorizationAccessException {
+ return baseConfigurableAccessPolicyProvider.deleteAccessPolicy(accessPolicy);
+ }
+
+ @Override
+ public Set<AccessPolicy> getAccessPolicies() throws AuthorizationAccessException {
+ return baseConfigurableAccessPolicyProvider.getAccessPolicies();
+ }
+
+ @Override
+ public AccessPolicy getAccessPolicy(String identifier) throws AuthorizationAccessException {
+ return baseConfigurableAccessPolicyProvider.getAccessPolicy(identifier);
+ }
+
+ @Override
+ public AccessPolicy getAccessPolicy(String resourceIdentifier, RequestAction action) throws AuthorizationAccessException {
+ return baseConfigurableAccessPolicyProvider.getAccessPolicy(resourceIdentifier, action);
+ }
+
+ @Override
+ public UserGroupProvider getUserGroupProvider() {
+ final UserGroupProvider baseUserGroupProvider = baseConfigurableAccessPolicyProvider.getUserGroupProvider();
+ if (baseUserGroupProvider instanceof ConfigurableUserGroupProvider) {
+ final ConfigurableUserGroupProvider baseConfigurableUserGroupProvider = (ConfigurableUserGroupProvider) baseUserGroupProvider;
+ return new ConfigurableUserGroupProvider() {
+ @Override
+ public String getFingerprint() throws AuthorizationAccessException {
+ return baseConfigurableUserGroupProvider.getFingerprint();
+ }
+
+ @Override
+ public void inheritFingerprint(String fingerprint) throws AuthorizationAccessException {
+ baseConfigurableUserGroupProvider.inheritFingerprint(fingerprint);
+ }
+
+ @Override
+ public void checkInheritability(String proposedFingerprint) throws AuthorizationAccessException, UninheritableAuthorizationsException {
+ baseConfigurableUserGroupProvider.checkInheritability(proposedFingerprint);
+ }
+
+ @Override
+ public User addUser(User user) throws AuthorizationAccessException {
+ if (tenantExists(baseConfigurableUserGroupProvider, user.getIdentifier(), user.getIdentity())) {
+ throw new IllegalStateException(String.format("User/user group already exists with the identity '%s'.", user.getIdentity()));
+ }
+ return baseConfigurableUserGroupProvider.addUser(user);
+ }
+
+ @Override
+ public User updateUser(User user) throws AuthorizationAccessException {
+ if (tenantExists(baseConfigurableUserGroupProvider, user.getIdentifier(), user.getIdentity())) {
+ throw new IllegalStateException(String.format("User/user group already exists with the identity '%s'.", user.getIdentity()));
+ }
+ return baseConfigurableUserGroupProvider.updateUser(user);
+ }
+
+ @Override
+ public User deleteUser(User user) throws AuthorizationAccessException {
+ return baseConfigurableUserGroupProvider.deleteUser(user);
+ }
+
+ @Override
+ public Group addGroup(Group group) throws AuthorizationAccessException {
+ if (tenantExists(baseConfigurableUserGroupProvider, group.getIdentifier(), group.getName())) {
+ throw new IllegalStateException(String.format("User/user group already exists with the identity '%s'.", group.getName()));
+ }
+ return baseConfigurableUserGroupProvider.addGroup(group);
+ }
+
+ @Override
+ public Group updateGroup(Group group) throws AuthorizationAccessException {
+ if (tenantExists(baseConfigurableUserGroupProvider, group.getIdentifier(), group.getName())) {
+ throw new IllegalStateException(String.format("User/user group already exists with the identity '%s'.", group.getName()));
+ }
+ return baseConfigurableUserGroupProvider.updateGroup(group);
+ }
+
+ @Override
+ public Group deleteGroup(Group group) throws AuthorizationAccessException {
+ return baseConfigurableUserGroupProvider.deleteGroup(group);
+ }
+
+ @Override
+ public Set<User> getUsers() throws AuthorizationAccessException {
+ return baseConfigurableUserGroupProvider.getUsers();
+ }
+
+ @Override
+ public User getUser(String identifier) throws AuthorizationAccessException {
+ return baseConfigurableUserGroupProvider.getUser(identifier);
+ }
+
+ @Override
+ public User getUserByIdentity(String identity) throws AuthorizationAccessException {
+ return baseConfigurableUserGroupProvider.getUserByIdentity(identity);
+ }
+
+ @Override
+ public Set<Group> getGroups() throws AuthorizationAccessException {
+ return baseConfigurableUserGroupProvider.getGroups();
+ }
+
+ @Override
+ public Group getGroup(String identifier) throws AuthorizationAccessException {
+ return baseConfigurableUserGroupProvider.getGroup(identifier);
+ }
+
+ @Override
+ public UserAndGroups getUserAndGroups(String identity) throws AuthorizationAccessException {
+ return baseConfigurableUserGroupProvider.getUserAndGroups(identity);
+ }
+
+ @Override
+ public void initialize(UserGroupProviderInitializationContext initializationContext) throws AuthorizerCreationException {
+ baseConfigurableUserGroupProvider.initialize(initializationContext);
+ }
+
+ @Override
+ public void onConfigured(AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
+ baseConfigurableUserGroupProvider.onConfigured(configurationContext);
+ }
+
+ @Override
+ public void preDestruction() throws AuthorizerDestructionException {
+ baseConfigurableUserGroupProvider.preDestruction();
+ }
+ };
+ } else {
+ return baseUserGroupProvider;
+ }
+ }
+
+ @Override
+ public void initialize(AccessPolicyProviderInitializationContext initializationContext) throws AuthorizerCreationException {
+ baseConfigurableAccessPolicyProvider.initialize(initializationContext);
+ }
+
+ @Override
+ public void onConfigured(AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
+ baseConfigurableAccessPolicyProvider.onConfigured(configurationContext);
+ }
+
+ @Override
+ public void preDestruction() throws AuthorizerDestructionException {
+ baseConfigurableAccessPolicyProvider.preDestruction();
+ }
+ };
+ } else {
+ return baseAccessPolicyProvider;
+ }
+ }
+
+ @Override
+ public AuthorizationResult authorize(AuthorizationRequest request) throws AuthorizationAccessException {
+ return baseManagedAuthorizer.authorize(request);
+ }
+
+ @Override
+ public void initialize(AuthorizerInitializationContext initializationContext) throws AuthorizerCreationException {
+ baseManagedAuthorizer.initialize(initializationContext);
+ }
+
+ @Override
+ public void onConfigured(AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
+ baseManagedAuthorizer.onConfigured(configurationContext);
+
+ final AccessPolicyProvider accessPolicyProvider = baseManagedAuthorizer.getAccessPolicyProvider();
+ final UserGroupProvider userGroupProvider = accessPolicyProvider.getUserGroupProvider();
+
+ // ensure that only one policy per resource-action exists
+ for (AccessPolicy accessPolicy : accessPolicyProvider.getAccessPolicies()) {
+ if (policyExists(accessPolicyProvider, accessPolicy)) {
+ throw new AuthorizerCreationException(String.format("Found multiple policies for '%s' with '%s'.", accessPolicy.getResource(), accessPolicy.getAction()));
+ }
+ }
+
+ // ensure that only one group exists per identity
+ for (User user : userGroupProvider.getUsers()) {
+ if (tenantExists(userGroupProvider, user.getIdentifier(), user.getIdentity())) {
+ throw new AuthorizerCreationException(String.format("Found multiple users/user groups with identity '%s'.", user.getIdentity()));
+ }
+ }
+
+ // ensure that only one group exists per identity
+ for (Group group : userGroupProvider.getGroups()) {
+ if (tenantExists(userGroupProvider, group.getIdentifier(), group.getName())) {
+ throw new AuthorizerCreationException(String.format("Found multiple users/user groups with name '%s'.", group.getName()));
+ }
+ }
+ }
+
+ @Override
+ public void preDestruction() throws AuthorizerDestructionException {
+ baseManagedAuthorizer.preDestruction();
+ }
+ };
+ } else {
+ return baseAuthorizer;
+ }
+ }
+
+ /**
+ * Decorates the base authorizer to ensure the nar context classloader is used when invoking the underlying methods.
+ *
+ * @param baseAuthorizer base authorizer
+ * @return authorizer
+ */
+ public static Authorizer withNarLoader(final Authorizer baseAuthorizer) {
+ if (baseAuthorizer instanceof ManagedAuthorizer) {
+ final ManagedAuthorizer baseManagedAuthorizer = (ManagedAuthorizer) baseAuthorizer;
+ return new ManagedAuthorizer() {
+ @Override
+ public String getFingerprint() throws AuthorizationAccessException {
+ try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+ return baseManagedAuthorizer.getFingerprint();
+ }
+ }
+
+ @Override
+ public void inheritFingerprint(String fingerprint) throws AuthorizationAccessException {
+ try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+ baseManagedAuthorizer.inheritFingerprint(fingerprint);
+ }
+ }
+
+ @Override
+ public void checkInheritability(String proposedFingerprint) throws AuthorizationAccessException, UninheritableAuthorizationsException {
+ try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+ baseManagedAuthorizer.checkInheritability(proposedFingerprint);
+ }
+ }
+
+ @Override
+ public AccessPolicyProvider getAccessPolicyProvider() {
+ try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+ return baseManagedAuthorizer.getAccessPolicyProvider();
+ }
+ }
+
+ @Override
+ public AuthorizationResult authorize(AuthorizationRequest request) throws AuthorizationAccessException {
+ try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+ return baseManagedAuthorizer.authorize(request);
+ }
+ }
+
+ @Override
+ public void initialize(AuthorizerInitializationContext initializationContext) throws AuthorizerCreationException {
+ try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+ baseManagedAuthorizer.initialize(initializationContext);
+ }
+ }
+
+ @Override
+ public void onConfigured(AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
+ try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+ baseManagedAuthorizer.onConfigured(configurationContext);
+ }
+ }
+
+ @Override
+ public void preDestruction() throws AuthorizerDestructionException {
+ try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+ baseManagedAuthorizer.preDestruction();
+ }
+ }
+ };
+ } else {
+ return new Authorizer() {
+ @Override
+ public AuthorizationResult authorize(final AuthorizationRequest request) throws AuthorizationAccessException {
+ try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+ return baseAuthorizer.authorize(request);
+ }
+ }
+
+ @Override
+ public void initialize(AuthorizerInitializationContext initializationContext) throws AuthorizerCreationException {
+ try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+ baseAuthorizer.initialize(initializationContext);
+ }
+ }
+
+ @Override
+ public void onConfigured(AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
+ try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+ baseAuthorizer.onConfigured(configurationContext);
+ }
+ }
+
+ @Override
+ public void preDestruction() throws AuthorizerDestructionException {
+ try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+ baseAuthorizer.preDestruction();
+ }
+ }
+ };
+ }
+ }
+
+ private AuthorizerFactory() {}
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/4ed7511b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/java/org/apache/nifi/authorization/AuthorizerFactoryBean.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/java/org/apache/nifi/authorization/AuthorizerFactoryBean.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/java/org/apache/nifi/authorization/AuthorizerFactoryBean.java
index b934cb8..9de8756 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/java/org/apache/nifi/authorization/AuthorizerFactoryBean.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/java/org/apache/nifi/authorization/AuthorizerFactoryBean.java
@@ -25,7 +25,6 @@ import org.apache.nifi.authorization.generated.Authorizers;
import org.apache.nifi.authorization.generated.Property;
import org.apache.nifi.bundle.Bundle;
import org.apache.nifi.nar.ExtensionManager;
-import org.apache.nifi.nar.NarCloseable;
import org.apache.nifi.util.NiFiProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -49,12 +48,11 @@ import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.Set;
/**
* Factory bean for loading the configured authorizer.
*/
-public class AuthorizerFactoryBean implements FactoryBean, DisposableBean, AuthorizerLookup {
+public class AuthorizerFactoryBean implements FactoryBean, DisposableBean, UserGroupProviderLookup, AccessPolicyProviderLookup, AuthorizerLookup {
private static final Logger logger = LoggerFactory.getLogger(AuthorizerFactoryBean.class);
private static final String AUTHORIZERS_XSD = "/authorizers.xsd";
@@ -74,8 +72,19 @@ public class AuthorizerFactoryBean implements FactoryBean, DisposableBean, Autho
private Authorizer authorizer;
private NiFiProperties properties;
+ private final Map<String, UserGroupProvider> userGroupProviders = new HashMap<>();
+ private final Map<String, AccessPolicyProvider> accessPolicyProviders = new HashMap<>();
private final Map<String, Authorizer> authorizers = new HashMap<>();
+ @Override
+ public UserGroupProvider getUserGroupProvider(String identifier) {
+ return userGroupProviders.get(identifier);
+ }
+
+ @Override
+ public AccessPolicyProvider getAccessPolicyProvider(String identifier) {
+ return accessPolicyProviders.get(identifier);
+ }
@Override
public Authorizer getAuthorizer(String identifier) {
@@ -98,6 +107,28 @@ public class AuthorizerFactoryBean implements FactoryBean, DisposableBean, Autho
} else {
final Authorizers authorizerConfiguration = loadAuthorizersConfiguration();
+ // create each user group provider
+ for (final org.apache.nifi.authorization.generated.UserGroupProvider userGroupProvider : authorizerConfiguration.getUserGroupProvider()) {
+ userGroupProviders.put(userGroupProvider.getIdentifier(), createUserGroupProvider(userGroupProvider.getIdentifier(), userGroupProvider.getClazz()));
+ }
+
+ // configure each user group provider
+ for (final org.apache.nifi.authorization.generated.UserGroupProvider provider : authorizerConfiguration.getUserGroupProvider()) {
+ final UserGroupProvider instance = userGroupProviders.get(provider.getIdentifier());
+ instance.onConfigured(loadAuthorizerConfiguration(provider.getIdentifier(), provider.getProperty()));
+ }
+
+ // create each access policy provider
+ for (final org.apache.nifi.authorization.generated.AccessPolicyProvider accessPolicyProvider : authorizerConfiguration.getAccessPolicyProvider()) {
+ accessPolicyProviders.put(accessPolicyProvider.getIdentifier(), createAccessPolicyProvider(accessPolicyProvider.getIdentifier(), accessPolicyProvider.getClazz()));
+ }
+
+ // configure each access policy provider
+ for (final org.apache.nifi.authorization.generated.AccessPolicyProvider provider : authorizerConfiguration.getAccessPolicyProvider()) {
+ final AccessPolicyProvider instance = accessPolicyProviders.get(provider.getIdentifier());
+ instance.onConfigured(loadAuthorizerConfiguration(provider.getIdentifier(), provider.getProperty()));
+ }
+
// create each authorizer
for (final org.apache.nifi.authorization.generated.Authorizer authorizer : authorizerConfiguration.getAuthorizer()) {
authorizers.put(authorizer.getIdentifier(), createAuthorizer(authorizer.getIdentifier(), authorizer.getClazz()));
@@ -106,7 +137,7 @@ public class AuthorizerFactoryBean implements FactoryBean, DisposableBean, Autho
// configure each authorizer
for (final org.apache.nifi.authorization.generated.Authorizer provider : authorizerConfiguration.getAuthorizer()) {
final Authorizer instance = authorizers.get(provider.getIdentifier());
- instance.onConfigured(loadAuthorizerConfiguration(provider));
+ instance.onConfigured(loadAuthorizerConfiguration(provider.getIdentifier(), provider.getProperty()));
}
// get the authorizer instance
@@ -146,6 +177,102 @@ public class AuthorizerFactoryBean implements FactoryBean, DisposableBean, Autho
}
}
+ private UserGroupProvider createUserGroupProvider(final String identifier, final String userGroupProviderClassName) throws Exception {
+ // get the classloader for the specified user group provider
+ final List<Bundle> userGroupProviderBundles = ExtensionManager.getBundles(userGroupProviderClassName);
+
+ if (userGroupProviderBundles.size() == 0) {
+ throw new Exception(String.format("The specified user group provider class '%s' is not known to this nifi.", userGroupProviderClassName));
+ }
+
+ if (userGroupProviderBundles.size() > 1) {
+ throw new Exception(String.format("Multiple bundles found for the specified user group provider class '%s', only one is allowed.", userGroupProviderClassName));
+ }
+
+ final Bundle userGroupProviderBundle = userGroupProviderBundles.get(0);
+ final ClassLoader userGroupProviderClassLoader = userGroupProviderBundle.getClassLoader();
+
+ // get the current context classloader
+ final ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
+
+ final UserGroupProvider instance;
+ try {
+ // set the appropriate class loader
+ Thread.currentThread().setContextClassLoader(userGroupProviderClassLoader);
+
+ // attempt to load the class
+ Class<?> rawUserGroupProviderClass = Class.forName(userGroupProviderClassName, true, userGroupProviderClassLoader);
+ Class<? extends UserGroupProvider> userGroupProviderClass = rawUserGroupProviderClass.asSubclass(UserGroupProvider.class);
+
+ // otherwise create a new instance
+ Constructor constructor = userGroupProviderClass.getConstructor();
+ instance = (UserGroupProvider) constructor.newInstance();
+
+ // method injection
+ performMethodInjection(instance, userGroupProviderClass);
+
+ // field injection
+ performFieldInjection(instance, userGroupProviderClass);
+
+ // call post construction lifecycle event
+ instance.initialize(new StandardAuthorizerInitializationContext(identifier, this, this, this));
+ } finally {
+ if (currentClassLoader != null) {
+ Thread.currentThread().setContextClassLoader(currentClassLoader);
+ }
+ }
+
+ return UserGroupProviderFactory.withNarLoader(instance);
+ }
+
+ private AccessPolicyProvider createAccessPolicyProvider(final String identifier, final String accessPolicyProviderClassName) throws Exception {
+ // get the classloader for the specified access policy provider
+ final List<Bundle> accessPolicyProviderBundles = ExtensionManager.getBundles(accessPolicyProviderClassName);
+
+ if (accessPolicyProviderBundles.size() == 0) {
+ throw new Exception(String.format("The specified access policy provider class '%s' is not known to this nifi.", accessPolicyProviderClassName));
+ }
+
+ if (accessPolicyProviderBundles.size() > 1) {
+ throw new Exception(String.format("Multiple bundles found for the specified access policy provider class '%s', only one is allowed.", accessPolicyProviderClassName));
+ }
+
+ final Bundle accessPolicyProviderBundle = accessPolicyProviderBundles.get(0);
+ final ClassLoader accessPolicyProviderClassLoader = accessPolicyProviderBundle.getClassLoader();
+
+ // get the current context classloader
+ final ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
+
+ final AccessPolicyProvider instance;
+ try {
+ // set the appropriate class loader
+ Thread.currentThread().setContextClassLoader(accessPolicyProviderClassLoader);
+
+ // attempt to load the class
+ Class<?> rawAccessPolicyProviderClass = Class.forName(accessPolicyProviderClassName, true, accessPolicyProviderClassLoader);
+ Class<? extends AccessPolicyProvider> accessPolicyClass = rawAccessPolicyProviderClass.asSubclass(AccessPolicyProvider.class);
+
+ // otherwise create a new instance
+ Constructor constructor = accessPolicyClass.getConstructor();
+ instance = (AccessPolicyProvider) constructor.newInstance();
+
+ // method injection
+ performMethodInjection(instance, accessPolicyClass);
+
+ // field injection
+ performFieldInjection(instance, accessPolicyClass);
+
+ // call post construction lifecycle event
+ instance.initialize(new StandardAuthorizerInitializationContext(identifier, this, this, this));
+ } finally {
+ if (currentClassLoader != null) {
+ Thread.currentThread().setContextClassLoader(currentClassLoader);
+ }
+ }
+
+ return AccessPolicyProviderFactory.withNarLoader(instance);
+ }
+
private Authorizer createAuthorizer(final String identifier, final String authorizerClassName) throws Exception {
// get the classloader for the specified authorizer
final List<Bundle> authorizerBundles = ExtensionManager.getBundles(authorizerClassName);
@@ -184,26 +311,26 @@ public class AuthorizerFactoryBean implements FactoryBean, DisposableBean, Autho
performFieldInjection(instance, authorizerClass);
// call post construction lifecycle event
- instance.initialize(new StandardAuthorizerInitializationContext(identifier, this));
+ instance.initialize(new StandardAuthorizerInitializationContext(identifier, this, this, this));
} finally {
if (currentClassLoader != null) {
Thread.currentThread().setContextClassLoader(currentClassLoader);
}
}
- return withNarLoader(instance);
+ return AuthorizerFactory.installIntegrityChecks(AuthorizerFactory.withNarLoader(instance));
}
- private AuthorizerConfigurationContext loadAuthorizerConfiguration(final org.apache.nifi.authorization.generated.Authorizer authorizer) {
+ private AuthorizerConfigurationContext loadAuthorizerConfiguration(final String identifier, final List<Property> properties) {
final Map<String, String> authorizerProperties = new HashMap<>();
- for (final Property property : authorizer.getProperty()) {
+ for (final Property property : properties) {
authorizerProperties.put(property.getName(), property.getValue());
}
- return new StandardAuthorizerConfigurationContext(authorizer.getIdentifier(), authorizerProperties);
+ return new StandardAuthorizerConfigurationContext(identifier, authorizerProperties);
}
- private void performMethodInjection(final Authorizer instance, final Class authorizerClass) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+ private void performMethodInjection(final Object instance, final Class authorizerClass) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
for (final Method method : authorizerClass.getMethods()) {
if (method.isAnnotationPresent(AuthorizerContext.class)) {
// make the method accessible
@@ -235,7 +362,7 @@ public class AuthorizerFactoryBean implements FactoryBean, DisposableBean, Autho
}
}
- private void performFieldInjection(final Authorizer instance, final Class authorizerClass) throws IllegalArgumentException, IllegalAccessException {
+ private void performFieldInjection(final Object instance, final Class authorizerClass) throws IllegalArgumentException, IllegalAccessException {
for (final Field field : authorizerClass.getDeclaredFields()) {
if (field.isAnnotationPresent(AuthorizerContext.class)) {
// make the method accessible
@@ -291,189 +418,6 @@ public class AuthorizerFactoryBean implements FactoryBean, DisposableBean, Autho
};
}
- /**
- * Decorates the base authorizer to ensure the nar context classloader is used when invoking the underlying methods.
- *
- * @param baseAuthorizer base authorizer
- * @return authorizer
- */
- public Authorizer withNarLoader(final Authorizer baseAuthorizer) {
- if (baseAuthorizer instanceof AbstractPolicyBasedAuthorizer) {
- AbstractPolicyBasedAuthorizer policyBasedAuthorizer = (AbstractPolicyBasedAuthorizer) baseAuthorizer;
- return new AbstractPolicyBasedAuthorizer() {
- @Override
- public Group doAddGroup(Group group) throws AuthorizationAccessException {
- try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
- return policyBasedAuthorizer.addGroup(group);
- }
- }
-
- @Override
- public Group getGroup(String identifier) throws AuthorizationAccessException {
- try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
- return policyBasedAuthorizer.getGroup(identifier);
- }
- }
-
- @Override
- public Group doUpdateGroup(Group group) throws AuthorizationAccessException {
- try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
- return policyBasedAuthorizer.updateGroup(group);
- }
- }
-
- @Override
- public Group deleteGroup(Group group) throws AuthorizationAccessException {
- try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
- return policyBasedAuthorizer.deleteGroup(group);
- }
- }
-
- @Override
- public Set<Group> getGroups() throws AuthorizationAccessException {
- try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
- return policyBasedAuthorizer.getGroups();
- }
- }
-
- @Override
- public User doAddUser(User user) throws AuthorizationAccessException {
- try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
- return policyBasedAuthorizer.addUser(user);
- }
- }
-
- @Override
- public User getUser(String identifier) throws AuthorizationAccessException {
- try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
- return policyBasedAuthorizer.getUser(identifier);
- }
- }
-
- @Override
- public User getUserByIdentity(String identity) throws AuthorizationAccessException {
- try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
- return policyBasedAuthorizer.getUserByIdentity(identity);
- }
- }
-
- @Override
- public User doUpdateUser(User user) throws AuthorizationAccessException {
- try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
- return policyBasedAuthorizer.updateUser(user);
- }
- }
-
- @Override
- public User deleteUser(User user) throws AuthorizationAccessException {
- try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
- return policyBasedAuthorizer.deleteUser(user);
- }
- }
-
- @Override
- public Set<User> getUsers() throws AuthorizationAccessException {
- try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
- return policyBasedAuthorizer.getUsers();
- }
- }
-
- @Override
- public AccessPolicy doAddAccessPolicy(AccessPolicy accessPolicy) throws AuthorizationAccessException {
- try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
- return policyBasedAuthorizer.addAccessPolicy(accessPolicy);
- }
- }
-
- @Override
- public AccessPolicy getAccessPolicy(String identifier) throws AuthorizationAccessException {
- try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
- return policyBasedAuthorizer.getAccessPolicy(identifier);
- }
- }
-
- @Override
- public AccessPolicy updateAccessPolicy(AccessPolicy accessPolicy) throws AuthorizationAccessException {
- try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
- return policyBasedAuthorizer.updateAccessPolicy(accessPolicy);
- }
- }
-
- @Override
- public AccessPolicy deleteAccessPolicy(AccessPolicy accessPolicy) throws AuthorizationAccessException {
- try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
- return policyBasedAuthorizer.deleteAccessPolicy(accessPolicy);
- }
- }
-
- @Override
- public Set<AccessPolicy> getAccessPolicies() throws AuthorizationAccessException {
- try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
- return policyBasedAuthorizer.getAccessPolicies();
- }
- }
-
- @Override
- public UsersAndAccessPolicies getUsersAndAccessPolicies() throws AuthorizationAccessException {
- try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
- return policyBasedAuthorizer.getUsersAndAccessPolicies();
- }
- }
-
- @Override
- public void initialize(AuthorizerInitializationContext initializationContext) throws AuthorizerCreationException {
- try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
- policyBasedAuthorizer.initialize(initializationContext);
- }
- }
-
- @Override
- public void doOnConfigured(AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
- try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
- policyBasedAuthorizer.onConfigured(configurationContext);
- }
- }
-
- @Override
- public void preDestruction() throws AuthorizerDestructionException {
- try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
- baseAuthorizer.preDestruction();
- }
- }
- };
- } else {
- return new Authorizer() {
- @Override
- public AuthorizationResult authorize(final AuthorizationRequest request) throws AuthorizationAccessException {
- try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
- return baseAuthorizer.authorize(request);
- }
- }
-
- @Override
- public void initialize(AuthorizerInitializationContext initializationContext) throws AuthorizerCreationException {
- try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
- baseAuthorizer.initialize(initializationContext);
- }
- }
-
- @Override
- public void onConfigured(AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
- try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
- baseAuthorizer.onConfigured(configurationContext);
- }
- }
-
- @Override
- public void preDestruction() throws AuthorizerDestructionException {
- try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
- baseAuthorizer.preDestruction();
- }
- }
- };
- }
- }
-
@Override
public Class getObjectType() {
return Authorizer.class;