mirror of https://github.com/apache/nifi.git
NIFI-2171 Removing list of groups from User
- Making FileAuthorizer not update the resource or action when updating an AccessPolicy - Adding corresponding READ policies during initial seeding and legacy conversions - Adding checks to FileAuthorizer to ensure only one policy per resource-action - Removing merging of policies on legacy conversion since we have one action per policy now - This closes #608
This commit is contained in:
parent
f4c94e349c
commit
c5889314ca
|
@ -17,6 +17,7 @@
|
|||
package org.apache.nifi.authorization;
|
||||
|
||||
import org.apache.nifi.authorization.exception.AuthorizationAccessException;
|
||||
import org.apache.nifi.authorization.exception.AuthorizerCreationException;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
|
@ -48,7 +49,7 @@ public abstract class AbstractPolicyBasedAuthorizer implements Authorizer {
|
|||
static final XMLOutputFactory XML_OUTPUT_FACTORY = XMLOutputFactory.newInstance();
|
||||
|
||||
static final String USER_ELEMENT = "user";
|
||||
static final String USER_GROUP_ELEMENT = "userGroup";
|
||||
static final String GROUP_USER_ELEMENT = "groupUser";
|
||||
static final String GROUP_ELEMENT = "group";
|
||||
static final String POLICY_ELEMENT = "policy";
|
||||
static final String POLICY_USER_ELEMENT = "policyUser";
|
||||
|
@ -61,6 +62,44 @@ public abstract class AbstractPolicyBasedAuthorizer implements Authorizer {
|
|||
|
||||
public static final String EMPTY_FINGERPRINT = "EMPTY";
|
||||
|
||||
@Override
|
||||
public final void onConfigured(final AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
|
||||
doOnConfigured(configurationContext);
|
||||
|
||||
// ensure that only one policy per resource-action exists
|
||||
for (AccessPolicy accessPolicy : getAccessPolicies()) {
|
||||
if (policyExists(accessPolicy)) {
|
||||
throw new AuthorizerCreationException("Found multiple policies for " + accessPolicy.getResource()
|
||||
+ " with " + accessPolicy.getAction());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows sub-classes to take action when onConfigured is called.
|
||||
*
|
||||
* @param configurationContext the configuration context
|
||||
* @throws AuthorizerCreationException if an error occurs during onConfigured process
|
||||
*/
|
||||
protected abstract void doOnConfigured(final AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException;
|
||||
|
||||
/**
|
||||
* 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 boolean policyExists(final AccessPolicy checkAccessPolicy) {
|
||||
for (AccessPolicy accessPolicy : getAccessPolicies()) {
|
||||
if (!accessPolicy.getIdentifier().equals(checkAccessPolicy.getIdentifier())
|
||||
&& accessPolicy.getResource().equals(checkAccessPolicy.getResource())
|
||||
&& accessPolicy.getAction().equals(checkAccessPolicy.getAction())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final AuthorizationResult authorize(AuthorizationRequest request) throws AuthorizationAccessException {
|
||||
final UsersAndAccessPolicies usersAndAccessPolicies = getUsersAndAccessPolicies();
|
||||
|
@ -77,9 +116,11 @@ public abstract class AbstractPolicyBasedAuthorizer implements Authorizer {
|
|||
return AuthorizationResult.denied("Unknown user with identity " + request.getIdentity());
|
||||
}
|
||||
|
||||
final Set<Group> userGroups = usersAndAccessPolicies.getGroups(user.getIdentity());
|
||||
|
||||
for (AccessPolicy policy : policies) {
|
||||
final boolean containsUser = policy.getUsers().contains(user.getIdentifier());
|
||||
if (policy.getAction() == request.getAction() && (containsUser || containsGroup(user, policy)) ) {
|
||||
if (policy.getAction() == request.getAction() && (containsUser || containsGroup(userGroups, policy)) ) {
|
||||
return AuthorizationResult.approved();
|
||||
}
|
||||
}
|
||||
|
@ -88,13 +129,13 @@ public abstract class AbstractPolicyBasedAuthorizer implements Authorizer {
|
|||
}
|
||||
|
||||
|
||||
private boolean containsGroup(final User user, final AccessPolicy policy) {
|
||||
if (user.getGroups().isEmpty() || policy.getGroups().isEmpty()) {
|
||||
private boolean containsGroup(Set<Group> userGroups, final AccessPolicy policy) {
|
||||
if (userGroups.isEmpty() || policy.getGroups().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (String userGroup : user.getGroups()) {
|
||||
if (policy.getGroups().contains(userGroup)) {
|
||||
for (Group userGroup : userGroups) {
|
||||
if (policy.getGroups().contains(userGroup.getIdentifier())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -200,6 +241,20 @@ public abstract class AbstractPolicyBasedAuthorizer implements Authorizer {
|
|||
*/
|
||||
public abstract Set<User> getUsers() throws AuthorizationAccessException;
|
||||
|
||||
/**
|
||||
* Adds the given policy ensuring that multiple policies can not be added for the same resource and action.
|
||||
*
|
||||
* @param accessPolicy the policy to add
|
||||
* @return the policy that was added
|
||||
* @throws AuthorizationAccessException if there was an unexpected error performing the operation
|
||||
*/
|
||||
public final synchronized AccessPolicy addAccessPolicy(AccessPolicy accessPolicy) throws AuthorizationAccessException {
|
||||
if (policyExists(accessPolicy)) {
|
||||
throw new IllegalStateException("Found multiple policies for " + accessPolicy.getResource()
|
||||
+ " with " + accessPolicy.getAction());
|
||||
}
|
||||
return doAddAccessPolicy(accessPolicy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given policy.
|
||||
|
@ -208,7 +263,7 @@ public abstract class AbstractPolicyBasedAuthorizer implements Authorizer {
|
|||
* @return the policy that was added
|
||||
* @throws AuthorizationAccessException if there was an unexpected error performing the operation
|
||||
*/
|
||||
public abstract AccessPolicy addAccessPolicy(AccessPolicy accessPolicy) throws AuthorizationAccessException;
|
||||
protected abstract AccessPolicy doAddAccessPolicy(AccessPolicy accessPolicy) throws AuthorizationAccessException;
|
||||
|
||||
/**
|
||||
* Retrieves the policy with the given identifier.
|
||||
|
@ -304,20 +359,21 @@ public abstract class AbstractPolicyBasedAuthorizer implements Authorizer {
|
|||
.identifier(element.getAttribute(IDENTIFIER_ATTR))
|
||||
.identity(element.getAttribute(IDENTITY_ATTR));
|
||||
|
||||
NodeList userGroups = element.getElementsByTagName(USER_GROUP_ELEMENT);
|
||||
for (int i=0; i < userGroups.getLength(); i++) {
|
||||
Element userGroupNode = (Element) userGroups.item(i);
|
||||
builder.addGroup(userGroupNode.getAttribute(IDENTIFIER_ATTR));
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private Group parseGroup(final Element element) {
|
||||
return new Group.Builder()
|
||||
final Group.Builder builder = new Group.Builder()
|
||||
.identifier(element.getAttribute(IDENTIFIER_ATTR))
|
||||
.name(element.getAttribute(NAME_ATTR))
|
||||
.build();
|
||||
.name(element.getAttribute(NAME_ATTR));
|
||||
|
||||
NodeList groupUsers = element.getElementsByTagName(GROUP_USER_ELEMENT);
|
||||
for (int i=0; i < groupUsers.getLength(); i++) {
|
||||
Element groupUserNode = (Element) groupUsers.item(i);
|
||||
builder.addUser(groupUserNode.getAttribute(IDENTIFIER_ATTR));
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private AccessPolicy parsePolicy(final Element element) {
|
||||
|
@ -403,26 +459,26 @@ public abstract class AbstractPolicyBasedAuthorizer implements Authorizer {
|
|||
}
|
||||
|
||||
private void writeUser(final XMLStreamWriter writer, final User user) throws XMLStreamException {
|
||||
List<String> userGroups = new ArrayList<>(user.getGroups());
|
||||
Collections.sort(userGroups);
|
||||
|
||||
writer.writeStartElement(USER_ELEMENT);
|
||||
writer.writeAttribute(IDENTIFIER_ATTR, user.getIdentifier());
|
||||
writer.writeAttribute(IDENTITY_ATTR, user.getIdentity());
|
||||
|
||||
for (String userGroup : userGroups) {
|
||||
writer.writeStartElement(USER_GROUP_ELEMENT);
|
||||
writer.writeAttribute(IDENTIFIER_ATTR, userGroup);
|
||||
writer.writeEndElement();
|
||||
}
|
||||
|
||||
writer.writeEndElement();
|
||||
}
|
||||
|
||||
private void writeGroup(final XMLStreamWriter writer, final Group group) throws XMLStreamException {
|
||||
List<String> users = new ArrayList<>(group.getUsers());
|
||||
Collections.sort(users);
|
||||
|
||||
writer.writeStartElement(GROUP_ELEMENT);
|
||||
writer.writeAttribute(IDENTIFIER_ATTR, group.getIdentifier());
|
||||
writer.writeAttribute(NAME_ATTR, group.getName());
|
||||
|
||||
for (String user : users) {
|
||||
writer.writeStartElement(GROUP_USER_ELEMENT);
|
||||
writer.writeAttribute(IDENTIFIER_ATTR, user);
|
||||
writer.writeEndElement();
|
||||
}
|
||||
|
||||
writer.writeEndElement();
|
||||
}
|
||||
|
||||
|
|
|
@ -16,10 +16,7 @@
|
|||
*/
|
||||
package org.apache.nifi.authorization;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A user to create authorization policies for.
|
||||
|
@ -30,12 +27,9 @@ public class User {
|
|||
|
||||
private final String identity;
|
||||
|
||||
private final Set<String> groups;
|
||||
|
||||
private User(final Builder builder) {
|
||||
this.identifier = builder.identifier;
|
||||
this.identity = builder.identity;
|
||||
this.groups = Collections.unmodifiableSet(new HashSet<>(builder.groups));
|
||||
|
||||
if (identifier == null || identifier.trim().isEmpty()) {
|
||||
throw new IllegalArgumentException("Identifier can not be null or empty");
|
||||
|
@ -61,13 +55,6 @@ public class User {
|
|||
return identity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return an unmodifiable set of group ids
|
||||
*/
|
||||
public Set<String> getGroups() {
|
||||
return groups;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
|
@ -98,7 +85,6 @@ public class User {
|
|||
|
||||
private String identifier;
|
||||
private String identity;
|
||||
private Set<String> groups = new HashSet<>();
|
||||
private final boolean fromUser;
|
||||
|
||||
/**
|
||||
|
@ -122,8 +108,6 @@ public class User {
|
|||
|
||||
this.identifier = other.getIdentifier();
|
||||
this.identity = other.getIdentity();
|
||||
this.groups.clear();
|
||||
this.groups.addAll(other.getGroups());
|
||||
this.fromUser = true;
|
||||
}
|
||||
|
||||
|
@ -155,68 +139,6 @@ public class User {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all groups from the provided set to the builder's set of groups.
|
||||
*
|
||||
* @param groups the groups to add
|
||||
* @return the builder
|
||||
*/
|
||||
public Builder addGroups(final Set<String> groups) {
|
||||
if (groups != null) {
|
||||
this.groups.addAll(groups);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the provided group to the builder's set of groups.
|
||||
*
|
||||
* @param group the group to add
|
||||
* @return the builder
|
||||
*/
|
||||
public Builder addGroup(final String group) {
|
||||
if (group != null) {
|
||||
this.groups.add(group);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all groups in the provided set from the builder's set of groups.
|
||||
*
|
||||
* @param groups the groups to remove
|
||||
* @return the builder
|
||||
*/
|
||||
public Builder removeGroups(final Set<String> groups) {
|
||||
if (groups != null) {
|
||||
this.groups.removeAll(groups);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the provided group from the builder's set of groups.
|
||||
*
|
||||
* @param group the group to remove
|
||||
* @return the builder
|
||||
*/
|
||||
public Builder removeGroup(final String group) {
|
||||
if (group != null) {
|
||||
this.groups.remove(group);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the builder's set of groups so that groups is non-null with size == 0.
|
||||
*
|
||||
* @return the builder
|
||||
*/
|
||||
public Builder clearGroups() {
|
||||
this.groups.clear();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a new User constructed from the state of the builder
|
||||
*/
|
||||
|
|
|
@ -40,4 +40,12 @@ public interface UsersAndAccessPolicies {
|
|||
*/
|
||||
public User getUser(final String identity);
|
||||
|
||||
/**
|
||||
* Retrieves the groups for a given user identity.
|
||||
*
|
||||
* @param userIdentity a user identity
|
||||
* @return the set of groups for the given user identity
|
||||
*/
|
||||
public Set<Group> getGroups(final String userIdentity);
|
||||
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.junit.Assert;
|
|||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
@ -104,11 +105,18 @@ public class TestAbstractPolicyBasedAuthorizer {
|
|||
final User user = new User.Builder()
|
||||
.identity(userIdentity)
|
||||
.identifier(userIdentifier)
|
||||
.addGroup(groupIdentifier)
|
||||
.build();
|
||||
|
||||
when(usersAndAccessPolicies.getUser(userIdentity)).thenReturn(user);
|
||||
|
||||
final Group group = new Group.Builder()
|
||||
.identifier(groupIdentifier)
|
||||
.name(groupIdentifier)
|
||||
.addUser(user.getIdentifier())
|
||||
.build();
|
||||
|
||||
when(usersAndAccessPolicies.getGroups(userIdentity)).thenReturn(Collections.singleton(group));
|
||||
|
||||
final AuthorizationRequest request = new AuthorizationRequest.Builder()
|
||||
.identity(userIdentity)
|
||||
.resource(TEST_RESOURCE)
|
||||
|
@ -180,11 +188,11 @@ public class TestAbstractPolicyBasedAuthorizer {
|
|||
public void testGetFingerprint() {
|
||||
// create the users, groups, and policies
|
||||
|
||||
Group group1 = new Group.Builder().identifier("group-id-1").name("group-1").build();
|
||||
Group group2 = new Group.Builder().identifier("group-id-2").name("group-2").build();
|
||||
User user1 = new User.Builder().identifier("user-id-1").identity("user-1").build();
|
||||
User user2 = new User.Builder().identifier("user-id-2").identity("user-2").build();
|
||||
|
||||
User user1 = new User.Builder().identifier("user-id-1").identity("user-1").addGroup(group1.getIdentifier()).build();
|
||||
User user2 = new User.Builder().identifier("user-id-2").identity("user-2").addGroup(group2.getIdentifier()).build();
|
||||
Group group1 = new Group.Builder().identifier("group-id-1").name("group-1").addUser(user1.getIdentifier()).build();
|
||||
Group group2 = new Group.Builder().identifier("group-id-2").name("group-2").addUser(user2.getIdentifier()).build();
|
||||
|
||||
AccessPolicy policy1 = new AccessPolicy.Builder()
|
||||
.identifier("policy-id-1")
|
||||
|
@ -251,12 +259,13 @@ public class TestAbstractPolicyBasedAuthorizer {
|
|||
|
||||
@Test
|
||||
public void testInheritFingerprint() {
|
||||
Group group1 = new Group.Builder().identifier("group-id-1").name("group-1").build();
|
||||
Group group2 = new Group.Builder().identifier("group-id-2").name("group-2").build();
|
||||
|
||||
User user1 = new User.Builder().identifier("user-id-1").identity("user-1").addGroup(group1.getIdentifier()).build();
|
||||
User user1 = new User.Builder().identifier("user-id-1").identity("user-1").build();
|
||||
User user2 = new User.Builder().identifier("user-id-2").identity("user-2").build();
|
||||
|
||||
Group group1 = new Group.Builder().identifier("group-id-1").name("group-1").addUser(user1.getIdentifier()).build();
|
||||
Group group2 = new Group.Builder().identifier("group-id-2").name("group-2").build();
|
||||
|
||||
AccessPolicy policy1 = new AccessPolicy.Builder()
|
||||
.identifier("policy-id-1")
|
||||
.resource("resource1")
|
||||
|
@ -392,7 +401,7 @@ public class TestAbstractPolicyBasedAuthorizer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public AccessPolicy addAccessPolicy(AccessPolicy accessPolicy) throws AuthorizationAccessException {
|
||||
protected AccessPolicy doAddAccessPolicy(AccessPolicy accessPolicy) throws AuthorizationAccessException {
|
||||
policies.add(accessPolicy);
|
||||
return accessPolicy;
|
||||
}
|
||||
|
@ -428,7 +437,7 @@ public class TestAbstractPolicyBasedAuthorizer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onConfigured(AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
|
||||
public void doOnConfigured(AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -18,12 +18,7 @@ package org.apache.nifi.authorization;
|
|||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class TestUser {
|
||||
|
||||
|
@ -37,25 +32,16 @@ public class TestUser {
|
|||
final User user = new User.Builder()
|
||||
.identifier(identifier)
|
||||
.identity(identity)
|
||||
.addGroup(group1)
|
||||
.addGroup(group2)
|
||||
.build();
|
||||
|
||||
assertEquals(identifier, user.getIdentifier());
|
||||
assertEquals(identity, user.getIdentity());
|
||||
|
||||
assertNotNull(user.getGroups());
|
||||
assertEquals(2, user.getGroups().size());
|
||||
assertTrue(user.getGroups().contains(group1));
|
||||
assertTrue(user.getGroups().contains(group2));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testMissingIdentifier() {
|
||||
new User.Builder()
|
||||
.identity("user1")
|
||||
.addGroup("group1")
|
||||
.addGroup("group2")
|
||||
.build();
|
||||
}
|
||||
|
||||
|
@ -63,28 +49,9 @@ public class TestUser {
|
|||
public void testMissingIdentity() {
|
||||
new User.Builder()
|
||||
.identifier("1")
|
||||
.addGroup("group1")
|
||||
.addGroup("group2")
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMissingGroups() {
|
||||
final String identifier = "1";
|
||||
final String identity = "user1";
|
||||
|
||||
final User user = new User.Builder()
|
||||
.identifier(identifier)
|
||||
.identity(identity)
|
||||
.build();
|
||||
|
||||
assertEquals(identifier, user.getIdentifier());
|
||||
assertEquals(identity, user.getIdentity());
|
||||
|
||||
assertNotNull(user.getGroups());
|
||||
assertEquals(0, user.getGroups().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFromUser() {
|
||||
final String identifier = "1";
|
||||
|
@ -95,22 +62,14 @@ public class TestUser {
|
|||
final User user = new User.Builder()
|
||||
.identifier(identifier)
|
||||
.identity(identity)
|
||||
.addGroup(group1)
|
||||
.addGroup(group2)
|
||||
.build();
|
||||
|
||||
assertEquals(identifier, user.getIdentifier());
|
||||
assertEquals(identity, user.getIdentity());
|
||||
|
||||
assertNotNull(user.getGroups());
|
||||
assertEquals(2, user.getGroups().size());
|
||||
assertTrue(user.getGroups().contains(group1));
|
||||
assertTrue(user.getGroups().contains(group2));
|
||||
|
||||
final User user2 = new User.Builder(user).build();
|
||||
assertEquals(user.getIdentifier(), user2.getIdentifier());
|
||||
assertEquals(user.getIdentity(), user2.getIdentity());
|
||||
assertEquals(user.getGroups(), user2.getGroups());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
|
@ -118,53 +77,9 @@ public class TestUser {
|
|||
final User user = new User.Builder()
|
||||
.identifier("1")
|
||||
.identity("user1")
|
||||
.addGroup("group1")
|
||||
.addGroup("group2")
|
||||
.build();
|
||||
|
||||
new User.Builder(user).identifier("2").build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddRemoveClearGroups() {
|
||||
final User.Builder builder = new User.Builder()
|
||||
.identifier("1")
|
||||
.identity("user1")
|
||||
.addGroup("group1");
|
||||
|
||||
final User user1 = builder.build();
|
||||
assertNotNull(user1.getGroups());
|
||||
assertEquals(1, user1.getGroups().size());
|
||||
assertTrue(user1.getGroups().contains("group1"));
|
||||
|
||||
final Set<String> moreGroups = new HashSet<>();
|
||||
moreGroups.add("group2");
|
||||
moreGroups.add("group3");
|
||||
moreGroups.add("group4");
|
||||
|
||||
final User user2 = builder.addGroups(moreGroups).build();
|
||||
assertEquals(4, user2.getGroups().size());
|
||||
assertTrue(user2.getGroups().contains("group1"));
|
||||
assertTrue(user2.getGroups().contains("group2"));
|
||||
assertTrue(user2.getGroups().contains("group3"));
|
||||
assertTrue(user2.getGroups().contains("group4"));
|
||||
|
||||
final User user3 = builder.removeGroup("group2").build();
|
||||
assertEquals(3, user3.getGroups().size());
|
||||
assertTrue(user3.getGroups().contains("group1"));
|
||||
assertTrue(user3.getGroups().contains("group3"));
|
||||
assertTrue(user3.getGroups().contains("group4"));
|
||||
|
||||
final Set<String> removeGroups = new HashSet<>();
|
||||
removeGroups.add("group1");
|
||||
removeGroups.add("group4");
|
||||
|
||||
final User user4 = builder.removeGroups(removeGroups).build();
|
||||
assertEquals(1, user4.getGroups().size());
|
||||
assertTrue(user4.getGroups().contains("group3"));
|
||||
|
||||
final User user5 = builder.clearGroups().build();
|
||||
assertEquals(0, user5.getGroups().size());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -369,7 +369,7 @@ public class AuthorizerFactoryBean implements FactoryBean, DisposableBean, Autho
|
|||
}
|
||||
|
||||
@Override
|
||||
public AccessPolicy addAccessPolicy(AccessPolicy accessPolicy) throws AuthorizationAccessException {
|
||||
public AccessPolicy doAddAccessPolicy(AccessPolicy accessPolicy) throws AuthorizationAccessException {
|
||||
try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
|
||||
return policyBasedAuthorizer.addAccessPolicy(accessPolicy);
|
||||
}
|
||||
|
@ -418,7 +418,7 @@ public class AuthorizerFactoryBean implements FactoryBean, DisposableBean, Autho
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onConfigured(AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
|
||||
public void doOnConfigured(AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
|
||||
try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
|
||||
policyBasedAuthorizer.onConfigured(configurationContext);
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ public class AuthorizationsHolder implements UsersAndAccessPolicies {
|
|||
|
||||
private final Set<Group> allGroups;
|
||||
private final Map<String,Group> groupsById;
|
||||
private final Map<String, Set<Group>> groupsByUserIdentity;
|
||||
|
||||
/**
|
||||
* Creates a new holder and populates all convenience data structures.
|
||||
|
@ -75,6 +76,9 @@ public class AuthorizationsHolder implements UsersAndAccessPolicies {
|
|||
// create a convenience map to retrieve a group by id
|
||||
final Map<String, Group> groupByIdMap = Collections.unmodifiableMap(createGroupByIdMap(allGroups));
|
||||
|
||||
// create a convenience map to retrieve the groups for a user identity
|
||||
final Map<String, Set<Group>> groupsByUserIdentityMap = Collections.unmodifiableMap(createGroupsByUserIdentityMap(allGroups, allUsers));
|
||||
|
||||
// create a convenience map from resource id to policies
|
||||
final Map<String, Set<AccessPolicy>> policiesByResourceMap = Collections.unmodifiableMap(createResourcePolicyMap(allPolicies));
|
||||
|
||||
|
@ -88,6 +92,7 @@ public class AuthorizationsHolder implements UsersAndAccessPolicies {
|
|||
this.usersById = userByIdMap;
|
||||
this.usersByIdentity = userByIdentityMap;
|
||||
this.groupsById = groupByIdMap;
|
||||
this.groupsByUserIdentity = groupsByUserIdentityMap;
|
||||
this.policiesByResource = policiesByResourceMap;
|
||||
this.policiesById = policiesByIdMap;
|
||||
}
|
||||
|
@ -158,12 +163,6 @@ public class AuthorizationsHolder implements UsersAndAccessPolicies {
|
|||
.identity(user.getIdentity())
|
||||
.identifier(user.getIdentifier());
|
||||
|
||||
if (user.getGroup() != null) {
|
||||
for (org.apache.nifi.authorization.file.generated.User.Group group : user.getGroup()) {
|
||||
builder.addGroup(group.getIdentifier());
|
||||
}
|
||||
}
|
||||
|
||||
allUsers.add(builder.build());
|
||||
}
|
||||
|
||||
|
@ -188,9 +187,9 @@ public class AuthorizationsHolder implements UsersAndAccessPolicies {
|
|||
.identifier(group.getIdentifier())
|
||||
.name(group.getName());
|
||||
|
||||
// need to figured out what users are in this group by going through the users list
|
||||
final Set<String> groupUsers = getUsersForGroup(users, group.getIdentifier());
|
||||
builder.addUsers(groupUsers);
|
||||
for (org.apache.nifi.authorization.file.generated.Group.User groupUser : group.getUser()) {
|
||||
builder.addUser(groupUser.getIdentifier());
|
||||
}
|
||||
|
||||
allGroups.add(builder.build());
|
||||
}
|
||||
|
@ -198,32 +197,6 @@ public class AuthorizationsHolder implements UsersAndAccessPolicies {
|
|||
return allGroups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the set of user identifiers that are part of the given group.
|
||||
*
|
||||
* @param users the JAXB Users element
|
||||
* @param groupId the group id to get the users for
|
||||
* @return the user identifiers that belong to the group with the given identifier
|
||||
*/
|
||||
private Set<String> getUsersForGroup(org.apache.nifi.authorization.file.generated.Users users, final String groupId) {
|
||||
Set<String> groupUsers = new HashSet<>();
|
||||
|
||||
if (users != null && users.getUser()!= null) {
|
||||
for (org.apache.nifi.authorization.file.generated.User user : users.getUser()) {
|
||||
if (user.getGroup() != null) {
|
||||
for (org.apache.nifi.authorization.file.generated.User.Group group : user.getGroup()) {
|
||||
if (group.getIdentifier().equals(groupId)) {
|
||||
groupUsers.add(user.getIdentifier());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return groupUsers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a map from resource identifier to the set of policies for the given resource.
|
||||
*
|
||||
|
@ -287,6 +260,32 @@ public class AuthorizationsHolder implements UsersAndAccessPolicies {
|
|||
return groupsMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Map from user identity to the set of Groups for that identity.
|
||||
*
|
||||
* @param groups all groups
|
||||
* @param users all users
|
||||
* @return a Map from User identity to the set of Groups for that identity
|
||||
*/
|
||||
private Map<String, Set<Group>> createGroupsByUserIdentityMap(final Set<Group> groups, final Set<User> users) {
|
||||
Map<String, Set<Group>> groupsByUserIdentity = new HashMap<>();
|
||||
|
||||
for (User user : users) {
|
||||
Set<Group> userGroups = new HashSet<>();
|
||||
for (Group group : groups) {
|
||||
for (String groupUser : group.getUsers()) {
|
||||
if (groupUser.equals(user.getIdentifier())) {
|
||||
userGroups.add(group);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
groupsByUserIdentity.put(user.getIdentity(), userGroups);
|
||||
}
|
||||
|
||||
return groupsByUserIdentity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Map from policy identifier to AccessPolicy.
|
||||
*
|
||||
|
@ -353,4 +352,12 @@ public class AuthorizationsHolder implements UsersAndAccessPolicies {
|
|||
return usersByIdentity.get(identity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Group> getGroups(String userIdentity) {
|
||||
if (userIdentity == null) {
|
||||
throw new IllegalArgumentException("User Identity cannot be null");
|
||||
}
|
||||
return groupsByUserIdentity.get(userIdentity);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -130,7 +130,7 @@ public class FileAuthorizer extends AbstractPolicyBasedAuthorizer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onConfigured(final AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
|
||||
public void doOnConfigured(final AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
|
||||
try {
|
||||
final PropertyValue authorizationsPath = configurationContext.getProperty(PROP_AUTHORIZATIONS_FILE);
|
||||
if (StringUtils.isBlank(authorizationsPath.getValue())) {
|
||||
|
@ -324,13 +324,16 @@ public class FileAuthorizer extends AbstractPolicyBasedAuthorizer {
|
|||
|
||||
// grant the user read access to the root process group resource
|
||||
if (rootGroupId != null) {
|
||||
addAccessPolicy(authorizations, ResourceType.ProcessGroup.getValue() + "/" + rootGroupId, adminUser.getIdentifier(), READ_CODE);
|
||||
addAccessPolicy(authorizations, ResourceType.ProcessGroup.getValue() + "/" + rootGroupId, adminUser.getIdentifier(), WRITE_CODE);
|
||||
}
|
||||
|
||||
// grant the user read/write access to the /tenants resource
|
||||
addAccessPolicy(authorizations, ResourceType.Tenant.getValue(), adminUser.getIdentifier(), READ_CODE);
|
||||
addAccessPolicy(authorizations, ResourceType.Tenant.getValue(), adminUser.getIdentifier(), WRITE_CODE);
|
||||
|
||||
// grant the user read/write access to the /policies resource
|
||||
addAccessPolicy(authorizations, ResourceType.Policy.getValue(), adminUser.getIdentifier(), READ_CODE);
|
||||
addAccessPolicy(authorizations, ResourceType.Policy.getValue(), adminUser.getIdentifier(), WRITE_CODE);
|
||||
}
|
||||
|
||||
|
@ -372,8 +375,7 @@ public class FileAuthorizer extends AbstractPolicyBasedAuthorizer {
|
|||
// create mapping from Role to access policies
|
||||
final Map<Role,Set<RoleAccessPolicy>> roleAccessPolicies = RoleAccessPolicy.getMappings(rootGroupId);
|
||||
|
||||
final List<Policy> readPolicies = new ArrayList<>();
|
||||
final List<Policy> readWritePolicies = new ArrayList<>();
|
||||
final List<Policy> allPolicies = new ArrayList<>();
|
||||
|
||||
for (org.apache.nifi.user.generated.User legacyUser : users.getUser()) {
|
||||
// create the identifier of the new user based on the DN
|
||||
|
@ -389,9 +391,9 @@ public class FileAuthorizer extends AbstractPolicyBasedAuthorizer {
|
|||
// if there was a group name find or create the group and add the user to it
|
||||
org.apache.nifi.authorization.file.generated.Group group = getOrCreateGroup(authorizations, legacyUser.getGroup());
|
||||
if (group != null) {
|
||||
org.apache.nifi.authorization.file.generated.User.Group userGroup = new org.apache.nifi.authorization.file.generated.User.Group();
|
||||
userGroup.setIdentifier(group.getIdentifier());
|
||||
user.getGroup().add(userGroup);
|
||||
org.apache.nifi.authorization.file.generated.Group.User groupUser = new org.apache.nifi.authorization.file.generated.Group.User();
|
||||
groupUser.setIdentifier(userIdentifier);
|
||||
group.getUser().add(groupUser);
|
||||
}
|
||||
|
||||
// create policies based on the given role
|
||||
|
@ -400,16 +402,13 @@ public class FileAuthorizer extends AbstractPolicyBasedAuthorizer {
|
|||
Set<RoleAccessPolicy> policies = roleAccessPolicies.get(role);
|
||||
|
||||
for (RoleAccessPolicy roleAccessPolicy : policies) {
|
||||
// determine if we should use the read policies or read-write policies
|
||||
List<Policy> searchPolicies = roleAccessPolicy.getActions().equals(RoleAccessPolicy.READ_ACTION)
|
||||
? readPolicies : readWritePolicies;
|
||||
|
||||
// get the matching policy, or create a new one
|
||||
Policy policy = getOrCreatePolicy(
|
||||
searchPolicies,
|
||||
allPolicies,
|
||||
seedIdentity,
|
||||
roleAccessPolicy.getResource(),
|
||||
roleAccessPolicy.getActions());
|
||||
roleAccessPolicy.getAction());
|
||||
|
||||
// determine if the user already exists in the policy
|
||||
boolean userExists = false;
|
||||
|
@ -431,77 +430,7 @@ public class FileAuthorizer extends AbstractPolicyBasedAuthorizer {
|
|||
|
||||
}
|
||||
|
||||
// merge the policies and add the result to the overall authorizations instance
|
||||
final List<Policy> mergedPolicies = merge(readPolicies, readWritePolicies);
|
||||
authorizations.getPolicies().getPolicy().addAll(mergedPolicies);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges the provided read and read-write policies. Any users that are in a read policy and also in a read-write
|
||||
* policy for the same resource will be removed from the read policy. If users are still left in the read policy
|
||||
* after checking each user, then the read policy will still be included in the merged list.
|
||||
*
|
||||
* @param readPolicies the read policies
|
||||
* @param readWritePolicies the read-write policies
|
||||
* @return the merged list of policies
|
||||
*/
|
||||
private List<Policy> merge(List<Policy> readPolicies, List<Policy> readWritePolicies) {
|
||||
final List<Policy> mergedPolicies = new ArrayList<>(readWritePolicies);
|
||||
|
||||
logger.debug("Merging {} read policies and {} read-write policies",
|
||||
new Object[] {readPolicies.size(), readWritePolicies.size()});
|
||||
|
||||
for (Policy readPolicy : readPolicies) {
|
||||
logger.debug("Processing read policy {} for resource {} with actions {}",
|
||||
new Object[] {readPolicy.getIdentifier(), readPolicy.getResource(), readPolicy.getAction()});
|
||||
|
||||
// try to find a matching read-write policy for the same resource
|
||||
Policy foundReadWritePolicy = null;
|
||||
for (Policy readWritePolicy : readWritePolicies) {
|
||||
if (readWritePolicy.getResource().equals(readPolicy.getResource())) {
|
||||
foundReadWritePolicy = readWritePolicy;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if we didn't find a match then we just add the current read policy to the merged list
|
||||
if (foundReadWritePolicy == null) {
|
||||
logger.debug("no matching write policy found, adding read policy {} to merged policies",
|
||||
new Object[] {readPolicy.getIdentifier()});
|
||||
mergedPolicies.add(readPolicy);
|
||||
} else {
|
||||
// check each user from the read policy
|
||||
Iterator<Policy.User> userIter = readPolicy.getUser().iterator();
|
||||
while (userIter.hasNext()) {
|
||||
Policy.User readUser = userIter.next();
|
||||
|
||||
// determine if the user from the read policy exists in the read-write policy
|
||||
boolean userInReadWrite = false;
|
||||
for (Policy.User readWriteUser : foundReadWritePolicy.getUser()) {
|
||||
if (readWriteUser.getIdentifier().equals(readUser.getIdentifier())) {
|
||||
userInReadWrite = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if the user was in the read-write policy, remove them from read policy
|
||||
if (userInReadWrite) {
|
||||
logger.debug("Removing user {} from read policy {}", new Object[] {readUser.getIdentifier(), readPolicy.getIdentifier()});
|
||||
userIter.remove();
|
||||
}
|
||||
}
|
||||
|
||||
// after checking all users, see if any are still left in the read policy
|
||||
// if there are still some users, then add the read policy to the merged list
|
||||
if (readPolicy.getUser().size() > 0) {
|
||||
logger.debug("Read policy still has {} users, adding read policy {} to merged list",
|
||||
new Object[] {readPolicy.getUser().size(), readPolicy.getIdentifier()});
|
||||
mergedPolicies.add(readPolicy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mergedPolicies;
|
||||
authorizations.getPolicies().getPolicy().addAll(allPolicies);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -652,16 +581,11 @@ public class FileAuthorizer extends AbstractPolicyBasedAuthorizer {
|
|||
jaxbGroup.setIdentifier(group.getIdentifier());
|
||||
jaxbGroup.setName(group.getName());
|
||||
|
||||
// find each user and add the group to that user
|
||||
// add each user to the group
|
||||
for (String groupUser : group.getUsers()) {
|
||||
for (org.apache.nifi.authorization.file.generated.User jaxbUser : jaxbUsers) {
|
||||
if (jaxbUser.getIdentifier().equals(groupUser)) {
|
||||
final org.apache.nifi.authorization.file.generated.User.Group jaxbUserGroup = new org.apache.nifi.authorization.file.generated.User.Group();
|
||||
jaxbUserGroup.setIdentifier(group.getIdentifier());
|
||||
jaxbUser.getGroup().add(jaxbUserGroup);
|
||||
break;
|
||||
}
|
||||
}
|
||||
org.apache.nifi.authorization.file.generated.Group.User jaxbGroupUser = new org.apache.nifi.authorization.file.generated.Group.User();
|
||||
jaxbGroupUser.setIdentifier(groupUser);
|
||||
jaxbGroup.getUser().add(jaxbGroupUser);
|
||||
}
|
||||
|
||||
authorizations.getGroups().getGroup().add(jaxbGroup);
|
||||
|
@ -687,9 +611,6 @@ public class FileAuthorizer extends AbstractPolicyBasedAuthorizer {
|
|||
|
||||
final Authorizations authorizations = this.authorizationsHolder.get().getAuthorizations();
|
||||
|
||||
// determine that all users in the group exist before doing anything, throw an exception if they don't
|
||||
final Set<org.apache.nifi.authorization.file.generated.User> jaxbUsers = checkGroupUsers(group, authorizations.getUsers().getUser());
|
||||
|
||||
// find the group that needs to be update
|
||||
org.apache.nifi.authorization.file.generated.Group updateGroup = null;
|
||||
for (org.apache.nifi.authorization.file.generated.Group jaxbGroup : authorizations.getGroups().getGroup()) {
|
||||
|
@ -704,41 +625,12 @@ public class FileAuthorizer extends AbstractPolicyBasedAuthorizer {
|
|||
return null;
|
||||
}
|
||||
|
||||
// now we know group and all users exist so perform the updates
|
||||
|
||||
// first find each user and add the group to that user
|
||||
// reset the list of users and add each user to the group
|
||||
updateGroup.getUser().clear();
|
||||
for (String groupUser : group.getUsers()) {
|
||||
for (org.apache.nifi.authorization.file.generated.User jaxbUser : jaxbUsers) {
|
||||
if (jaxbUser.getIdentifier().equals(groupUser)) {
|
||||
final org.apache.nifi.authorization.file.generated.User.Group jaxbUserGroup = new org.apache.nifi.authorization.file.generated.User.Group();
|
||||
jaxbUserGroup.setIdentifier(group.getIdentifier());
|
||||
jaxbUser.getGroup().add(jaxbUserGroup);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now go through every user, check each group in the user to see if it still
|
||||
for (org.apache.nifi.authorization.file.generated.User jaxbUser : authorizations.getUsers().getUser()) {
|
||||
Iterator<org.apache.nifi.authorization.file.generated.User.Group> userGroupIter = jaxbUser.getGroup().iterator();
|
||||
while (userGroupIter.hasNext()) {
|
||||
final org.apache.nifi.authorization.file.generated.User.Group userGroup = userGroupIter.next();
|
||||
|
||||
// we only care about finding the group that is currently being updated
|
||||
if (userGroup.getIdentifier().equals(group.getIdentifier())) {
|
||||
boolean stillInGroup = false;
|
||||
for (String groupUser : group.getUsers()) {
|
||||
if (groupUser.equals(jaxbUser.getIdentifier())) {
|
||||
stillInGroup = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!stillInGroup) {
|
||||
userGroupIter.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
org.apache.nifi.authorization.file.generated.Group.User jaxbGroupUser = new org.apache.nifi.authorization.file.generated.Group.User();
|
||||
jaxbGroupUser.setIdentifier(groupUser);
|
||||
updateGroup.getUser().add(jaxbGroupUser);
|
||||
}
|
||||
|
||||
updateGroup.setName(group.getName());
|
||||
|
@ -753,18 +645,6 @@ public class FileAuthorizer extends AbstractPolicyBasedAuthorizer {
|
|||
final Authorizations authorizations = this.authorizationsHolder.get().getAuthorizations();
|
||||
final List<org.apache.nifi.authorization.file.generated.Group> groups = authorizations.getGroups().getGroup();
|
||||
|
||||
// for each user iterate over the group references and remove the group reference if it matches the group being deleted
|
||||
for (org.apache.nifi.authorization.file.generated.User user : authorizations.getUsers().getUser()) {
|
||||
Iterator<org.apache.nifi.authorization.file.generated.User.Group> userGroupIter = user.getGroup().iterator();
|
||||
while (userGroupIter.hasNext()) {
|
||||
org.apache.nifi.authorization.file.generated.User.Group userGroup = userGroupIter.next();
|
||||
if (userGroup.getIdentifier().equals(group.getIdentifier())) {
|
||||
userGroupIter.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// for each policy iterate over the group reference and remove the group reference if it matches the group being deleted
|
||||
for (Policy policy : authorizations.getPolicies().getPolicy()) {
|
||||
Iterator<Policy.Group> policyGroupIter = policy.getGroup().iterator();
|
||||
|
@ -844,12 +724,6 @@ public class FileAuthorizer extends AbstractPolicyBasedAuthorizer {
|
|||
final org.apache.nifi.authorization.file.generated.User jaxbUser = new org.apache.nifi.authorization.file.generated.User();
|
||||
jaxbUser.setIdentifier(user.getIdentifier());
|
||||
jaxbUser.setIdentity(user.getIdentity());
|
||||
|
||||
for (String groupIdentifier : user.getGroups()) {
|
||||
org.apache.nifi.authorization.file.generated.User.Group group = new org.apache.nifi.authorization.file.generated.User.Group();
|
||||
group.setIdentifier(groupIdentifier);
|
||||
jaxbUser.getGroup().add(group);
|
||||
}
|
||||
return jaxbUser;
|
||||
}
|
||||
|
||||
|
@ -896,14 +770,6 @@ public class FileAuthorizer extends AbstractPolicyBasedAuthorizer {
|
|||
return null;
|
||||
} else {
|
||||
updateUser.setIdentity(user.getIdentity());
|
||||
|
||||
updateUser.getGroup().clear();
|
||||
for (String groupIdentifier : user.getGroups()) {
|
||||
org.apache.nifi.authorization.file.generated.User.Group group = new org.apache.nifi.authorization.file.generated.User.Group();
|
||||
group.setIdentifier(groupIdentifier);
|
||||
updateUser.getGroup().add(group);
|
||||
}
|
||||
|
||||
saveAndRefreshHolder(authorizations);
|
||||
|
||||
final AuthorizationsHolder holder = authorizationsHolder.get();
|
||||
|
@ -920,6 +786,18 @@ public class FileAuthorizer extends AbstractPolicyBasedAuthorizer {
|
|||
final Authorizations authorizations = this.authorizationsHolder.get().getAuthorizations();
|
||||
final List<org.apache.nifi.authorization.file.generated.User> users = authorizations.getUsers().getUser();
|
||||
|
||||
// for each group iterate over the user references and remove the user reference if it matches the user being deleted
|
||||
for (org.apache.nifi.authorization.file.generated.Group group : authorizations.getGroups().getGroup()) {
|
||||
Iterator<org.apache.nifi.authorization.file.generated.Group.User> groupUserIter = group.getUser().iterator();
|
||||
while (groupUserIter.hasNext()) {
|
||||
org.apache.nifi.authorization.file.generated.Group.User groupUser = groupUserIter.next();
|
||||
if (groupUser.getIdentifier().equals(user.getIdentifier())) {
|
||||
groupUserIter.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove any references to the user being deleted from policies
|
||||
for (Policy policy : authorizations.getPolicies().getPolicy()) {
|
||||
Iterator<Policy.User> policyUserIter = policy.getUser().iterator();
|
||||
|
@ -960,7 +838,7 @@ public class FileAuthorizer extends AbstractPolicyBasedAuthorizer {
|
|||
// ------------------ AccessPolicies ------------------
|
||||
|
||||
@Override
|
||||
public synchronized AccessPolicy addAccessPolicy(final AccessPolicy accessPolicy) throws AuthorizationAccessException {
|
||||
public synchronized AccessPolicy doAddAccessPolicy(final AccessPolicy accessPolicy) throws AuthorizationAccessException {
|
||||
if (accessPolicy == null) {
|
||||
throw new IllegalArgumentException("AccessPolicy cannot be null");
|
||||
}
|
||||
|
@ -981,7 +859,20 @@ public class FileAuthorizer extends AbstractPolicyBasedAuthorizer {
|
|||
private Policy createJAXBPolicy(final AccessPolicy accessPolicy) {
|
||||
final Policy policy = new Policy();
|
||||
policy.setIdentifier(accessPolicy.getIdentifier());
|
||||
transferState(accessPolicy, policy);
|
||||
policy.setResource(accessPolicy.getResource());
|
||||
|
||||
switch (accessPolicy.getAction()) {
|
||||
case READ:
|
||||
policy.setAction(READ_CODE);
|
||||
break;
|
||||
case WRITE:
|
||||
policy.setAction(WRITE_CODE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
transferUsersAndGroups(accessPolicy, policy);
|
||||
return policy;
|
||||
}
|
||||
|
||||
|
@ -1018,7 +909,7 @@ public class FileAuthorizer extends AbstractPolicyBasedAuthorizer {
|
|||
}
|
||||
|
||||
// update the Policy, save, reload, and return
|
||||
transferState(accessPolicy, updatePolicy);
|
||||
transferUsersAndGroups(accessPolicy, updatePolicy);
|
||||
saveAndRefreshHolder(authorizations);
|
||||
|
||||
final AuthorizationsHolder holder = authorizationsHolder.get();
|
||||
|
@ -1073,9 +964,7 @@ public class FileAuthorizer extends AbstractPolicyBasedAuthorizer {
|
|||
* @param accessPolicy the AccessPolicy to transfer state from
|
||||
* @param policy the Policy to transfer state to
|
||||
*/
|
||||
private void transferState(AccessPolicy accessPolicy, Policy policy) {
|
||||
policy.setResource(accessPolicy.getResource());
|
||||
|
||||
private void transferUsersAndGroups(AccessPolicy accessPolicy, Policy policy) {
|
||||
// add users to the policy
|
||||
policy.getUser().clear();
|
||||
for (String userIdentifier : accessPolicy.getUsers()) {
|
||||
|
@ -1091,13 +980,6 @@ public class FileAuthorizer extends AbstractPolicyBasedAuthorizer {
|
|||
policyGroup.setIdentifier(groupIdentifier);
|
||||
policy.getGroup().add(policyGroup);
|
||||
}
|
||||
|
||||
// add the action to the access policy
|
||||
if (accessPolicy.getAction() == RequestAction.READ) {
|
||||
policy.setAction(READ_CODE);
|
||||
} else {
|
||||
policy.setAction(WRITE_CODE);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,19 +33,19 @@ public final class RoleAccessPolicy {
|
|||
static final String WRITE_ACTION = "W";
|
||||
|
||||
private final String resource;
|
||||
private final String actions;
|
||||
private final String action;
|
||||
|
||||
private RoleAccessPolicy(final String resource, final String actions) {
|
||||
private RoleAccessPolicy(final String resource, final String action) {
|
||||
this.resource = resource;
|
||||
this.actions = actions;
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
public String getResource() {
|
||||
return resource;
|
||||
}
|
||||
|
||||
public String getActions() {
|
||||
return actions;
|
||||
public String getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
public static Map<Role,Set<RoleAccessPolicy>> getMappings(final String rootGroupId) {
|
||||
|
@ -62,13 +62,18 @@ public final class RoleAccessPolicy {
|
|||
|
||||
final Set<RoleAccessPolicy> provenancePolicies = new HashSet<>();
|
||||
provenancePolicies.add(new RoleAccessPolicy(ResourceType.Provenance.getValue(), READ_ACTION));
|
||||
if (rootGroupId != null) {
|
||||
provenancePolicies.add(new RoleAccessPolicy(ResourceType.ProvenanceEvent.getValue() + ResourceType.ProcessGroup.getValue() + "/" + rootGroupId, READ_ACTION));
|
||||
}
|
||||
roleAccessPolicies.put(Role.ROLE_PROVENANCE, Collections.unmodifiableSet(provenancePolicies));
|
||||
|
||||
final Set<RoleAccessPolicy> dfmPolicies = new HashSet<>();
|
||||
dfmPolicies.add(new RoleAccessPolicy(ResourceType.Flow.getValue(), READ_ACTION));
|
||||
dfmPolicies.add(new RoleAccessPolicy(ResourceType.Controller.getValue(), READ_ACTION));
|
||||
dfmPolicies.add(new RoleAccessPolicy(ResourceType.Controller.getValue(), WRITE_ACTION));
|
||||
dfmPolicies.add(new RoleAccessPolicy(ResourceType.System.getValue(), READ_ACTION));
|
||||
if (rootGroupId != null) {
|
||||
dfmPolicies.add(new RoleAccessPolicy(ResourceType.ProcessGroup.getValue() + "/" + rootGroupId, READ_ACTION));
|
||||
dfmPolicies.add(new RoleAccessPolicy(ResourceType.ProcessGroup.getValue() + "/" + rootGroupId, WRITE_ACTION));
|
||||
}
|
||||
roleAccessPolicies.put(Role.ROLE_DFM, Collections.unmodifiableSet(dfmPolicies));
|
||||
|
@ -79,16 +84,20 @@ public final class RoleAccessPolicy {
|
|||
if (rootGroupId != null) {
|
||||
adminPolicies.add(new RoleAccessPolicy(ResourceType.ProcessGroup.getValue() + "/" + rootGroupId, READ_ACTION));
|
||||
}
|
||||
adminPolicies.add(new RoleAccessPolicy(ResourceType.Tenant.getValue(), READ_ACTION));
|
||||
adminPolicies.add(new RoleAccessPolicy(ResourceType.Tenant.getValue(), WRITE_ACTION));
|
||||
adminPolicies.add(new RoleAccessPolicy(ResourceType.Policy.getValue(), READ_ACTION));
|
||||
adminPolicies.add(new RoleAccessPolicy(ResourceType.Policy.getValue(), WRITE_ACTION));
|
||||
roleAccessPolicies.put(Role.ROLE_ADMIN, Collections.unmodifiableSet(adminPolicies));
|
||||
|
||||
final Set<RoleAccessPolicy> proxyPolicies = new HashSet<>();
|
||||
proxyPolicies.add(new RoleAccessPolicy(ResourceType.Proxy.getValue(), READ_ACTION));
|
||||
proxyPolicies.add(new RoleAccessPolicy(ResourceType.Proxy.getValue(), WRITE_ACTION));
|
||||
roleAccessPolicies.put(Role.ROLE_PROXY, Collections.unmodifiableSet(proxyPolicies));
|
||||
|
||||
final Set<RoleAccessPolicy> nifiPolicies = new HashSet<>();
|
||||
nifiPolicies.add(new RoleAccessPolicy(ResourceType.Controller.getValue(), READ_ACTION));
|
||||
nifiPolicies.add(new RoleAccessPolicy(ResourceType.SiteToSite.getValue(), READ_ACTION));
|
||||
nifiPolicies.add(new RoleAccessPolicy(ResourceType.SiteToSite.getValue(), WRITE_ACTION));
|
||||
roleAccessPolicies.put(Role.ROLE_NIFI, Collections.unmodifiableSet(nifiPolicies));
|
||||
|
||||
|
|
|
@ -17,6 +17,20 @@
|
|||
|
||||
<!-- group -->
|
||||
<xs:complexType name="Group">
|
||||
<xs:sequence>
|
||||
<xs:element name="user" minOccurs="0" maxOccurs="unbounded" >
|
||||
<xs:complexType>
|
||||
<xs:attribute name="identifier">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:minLength value="1"/>
|
||||
<xs:pattern value=".*[^\s].*"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="identifier">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:string">
|
||||
|
@ -44,20 +58,6 @@
|
|||
|
||||
<!-- user -->
|
||||
<xs:complexType name="User">
|
||||
<xs:sequence>
|
||||
<xs:element name="group" minOccurs="0" maxOccurs="unbounded" >
|
||||
<xs:complexType>
|
||||
<xs:attribute name="identifier">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:minLength value="1"/>
|
||||
<xs:pattern value=".*[^\s].*"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="identifier">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:string">
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.apache.nifi.authorization.resource.ResourceType;
|
|||
import org.apache.nifi.util.NiFiProperties;
|
||||
import org.apache.nifi.util.file.FileUtils;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
@ -79,14 +80,15 @@ public class FileAuthorizerTest {
|
|||
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" +
|
||||
"<authorizations>" +
|
||||
" <groups>" +
|
||||
" <group identifier=\"group-1\" name=\"group-1\" />" +
|
||||
" <group identifier=\"group-2\" name=\"group-2\" />" +
|
||||
" <group identifier=\"group-1\" name=\"group-1\">" +
|
||||
" <user identifier=\"user-1\" />" +
|
||||
" </group>" +
|
||||
" <group identifier=\"group-2\" name=\"group-2\">" +
|
||||
" <user identifier=\"user-2\" />" +
|
||||
" </group>" +
|
||||
" </groups>" +
|
||||
" <users>" +
|
||||
" <user identifier=\"user-1\" identity=\"user-1\">" +
|
||||
" <group identifier=\"group-1\" />" +
|
||||
" <group identifier=\"group-2\" />" +
|
||||
" </user>\n" +
|
||||
" <user identifier=\"user-1\" identity=\"user-1\" />" +
|
||||
" <user identifier=\"user-2\" identity=\"user-2\" />" +
|
||||
" </users>" +
|
||||
" <policies>" +
|
||||
|
@ -154,13 +156,11 @@ public class FileAuthorizerTest {
|
|||
final Set<User> users = authorizer.getUsers();
|
||||
assertEquals(1, users.size());
|
||||
|
||||
// the user has monitor and DFM, but we should only end up with one policy per resource
|
||||
// since DFM has RW to all the same resources that monitor has R
|
||||
UsersAndAccessPolicies usersAndAccessPolicies = authorizer.getUsersAndAccessPolicies();
|
||||
assertEquals(1, usersAndAccessPolicies.getAccessPolicies(ResourceType.Flow.getValue()).size());
|
||||
assertEquals(1, usersAndAccessPolicies.getAccessPolicies(ResourceType.Controller.getValue()).size());
|
||||
assertEquals(2, usersAndAccessPolicies.getAccessPolicies(ResourceType.Controller.getValue()).size());
|
||||
assertEquals(1, usersAndAccessPolicies.getAccessPolicies(ResourceType.System.getValue()).size());
|
||||
assertEquals(1, usersAndAccessPolicies.getAccessPolicies(ResourceType.ProcessGroup.getValue() + "/" + ROOT_GROUP_ID).size());
|
||||
assertEquals(2, usersAndAccessPolicies.getAccessPolicies(ResourceType.ProcessGroup.getValue() + "/" + ROOT_GROUP_ID).size());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -216,7 +216,7 @@ public class FileAuthorizerTest {
|
|||
|
||||
// verify user2's policies
|
||||
final Map<String,Set<RequestAction>> user2Policies = getResourceActions(policies, user2);
|
||||
assertEquals(1, user2Policies.size());
|
||||
assertEquals(2, user2Policies.size());
|
||||
|
||||
assertTrue(user2Policies.containsKey(ResourceType.Provenance.getValue()));
|
||||
assertEquals(1, user2Policies.get(ResourceType.Provenance.getValue()).size());
|
||||
|
@ -231,7 +231,7 @@ public class FileAuthorizerTest {
|
|||
assertTrue(user3Policies.get(ResourceType.Flow.getValue()).contains(RequestAction.READ));
|
||||
|
||||
assertTrue(user3Policies.containsKey(ResourceType.ProcessGroup.getValue() + "/" + ROOT_GROUP_ID));
|
||||
assertEquals(1, user3Policies.get(ResourceType.ProcessGroup.getValue() + "/" + ROOT_GROUP_ID).size());
|
||||
assertEquals(2, user3Policies.get(ResourceType.ProcessGroup.getValue() + "/" + ROOT_GROUP_ID).size());
|
||||
assertTrue(user3Policies.get(ResourceType.ProcessGroup.getValue() + "/" + ROOT_GROUP_ID).contains(RequestAction.WRITE));
|
||||
|
||||
// verify user4's policies
|
||||
|
@ -247,11 +247,11 @@ public class FileAuthorizerTest {
|
|||
assertTrue(user4Policies.get(ResourceType.ProcessGroup.getValue() + "/" + ROOT_GROUP_ID).contains(RequestAction.READ));
|
||||
|
||||
assertTrue(user4Policies.containsKey(ResourceType.Tenant.getValue()));
|
||||
assertEquals(1, user4Policies.get(ResourceType.Tenant.getValue()).size());
|
||||
assertEquals(2, user4Policies.get(ResourceType.Tenant.getValue()).size());
|
||||
assertTrue(user4Policies.get(ResourceType.Tenant.getValue()).contains(RequestAction.WRITE));
|
||||
|
||||
assertTrue(user4Policies.containsKey(ResourceType.Policy.getValue()));
|
||||
assertEquals(1, user4Policies.get(ResourceType.Policy.getValue()).size());
|
||||
assertEquals(2, user4Policies.get(ResourceType.Policy.getValue()).size());
|
||||
assertTrue(user4Policies.get(ResourceType.Policy.getValue()).contains(RequestAction.WRITE));
|
||||
|
||||
// verify user5's policies
|
||||
|
@ -259,7 +259,7 @@ public class FileAuthorizerTest {
|
|||
assertEquals(1, user5Policies.size());
|
||||
|
||||
assertTrue(user5Policies.containsKey(ResourceType.Proxy.getValue()));
|
||||
assertEquals(1, user5Policies.get(ResourceType.Proxy.getValue()).size());
|
||||
assertEquals(2, user5Policies.get(ResourceType.Proxy.getValue()).size());
|
||||
assertTrue(user5Policies.get(ResourceType.Proxy.getValue()).contains(RequestAction.WRITE));
|
||||
|
||||
// verify user6's policies
|
||||
|
@ -267,7 +267,7 @@ public class FileAuthorizerTest {
|
|||
assertEquals(2, user6Policies.size());
|
||||
|
||||
assertTrue(user6Policies.containsKey(ResourceType.SiteToSite.getValue()));
|
||||
assertEquals(1, user6Policies.get(ResourceType.SiteToSite.getValue()).size());
|
||||
assertEquals(2, user6Policies.get(ResourceType.SiteToSite.getValue()).size());
|
||||
assertTrue(user6Policies.get(ResourceType.SiteToSite.getValue()).contains(RequestAction.WRITE));
|
||||
}
|
||||
|
||||
|
@ -529,7 +529,7 @@ public class FileAuthorizerTest {
|
|||
&& group.getUsers().size() == 1 && group.getUsers().contains("user-1")) {
|
||||
foundGroup1 = true;
|
||||
} else if (group.getIdentifier().equals("group-2") && group.getName().equals("group-2")
|
||||
&& group.getUsers().size() == 1 && group.getUsers().contains("user-1")) {
|
||||
&& group.getUsers().size() == 1 && group.getUsers().contains("user-2")) {
|
||||
foundGroup2 = true;
|
||||
}
|
||||
}
|
||||
|
@ -544,12 +544,9 @@ public class FileAuthorizerTest {
|
|||
boolean foundUser2 = false;
|
||||
|
||||
for (User user : users) {
|
||||
if (user.getIdentifier().equals("user-1") && user.getIdentity().equals("user-1")
|
||||
&& user.getGroups().size() == 2 && user.getGroups().contains("group-1")
|
||||
&& user.getGroups().contains("group-2")) {
|
||||
if (user.getIdentifier().equals("user-1") && user.getIdentity().equals("user-1")) {
|
||||
foundUser1 = true;
|
||||
} else if (user.getIdentifier().equals("user-2") && user.getIdentity().equals("user-2")
|
||||
&& user.getGroups().size() == 0) {
|
||||
} else if (user.getIdentifier().equals("user-2") && user.getIdentity().equals("user-2")) {
|
||||
foundUser2 = true;
|
||||
}
|
||||
}
|
||||
|
@ -598,17 +595,12 @@ public class FileAuthorizerTest {
|
|||
final User user = new User.Builder()
|
||||
.identifier("user-1")
|
||||
.identity("user-identity-1")
|
||||
.addGroup("group1")
|
||||
.addGroup("group2")
|
||||
.build();
|
||||
|
||||
final User addedUser = authorizer.addUser(user);
|
||||
assertNotNull(addedUser);
|
||||
assertEquals(user.getIdentifier(), addedUser.getIdentifier());
|
||||
assertEquals(user.getIdentity(), addedUser.getIdentity());
|
||||
assertEquals(2, addedUser.getGroups().size());
|
||||
assertTrue(addedUser.getGroups().contains("group1"));
|
||||
assertTrue(addedUser.getGroups().contains("group2"));
|
||||
|
||||
final Set<User> users = authorizer.getUsers();
|
||||
assertEquals(1, users.size());
|
||||
|
@ -711,15 +703,12 @@ public class FileAuthorizerTest {
|
|||
final User user = new User.Builder()
|
||||
.identifier("user-1")
|
||||
.identity("new-identity")
|
||||
.addGroup("new-group")
|
||||
.build();
|
||||
|
||||
final User updatedUser = authorizer.updateUser(user);
|
||||
assertNotNull(updatedUser);
|
||||
assertEquals(user.getIdentifier(), updatedUser.getIdentifier());
|
||||
assertEquals(user.getIdentity(), updatedUser.getIdentity());
|
||||
assertEquals(1, updatedUser.getGroups().size());
|
||||
assertTrue(updatedUser.getGroups().contains("new-group"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -731,7 +720,6 @@ public class FileAuthorizerTest {
|
|||
final User user = new User.Builder()
|
||||
.identifier("user-X")
|
||||
.identity("new-identity")
|
||||
.addGroup("new-group")
|
||||
.build();
|
||||
|
||||
final User updatedUser = authorizer.updateUser(user);
|
||||
|
@ -781,10 +769,6 @@ public class FileAuthorizerTest {
|
|||
|
||||
final Set<Group> groups = authorizer.getGroups();
|
||||
assertEquals(3, groups.size());
|
||||
|
||||
final User user = authorizer.getUser("user-1");
|
||||
assertNotNull(user);
|
||||
assertTrue(user.getGroups().contains(group.getIdentifier()));
|
||||
}
|
||||
|
||||
|
||||
|
@ -832,12 +816,6 @@ public class FileAuthorizerTest {
|
|||
authorizer.onConfigured(configurationContext);
|
||||
assertEquals(2, authorizer.getGroups().size());
|
||||
|
||||
// retrieve user-1 and verify its in group-1
|
||||
final User user1 = authorizer.getUser("user-1");
|
||||
assertNotNull(user1);
|
||||
assertEquals(2, user1.getGroups().size());
|
||||
assertTrue(user1.getGroups().contains("group-1"));
|
||||
|
||||
final AccessPolicy policy1 = authorizer.getAccessPolicy("policy-1");
|
||||
assertTrue(policy1.getGroups().contains("group-1"));
|
||||
|
||||
|
@ -856,12 +834,6 @@ public class FileAuthorizerTest {
|
|||
// verify we can no longer retrieve group-1 by identifier
|
||||
assertNull(authorizer.getGroup(group.getIdentifier()));
|
||||
|
||||
// verify user-1 is no longer in group-1
|
||||
final User updatedUser1 = authorizer.getUser("user-1");
|
||||
assertNotNull(updatedUser1);
|
||||
assertEquals(1, updatedUser1.getGroups().size());
|
||||
assertFalse(updatedUser1.getGroups().contains("group-1"));
|
||||
|
||||
// verify group-1 is no longer in policy-1
|
||||
final AccessPolicy updatedPolicy1 = authorizer.getAccessPolicy("policy-1");
|
||||
assertFalse(updatedPolicy1.getGroups().contains("group-1"));
|
||||
|
@ -890,12 +862,9 @@ public class FileAuthorizerTest {
|
|||
assertEquals(2, authorizer.getGroups().size());
|
||||
|
||||
// verify user-1 is in group-1 before the update
|
||||
final User user1Before = authorizer.getUser("user-1");
|
||||
assertTrue(user1Before.getGroups().contains("group-1"));
|
||||
|
||||
// verify user-2 is NOT in group-1 before the update
|
||||
final User user2Before = authorizer.getUser("user-2");
|
||||
assertFalse(user2Before.getGroups().contains("group-1"));
|
||||
final Group groupBefore = authorizer.getGroup("group-1");
|
||||
assertEquals(1, groupBefore.getUsers().size());
|
||||
assertTrue(groupBefore.getUsers().contains("user-1"));
|
||||
|
||||
final Group group = new Group.Builder()
|
||||
.identifier("group-1")
|
||||
|
@ -907,13 +876,8 @@ public class FileAuthorizerTest {
|
|||
assertEquals(group.getIdentifier(), updatedGroup.getIdentifier());
|
||||
assertEquals(group.getName(), updatedGroup.getName());
|
||||
|
||||
// user-1 should no longer be in group-1
|
||||
final User user1After = authorizer.getUser("user-1");
|
||||
assertFalse(user1After.getGroups().contains("group-1"));
|
||||
|
||||
// user-2 should now be in group-1
|
||||
final User user2After = authorizer.getUser("user-2");
|
||||
assertTrue(user2After.getGroups().contains("group-1"));
|
||||
assertEquals(1, updatedGroup.getUsers().size());
|
||||
assertTrue(updatedGroup.getUsers().contains("user-2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -967,9 +931,13 @@ public class FileAuthorizerTest {
|
|||
.action(RequestAction.READ)
|
||||
.build();
|
||||
|
||||
try {
|
||||
final AccessPolicy returnedPolicy2 = authorizer.addAccessPolicy(policy2);
|
||||
assertNotNull(returnedPolicy2);
|
||||
assertEquals(2, authorizer.getAccessPolicies().size());
|
||||
Assert.fail("Should have thrown exception");
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
assertEquals(1, authorizer.getAccessPolicies().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -1043,7 +1011,7 @@ public class FileAuthorizerTest {
|
|||
final AccessPolicy updateAccessPolicy = authorizer.updateAccessPolicy(policy);
|
||||
assertNotNull(updateAccessPolicy);
|
||||
assertEquals("policy-1", updateAccessPolicy.getIdentifier());
|
||||
assertEquals("resource-A", updateAccessPolicy.getResource());
|
||||
assertEquals("/flow", updateAccessPolicy.getResource());
|
||||
|
||||
assertEquals(1, updateAccessPolicy.getUsers().size());
|
||||
assertTrue(updateAccessPolicy.getUsers().contains("user-A"));
|
||||
|
|
|
@ -71,12 +71,12 @@ public class TestFlowController {
|
|||
properties.setProperty("nifi.remote.input.socket.port", "");
|
||||
properties.setProperty("nifi.remote.input.secure", "");
|
||||
|
||||
Group group1 = new Group.Builder().identifier("group-id-1").name("group-1").build();
|
||||
Group group2 = new Group.Builder().identifier("group-id-2").name("group-2").build();
|
||||
|
||||
User user1 = new User.Builder().identifier("user-id-1").identity("user-1").addGroup(group1.getIdentifier()).build();
|
||||
User user1 = new User.Builder().identifier("user-id-1").identity("user-1").build();
|
||||
User user2 = new User.Builder().identifier("user-id-2").identity("user-2").build();
|
||||
|
||||
Group group1 = new Group.Builder().identifier("group-id-1").name("group-1").addUser(user1.getIdentifier()).build();
|
||||
Group group2 = new Group.Builder().identifier("group-id-2").name("group-2").build();
|
||||
|
||||
AccessPolicy policy1 = new AccessPolicy.Builder()
|
||||
.identifier("policy-id-1")
|
||||
.resource("resource1")
|
||||
|
@ -135,7 +135,7 @@ public class TestFlowController {
|
|||
// had a problem verifying the call to inheritFingerprint didn't happen, so just verify none of the add methods got called
|
||||
verify(authorizer, times(0)).addUser(any(User.class));
|
||||
verify(authorizer, times(0)).addGroup(any(Group.class));
|
||||
verify(authorizer, times(0)).addAccessPolicy(any(AccessPolicy.class));
|
||||
//verify(authorizer, times(0)).addAccessPolicy(any(AccessPolicy.class));
|
||||
}
|
||||
|
||||
@Test(expected = UninheritableFlowException.class)
|
||||
|
|
|
@ -515,10 +515,11 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
|||
@Override
|
||||
public UserEntity updateUser(final Revision revision, final UserDTO userDTO) {
|
||||
final Authorizable usersAuthorizable = authorizableLookup.getTenantAuthorizable();
|
||||
final Set<Group> groups = userGroupDAO.getUserGroupsForUser(userDTO.getId());
|
||||
final RevisionUpdate<UserDTO> snapshot = updateComponent(revision,
|
||||
usersAuthorizable,
|
||||
() -> userDAO.updateUser(userDTO),
|
||||
user -> dtoFactory.createUserDto(user, user.getGroups().stream().map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet())));
|
||||
user -> dtoFactory.createUserDto(user, groups.stream().map(g -> g.getIdentifier()).map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet())));
|
||||
|
||||
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(usersAuthorizable);
|
||||
return entityFactory.createUserEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy);
|
||||
|
@ -934,7 +935,8 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
|||
@Override
|
||||
public UserEntity deleteUser(final Revision revision, final String userId) {
|
||||
final User user = userDAO.getUser(userId);
|
||||
final Set<TenantEntity> userGroups = user != null ? user.getGroups().stream().map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet()) : null;
|
||||
final Set<TenantEntity> userGroups = user != null ? userGroupDAO.getUserGroupsForUser(userId).stream()
|
||||
.map(g -> g.getIdentifier()).map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet()) : null;
|
||||
final UserDTO snapshot = deleteComponent(
|
||||
revision,
|
||||
authorizableLookup.getTenantAuthorizable(),
|
||||
|
@ -1229,8 +1231,9 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
|||
final Authorizable tenantAuthorizable = authorizableLookup.getTenantAuthorizable();
|
||||
final String creator = NiFiUserUtils.getNiFiUserIdentity();
|
||||
final User newUser = userDAO.createUser(userDTO);
|
||||
final UserDTO newUserDto = dtoFactory.createUserDto(newUser, newUser.getGroups().stream()
|
||||
.map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet()));
|
||||
final Set<Group> groups = userGroupDAO.getUserGroupsForUser(newUser.getIdentifier());
|
||||
final UserDTO newUserDto = dtoFactory.createUserDto(newUser, groups.stream()
|
||||
.map(g -> g.getIdentifier()).map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet()));
|
||||
|
||||
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(authorizableLookup.getTenantAuthorizable());
|
||||
return entityFactory.createUserEntity(newUserDto, dtoFactory.createRevisionDTO(new FlowModification(revision, creator)), accessPolicy);
|
||||
|
@ -2233,20 +2236,8 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
|||
|
||||
@Override
|
||||
public UserEntity getUser(final String userId) {
|
||||
final Authorizable usersAuthorizable = authorizableLookup.getTenantAuthorizable();
|
||||
final RevisionDTO userRevision = dtoFactory.createRevisionDTO(revisionManager.getRevision(userId));
|
||||
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(usersAuthorizable);
|
||||
final User user = userDAO.getUser(userId);
|
||||
final Set<TenantEntity> userGroups = user.getGroups().stream()
|
||||
.map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet());
|
||||
return entityFactory.createUserEntity(dtoFactory.createUserDto(user, userGroups), userRevision, accessPolicy);
|
||||
}
|
||||
|
||||
private UserEntity createUserEntity(final User user) {
|
||||
final RevisionDTO userRevision = dtoFactory.createRevisionDTO(revisionManager.getRevision(user.getIdentifier()));
|
||||
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(authorizableLookup.getTenantAuthorizable());
|
||||
final Set<TenantEntity> userGroups = user.getGroups().stream().map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet());
|
||||
return entityFactory.createUserEntity(dtoFactory.createUserDto(user, userGroups), userRevision, accessPolicy);
|
||||
return createUserEntity(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -2257,6 +2248,14 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
|||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
private UserEntity createUserEntity(final User user) {
|
||||
final RevisionDTO userRevision = dtoFactory.createRevisionDTO(revisionManager.getRevision(user.getIdentifier()));
|
||||
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(authorizableLookup.getTenantAuthorizable());
|
||||
final Set<TenantEntity> userGroups = userGroupDAO.getUserGroupsForUser(user.getIdentifier()).stream()
|
||||
.map(g -> g.getIdentifier()).map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet());
|
||||
return entityFactory.createUserEntity(dtoFactory.createUserDto(user, userGroups), userRevision, accessPolicy);
|
||||
}
|
||||
|
||||
private UserGroupEntity createUserGroupEntity(final Group userGroup) {
|
||||
final RevisionDTO userGroupRevision = dtoFactory.createRevisionDTO(revisionManager.getRevision(userGroup.getIdentifier()));
|
||||
final Set<TenantEntity> users = userGroup.getUsers().stream().map(mapUserIdToTenantEntity()).collect(Collectors.toSet());
|
||||
|
|
|
@ -45,6 +45,14 @@ public interface UserGroupDAO {
|
|||
*/
|
||||
Group getUserGroup(String userGroupId);
|
||||
|
||||
/**
|
||||
* Gets the groups for the user with the specified ID.
|
||||
*
|
||||
* @param userId The user ID
|
||||
* @return The set of groups
|
||||
*/
|
||||
Set<Group> getUserGroupsForUser(String userId);
|
||||
|
||||
/**
|
||||
* Gets all user groups.
|
||||
*
|
||||
|
|
|
@ -107,7 +107,7 @@ public class StandardPolicyBasedAuthorizerDAO implements AccessPolicyDAO, UserGr
|
|||
}
|
||||
|
||||
@Override
|
||||
public AccessPolicy addAccessPolicy(final AccessPolicy accessPolicy) throws AuthorizationAccessException {
|
||||
public AccessPolicy doAddAccessPolicy(final AccessPolicy accessPolicy) throws AuthorizationAccessException {
|
||||
throw new IllegalStateException(MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER);
|
||||
}
|
||||
|
||||
|
@ -141,7 +141,7 @@ public class StandardPolicyBasedAuthorizerDAO implements AccessPolicyDAO, UserGr
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onConfigured(final AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
|
||||
public void doOnConfigured(final AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -219,6 +219,13 @@ public class StandardPolicyBasedAuthorizerDAO implements AccessPolicyDAO, UserGr
|
|||
return userGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Group> getUserGroupsForUser(String userId) {
|
||||
return authorizer.getGroups().stream()
|
||||
.filter(g -> g.getUsers().contains(userId))
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Group> getUserGroups() {
|
||||
return authorizer.getGroups();
|
||||
|
@ -278,11 +285,7 @@ public class StandardPolicyBasedAuthorizerDAO implements AccessPolicyDAO, UserGr
|
|||
}
|
||||
|
||||
private User buildUser(final String identifier, final UserDTO userDTO) {
|
||||
final Set<TenantEntity> groups = userDTO.getUserGroups();
|
||||
final User.Builder builder = new User.Builder().identifier(identifier).identity(userDTO.getIdentity());
|
||||
if (groups != null) {
|
||||
builder.addGroups(groups.stream().map(ComponentEntity::getId).collect(Collectors.toSet()));
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
|
|
@ -16,19 +16,12 @@
|
|||
*/
|
||||
package org.apache.nifi.web.dao.impl
|
||||
|
||||
import org.apache.nifi.authorization.AbstractPolicyBasedAuthorizer
|
||||
import org.apache.nifi.authorization.AccessPolicy
|
||||
import org.apache.nifi.authorization.Authorizer
|
||||
import org.apache.nifi.authorization.Group
|
||||
import org.apache.nifi.authorization.RequestAction
|
||||
import org.apache.nifi.authorization.User
|
||||
import org.apache.nifi.authorization.*
|
||||
import org.apache.nifi.web.ResourceNotFoundException
|
||||
import org.apache.nifi.web.api.dto.AccessPolicyDTO
|
||||
import org.apache.nifi.web.api.dto.UserDTO
|
||||
import org.apache.nifi.web.api.dto.UserGroupDTO
|
||||
import org.apache.nifi.web.api.entity.TenantEntity
|
||||
import org.apache.nifi.web.api.entity.UserEntity
|
||||
import org.apache.nifi.web.api.entity.UserGroupEntity
|
||||
import spock.lang.Specification
|
||||
import spock.lang.Unroll
|
||||
|
||||
|
@ -100,14 +93,15 @@ class StandardPolicyBasedAuthorizerDAOSpec extends Specification {
|
|||
noExceptionThrown()
|
||||
|
||||
then:
|
||||
1 * authorizer.addAccessPolicy(accessPolicy) >> accessPolicy
|
||||
1 * authorizer.getAccessPolicies() >> accessPolicies
|
||||
1 * authorizer.doAddAccessPolicy(accessPolicy) >> accessPolicy
|
||||
0 * _
|
||||
result?.equals accessPolicy
|
||||
|
||||
where:
|
||||
accessPolicy | _
|
||||
accessPolicy | accessPolicies
|
||||
new AccessPolicy.Builder().identifier('policy-id-1').resource('/fake/resource').addUser('user-id-1').addGroup('user-group-id-1')
|
||||
.action(RequestAction.WRITE).build() | _
|
||||
.action(RequestAction.WRITE).build() | [] as Set
|
||||
}
|
||||
|
||||
@Unroll
|
||||
|
@ -409,7 +403,7 @@ class StandardPolicyBasedAuthorizerDAOSpec extends Specification {
|
|||
|
||||
where:
|
||||
user | _
|
||||
new User.Builder().identifier('user-id-1').identity('user identity').addGroup('user-group-id-1').build() | _
|
||||
new User.Builder().identifier('user-id-1').identity('user identity').build() | _
|
||||
}
|
||||
|
||||
@Unroll
|
||||
|
@ -432,7 +426,7 @@ class StandardPolicyBasedAuthorizerDAOSpec extends Specification {
|
|||
|
||||
where:
|
||||
user | _
|
||||
new User.Builder().identifier('user-id-1').identity('user identity').addGroup('user-group-id-1').build() | _
|
||||
new User.Builder().identifier('user-id-1').identity('user identity').build() | _
|
||||
}
|
||||
|
||||
@Unroll
|
||||
|
@ -451,7 +445,7 @@ class StandardPolicyBasedAuthorizerDAOSpec extends Specification {
|
|||
|
||||
where:
|
||||
user | _
|
||||
new User.Builder().identifier('user-id-1').identity('user identity').addGroup('user-group-id-1').build() | _
|
||||
new User.Builder().identifier('user-id-1').identity('user identity').build() | _
|
||||
}
|
||||
|
||||
@Unroll
|
||||
|
@ -485,7 +479,7 @@ class StandardPolicyBasedAuthorizerDAOSpec extends Specification {
|
|||
|
||||
where:
|
||||
users | _
|
||||
[new User.Builder().identifier('user-id-1').identity('user identity').addGroup('user-group-id-1').build()] as Set | _
|
||||
[new User.Builder().identifier('user-id-1').identity('user identity').build()] as Set | _
|
||||
}
|
||||
|
||||
@Unroll
|
||||
|
@ -506,7 +500,7 @@ class StandardPolicyBasedAuthorizerDAOSpec extends Specification {
|
|||
|
||||
where:
|
||||
user | _
|
||||
new User.Builder().identifier('user-id-1').identity('user identity').addGroup('user-group-id-1').build() | _
|
||||
new User.Builder().identifier('user-id-1').identity('user identity').build() | _
|
||||
}
|
||||
|
||||
@Unroll
|
||||
|
@ -542,7 +536,7 @@ class StandardPolicyBasedAuthorizerDAOSpec extends Specification {
|
|||
|
||||
where:
|
||||
user | _
|
||||
new User.Builder().identifier('user-id-1').identity('user identity').addGroup('user-group-id-1').build() | _
|
||||
new User.Builder().identifier('user-id-1').identity('user identity').build() | _
|
||||
}
|
||||
|
||||
@Unroll
|
||||
|
|
Loading…
Reference in New Issue