mirror of https://github.com/apache/nifi.git
NIFI-1952 Create REST endpoints for user/group/policy management
created REST Resources for users, groups, and access policies added Authorizables for users, groups, and access policies added methods to DtoFactory and EntityFactory to create objects for users, groups, and access policies extracted anonymous AuthorizableLookup impl in StandardNiFiServiceFacade.java to a protected class to make the lookup call mockable in tests added methods to manage users/groups/access policies to StandardNiFiServiceFacade added StandardNiFiServiceFacadeSpec to unit-test management of users/groups/access policies added implementations for UserDAO, GroupDAO, AccessPolicyDAO. added spring config for user/group/policy resources and daos Updated user/group/policy creation via REST resources, no longer requires the use of the revision manager updated StandardNiFiServiceFacadeSpec based on user/group/policy creation changes condensed user/group/policy DAOs to a single DAO (StandardPolicyBasedAuthorizerDAO) fixed spring config of user/group/policy REST resources Updated to return ComponentEntity objects instead of just their IDs mid-progress on updating tests updated code and tests to return component entities from REST endpoints for users, groups, policies This closes #526
This commit is contained in:
parent
32facaedb4
commit
f47be77b6a
|
@ -24,7 +24,7 @@ import java.util.Set;
|
|||
/**
|
||||
* A group that users can belong to.
|
||||
*/
|
||||
public class Group {
|
||||
public class Group { // TODO rename to UserGroup
|
||||
|
||||
private final String identifier;
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ import java.lang.reflect.InvocationTargetException;
|
|||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Factory bean for loading the configured authorizer.
|
||||
|
@ -287,35 +288,180 @@ public class AuthorizerFactoryBean implements FactoryBean, DisposableBean, Autho
|
|||
* @return authorizer
|
||||
*/
|
||||
public Authorizer withNarLoader(final Authorizer baseAuthorizer) {
|
||||
return new Authorizer() {
|
||||
@Override
|
||||
public AuthorizationResult authorize(final AuthorizationRequest request) throws AuthorizationAccessException {
|
||||
try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
|
||||
return baseAuthorizer.authorize(request);
|
||||
if (baseAuthorizer instanceof AbstractPolicyBasedAuthorizer) {
|
||||
AbstractPolicyBasedAuthorizer policyBasedAuthorizer = (AbstractPolicyBasedAuthorizer) baseAuthorizer;
|
||||
return new AbstractPolicyBasedAuthorizer() {
|
||||
@Override
|
||||
public Group addGroup(Group group) throws AuthorizationAccessException {
|
||||
try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
|
||||
return policyBasedAuthorizer.addGroup(group);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(AuthorizerInitializationContext initializationContext) throws AuthorizerCreationException {
|
||||
try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
|
||||
baseAuthorizer.initialize(initializationContext);
|
||||
@Override
|
||||
public Group getGroup(String identifier) throws AuthorizationAccessException {
|
||||
try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
|
||||
return policyBasedAuthorizer.getGroup(identifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigured(AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
|
||||
try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
|
||||
baseAuthorizer.onConfigured(configurationContext);
|
||||
@Override
|
||||
public Group updateGroup(Group group) throws AuthorizationAccessException {
|
||||
try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
|
||||
return policyBasedAuthorizer.updateGroup(group);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preDestruction() throws AuthorizerDestructionException {
|
||||
try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
|
||||
baseAuthorizer.preDestruction();
|
||||
@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 addUser(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 updateUser(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 addAccessPolicy(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 onConfigured(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
|
||||
|
|
|
@ -17,15 +17,21 @@
|
|||
package org.apache.nifi.web.api.dto;
|
||||
|
||||
import com.wordnik.swagger.annotations.ApiModelProperty;
|
||||
import org.apache.nifi.web.api.entity.UserEntity;
|
||||
import org.apache.nifi.web.api.entity.UserGroupEntity;
|
||||
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Details for the access configuration.
|
||||
*/
|
||||
@XmlType(name = "accessPolicy")
|
||||
public class AccessPolicyDTO {
|
||||
public class AccessPolicyDTO extends ComponentDTO {
|
||||
|
||||
private String resource;
|
||||
private Set<UserEntity> users;
|
||||
private Set<UserGroupEntity> userGroups;
|
||||
private Boolean canRead;
|
||||
private Boolean canWrite;
|
||||
|
||||
|
@ -59,4 +65,39 @@ public class AccessPolicyDTO {
|
|||
this.canWrite = canWrite;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The resource ID for this access policy.
|
||||
*/
|
||||
@ApiModelProperty(value="The resource ID for this access policy.")
|
||||
public String getResource() {
|
||||
return resource;
|
||||
}
|
||||
|
||||
public void setResource(String resource) {
|
||||
this.resource = resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The set of user IDs associated with this access policy.
|
||||
*/
|
||||
@ApiModelProperty(value = "The set of user IDs associated with this access policy.")
|
||||
public Set<UserEntity> getUsers() {
|
||||
return users;
|
||||
}
|
||||
|
||||
public void setUsers(Set<UserEntity> users) {
|
||||
this.users = users;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The set of user group IDs associated with this access policy.
|
||||
*/
|
||||
@ApiModelProperty(value = "The set of user group IDs associated with this access policy.")
|
||||
public Set<UserGroupEntity> getUserGroups() {
|
||||
return userGroups;
|
||||
}
|
||||
|
||||
public void setUserGroups(Set<UserGroupEntity> userGroups) {
|
||||
this.userGroups = userGroups;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,171 +17,43 @@
|
|||
package org.apache.nifi.web.api.dto;
|
||||
|
||||
import com.wordnik.swagger.annotations.ApiModelProperty;
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
import org.apache.nifi.web.api.entity.UserGroupEntity;
|
||||
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
import org.apache.nifi.web.api.dto.util.DateTimeAdapter;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A user of this NiFi.
|
||||
*/
|
||||
@XmlType(name = "user")
|
||||
public class UserDTO {
|
||||
public class UserDTO extends ComponentDTO {
|
||||
|
||||
private String id;
|
||||
private String dn;
|
||||
private String userName;
|
||||
private String userGroup;
|
||||
private String justification;
|
||||
private Date creation;
|
||||
private String status;
|
||||
|
||||
private Date lastVerified;
|
||||
private Date lastAccessed;
|
||||
private Set<String> authorities;
|
||||
private String identity;
|
||||
private Set<UserGroupEntity> groups;
|
||||
|
||||
/**
|
||||
* @return user id
|
||||
* @return users identity
|
||||
*/
|
||||
@ApiModelProperty(
|
||||
value = "The id of the user."
|
||||
value = "The identity of the user."
|
||||
)
|
||||
public String getId() {
|
||||
return id;
|
||||
public String getIdentity() {
|
||||
return identity;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
public void setIdentity(String identity) {
|
||||
this.identity = identity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return users authorities
|
||||
* @return groups to which the user belongs
|
||||
*/
|
||||
@ApiModelProperty(
|
||||
value = "The users authorities."
|
||||
)
|
||||
public Set<String> getAuthorities() {
|
||||
return authorities;
|
||||
@ApiModelProperty(value = "The groups to which the user belongs.")
|
||||
public Set<UserGroupEntity> getGroups() {
|
||||
return groups;
|
||||
}
|
||||
|
||||
public void setAuthorities(Set<String> authorities) {
|
||||
this.authorities = authorities;
|
||||
public void setGroups(Set<UserGroupEntity> groups) {
|
||||
this.groups = groups;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return creation time for this users account
|
||||
*/
|
||||
@XmlJavaTypeAdapter(DateTimeAdapter.class)
|
||||
@ApiModelProperty(
|
||||
value = "The timestamp when the user was created."
|
||||
)
|
||||
public Date getCreation() {
|
||||
return creation;
|
||||
}
|
||||
|
||||
public void setCreation(Date creation) {
|
||||
this.creation = creation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return users DN
|
||||
*/
|
||||
@ApiModelProperty(
|
||||
value = "The dn of the user."
|
||||
)
|
||||
public String getDn() {
|
||||
return dn;
|
||||
}
|
||||
|
||||
public void setDn(String dn) {
|
||||
this.dn = dn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return users name. If the name could not be extracted from the DN, this value will be the entire DN
|
||||
*/
|
||||
@ApiModelProperty(
|
||||
value = "The username. If it could not be extracted from the DN, this value will be the entire DN."
|
||||
)
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return user group
|
||||
*/
|
||||
@ApiModelProperty(
|
||||
value = "The group this user belongs to."
|
||||
)
|
||||
public String getUserGroup() {
|
||||
return userGroup;
|
||||
}
|
||||
|
||||
public void setUserGroup(String userGroup) {
|
||||
this.userGroup = userGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return users account justification
|
||||
*/
|
||||
@ApiModelProperty(
|
||||
value = "The justification for the user account."
|
||||
)
|
||||
public String getJustification() {
|
||||
return justification;
|
||||
}
|
||||
|
||||
public void setJustification(String justification) {
|
||||
this.justification = justification;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return time that the user last accessed the system
|
||||
*/
|
||||
@XmlJavaTypeAdapter(DateTimeAdapter.class)
|
||||
@ApiModelProperty(
|
||||
value = "The timestamp the user last accessed the system."
|
||||
)
|
||||
public Date getLastAccessed() {
|
||||
return lastAccessed;
|
||||
}
|
||||
|
||||
public void setLastAccessed(Date lastAccessed) {
|
||||
this.lastAccessed = lastAccessed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return time that the users credentials were last verified
|
||||
*/
|
||||
@XmlJavaTypeAdapter(DateTimeAdapter.class)
|
||||
@ApiModelProperty(
|
||||
value = "The timestamp the user authorities were verified."
|
||||
)
|
||||
public Date getLastVerified() {
|
||||
return lastVerified;
|
||||
}
|
||||
|
||||
public void setLastVerified(Date lastVerified) {
|
||||
this.lastVerified = lastVerified;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return status of the users account
|
||||
*/
|
||||
@ApiModelProperty(
|
||||
value = "The user status."
|
||||
)
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,73 +17,44 @@
|
|||
package org.apache.nifi.web.api.dto;
|
||||
|
||||
import com.wordnik.swagger.annotations.ApiModelProperty;
|
||||
import java.util.Set;
|
||||
import org.apache.nifi.web.api.entity.UserEntity;
|
||||
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A user group in this NiFi.
|
||||
*/
|
||||
@XmlType(name = "userGroup")
|
||||
public class UserGroupDTO {
|
||||
public class UserGroupDTO extends ComponentDTO {
|
||||
|
||||
private String group;
|
||||
private Set<String> userIds;
|
||||
private Set<String> authorities;
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* @return user group
|
||||
*/
|
||||
@ApiModelProperty(
|
||||
value = "The user group."
|
||||
)
|
||||
public String getGroup() {
|
||||
return group;
|
||||
}
|
||||
|
||||
public void setGroup(String group) {
|
||||
this.group = group;
|
||||
}
|
||||
private String name;
|
||||
private Set<UserEntity> users;
|
||||
|
||||
/**
|
||||
* @return users in this group
|
||||
*/
|
||||
@ApiModelProperty(
|
||||
value = "The users that belong to the group."
|
||||
value = "The users that belong to the user group."
|
||||
)
|
||||
public Set<String> getUserIds() {
|
||||
return userIds;
|
||||
public Set<UserEntity> getUsers() {
|
||||
return users;
|
||||
}
|
||||
|
||||
public void setUserIds(Set<String> userIds) {
|
||||
this.userIds = userIds;
|
||||
public void setUsers(Set<UserEntity> users) {
|
||||
this.users = users;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return status of the users account
|
||||
*
|
||||
* @return name of the user group
|
||||
*/
|
||||
@ApiModelProperty(
|
||||
value = "The status of the users accounts."
|
||||
)
|
||||
public String getStatus() {
|
||||
return status;
|
||||
@ApiModelProperty(value = "The name of the user group.")
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return users authorities
|
||||
*/
|
||||
@ApiModelProperty(
|
||||
value = "The authorities of the users."
|
||||
)
|
||||
public Set<String> getAuthorities() {
|
||||
return authorities;
|
||||
}
|
||||
|
||||
public void setAuthorities(Set<String> authorities) {
|
||||
this.authorities = authorities;
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.web.api.entity;
|
||||
|
||||
import org.apache.nifi.web.api.dto.AccessPolicyDTO;
|
||||
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
/**
|
||||
* A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to an {@link AccessPolicyDTO}.
|
||||
*/
|
||||
@XmlRootElement(name = "accessPolicyEntity")
|
||||
public class AccessPolicyEntity extends ComponentEntity {
|
||||
|
||||
private AccessPolicyDTO component;
|
||||
|
||||
/**
|
||||
* The {@link AccessPolicyDTO} that is being serialized.
|
||||
*
|
||||
* @return The {@link AccessPolicyDTO} object
|
||||
*/
|
||||
public AccessPolicyDTO getComponent() {
|
||||
return component;
|
||||
}
|
||||
|
||||
public void setComponent(AccessPolicyDTO component) {
|
||||
this.component = component;
|
||||
}
|
||||
|
||||
}
|
|
@ -16,28 +16,29 @@
|
|||
*/
|
||||
package org.apache.nifi.web.api.entity;
|
||||
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import org.apache.nifi.web.api.dto.UserDTO;
|
||||
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
/**
|
||||
* A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a UserDTO.
|
||||
*/
|
||||
@XmlRootElement(name = "userEntity")
|
||||
public class UserEntity extends Entity {
|
||||
public class UserEntity extends ComponentEntity {
|
||||
|
||||
private UserDTO user;
|
||||
private UserDTO component;
|
||||
|
||||
/**
|
||||
* The UserDTO that is being serialized.
|
||||
*
|
||||
* @return The UserDTO object
|
||||
*/
|
||||
public UserDTO getUser() {
|
||||
return user;
|
||||
public UserDTO getComponent() {
|
||||
return component;
|
||||
}
|
||||
|
||||
public void setUser(UserDTO user) {
|
||||
this.user = user;
|
||||
public void setComponent(UserDTO component) {
|
||||
this.component = component;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,21 +23,21 @@ import org.apache.nifi.web.api.dto.UserGroupDTO;
|
|||
* A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a UserGroupDTO.
|
||||
*/
|
||||
@XmlRootElement(name = "userGroupEntity")
|
||||
public class UserGroupEntity extends Entity {
|
||||
public class UserGroupEntity extends ComponentEntity {
|
||||
|
||||
private UserGroupDTO userGroup;
|
||||
private UserGroupDTO component;
|
||||
|
||||
/**
|
||||
* The UserGroupDTO that is being serialized.
|
||||
*
|
||||
* @return The UserGroupDTO object
|
||||
*/
|
||||
public UserGroupDTO getUserGroup() {
|
||||
return userGroup;
|
||||
public UserGroupDTO getComponent() {
|
||||
return component;
|
||||
}
|
||||
|
||||
public void setUserGroup(UserGroupDTO userGroup) {
|
||||
this.userGroup = userGroup;
|
||||
public void setComponent(UserGroupDTO component) {
|
||||
this.component = component;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.authorization.resource;
|
||||
|
||||
import org.apache.nifi.authorization.Resource;
|
||||
|
||||
public class AccessPoliciesAuthorizable implements Authorizable {
|
||||
|
||||
@Override
|
||||
public Authorizable getParentAuthorizable() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resource getResource() {
|
||||
return ResourceFactory.getPoliciesResource();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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.resource;
|
||||
|
||||
import org.apache.nifi.authorization.AccessPolicy;
|
||||
import org.apache.nifi.authorization.Resource;
|
||||
|
||||
public class AccessPolicyAuthorizable implements Authorizable {
|
||||
|
||||
private final AccessPolicy policy;
|
||||
|
||||
public AccessPolicyAuthorizable(AccessPolicy policy) {
|
||||
this.policy = policy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authorizable getParentAuthorizable() {
|
||||
return new Authorizable() {
|
||||
@Override
|
||||
public Authorizable getParentAuthorizable() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resource getResource() {
|
||||
return ResourceFactory.getPoliciesResource();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resource getResource() {
|
||||
return ResourceFactory.getPolicyResource(policy.getIdentifier());
|
||||
}
|
||||
|
||||
public AccessPolicy getPolicy() {
|
||||
return policy;
|
||||
}
|
||||
}
|
|
@ -16,7 +16,10 @@
|
|||
*/
|
||||
package org.apache.nifi.authorization.resource;
|
||||
|
||||
import org.apache.nifi.authorization.AccessPolicy;
|
||||
import org.apache.nifi.authorization.Group;
|
||||
import org.apache.nifi.authorization.Resource;
|
||||
import org.apache.nifi.authorization.User;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
|
@ -286,6 +289,45 @@ public final class ResourceFactory {
|
|||
}
|
||||
};
|
||||
|
||||
private final static Resource POLICIES_RESOURCE = new Resource() {
|
||||
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return "/policies";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Access Policies";
|
||||
}
|
||||
};
|
||||
|
||||
private final static Resource USERS_RESOURCE = new Resource() {
|
||||
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return "/users";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Users";
|
||||
}
|
||||
};
|
||||
|
||||
private final static Resource USERGROUPS_RESOURCE = new Resource() {
|
||||
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return "/user-groups";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "User Groups";
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the Resource for accessing Connections.
|
||||
*
|
||||
|
@ -486,6 +528,54 @@ public final class ResourceFactory {
|
|||
return USER_RESOURCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link Resource} for accessing {@link AccessPolicy}s.
|
||||
* @return The policies resource
|
||||
*/
|
||||
public static Resource getPoliciesResource() {
|
||||
return POLICIES_RESOURCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a Resource for accessing an {@link AccessPolicy} configuration.
|
||||
*
|
||||
* @param identifier The identifier of the component being accessed
|
||||
* @return The resource
|
||||
*/
|
||||
public static Resource getPolicyResource(final String identifier) {
|
||||
Objects.requireNonNull(identifier, "The component identifier must be specified.");
|
||||
|
||||
return new Resource() {
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return String.format("%s/%s", POLICIES_RESOURCE.getIdentifier(), identifier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return identifier;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a Resource for accessing {@link User} configurations.
|
||||
*
|
||||
* @return The resource
|
||||
*/
|
||||
public static Resource getUsersResource() {
|
||||
return USERS_RESOURCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a Resource for accessing {@link Group}s configuration.
|
||||
*
|
||||
* @return The resource
|
||||
*/
|
||||
public static Resource getUserGroupsResource() {
|
||||
return USERGROUPS_RESOURCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a Resource for accessing a component configuration.
|
||||
*
|
||||
|
|
|
@ -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.resource;
|
||||
|
||||
import org.apache.nifi.authorization.Resource;
|
||||
|
||||
public class UserGroupsAuthorizable implements Authorizable {
|
||||
@Override
|
||||
public Authorizable getParentAuthorizable() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resource getResource() {
|
||||
return ResourceFactory.getUserGroupsResource();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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.resource;
|
||||
|
||||
import org.apache.nifi.authorization.Resource;
|
||||
|
||||
public class UsersAuthorizable implements Authorizable {
|
||||
|
||||
@Override
|
||||
public Authorizable getParentAuthorizable() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resource getResource() {
|
||||
return ResourceFactory.getUsersResource();
|
||||
}
|
||||
|
||||
}
|
|
@ -16,6 +16,9 @@
|
|||
*/
|
||||
package org.apache.nifi.web;
|
||||
|
||||
import org.apache.nifi.authorization.AccessPolicy;
|
||||
import org.apache.nifi.authorization.Group;
|
||||
import org.apache.nifi.authorization.User;
|
||||
import org.apache.nifi.authorization.resource.Authorizable;
|
||||
import org.apache.nifi.controller.Snippet;
|
||||
|
||||
|
@ -151,4 +154,29 @@ public interface AuthorizableLookup {
|
|||
* @return snippet of authorizable's
|
||||
*/
|
||||
Snippet getSnippet(String id);
|
||||
|
||||
/**
|
||||
* Get the {@link Authorizable} that represents the resource of {@link User}s.
|
||||
* @return authorizable
|
||||
*/
|
||||
Authorizable getUsersAuthorizable();
|
||||
|
||||
/**
|
||||
* Get the {@link Authorizable} that represents the resource of {@link Group}s.
|
||||
* @return authorizable
|
||||
*/
|
||||
Authorizable getUserGroupsAuthorizable();
|
||||
|
||||
/**
|
||||
* Get the {@link Authorizable} the represents the parent resource of {@link AccessPolicy} resources.
|
||||
* @return authorizable
|
||||
*/
|
||||
Authorizable getAccessPoliciesAuthorizable();
|
||||
|
||||
/**
|
||||
* Get the {@link Authorizable} the represents the {@link AccessPolicy} with the given ID.
|
||||
* @param id access policy ID
|
||||
* @return authorizable
|
||||
*/
|
||||
Authorizable getAccessPolicyAuthorizable(String id);
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import org.apache.nifi.controller.ScheduledState;
|
|||
import org.apache.nifi.controller.repository.claim.ContentDirection;
|
||||
import org.apache.nifi.controller.service.ControllerServiceState;
|
||||
import org.apache.nifi.groups.ProcessGroup;
|
||||
import org.apache.nifi.web.api.dto.AccessPolicyDTO;
|
||||
import org.apache.nifi.web.api.dto.BulletinBoardDTO;
|
||||
import org.apache.nifi.web.api.dto.BulletinQueryDTO;
|
||||
import org.apache.nifi.web.api.dto.ClusterDTO;
|
||||
|
@ -50,6 +51,8 @@ import org.apache.nifi.web.api.dto.ResourceDTO;
|
|||
import org.apache.nifi.web.api.dto.SnippetDTO;
|
||||
import org.apache.nifi.web.api.dto.SystemDiagnosticsDTO;
|
||||
import org.apache.nifi.web.api.dto.TemplateDTO;
|
||||
import org.apache.nifi.web.api.dto.UserDTO;
|
||||
import org.apache.nifi.web.api.dto.UserGroupDTO;
|
||||
import org.apache.nifi.web.api.dto.action.ActionDTO;
|
||||
import org.apache.nifi.web.api.dto.action.HistoryDTO;
|
||||
import org.apache.nifi.web.api.dto.action.HistoryQueryDTO;
|
||||
|
@ -65,6 +68,7 @@ import org.apache.nifi.web.api.dto.status.ProcessGroupStatusDTO;
|
|||
import org.apache.nifi.web.api.dto.status.ProcessorStatusDTO;
|
||||
import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO;
|
||||
import org.apache.nifi.web.api.dto.status.StatusHistoryDTO;
|
||||
import org.apache.nifi.web.api.entity.AccessPolicyEntity;
|
||||
import org.apache.nifi.web.api.entity.ConnectionEntity;
|
||||
import org.apache.nifi.web.api.entity.ControllerConfigurationEntity;
|
||||
import org.apache.nifi.web.api.entity.ControllerServiceEntity;
|
||||
|
@ -81,6 +85,8 @@ import org.apache.nifi.web.api.entity.RemoteProcessGroupPortEntity;
|
|||
import org.apache.nifi.web.api.entity.ReportingTaskEntity;
|
||||
import org.apache.nifi.web.api.entity.ScheduleComponentsEntity;
|
||||
import org.apache.nifi.web.api.entity.SnippetEntity;
|
||||
import org.apache.nifi.web.api.entity.UserEntity;
|
||||
import org.apache.nifi.web.api.entity.UserGroupEntity;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
@ -1179,6 +1185,110 @@ public interface NiFiServiceFacade {
|
|||
*/
|
||||
LabelEntity deleteLabel(Revision revision, String labelId);
|
||||
|
||||
// ----------------------------------------
|
||||
// User methods
|
||||
// ----------------------------------------
|
||||
/**
|
||||
* Creates a user.
|
||||
* @param revision The starting revision
|
||||
* @param userDTO The user DTO
|
||||
* @return The user transfer object
|
||||
*/
|
||||
UserEntity createUser(Revision revision, UserDTO userDTO);
|
||||
|
||||
/**
|
||||
* Gets the user with the specified ID.
|
||||
* @param userId The user ID
|
||||
* @param prune If true, the users in the groups to which this user belongs will not be returned
|
||||
* @return The user transfer object
|
||||
*/
|
||||
UserEntity getUser(String userId, boolean prune);
|
||||
|
||||
/**
|
||||
* Updates the specified user.
|
||||
* @param revision Revision to compare with current base revision
|
||||
* @param userDTO The user DTO
|
||||
* @return The user transfer object
|
||||
*/
|
||||
UpdateResult<UserEntity> updateUser(Revision revision, UserDTO userDTO);
|
||||
|
||||
/**
|
||||
* Deletes the specified user.
|
||||
* @param revision Revision to compare with current base revision
|
||||
* @param userId The user ID
|
||||
* @return The user transfer object of the deleted user
|
||||
*/
|
||||
UserEntity deleteUser(Revision revision, String userId);
|
||||
|
||||
// ----------------------------------------
|
||||
// Group methods
|
||||
// ----------------------------------------
|
||||
/**
|
||||
* Creates a user group.
|
||||
* @param revision The starting revision
|
||||
* @param userGroupDTO The user group DTO
|
||||
* @return The user group transfer object
|
||||
*/
|
||||
UserGroupEntity createUserGroup(Revision revision, UserGroupDTO userGroupDTO);
|
||||
|
||||
/**
|
||||
* Gets the user group with the specified ID.
|
||||
* @param userGroupId The user group ID
|
||||
* @param prune If true, the user groups of the users in this user group will not be returned
|
||||
* @return The user group transfer object
|
||||
*/
|
||||
UserGroupEntity getUserGroup(String userGroupId, boolean prune);
|
||||
|
||||
/**
|
||||
* Updates the specified user group.
|
||||
* @param revision Revision to compare with current base revision
|
||||
* @param userGroupDTO The user group DTO
|
||||
* @return The user group transfer object
|
||||
*/
|
||||
UpdateResult<UserGroupEntity> updateUserGroup(Revision revision, UserGroupDTO userGroupDTO);
|
||||
|
||||
/**
|
||||
* Deletes the specified user group.
|
||||
* @param revision Revision to compare with current base revision
|
||||
* @param userGroupId The user group ID
|
||||
* @return The user group transfer object of the deleted user group
|
||||
*/
|
||||
UserGroupEntity deleteUserGroup(Revision revision, String userGroupId);
|
||||
|
||||
// ----------------------------------------
|
||||
// AccessPolicy methods
|
||||
// ----------------------------------------
|
||||
/**
|
||||
* Creates an access policy.
|
||||
* @param revision The starting revision
|
||||
* @param accessPolicyDTO The access policy DTO
|
||||
* @return The access policy transfer object
|
||||
*/
|
||||
AccessPolicyEntity createAccessPolicy(Revision revision, AccessPolicyDTO accessPolicyDTO);
|
||||
|
||||
/**
|
||||
* Gets the access policy with the specified ID.
|
||||
* @param accessPolicyId access policy ID
|
||||
* @return The access policy transfer object
|
||||
*/
|
||||
AccessPolicyEntity getAccessPolicy(String accessPolicyId);
|
||||
|
||||
/**
|
||||
* Updates the specified access policy.
|
||||
* @param revision Revision to compare with current base revision
|
||||
* @param accessPolicyDTO The access policy DTO
|
||||
* @return The access policy transfer object
|
||||
*/
|
||||
UpdateResult<AccessPolicyEntity> updateAccessPolicy(Revision revision, AccessPolicyDTO accessPolicyDTO);
|
||||
|
||||
/**
|
||||
* Deletes the specified access policy.
|
||||
* @param revision Revision to compare with current base revision
|
||||
* @param accessPolicyId The access policy ID
|
||||
* @return The access policy transfer object of the deleted access policy
|
||||
*/
|
||||
AccessPolicyEntity deleteAccessPolicy(Revision revision, String accessPolicyId);
|
||||
|
||||
// ----------------------------------------
|
||||
// Controller Services methods
|
||||
// ----------------------------------------
|
||||
|
|
|
@ -0,0 +1,242 @@
|
|||
/*
|
||||
* 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.web;
|
||||
|
||||
import org.apache.nifi.authorization.resource.AccessPoliciesAuthorizable;
|
||||
import org.apache.nifi.authorization.resource.AccessPolicyAuthorizable;
|
||||
import org.apache.nifi.authorization.resource.Authorizable;
|
||||
import org.apache.nifi.authorization.resource.UserGroupsAuthorizable;
|
||||
import org.apache.nifi.authorization.resource.UsersAuthorizable;
|
||||
import org.apache.nifi.controller.ConfiguredComponent;
|
||||
import org.apache.nifi.controller.Snippet;
|
||||
import org.apache.nifi.controller.service.ControllerServiceNode;
|
||||
import org.apache.nifi.controller.service.ControllerServiceReference;
|
||||
import org.apache.nifi.groups.ProcessGroup;
|
||||
import org.apache.nifi.groups.RemoteProcessGroup;
|
||||
import org.apache.nifi.web.controller.ControllerFacade;
|
||||
import org.apache.nifi.web.dao.AccessPolicyDAO;
|
||||
import org.apache.nifi.web.dao.ConnectionDAO;
|
||||
import org.apache.nifi.web.dao.ControllerServiceDAO;
|
||||
import org.apache.nifi.web.dao.FunnelDAO;
|
||||
import org.apache.nifi.web.dao.LabelDAO;
|
||||
import org.apache.nifi.web.dao.PortDAO;
|
||||
import org.apache.nifi.web.dao.ProcessGroupDAO;
|
||||
import org.apache.nifi.web.dao.ProcessorDAO;
|
||||
import org.apache.nifi.web.dao.RemoteProcessGroupDAO;
|
||||
import org.apache.nifi.web.dao.ReportingTaskDAO;
|
||||
import org.apache.nifi.web.dao.SnippetDAO;
|
||||
import org.apache.nifi.web.dao.TemplateDAO;
|
||||
|
||||
|
||||
class StandardAuthorizableLookup implements AuthorizableLookup {
|
||||
|
||||
private static final UsersAuthorizable USERS_AUTHORIZABLE = new UsersAuthorizable();
|
||||
private static final UserGroupsAuthorizable USER_GROUPS_AUTHORIZABLE = new UserGroupsAuthorizable();
|
||||
private static final Authorizable ACCESS_POLICIES_AUTHORIZABLE = new AccessPoliciesAuthorizable();
|
||||
|
||||
// nifi core components
|
||||
private ControllerFacade controllerFacade;
|
||||
|
||||
// data access objects
|
||||
private ProcessorDAO processorDAO;
|
||||
private ProcessGroupDAO processGroupDAO;
|
||||
private RemoteProcessGroupDAO remoteProcessGroupDAO;
|
||||
private LabelDAO labelDAO;
|
||||
private FunnelDAO funnelDAO;
|
||||
private SnippetDAO snippetDAO;
|
||||
private PortDAO inputPortDAO;
|
||||
private PortDAO outputPortDAO;
|
||||
private ConnectionDAO connectionDAO;
|
||||
private ControllerServiceDAO controllerServiceDAO;
|
||||
private ReportingTaskDAO reportingTaskDAO;
|
||||
private TemplateDAO templateDAO;
|
||||
private AccessPolicyDAO accessPolicyDAO;
|
||||
|
||||
@Override
|
||||
public Authorizable getProcessor(final String id) {
|
||||
return processorDAO.getProcessor(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authorizable getInputPort(final String id) {
|
||||
return inputPortDAO.getPort(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authorizable getOutputPort(final String id) {
|
||||
return outputPortDAO.getPort(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authorizable getConnection(final String id) {
|
||||
return connectionDAO.getConnection(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authorizable getProcessGroup(final String id) {
|
||||
return processGroupDAO.getProcessGroup(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authorizable getRemoteProcessGroup(final String id) {
|
||||
return remoteProcessGroupDAO.getRemoteProcessGroup(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authorizable getRemoteProcessGroupInputPort(final String remoteProcessGroupId, final String id) {
|
||||
final RemoteProcessGroup remoteProcessGroup = remoteProcessGroupDAO.getRemoteProcessGroup(remoteProcessGroupId);
|
||||
return remoteProcessGroup.getInputPort(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authorizable getRemoteProcessGroupOutputPort(final String remoteProcessGroupId, final String id) {
|
||||
final RemoteProcessGroup remoteProcessGroup = remoteProcessGroupDAO.getRemoteProcessGroup(remoteProcessGroupId);
|
||||
return remoteProcessGroup.getOutputPort(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authorizable getLabel(final String id) {
|
||||
return labelDAO.getLabel(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authorizable getFunnel(final String id) {
|
||||
return funnelDAO.getFunnel(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authorizable getControllerService(final String id) {
|
||||
return controllerServiceDAO.getControllerService(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authorizable getControllerServiceReferencingComponent(String controllerSeriveId, String id) {
|
||||
final ControllerServiceNode controllerService = controllerServiceDAO.getControllerService(controllerSeriveId);
|
||||
final ControllerServiceReference referencingComponents = controllerService.getReferences();
|
||||
|
||||
ConfiguredComponent reference = null;
|
||||
for (final ConfiguredComponent component : referencingComponents.getReferencingComponents()) {
|
||||
if (component.getIdentifier().equals(id)) {
|
||||
reference = component;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (reference == null) {
|
||||
throw new ResourceNotFoundException("Unable to find referencing component with id " + id);
|
||||
}
|
||||
|
||||
return reference;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authorizable getReportingTask(final String id) {
|
||||
return reportingTaskDAO.getReportingTask(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Snippet getSnippet(final String id) {
|
||||
return snippetDAO.getSnippet(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authorizable getUsersAuthorizable() {
|
||||
return USERS_AUTHORIZABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authorizable getUserGroupsAuthorizable() {
|
||||
return USER_GROUPS_AUTHORIZABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authorizable getAccessPoliciesAuthorizable() {
|
||||
return ACCESS_POLICIES_AUTHORIZABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authorizable getAccessPolicyAuthorizable(String id) {
|
||||
return new AccessPolicyAuthorizable(accessPolicyDAO.getAccessPolicy(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authorizable getTemplate(final String id) {
|
||||
return templateDAO.getTemplate(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authorizable getConnectable(String id) {
|
||||
final ProcessGroup group = processGroupDAO.getProcessGroup(controllerFacade.getRootGroupId());
|
||||
return group.findConnectable(id);
|
||||
}
|
||||
|
||||
public void setProcessorDAO(ProcessorDAO processorDAO) {
|
||||
this.processorDAO = processorDAO;
|
||||
}
|
||||
|
||||
public void setProcessGroupDAO(ProcessGroupDAO processGroupDAO) {
|
||||
this.processGroupDAO = processGroupDAO;
|
||||
}
|
||||
|
||||
public void setRemoteProcessGroupDAO(RemoteProcessGroupDAO remoteProcessGroupDAO) {
|
||||
this.remoteProcessGroupDAO = remoteProcessGroupDAO;
|
||||
}
|
||||
|
||||
public void setLabelDAO(LabelDAO labelDAO) {
|
||||
this.labelDAO = labelDAO;
|
||||
}
|
||||
|
||||
public void setFunnelDAO(FunnelDAO funnelDAO) {
|
||||
this.funnelDAO = funnelDAO;
|
||||
}
|
||||
|
||||
public void setSnippetDAO(SnippetDAO snippetDAO) {
|
||||
this.snippetDAO = snippetDAO;
|
||||
}
|
||||
|
||||
public void setInputPortDAO(PortDAO inputPortDAO) {
|
||||
this.inputPortDAO = inputPortDAO;
|
||||
}
|
||||
|
||||
public void setOutputPortDAO(PortDAO outputPortDAO) {
|
||||
this.outputPortDAO = outputPortDAO;
|
||||
}
|
||||
|
||||
public void setConnectionDAO(ConnectionDAO connectionDAO) {
|
||||
this.connectionDAO = connectionDAO;
|
||||
}
|
||||
|
||||
public void setControllerServiceDAO(ControllerServiceDAO controllerServiceDAO) {
|
||||
this.controllerServiceDAO = controllerServiceDAO;
|
||||
}
|
||||
|
||||
public void setReportingTaskDAO(ReportingTaskDAO reportingTaskDAO) {
|
||||
this.reportingTaskDAO = reportingTaskDAO;
|
||||
}
|
||||
|
||||
public void setTemplateDAO(TemplateDAO templateDAO) {
|
||||
this.templateDAO = templateDAO;
|
||||
}
|
||||
|
||||
public void setAccessPolicyDAO(AccessPolicyDAO accessPolicyDAO) {
|
||||
this.accessPolicyDAO = accessPolicyDAO;
|
||||
}
|
||||
|
||||
public void setControllerFacade(ControllerFacade controllerFacade) {
|
||||
this.controllerFacade = controllerFacade;
|
||||
}
|
||||
}
|
|
@ -25,9 +25,12 @@ import org.apache.nifi.action.Operation;
|
|||
import org.apache.nifi.action.details.FlowChangePurgeDetails;
|
||||
import org.apache.nifi.admin.service.AuditService;
|
||||
import org.apache.nifi.admin.service.KeyService;
|
||||
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.Resource;
|
||||
import org.apache.nifi.authorization.User;
|
||||
import org.apache.nifi.authorization.resource.Authorizable;
|
||||
import org.apache.nifi.authorization.user.NiFiUser;
|
||||
import org.apache.nifi.authorization.user.NiFiUserUtils;
|
||||
|
@ -114,6 +117,8 @@ import org.apache.nifi.web.api.dto.RevisionDTO;
|
|||
import org.apache.nifi.web.api.dto.SnippetDTO;
|
||||
import org.apache.nifi.web.api.dto.SystemDiagnosticsDTO;
|
||||
import org.apache.nifi.web.api.dto.TemplateDTO;
|
||||
import org.apache.nifi.web.api.dto.UserDTO;
|
||||
import org.apache.nifi.web.api.dto.UserGroupDTO;
|
||||
import org.apache.nifi.web.api.dto.action.ActionDTO;
|
||||
import org.apache.nifi.web.api.dto.action.HistoryDTO;
|
||||
import org.apache.nifi.web.api.dto.action.HistoryQueryDTO;
|
||||
|
@ -130,6 +135,7 @@ import org.apache.nifi.web.api.dto.status.ProcessGroupStatusDTO;
|
|||
import org.apache.nifi.web.api.dto.status.ProcessorStatusDTO;
|
||||
import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO;
|
||||
import org.apache.nifi.web.api.dto.status.StatusHistoryDTO;
|
||||
import org.apache.nifi.web.api.entity.AccessPolicyEntity;
|
||||
import org.apache.nifi.web.api.entity.ConnectionEntity;
|
||||
import org.apache.nifi.web.api.entity.ControllerConfigurationEntity;
|
||||
import org.apache.nifi.web.api.entity.ControllerServiceEntity;
|
||||
|
@ -147,7 +153,10 @@ import org.apache.nifi.web.api.entity.RemoteProcessGroupPortEntity;
|
|||
import org.apache.nifi.web.api.entity.ReportingTaskEntity;
|
||||
import org.apache.nifi.web.api.entity.ScheduleComponentsEntity;
|
||||
import org.apache.nifi.web.api.entity.SnippetEntity;
|
||||
import org.apache.nifi.web.api.entity.UserEntity;
|
||||
import org.apache.nifi.web.api.entity.UserGroupEntity;
|
||||
import org.apache.nifi.web.controller.ControllerFacade;
|
||||
import org.apache.nifi.web.dao.AccessPolicyDAO;
|
||||
import org.apache.nifi.web.dao.ConnectionDAO;
|
||||
import org.apache.nifi.web.dao.ControllerServiceDAO;
|
||||
import org.apache.nifi.web.dao.FunnelDAO;
|
||||
|
@ -159,6 +168,8 @@ import org.apache.nifi.web.dao.RemoteProcessGroupDAO;
|
|||
import org.apache.nifi.web.dao.ReportingTaskDAO;
|
||||
import org.apache.nifi.web.dao.SnippetDAO;
|
||||
import org.apache.nifi.web.dao.TemplateDAO;
|
||||
import org.apache.nifi.web.dao.UserDAO;
|
||||
import org.apache.nifi.web.dao.UserGroupDAO;
|
||||
import org.apache.nifi.web.revision.DeleteRevisionTask;
|
||||
import org.apache.nifi.web.revision.ExpiredRevisionClaimException;
|
||||
import org.apache.nifi.web.revision.ReadOnlyRevisionCallback;
|
||||
|
@ -178,6 +189,7 @@ import java.nio.charset.StandardCharsets;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
@ -220,6 +232,9 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
|||
private ControllerServiceDAO controllerServiceDAO;
|
||||
private ReportingTaskDAO reportingTaskDAO;
|
||||
private TemplateDAO templateDAO;
|
||||
private UserDAO userDAO;
|
||||
private UserGroupDAO userGroupDAO;
|
||||
private AccessPolicyDAO accessPolicyDAO;
|
||||
private ClusterCoordinator clusterCoordinator;
|
||||
private HeartbeatMonitor heartbeatMonitor;
|
||||
|
||||
|
@ -234,105 +249,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
|||
|
||||
private Authorizer authorizer;
|
||||
|
||||
private final AuthorizableLookup authorizableLookup = new AuthorizableLookup() {
|
||||
@Override
|
||||
public Authorizable getProcessor(final String id) {
|
||||
return processorDAO.getProcessor(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authorizable getInputPort(final String id) {
|
||||
return inputPortDAO.getPort(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authorizable getOutputPort(final String id) {
|
||||
return outputPortDAO.getPort(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authorizable getConnection(final String id) {
|
||||
return connectionDAO.getConnection(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authorizable getProcessGroup(final String id) {
|
||||
return processGroupDAO.getProcessGroup(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authorizable getRemoteProcessGroup(final String id) {
|
||||
return remoteProcessGroupDAO.getRemoteProcessGroup(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authorizable getRemoteProcessGroupInputPort(final String remoteProcessGroupId, final String id) {
|
||||
final RemoteProcessGroup remoteProcessGroup = remoteProcessGroupDAO.getRemoteProcessGroup(remoteProcessGroupId);
|
||||
return remoteProcessGroup.getInputPort(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authorizable getRemoteProcessGroupOutputPort(final String remoteProcessGroupId, final String id) {
|
||||
final RemoteProcessGroup remoteProcessGroup = remoteProcessGroupDAO.getRemoteProcessGroup(remoteProcessGroupId);
|
||||
return remoteProcessGroup.getOutputPort(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authorizable getLabel(final String id) {
|
||||
return labelDAO.getLabel(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authorizable getFunnel(final String id) {
|
||||
return funnelDAO.getFunnel(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authorizable getControllerService(final String id) {
|
||||
return controllerServiceDAO.getControllerService(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authorizable getControllerServiceReferencingComponent(final String controllerSeriveId, final String id) {
|
||||
final ControllerServiceNode controllerService = controllerServiceDAO.getControllerService(controllerSeriveId);
|
||||
final ControllerServiceReference referencingComponents = controllerService.getReferences();
|
||||
|
||||
ConfiguredComponent reference = null;
|
||||
for (final ConfiguredComponent component : referencingComponents.getReferencingComponents()) {
|
||||
if (component.getIdentifier().equals(id)) {
|
||||
reference = component;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (reference == null) {
|
||||
throw new ResourceNotFoundException("Unable to find referencing component with id " + id);
|
||||
}
|
||||
|
||||
return reference;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authorizable getReportingTask(final String id) {
|
||||
return reportingTaskDAO.getReportingTask(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Snippet getSnippet(final String id) {
|
||||
return snippetDAO.getSnippet(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authorizable getTemplate(final String id) {
|
||||
return templateDAO.getTemplate(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authorizable getConnectable(final String id) {
|
||||
final ProcessGroup group = processGroupDAO.getProcessGroup(controllerFacade.getRootGroupId());
|
||||
return group.findConnectable(id);
|
||||
}
|
||||
};
|
||||
private AuthorizableLookup authorizableLookup;
|
||||
|
||||
// -----------------------------------------
|
||||
// Synchronization methods
|
||||
|
@ -597,6 +514,61 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
|||
// -----------------------------------------
|
||||
// Write Operations
|
||||
// -----------------------------------------
|
||||
@Override
|
||||
public UpdateResult<AccessPolicyEntity> updateAccessPolicy(final Revision revision, final AccessPolicyDTO accessPolicyDTO) {
|
||||
// if access policy does not exist, then create new access policy
|
||||
if (!accessPolicyDAO.hasAccessPolicy(accessPolicyDTO.getId())) {
|
||||
return new UpdateResult<>(createAccessPolicy(revision, accessPolicyDTO), false);
|
||||
}
|
||||
|
||||
final Authorizable accessPolicyAuthorizable = authorizableLookup.getAccessPolicyAuthorizable(accessPolicyDTO.getId());
|
||||
final RevisionUpdate<AccessPolicyDTO> snapshot = updateComponent(revision,
|
||||
accessPolicyAuthorizable,
|
||||
() -> accessPolicyDAO.updateAccessPolicy(accessPolicyDTO),
|
||||
accessPolicy -> {
|
||||
final Set<UserEntity> users = accessPolicy.getUsers().stream().map(userId -> getUser(userId, true) ).collect(Collectors.toSet());
|
||||
final Set<UserGroupEntity> userGroups = accessPolicy.getGroups().stream().map(userGroupId -> getUserGroup(userGroupId, true) ).collect(Collectors.toSet());
|
||||
return dtoFactory.createAccessPolicyDto(accessPolicy, userGroups, users);
|
||||
});
|
||||
|
||||
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(accessPolicyAuthorizable);
|
||||
return new UpdateResult<>(entityFactory.createAccessPolicyEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UpdateResult<UserEntity> updateUser(final Revision revision, final UserDTO userDTO) {
|
||||
// if user does not exist, then create new user
|
||||
if (!userDAO.hasUser(userDTO.getId())) {
|
||||
return new UpdateResult<>(createUser(revision, userDTO), false);
|
||||
}
|
||||
|
||||
final Authorizable usersAuthorizable = authorizableLookup.getUsersAuthorizable();
|
||||
final RevisionUpdate<UserDTO> snapshot = updateComponent(revision,
|
||||
usersAuthorizable,
|
||||
() -> userDAO.updateUser(userDTO),
|
||||
user -> dtoFactory.createUserDto(user, user.getGroups().stream().map(userGroupId -> getUserGroup(userGroupId, true)).collect(Collectors.toSet())));
|
||||
|
||||
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(usersAuthorizable);
|
||||
return new UpdateResult<>(entityFactory.createUserEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UpdateResult<UserGroupEntity> updateUserGroup(final Revision revision, final UserGroupDTO userGroupDTO) {
|
||||
// if user group does not exist, then create new user group
|
||||
if (!userGroupDAO.hasUserGroup(userGroupDTO.getId())) {
|
||||
return new UpdateResult<>(createUserGroup(revision, userGroupDTO), false);
|
||||
}
|
||||
|
||||
final Authorizable userGroupsAuthorizable = authorizableLookup.getUserGroupsAuthorizable();
|
||||
final RevisionUpdate<UserGroupDTO> snapshot = updateComponent(revision,
|
||||
userGroupsAuthorizable,
|
||||
() -> userGroupDAO.updateUserGroup(userGroupDTO),
|
||||
userGroup -> dtoFactory.createUserGroupDto(userGroup, userGroup.getUsers().stream().map(userId -> getUser(userId, true)).collect(Collectors.toSet())));
|
||||
|
||||
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(userGroupsAuthorizable);
|
||||
return new UpdateResult<>(entityFactory.createUserGroupEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UpdateResult<ConnectionEntity> updateConnection(final Revision revision, final ConnectionDTO connectionDTO) {
|
||||
// if connection does not exist, then create new connection
|
||||
|
@ -685,7 +657,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
|||
*/
|
||||
private <D, C> RevisionUpdate<D> updateComponent(final Revision revision, final Authorizable authorizable, final Supplier<C> daoUpdate, final Function<C, D> dtoCreation) {
|
||||
final NiFiUser user = NiFiUserUtils.getNiFiUser();
|
||||
final String modifier = user.getUserName();
|
||||
final String userName = NiFiUserUtils.getNiFiUserName();
|
||||
try {
|
||||
final RevisionUpdate<D> updatedComponent = revisionManager.updateRevision(new StandardRevisionClaim(revision), user, new UpdateRevisionTask<D>() {
|
||||
@Override
|
||||
|
@ -699,7 +671,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
|||
final Revision updatedRevision = incrementRevision(revision);
|
||||
final D dto = dtoCreation.apply(component);
|
||||
|
||||
final FlowModification lastModification = new FlowModification(updatedRevision, modifier);
|
||||
final FlowModification lastModification = new FlowModification(updatedRevision, userName);
|
||||
return new StandardRevisionUpdate<>(dto, lastModification);
|
||||
}
|
||||
});
|
||||
|
@ -730,7 +702,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
|||
final NiFiUser user = NiFiUserUtils.getNiFiUser();
|
||||
final RevisionClaim revisionClaim = new StandardRevisionClaim(revisions);
|
||||
|
||||
RevisionUpdate<SnippetDTO> snapshot;
|
||||
final RevisionUpdate<SnippetDTO> snapshot;
|
||||
try {
|
||||
snapshot = revisionManager.updateRevision(revisionClaim, user, new UpdateRevisionTask<SnippetDTO>() {
|
||||
@Override
|
||||
|
@ -905,19 +877,19 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
|||
@Override
|
||||
public ControllerConfigurationEntity updateControllerConfiguration(final Revision revision, final ControllerConfigurationDTO controllerConfigurationDTO) {
|
||||
final RevisionUpdate<ControllerConfigurationDTO> updatedComponent = updateComponent(
|
||||
revision,
|
||||
controllerFacade,
|
||||
() -> {
|
||||
if (controllerConfigurationDTO.getMaxTimerDrivenThreadCount() != null) {
|
||||
controllerFacade.setMaxTimerDrivenThreadCount(controllerConfigurationDTO.getMaxTimerDrivenThreadCount());
|
||||
}
|
||||
if (controllerConfigurationDTO.getMaxEventDrivenThreadCount() != null) {
|
||||
controllerFacade.setMaxEventDrivenThreadCount(controllerConfigurationDTO.getMaxEventDrivenThreadCount());
|
||||
}
|
||||
revision,
|
||||
controllerFacade,
|
||||
() -> {
|
||||
if (controllerConfigurationDTO.getMaxTimerDrivenThreadCount() != null) {
|
||||
controllerFacade.setMaxTimerDrivenThreadCount(controllerConfigurationDTO.getMaxTimerDrivenThreadCount());
|
||||
}
|
||||
if (controllerConfigurationDTO.getMaxEventDrivenThreadCount() != null) {
|
||||
controllerFacade.setMaxEventDrivenThreadCount(controllerConfigurationDTO.getMaxEventDrivenThreadCount());
|
||||
}
|
||||
|
||||
return controllerConfigurationDTO;
|
||||
},
|
||||
controller -> dtoFactory.createControllerConfigurationDto(controllerFacade, properties.getAutoRefreshInterval()));
|
||||
return controllerConfigurationDTO;
|
||||
},
|
||||
controller -> dtoFactory.createControllerConfigurationDto(controllerFacade, properties.getAutoRefreshInterval()));
|
||||
|
||||
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(controllerFacade);
|
||||
final RevisionDTO updateRevision = dtoFactory.createRevisionDTO(updatedComponent.getLastModification());
|
||||
|
@ -1067,6 +1039,48 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
|||
return entityFactory.createLabelEntity(snapshot, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserEntity deleteUser(final Revision revision, final String userId) {
|
||||
final User user = userDAO.getUser(userId);
|
||||
final Set<UserGroupEntity> userGroups = user != null ? user.getGroups().stream().map(userGroupId -> getUserGroup(userGroupId, true)).collect(Collectors.toSet()) : null;
|
||||
final UserDTO snapshot = deleteComponent(
|
||||
revision,
|
||||
authorizableLookup.getUsersAuthorizable(),
|
||||
() -> userDAO.deleteUser(userId),
|
||||
dtoFactory.createUserDto(user, userGroups));
|
||||
|
||||
return entityFactory.createUserEntity(snapshot, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserGroupEntity deleteUserGroup(final Revision revision, final String userGroupId) {
|
||||
final Group userGroup = userGroupDAO.getUserGroup(userGroupId);
|
||||
final Set<UserEntity> users = userGroup != null ? userGroup.getUsers().stream().map(userId -> getUser(userId, true)).collect(Collectors.toSet()) :
|
||||
null;
|
||||
final UserGroupDTO snapshot = deleteComponent(
|
||||
revision,
|
||||
authorizableLookup.getUserGroupsAuthorizable(),
|
||||
() -> userGroupDAO.deleteUserGroup(userGroupId),
|
||||
dtoFactory.createUserGroupDto(userGroup, users));
|
||||
|
||||
return entityFactory.createUserGroupEntity(snapshot, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccessPolicyEntity deleteAccessPolicy(final Revision revision, final String accessPolicyId) {
|
||||
final AccessPolicy accessPolicy = accessPolicyDAO.getAccessPolicy(accessPolicyId);
|
||||
final Set<UserGroupEntity> userGroups = accessPolicy != null ? accessPolicy.getGroups().stream().map(userGroupId -> getUserGroup(userGroupId, true)).collect(Collectors.toSet()) : null;
|
||||
final Set<UserEntity> users = accessPolicy != null ? accessPolicy.getUsers().stream().map(userId -> getUser(userId, true)).collect(Collectors.toSet()) : null;
|
||||
final AccessPolicyDTO snapshot = deleteComponent(
|
||||
revision,
|
||||
authorizableLookup.getAccessPolicyAuthorizable(accessPolicyId),
|
||||
() -> accessPolicyDAO.deleteAccessPolicy(accessPolicyId),
|
||||
dtoFactory.createAccessPolicyDto(accessPolicy, userGroups,
|
||||
users));
|
||||
|
||||
return entityFactory.createAccessPolicyEntity(snapshot, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FunnelEntity deleteFunnel(final Revision revision, final String funnelId) {
|
||||
final Funnel funnel = funnelDAO.getFunnel(funnelId);
|
||||
|
@ -1306,6 +1320,47 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
|||
return entityFactory.createFunnelEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccessPolicyEntity createAccessPolicy(final Revision revision, final AccessPolicyDTO accessPolicyDTO) {
|
||||
final String creator = NiFiUserUtils.getNiFiUserName();
|
||||
if (revision.getVersion() != 0) {
|
||||
throw new IllegalArgumentException("The revision must start at 0.");
|
||||
}
|
||||
final AccessPolicy newAccessPolicy = accessPolicyDAO.createAccessPolicy(accessPolicyDTO);
|
||||
final AccessPolicyDTO newAccessPolicyDto = dtoFactory.createAccessPolicyDto(newAccessPolicy,
|
||||
newAccessPolicy.getGroups().stream().map(userGroupId -> getUserGroup(userGroupId, true)).collect(Collectors.toSet()),
|
||||
newAccessPolicy.getUsers().stream().map(userId -> getUser(userId, true)).collect(Collectors.toSet()));
|
||||
|
||||
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(authorizableLookup.getAccessPolicyAuthorizable(newAccessPolicy.getIdentifier()));
|
||||
return entityFactory.createAccessPolicyEntity(newAccessPolicyDto, dtoFactory.createRevisionDTO(new FlowModification(revision, creator)), accessPolicy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserEntity createUser(final Revision revision, final UserDTO userDTO) {
|
||||
final String creator = NiFiUserUtils.getNiFiUserName();
|
||||
if (revision.getVersion() != 0) {
|
||||
throw new IllegalArgumentException("The revision must start at 0.");
|
||||
}
|
||||
final User newUser = userDAO.createUser(userDTO);
|
||||
final UserDTO newUserDto = dtoFactory.createUserDto(newUser, newUser.getGroups().stream().map(userGroupId -> getUserGroup(userGroupId, true)).collect(Collectors.toSet()));
|
||||
|
||||
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(authorizableLookup.getUsersAuthorizable());
|
||||
return entityFactory.createUserEntity(newUserDto, dtoFactory.createRevisionDTO(new FlowModification(revision, creator)), accessPolicy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserGroupEntity createUserGroup(final Revision revision, final UserGroupDTO userGroupDTO) {
|
||||
final String creator = NiFiUserUtils.getNiFiUserName();
|
||||
if (revision.getVersion() != 0) {
|
||||
throw new IllegalArgumentException("The revision must start at 0.");
|
||||
}
|
||||
final Group newUserGroup = userGroupDAO.createUserGroup(userGroupDTO);
|
||||
final UserGroupDTO newUserGroupDto = dtoFactory.createUserGroupDto(newUserGroup, newUserGroup.getUsers().stream().map(userId -> getUser(userId, true)).collect(Collectors.toSet()));
|
||||
|
||||
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(authorizableLookup.getUserGroupsAuthorizable());
|
||||
return entityFactory.createUserGroupEntity(newUserGroupDto, dtoFactory.createRevisionDTO(new FlowModification(revision, creator)), accessPolicy);
|
||||
}
|
||||
|
||||
private void validateSnippetContents(final FlowSnippetDTO flow) {
|
||||
// validate any processors
|
||||
if (flow.getProcessors() != null) {
|
||||
|
@ -2348,6 +2403,78 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
|||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccessPolicyEntity getAccessPolicy(final String accessPolicyId) {
|
||||
return revisionManager.get(accessPolicyId, rev -> {
|
||||
final Authorizable accessPolicyAuthorizable = authorizableLookup.getAccessPolicyAuthorizable(accessPolicyId);
|
||||
accessPolicyAuthorizable.authorize(authorizer, RequestAction.READ);
|
||||
|
||||
final RevisionDTO revision = dtoFactory.createRevisionDTO(rev);
|
||||
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(accessPolicyAuthorizable);
|
||||
final AccessPolicy requestedAccessPolicy = accessPolicyDAO.getAccessPolicy(accessPolicyId);
|
||||
return entityFactory.createAccessPolicyEntity(
|
||||
dtoFactory.createAccessPolicyDto(requestedAccessPolicy,
|
||||
requestedAccessPolicy.getGroups().stream().map(userGroupId -> getUserGroup(userGroupId, true)).collect(Collectors.toSet()),
|
||||
requestedAccessPolicy.getUsers().stream().map(userId -> getUser(userId, true)).collect(Collectors.toSet())),
|
||||
revision, accessPolicy);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserEntity getUser(final String userId, final boolean prune) {
|
||||
return revisionManager.get(userId, rev -> {
|
||||
final Authorizable usersAuthorizable = authorizableLookup.getUsersAuthorizable();
|
||||
usersAuthorizable.authorize(authorizer, RequestAction.READ);
|
||||
|
||||
final RevisionDTO revision = dtoFactory.createRevisionDTO(rev);
|
||||
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(usersAuthorizable);
|
||||
final User user = userDAO.getUser(userId);
|
||||
final Set<UserGroupEntity> userGroups = user.getGroups().stream()
|
||||
.map(userGroupId -> prune ? getUserGroupPruned(userGroupId) : getUserGroup(userGroupId, false))
|
||||
.collect(Collectors.toSet());
|
||||
return entityFactory.createUserEntity(dtoFactory.createUserDto(user, userGroups), revision, accessPolicy);
|
||||
});
|
||||
}
|
||||
|
||||
private UserEntity getUserPruned(final String userId) {
|
||||
return revisionManager.get(userId, rev -> {
|
||||
final Authorizable usersAuthorizable = authorizableLookup.getUsersAuthorizable();
|
||||
usersAuthorizable.authorize(authorizer, RequestAction.READ);
|
||||
|
||||
final RevisionDTO revision = dtoFactory.createRevisionDTO(rev);
|
||||
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(usersAuthorizable);
|
||||
final User user = userDAO.getUser(userId);
|
||||
return entityFactory.createUserEntity(dtoFactory.createUserDto(user, Collections.emptySet()), revision, accessPolicy);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserGroupEntity getUserGroup(final String userGroupId, final boolean prune) {
|
||||
return revisionManager.get(userGroupId, rev -> {
|
||||
final Authorizable userGroupsAuthorizable = authorizableLookup.getUserGroupsAuthorizable();
|
||||
userGroupsAuthorizable.authorize(authorizer, RequestAction.READ);
|
||||
|
||||
final RevisionDTO revision = dtoFactory.createRevisionDTO(rev);
|
||||
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(userGroupsAuthorizable);
|
||||
final Group userGroup = userGroupDAO.getUserGroup(userGroupId);
|
||||
final Set<UserEntity> users = userGroup.getUsers().stream().map(userId -> prune ? getUserPruned(userId) : getUser(userId, false)).collect(Collectors.toSet());
|
||||
return entityFactory.createUserGroupEntity(dtoFactory.createUserGroupDto(userGroup, users),
|
||||
revision, accessPolicy);
|
||||
});
|
||||
}
|
||||
|
||||
private UserGroupEntity getUserGroupPruned(final String userGroupId) {
|
||||
return revisionManager.get(userGroupId, rev -> {
|
||||
final Authorizable userGroupsAuthorizable = authorizableLookup.getUserGroupsAuthorizable();
|
||||
userGroupsAuthorizable.authorize(authorizer, RequestAction.READ);
|
||||
|
||||
final RevisionDTO revision = dtoFactory.createRevisionDTO(rev);
|
||||
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(userGroupsAuthorizable);
|
||||
final Group userGroup = userGroupDAO.getUserGroup(userGroupId);
|
||||
return entityFactory.createUserGroupEntity(dtoFactory.createUserGroupDto(userGroup, Collections.emptySet()), revision, accessPolicy);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<LabelEntity> getLabels(final String groupId) {
|
||||
final ProcessGroup group = processGroupDAO.getProcessGroup(groupId);
|
||||
|
@ -2944,10 +3071,25 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
|||
this.snippetUtils = snippetUtils;
|
||||
}
|
||||
|
||||
public void setAuthorizableLookup(final AuthorizableLookup authorizableLookup) {
|
||||
this.authorizableLookup = authorizableLookup;
|
||||
}
|
||||
|
||||
public void setAuthorizer(final Authorizer authorizer) {
|
||||
this.authorizer = authorizer;
|
||||
}
|
||||
|
||||
public void setUserDAO(final UserDAO userDAO) {
|
||||
this.userDAO = userDAO;
|
||||
}
|
||||
|
||||
public void setUserGroupDAO(final UserGroupDAO userGroupDAO) {
|
||||
this.userGroupDAO = userGroupDAO;
|
||||
}
|
||||
|
||||
public void setAccessPolicyDAO(final AccessPolicyDAO accessPolicyDAO) {
|
||||
this.accessPolicyDAO = accessPolicyDAO;
|
||||
}
|
||||
public void setClusterCoordinator(final ClusterCoordinator coordinator) {
|
||||
this.clusterCoordinator = coordinator;
|
||||
}
|
||||
|
@ -2956,7 +3098,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
|||
this.heartbeatMonitor = heartbeatMonitor;
|
||||
}
|
||||
|
||||
public void setBulletinRepository(BulletinRepository bulletinRepository) {
|
||||
public void setBulletinRepository(final BulletinRepository bulletinRepository) {
|
||||
this.bulletinRepository = bulletinRepository;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,440 @@
|
|||
/*
|
||||
* 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.web.api;
|
||||
|
||||
import com.wordnik.swagger.annotations.Api;
|
||||
import com.wordnik.swagger.annotations.ApiOperation;
|
||||
import com.wordnik.swagger.annotations.ApiParam;
|
||||
import com.wordnik.swagger.annotations.ApiResponse;
|
||||
import com.wordnik.swagger.annotations.ApiResponses;
|
||||
import com.wordnik.swagger.annotations.Authorization;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.nifi.authorization.Authorizer;
|
||||
import org.apache.nifi.authorization.RequestAction;
|
||||
import org.apache.nifi.authorization.resource.Authorizable;
|
||||
import org.apache.nifi.cluster.coordination.ClusterCoordinator;
|
||||
import org.apache.nifi.cluster.coordination.http.replication.RequestReplicator;
|
||||
import org.apache.nifi.util.NiFiProperties;
|
||||
import org.apache.nifi.web.NiFiServiceFacade;
|
||||
import org.apache.nifi.web.Revision;
|
||||
import org.apache.nifi.web.UpdateResult;
|
||||
import org.apache.nifi.web.api.dto.AccessPolicyDTO;
|
||||
import org.apache.nifi.web.api.dto.RevisionDTO;
|
||||
import org.apache.nifi.web.api.entity.AccessPolicyEntity;
|
||||
import org.apache.nifi.web.api.request.ClientIdParameter;
|
||||
import org.apache.nifi.web.api.request.LongParameter;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.DefaultValue;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.HttpMethod;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* RESTful endpoint for managing access policies.
|
||||
*/
|
||||
@Path("/policies")
|
||||
@Api(
|
||||
value = "/policies",
|
||||
description = "Endpoint for managing access policies."
|
||||
)
|
||||
public class AccessPolicyResource extends ApplicationResource {
|
||||
|
||||
private final NiFiServiceFacade serviceFacade;
|
||||
private final Authorizer authorizer;
|
||||
|
||||
public AccessPolicyResource(NiFiServiceFacade serviceFacade, Authorizer authorizer, NiFiProperties properties, RequestReplicator requestReplicator, ClusterCoordinator clusterCoordinator) {
|
||||
this.serviceFacade = serviceFacade;
|
||||
this.authorizer = authorizer;
|
||||
setProperties(properties);
|
||||
setRequestReplicator(requestReplicator);
|
||||
setClusterCoordinator(clusterCoordinator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the uri for the specified access policy.
|
||||
*
|
||||
* @param accessPolicyEntity accessPolicyEntity
|
||||
* @return accessPolicyEntity
|
||||
*/
|
||||
public AccessPolicyEntity populateRemainingAccessPolicyEntityContent(AccessPolicyEntity accessPolicyEntity) {
|
||||
if (accessPolicyEntity.getComponent() != null) {
|
||||
populateRemainingAccessPolicyContent(accessPolicyEntity.getComponent());
|
||||
}
|
||||
return accessPolicyEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the uri for the specified accessPolicy.
|
||||
*/
|
||||
public AccessPolicyDTO populateRemainingAccessPolicyContent(AccessPolicyDTO accessPolicy) {
|
||||
// populate the access policy href
|
||||
accessPolicy.setUri(generateResourceUri("policies", accessPolicy.getId()));
|
||||
return accessPolicy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new access policy.
|
||||
*
|
||||
* @param httpServletRequest request
|
||||
* @param accessPolicyEntity An accessPolicyEntity.
|
||||
* @return An accessPolicyEntity.
|
||||
*/
|
||||
@POST
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
// TODO - @PreAuthorize("hasRole('ROLE_DFM')")
|
||||
@ApiOperation(
|
||||
value = "Creates an access policy",
|
||||
notes = " Available resources:\n" +
|
||||
" /flow - READ - allows user/entity to load the UI and see the flow structure\n" +
|
||||
" - WRITE - NA\n" +
|
||||
" /resource - READ - allows user/entity to retrieve the available resources\n" +
|
||||
" - WRITE - NA\n" +
|
||||
" /system - READ - allows user/entity to retrieve system level diagnostics (CPU load, disk utilization, etc)\n" +
|
||||
" - WRITE - NA\n" +
|
||||
" /controller - READ - allows user/entity to retrieve configuration details for the controller (controller bulletins, thread pool, reporting tasks, etc)\n" +
|
||||
" - WRITE - allows user/entity to modify configuration details for the controller\n" +
|
||||
" /provenance - READ - allows user/entity to perform provenance requests. results will be filtered based on access to provenance data per component\n" +
|
||||
" - WRITE - NA\n" +
|
||||
" /token - READ - NA\n" +
|
||||
" - WRITE - allows user/entity to create a token for access the REST API\n" +
|
||||
" /site-to-site - READ - allows user/entity to retrieve configuration details for performing site to site data transfers with this NiFi\n" +
|
||||
" - WRITE - NA\n" +
|
||||
" /proxy - READ - NA\n" +
|
||||
" - WRITE - allows user/entity to create a proxy request on behalf of another user\n" +
|
||||
" /process-groups/{id} - READ - allows user/entity to retrieve configuration details for the process group and all descendant components without explicit " +
|
||||
"access policies\n" +
|
||||
" - WRITE - allows user/entity to create/update/delete configuration details for the process group and all descendant components without " +
|
||||
"explicit access policies\n" +
|
||||
" /processors/{id} - READ - allows user/entity to retrieve configuration details for the processor overriding any inherited authorizations from an ancestor " +
|
||||
"process group\n" +
|
||||
" - WRITE - allows user/entity to update/delete the processor overriding any inherited authorizations from an ancestor process group\n" +
|
||||
" /input-ports/{id} - READ - allows user/entity to retrieve configuration details for the input port overriding any inherited authorizations from an ancestor " +
|
||||
"process group\n" +
|
||||
" - WRITE - allows user/entity to update/delete the input port overriding any inherited authorizations from an ancestor process group\n" +
|
||||
" /output-ports/{id} - READ - allows user/entity to retrieve configuration details for the output port overriding any inherited authorizations from an ancestor " +
|
||||
"process group\n" +
|
||||
" - WRITE - allows user/entity to update/delete the output port overriding any inherited authorizations from an ancestor process group\n" +
|
||||
" /labels/{id} - READ - allows user/entity to retrieve configuration details for the label overriding any inherited authorizations from an ancestor " +
|
||||
"process group\n" +
|
||||
" - WRITE - allows user/entity to update/delete the label overriding any inherited authorizations from an ancestor process group\n" +
|
||||
" /connections/{id} - READ - allows user/entity to retrieve configuration details for the connection overriding any inherited authorizations from an ancestor " +
|
||||
"process group\n" +
|
||||
" - WRITE - allows user/entity to update/delete the label overriding any inherited authorizations from an ancestor process group\n" +
|
||||
" /remote-process-groups/{id} - READ - allows user/entity to retrieve configuration details for the remote process group overriding any inherited authorizations from an " +
|
||||
"ancestor process group\n" +
|
||||
" - WRITE - allows user/entity to update/delete the remote process group overriding any inherited authorizations from an ancestor process " +
|
||||
"group\n" +
|
||||
" /templates/{id} - READ - allows user/entity to retrieve configuration details for the template overriding any inherited authorizations from an ancestor " +
|
||||
"process group\n" +
|
||||
" - WRITE - allows user/entity to create/update/delete the template overriding any inherited authorizations from an ancestor process group\n" +
|
||||
" /controller-services/{id} - READ - allows user/entity to retrieve configuration details for the controller service overriding any inherited authorizations from an " +
|
||||
"ancestor process group\n" +
|
||||
" - WRITE - allows user/entity to update/delete the controller service overriding any inherited authorizations from an ancestor process " +
|
||||
"group\n" +
|
||||
" /reporting-tasks/{id} - READ - allows user/entity to retrieve configuration details for the reporting tasks overriding any inherited authorizations from the " +
|
||||
"controller\n" +
|
||||
" - WRITE - allows user/entity to create/update/delete the reporting tasks overriding any inherited authorizations from the controller\n" +
|
||||
" /{type}/{id}/provenance - READ - allows user/entity to view provenance data from the underlying component\n" +
|
||||
" - WRITE - NA\n",
|
||||
response = AccessPolicyEntity.class,
|
||||
authorizations = {
|
||||
@Authorization(value = "Data Flow Manager", type = "ROLE_DFM")
|
||||
}
|
||||
)
|
||||
@ApiResponses(
|
||||
value = {
|
||||
@ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
|
||||
@ApiResponse(code = 401, message = "Client could not be authenticated."),
|
||||
@ApiResponse(code = 403, message = "Client is not authorized to make this request."),
|
||||
@ApiResponse(code = 404, message = "The specified resource could not be found."),
|
||||
@ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
|
||||
}
|
||||
)
|
||||
public Response createAccessPolicy(
|
||||
@Context final HttpServletRequest httpServletRequest,
|
||||
@ApiParam(
|
||||
value = "The access policy configuration details.",
|
||||
required = true
|
||||
) final AccessPolicyEntity accessPolicyEntity) {
|
||||
|
||||
if (accessPolicyEntity == null || accessPolicyEntity.getComponent() == null) {
|
||||
throw new IllegalArgumentException("Access policy details must be specified.");
|
||||
}
|
||||
|
||||
if (accessPolicyEntity.getComponent().getId() != null) {
|
||||
throw new IllegalArgumentException("Access policy ID cannot be specified.");
|
||||
}
|
||||
|
||||
if (isReplicateRequest()) {
|
||||
return replicate(HttpMethod.POST, accessPolicyEntity);
|
||||
}
|
||||
|
||||
// handle expects request (usually from the cluster manager)
|
||||
final boolean validationPhase = isValidationPhase(httpServletRequest);
|
||||
if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) {
|
||||
// authorize access
|
||||
serviceFacade.authorizeAccess(lookup -> {
|
||||
final Authorizable accessPolicies = lookup.getAccessPoliciesAuthorizable();
|
||||
accessPolicies.authorize(authorizer, RequestAction.WRITE);
|
||||
});
|
||||
}
|
||||
if (validationPhase) {
|
||||
return generateContinueResponse().build();
|
||||
}
|
||||
|
||||
// set the access policy id as appropriate
|
||||
accessPolicyEntity.getComponent().setId(generateUuid());
|
||||
|
||||
// get revision from the config
|
||||
final RevisionDTO revisionDTO = accessPolicyEntity.getRevision();
|
||||
Revision revision = new Revision(revisionDTO.getVersion(), revisionDTO.getClientId(), accessPolicyEntity.getComponent().getId());
|
||||
|
||||
// create the access policy and generate the json
|
||||
final AccessPolicyEntity entity = serviceFacade.createAccessPolicy(revision, accessPolicyEntity.getComponent());
|
||||
populateRemainingAccessPolicyEntityContent(entity);
|
||||
|
||||
// build the response
|
||||
return clusterContext(generateCreatedResponse(URI.create(entity.getComponent().getUri()), entity)).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the specified access policy.
|
||||
*
|
||||
* @param id The id of the access policy to retrieve
|
||||
* @return An accessPolicyEntity.
|
||||
*/
|
||||
@GET
|
||||
@Consumes(MediaType.WILDCARD)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("{id}")
|
||||
// TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
|
||||
@ApiOperation(
|
||||
value = "Gets an access policy",
|
||||
response = AccessPolicyEntity.class,
|
||||
authorizations = {
|
||||
@Authorization(value = "Read Only", type = "ROLE_MONITOR"),
|
||||
@Authorization(value = "Data Flow Manager", type = "ROLE_DFM"),
|
||||
@Authorization(value = "Administrator", type = "ROLE_ADMIN")
|
||||
}
|
||||
)
|
||||
@ApiResponses(
|
||||
value = {
|
||||
@ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
|
||||
@ApiResponse(code = 401, message = "Client could not be authenticated."),
|
||||
@ApiResponse(code = 403, message = "Client is not authorized to make this request."),
|
||||
@ApiResponse(code = 404, message = "The specified resource could not be found."),
|
||||
@ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
|
||||
}
|
||||
)
|
||||
public Response getAccessPolicy(
|
||||
@ApiParam(
|
||||
value = "The access policy id.",
|
||||
required = true
|
||||
)
|
||||
@PathParam("id") final String id) {
|
||||
|
||||
if (isReplicateRequest()) {
|
||||
return replicate(HttpMethod.GET);
|
||||
}
|
||||
|
||||
// authorize access
|
||||
serviceFacade.authorizeAccess(lookup -> {
|
||||
final Authorizable accessPolicy = lookup.getAccessPolicyAuthorizable(id);
|
||||
accessPolicy.authorize(authorizer, RequestAction.READ);
|
||||
});
|
||||
|
||||
// get the access policy
|
||||
final AccessPolicyEntity entity = serviceFacade.getAccessPolicy(id);
|
||||
populateRemainingAccessPolicyEntityContent(entity);
|
||||
|
||||
return clusterContext(generateOkResponse(entity)).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an access policy.
|
||||
*
|
||||
* @param httpServletRequest request
|
||||
* @param id The id of the access policy to update.
|
||||
* @param accessPolicyEntity An accessPolicyEntity.
|
||||
* @return An accessPolicyEntity.
|
||||
*/
|
||||
@PUT
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("{id}")
|
||||
// TODO - @PreAuthorize("hasRole('ROLE_DFM')")
|
||||
@ApiOperation(
|
||||
value = "Updates a access policy",
|
||||
response = AccessPolicyEntity.class,
|
||||
authorizations = {
|
||||
@Authorization(value = "Data Flow Manager", type = "ROLE_DFM")
|
||||
}
|
||||
)
|
||||
@ApiResponses(
|
||||
value = {
|
||||
@ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
|
||||
@ApiResponse(code = 401, message = "Client could not be authenticated."),
|
||||
@ApiResponse(code = 403, message = "Client is not authorized to make this request."),
|
||||
@ApiResponse(code = 404, message = "The specified resource could not be found."),
|
||||
@ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
|
||||
}
|
||||
)
|
||||
public Response updateAccessPolicy(
|
||||
@Context final HttpServletRequest httpServletRequest,
|
||||
@ApiParam(
|
||||
value = "The access policy id.",
|
||||
required = true
|
||||
)
|
||||
@PathParam("id") final String id,
|
||||
@ApiParam(
|
||||
value = "The access policy configuration details.",
|
||||
required = true
|
||||
) final AccessPolicyEntity accessPolicyEntity) {
|
||||
|
||||
if (accessPolicyEntity == null || accessPolicyEntity.getComponent() == null) {
|
||||
throw new IllegalArgumentException("Access policy details must be specified.");
|
||||
}
|
||||
|
||||
if (accessPolicyEntity.getRevision() == null) {
|
||||
throw new IllegalArgumentException("Revision must be specified.");
|
||||
}
|
||||
|
||||
// ensure the ids are the same
|
||||
final AccessPolicyDTO accessPolicyDTO = accessPolicyEntity.getComponent();
|
||||
if (!id.equals(accessPolicyDTO.getId())) {
|
||||
throw new IllegalArgumentException(String.format("The access policy id (%s) in the request body does not equal the "
|
||||
+ "access policy id of the requested resource (%s).", accessPolicyDTO.getId(), id));
|
||||
}
|
||||
|
||||
if (isReplicateRequest()) {
|
||||
return replicate(HttpMethod.PUT, accessPolicyEntity);
|
||||
}
|
||||
|
||||
// Extract the revision
|
||||
final Revision revision = getRevision(accessPolicyEntity, id);
|
||||
return withWriteLock(
|
||||
serviceFacade,
|
||||
revision,
|
||||
lookup -> {
|
||||
final Authorizable accessPolicy = lookup.getAccessPolicyAuthorizable(id);
|
||||
accessPolicy.authorize(authorizer, RequestAction.WRITE);
|
||||
},
|
||||
null,
|
||||
() -> {
|
||||
// update the access policy
|
||||
final UpdateResult<AccessPolicyEntity> updateResult = serviceFacade.updateAccessPolicy(revision, accessPolicyDTO);
|
||||
|
||||
// get the results
|
||||
final AccessPolicyEntity entity = updateResult.getResult();
|
||||
populateRemainingAccessPolicyEntityContent(entity);
|
||||
|
||||
if (updateResult.isNew()) {
|
||||
return clusterContext(generateCreatedResponse(URI.create(entity.getComponent().getUri()), entity)).build();
|
||||
} else {
|
||||
return clusterContext(generateOkResponse(entity)).build();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified access policy.
|
||||
*
|
||||
* @param httpServletRequest request
|
||||
* @param version The revision is used to verify the client is working with
|
||||
* the latest version of the flow.
|
||||
* @param clientId Optional client id. If the client id is not specified, a
|
||||
* new one will be generated. This value (whether specified or generated) is
|
||||
* included in the response.
|
||||
* @param id The id of the access policy to remove.
|
||||
* @return A entity containing the client id and an updated revision.
|
||||
*/
|
||||
@DELETE
|
||||
@Consumes(MediaType.WILDCARD)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("{id}")
|
||||
// TODO - @PreAuthorize("hasRole('ROLE_DFM')")
|
||||
@ApiOperation(
|
||||
value = "Deletes an access policy",
|
||||
response = AccessPolicyEntity.class,
|
||||
authorizations = {
|
||||
@Authorization(value = "Data Flow Manager", type = "ROLE_DFM")
|
||||
}
|
||||
)
|
||||
@ApiResponses(
|
||||
value = {
|
||||
@ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
|
||||
@ApiResponse(code = 401, message = "Client could not be authenticated."),
|
||||
@ApiResponse(code = 403, message = "Client is not authorized to make this request."),
|
||||
@ApiResponse(code = 404, message = "The specified resource could not be found."),
|
||||
@ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
|
||||
}
|
||||
)
|
||||
public Response removeAccessPolicy(
|
||||
@Context final HttpServletRequest httpServletRequest,
|
||||
@ApiParam(
|
||||
value = "The revision is used to verify the client is working with the latest version of the flow.",
|
||||
required = false
|
||||
)
|
||||
@QueryParam(VERSION) final LongParameter version,
|
||||
@ApiParam(
|
||||
value = "If the client id is not specified, new one will be generated. This value (whether specified or generated) is included in the response.",
|
||||
required = false
|
||||
)
|
||||
@QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) final ClientIdParameter clientId,
|
||||
@ApiParam(
|
||||
value = "The access policy id.",
|
||||
required = true
|
||||
)
|
||||
@PathParam("id") final String id) {
|
||||
|
||||
if (isReplicateRequest()) {
|
||||
return replicate(HttpMethod.DELETE);
|
||||
}
|
||||
|
||||
// handle expects request (usually from the cluster manager)
|
||||
final Revision revision = new Revision(version == null ? null : version.getLong(), clientId.getClientId(), id);
|
||||
return withWriteLock(
|
||||
serviceFacade,
|
||||
revision,
|
||||
lookup -> {
|
||||
final Authorizable accessPolicy = lookup.getAccessPolicyAuthorizable(id);
|
||||
accessPolicy.authorize(authorizer, RequestAction.READ);
|
||||
},
|
||||
() -> {
|
||||
},
|
||||
() -> {
|
||||
// delete the specified access policy
|
||||
final AccessPolicyEntity entity = serviceFacade.deleteAccessPolicy(revision, id);
|
||||
return clusterContext(generateOkResponse(entity)).build();
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,385 @@
|
|||
/*
|
||||
* 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.web.api;
|
||||
|
||||
import com.wordnik.swagger.annotations.Api;
|
||||
import com.wordnik.swagger.annotations.ApiOperation;
|
||||
import com.wordnik.swagger.annotations.ApiParam;
|
||||
import com.wordnik.swagger.annotations.ApiResponse;
|
||||
import com.wordnik.swagger.annotations.ApiResponses;
|
||||
import com.wordnik.swagger.annotations.Authorization;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.nifi.authorization.Authorizer;
|
||||
import org.apache.nifi.authorization.RequestAction;
|
||||
import org.apache.nifi.authorization.resource.Authorizable;
|
||||
import org.apache.nifi.cluster.coordination.ClusterCoordinator;
|
||||
import org.apache.nifi.cluster.coordination.http.replication.RequestReplicator;
|
||||
import org.apache.nifi.util.NiFiProperties;
|
||||
import org.apache.nifi.web.NiFiServiceFacade;
|
||||
import org.apache.nifi.web.Revision;
|
||||
import org.apache.nifi.web.UpdateResult;
|
||||
import org.apache.nifi.web.api.dto.RevisionDTO;
|
||||
import org.apache.nifi.web.api.dto.UserGroupDTO;
|
||||
import org.apache.nifi.web.api.entity.UserGroupEntity;
|
||||
import org.apache.nifi.web.api.request.ClientIdParameter;
|
||||
import org.apache.nifi.web.api.request.LongParameter;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.DefaultValue;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.HttpMethod;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.net.URI;
|
||||
|
||||
@Path("/user-groups")
|
||||
@Api(
|
||||
value = "/user-groups",
|
||||
description = "Endpoint for managing user groups."
|
||||
)
|
||||
public class UserGroupsResource extends ApplicationResource {
|
||||
|
||||
private final NiFiServiceFacade serviceFacade;
|
||||
private final Authorizer authorizer;
|
||||
|
||||
public UserGroupsResource(NiFiServiceFacade serviceFacade, Authorizer authorizer, NiFiProperties properties, RequestReplicator requestReplicator, ClusterCoordinator clusterCoordinator) {
|
||||
this.serviceFacade = serviceFacade;
|
||||
this.authorizer = authorizer;
|
||||
setProperties(properties);
|
||||
setRequestReplicator(requestReplicator);
|
||||
setClusterCoordinator(clusterCoordinator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the uri for the specified user group.
|
||||
*
|
||||
* @param userGroupEntity userGroupEntity
|
||||
* @return userGroupEntity
|
||||
*/
|
||||
public UserGroupEntity populateRemainingUserGroupEntityContent(UserGroupEntity userGroupEntity) {
|
||||
if (userGroupEntity.getComponent() != null) {
|
||||
populateRemainingUserGroupContent(userGroupEntity.getComponent());
|
||||
}
|
||||
return userGroupEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the uri for the specified userGroup.
|
||||
*/
|
||||
public UserGroupDTO populateRemainingUserGroupContent(UserGroupDTO userGroup) {
|
||||
// populate the user group href
|
||||
userGroup.setUri(generateResourceUri("user-groups", userGroup.getId()));
|
||||
return userGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new user group.
|
||||
*
|
||||
* @param httpServletRequest request
|
||||
* @param userGroupEntity An userGroupEntity.
|
||||
* @return An userGroupEntity.
|
||||
*/
|
||||
@POST
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
// TODO - @PreAuthorize("hasRole('ROLE_DFM')")
|
||||
@ApiOperation(
|
||||
value = "Creates a user group",
|
||||
response = UserGroupEntity.class,
|
||||
authorizations = {
|
||||
@Authorization(value = "Data Flow Manager", type = "ROLE_DFM")
|
||||
}
|
||||
)
|
||||
@ApiResponses(
|
||||
value = {
|
||||
@ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
|
||||
@ApiResponse(code = 401, message = "Client could not be authenticated."),
|
||||
@ApiResponse(code = 403, message = "Client is not authorized to make this request."),
|
||||
@ApiResponse(code = 404, message = "The specified resource could not be found."),
|
||||
@ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
|
||||
}
|
||||
)
|
||||
public Response createUserGroup(
|
||||
@Context final HttpServletRequest httpServletRequest,
|
||||
@ApiParam(
|
||||
value = "The user group configuration details.",
|
||||
required = true
|
||||
) final UserGroupEntity userGroupEntity) {
|
||||
|
||||
if (userGroupEntity == null || userGroupEntity.getComponent() == null) {
|
||||
throw new IllegalArgumentException("User group details must be specified.");
|
||||
}
|
||||
|
||||
if (userGroupEntity.getComponent().getId() != null) {
|
||||
throw new IllegalArgumentException("User group ID cannot be specified.");
|
||||
}
|
||||
|
||||
if (isReplicateRequest()) {
|
||||
return replicate(HttpMethod.POST, userGroupEntity);
|
||||
}
|
||||
|
||||
// handle expects request (usually from the cluster manager)
|
||||
final boolean validationPhase = isValidationPhase(httpServletRequest);
|
||||
if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) {
|
||||
// authorize access
|
||||
serviceFacade.authorizeAccess(lookup -> {
|
||||
final Authorizable userGroups = lookup.getUserGroupsAuthorizable();
|
||||
userGroups.authorize(authorizer, RequestAction.WRITE);
|
||||
});
|
||||
}
|
||||
if (validationPhase) {
|
||||
return generateContinueResponse().build();
|
||||
}
|
||||
|
||||
// set the user group id as appropriate
|
||||
userGroupEntity.getComponent().setId(generateUuid());
|
||||
|
||||
// get revision from the config
|
||||
final RevisionDTO revisionDTO = userGroupEntity.getRevision();
|
||||
Revision revision = new Revision(revisionDTO.getVersion(), revisionDTO.getClientId(), userGroupEntity.getComponent().getId());
|
||||
|
||||
// create the user group and generate the json
|
||||
final UserGroupEntity entity = serviceFacade.createUserGroup(revision, userGroupEntity.getComponent());
|
||||
populateRemainingUserGroupEntityContent(entity);
|
||||
|
||||
// build the response
|
||||
return clusterContext(generateCreatedResponse(URI.create(entity.getComponent().getUri()), entity)).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the specified user group.
|
||||
*
|
||||
* @param id The id of the user group to retrieve
|
||||
* @return An userGroupEntity.
|
||||
*/
|
||||
@GET
|
||||
@Consumes(MediaType.WILDCARD)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("{id}")
|
||||
// TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
|
||||
@ApiOperation(
|
||||
value = "Gets a user group",
|
||||
response = UserGroupEntity.class,
|
||||
authorizations = {
|
||||
@Authorization(value = "Read Only", type = "ROLE_MONITOR"),
|
||||
@Authorization(value = "Data Flow Manager", type = "ROLE_DFM"),
|
||||
@Authorization(value = "Administrator", type = "ROLE_ADMIN")
|
||||
}
|
||||
)
|
||||
@ApiResponses(
|
||||
value = {
|
||||
@ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
|
||||
@ApiResponse(code = 401, message = "Client could not be authenticated."),
|
||||
@ApiResponse(code = 403, message = "Client is not authorized to make this request."),
|
||||
@ApiResponse(code = 404, message = "The specified resource could not be found."),
|
||||
@ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
|
||||
}
|
||||
)
|
||||
public Response getUserGroup(
|
||||
@ApiParam(
|
||||
value = "The user group id.",
|
||||
required = true
|
||||
)
|
||||
@PathParam("id") final String id) {
|
||||
|
||||
if (isReplicateRequest()) {
|
||||
return replicate(HttpMethod.GET);
|
||||
}
|
||||
|
||||
// authorize access
|
||||
serviceFacade.authorizeAccess(lookup -> {
|
||||
final Authorizable userGroups = lookup.getUserGroupsAuthorizable();
|
||||
userGroups.authorize(authorizer, RequestAction.READ);
|
||||
});
|
||||
|
||||
// get the user group
|
||||
final UserGroupEntity entity = serviceFacade.getUserGroup(id, true);
|
||||
populateRemainingUserGroupEntityContent(entity);
|
||||
|
||||
return clusterContext(generateOkResponse(entity)).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a user group.
|
||||
*
|
||||
* @param httpServletRequest request
|
||||
* @param id The id of the user group to update.
|
||||
* @param userGroupEntity An userGroupEntity.
|
||||
* @return An userGroupEntity.
|
||||
*/
|
||||
@PUT
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("{id}")
|
||||
// TODO - @PreAuthorize("hasRole('ROLE_DFM')")
|
||||
@ApiOperation(
|
||||
value = "Updates a user group",
|
||||
response = UserGroupEntity.class,
|
||||
authorizations = {
|
||||
@Authorization(value = "Data Flow Manager", type = "ROLE_DFM")
|
||||
}
|
||||
)
|
||||
@ApiResponses(
|
||||
value = {
|
||||
@ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
|
||||
@ApiResponse(code = 401, message = "Client could not be authenticated."),
|
||||
@ApiResponse(code = 403, message = "Client is not authorized to make this request."),
|
||||
@ApiResponse(code = 404, message = "The specified resource could not be found."),
|
||||
@ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
|
||||
}
|
||||
)
|
||||
public Response updateUserGroup(
|
||||
@Context final HttpServletRequest httpServletRequest,
|
||||
@ApiParam(
|
||||
value = "The user group id.",
|
||||
required = true
|
||||
)
|
||||
@PathParam("id") final String id,
|
||||
@ApiParam(
|
||||
value = "The user group configuration details.",
|
||||
required = true
|
||||
) final UserGroupEntity userGroupEntity) {
|
||||
|
||||
if (userGroupEntity == null || userGroupEntity.getComponent() == null) {
|
||||
throw new IllegalArgumentException("User group details must be specified.");
|
||||
}
|
||||
|
||||
if (userGroupEntity.getRevision() == null) {
|
||||
throw new IllegalArgumentException("Revision must be specified.");
|
||||
}
|
||||
|
||||
// ensure the ids are the same
|
||||
final UserGroupDTO userGroupDTO = userGroupEntity.getComponent();
|
||||
if (!id.equals(userGroupDTO.getId())) {
|
||||
throw new IllegalArgumentException(String.format("The user group id (%s) in the request body does not equal the "
|
||||
+ "user group id of the requested resource (%s).", userGroupDTO.getId(), id));
|
||||
}
|
||||
|
||||
if (isReplicateRequest()) {
|
||||
return replicate(HttpMethod.PUT, userGroupEntity);
|
||||
}
|
||||
|
||||
// Extract the revision
|
||||
final Revision revision = getRevision(userGroupEntity, id);
|
||||
return withWriteLock(
|
||||
serviceFacade,
|
||||
revision,
|
||||
lookup -> {
|
||||
final Authorizable userGroups = lookup.getUserGroupsAuthorizable();
|
||||
userGroups.authorize(authorizer, RequestAction.WRITE);
|
||||
},
|
||||
null,
|
||||
() -> {
|
||||
// update the user group
|
||||
final UpdateResult<UserGroupEntity> updateResult = serviceFacade.updateUserGroup(revision, userGroupDTO);
|
||||
|
||||
// get the results
|
||||
final UserGroupEntity entity = updateResult.getResult();
|
||||
populateRemainingUserGroupEntityContent(entity);
|
||||
|
||||
if (updateResult.isNew()) {
|
||||
return clusterContext(generateCreatedResponse(URI.create(entity.getComponent().getUri()), entity)).build();
|
||||
} else {
|
||||
return clusterContext(generateOkResponse(entity)).build();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified user group.
|
||||
*
|
||||
* @param httpServletRequest request
|
||||
* @param version The revision is used to verify the client is working with
|
||||
* the latest version of the flow.
|
||||
* @param clientId Optional client id. If the client id is not specified, a
|
||||
* new one will be generated. This value (whether specified or generated) is
|
||||
* included in the response.
|
||||
* @param id The id of the user group to remove.
|
||||
* @return A entity containing the client id and an updated revision.
|
||||
*/
|
||||
@DELETE
|
||||
@Consumes(MediaType.WILDCARD)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("{id}")
|
||||
// TODO - @PreAuthorize("hasRole('ROLE_DFM')")
|
||||
@ApiOperation(
|
||||
value = "Deletes a user group",
|
||||
response = UserGroupEntity.class,
|
||||
authorizations = {
|
||||
@Authorization(value = "Data Flow Manager", type = "ROLE_DFM")
|
||||
}
|
||||
)
|
||||
@ApiResponses(
|
||||
value = {
|
||||
@ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
|
||||
@ApiResponse(code = 401, message = "Client could not be authenticated."),
|
||||
@ApiResponse(code = 403, message = "Client is not authorized to make this request."),
|
||||
@ApiResponse(code = 404, message = "The specified resource could not be found."),
|
||||
@ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
|
||||
}
|
||||
)
|
||||
public Response removeUserGroup(
|
||||
@Context final HttpServletRequest httpServletRequest,
|
||||
@ApiParam(
|
||||
value = "The revision is used to verify the client is working with the latest version of the flow.",
|
||||
required = false
|
||||
)
|
||||
@QueryParam(VERSION) final LongParameter version,
|
||||
@ApiParam(
|
||||
value = "If the client id is not specified, new one will be generated. This value (whether specified or generated) is included in the response.",
|
||||
required = false
|
||||
)
|
||||
@QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) final ClientIdParameter clientId,
|
||||
@ApiParam(
|
||||
value = "The user group id.",
|
||||
required = true
|
||||
)
|
||||
@PathParam("id") final String id) {
|
||||
|
||||
if (isReplicateRequest()) {
|
||||
return replicate(HttpMethod.DELETE);
|
||||
}
|
||||
|
||||
// handle expects request (usually from the cluster manager)
|
||||
final Revision revision = new Revision(version == null ? null : version.getLong(), clientId.getClientId(), id);
|
||||
return withWriteLock(
|
||||
serviceFacade,
|
||||
revision,
|
||||
lookup -> {
|
||||
final Authorizable userGroups = lookup.getUserGroupsAuthorizable();
|
||||
userGroups.authorize(authorizer, RequestAction.READ);
|
||||
},
|
||||
() -> {
|
||||
},
|
||||
() -> {
|
||||
// delete the specified user group
|
||||
final UserGroupEntity entity = serviceFacade.deleteUserGroup(revision, id);
|
||||
return clusterContext(generateOkResponse(entity)).build();
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,385 @@
|
|||
/*
|
||||
* 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.web.api;
|
||||
|
||||
import com.wordnik.swagger.annotations.Api;
|
||||
import com.wordnik.swagger.annotations.ApiOperation;
|
||||
import com.wordnik.swagger.annotations.ApiParam;
|
||||
import com.wordnik.swagger.annotations.ApiResponse;
|
||||
import com.wordnik.swagger.annotations.ApiResponses;
|
||||
import com.wordnik.swagger.annotations.Authorization;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.nifi.authorization.Authorizer;
|
||||
import org.apache.nifi.authorization.RequestAction;
|
||||
import org.apache.nifi.authorization.resource.Authorizable;
|
||||
import org.apache.nifi.cluster.coordination.ClusterCoordinator;
|
||||
import org.apache.nifi.cluster.coordination.http.replication.RequestReplicator;
|
||||
import org.apache.nifi.util.NiFiProperties;
|
||||
import org.apache.nifi.web.NiFiServiceFacade;
|
||||
import org.apache.nifi.web.Revision;
|
||||
import org.apache.nifi.web.UpdateResult;
|
||||
import org.apache.nifi.web.api.dto.RevisionDTO;
|
||||
import org.apache.nifi.web.api.dto.UserDTO;
|
||||
import org.apache.nifi.web.api.entity.UserEntity;
|
||||
import org.apache.nifi.web.api.request.ClientIdParameter;
|
||||
import org.apache.nifi.web.api.request.LongParameter;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.DefaultValue;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.HttpMethod;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.net.URI;
|
||||
|
||||
@Path("/users")
|
||||
@Api(
|
||||
value = "/users",
|
||||
description = "Endpoint for managing users."
|
||||
)
|
||||
public class UsersResource extends ApplicationResource {
|
||||
|
||||
private final NiFiServiceFacade serviceFacade;
|
||||
private final Authorizer authorizer;
|
||||
|
||||
public UsersResource(NiFiServiceFacade serviceFacade, Authorizer authorizer, NiFiProperties properties, RequestReplicator requestReplicator, ClusterCoordinator clusterCoordinator) {
|
||||
this.serviceFacade = serviceFacade;
|
||||
this.authorizer = authorizer;
|
||||
setProperties(properties);
|
||||
setRequestReplicator(requestReplicator);
|
||||
setClusterCoordinator(clusterCoordinator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the uri for the specified user.
|
||||
*
|
||||
* @param userEntity userEntity
|
||||
* @return userEntity
|
||||
*/
|
||||
public UserEntity populateRemainingUserEntityContent(UserEntity userEntity) {
|
||||
if (userEntity.getComponent() != null) {
|
||||
populateRemainingUserContent(userEntity.getComponent());
|
||||
}
|
||||
return userEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the uri for the specified user.
|
||||
*/
|
||||
public UserDTO populateRemainingUserContent(UserDTO user) {
|
||||
// populate the user href
|
||||
user.setUri(generateResourceUri("users", user.getId()));
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new user.
|
||||
*
|
||||
* @param httpServletRequest request
|
||||
* @param userEntity An userEntity.
|
||||
* @return An userEntity.
|
||||
*/
|
||||
@POST
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
// TODO - @PreAuthorize("hasRole('ROLE_DFM')")
|
||||
@ApiOperation(
|
||||
value = "Creates a user",
|
||||
response = UserEntity.class,
|
||||
authorizations = {
|
||||
@Authorization(value = "Data Flow Manager", type = "ROLE_DFM")
|
||||
}
|
||||
)
|
||||
@ApiResponses(
|
||||
value = {
|
||||
@ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
|
||||
@ApiResponse(code = 401, message = "Client could not be authenticated."),
|
||||
@ApiResponse(code = 403, message = "Client is not authorized to make this request."),
|
||||
@ApiResponse(code = 404, message = "The specified resource could not be found."),
|
||||
@ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
|
||||
}
|
||||
)
|
||||
public Response createUser(
|
||||
@Context final HttpServletRequest httpServletRequest,
|
||||
@ApiParam(
|
||||
value = "The user configuration details.",
|
||||
required = true
|
||||
) final UserEntity userEntity) {
|
||||
|
||||
if (userEntity == null || userEntity.getComponent() == null) {
|
||||
throw new IllegalArgumentException("User details must be specified.");
|
||||
}
|
||||
|
||||
if (userEntity.getComponent().getId() != null) {
|
||||
throw new IllegalArgumentException("User ID cannot be specified.");
|
||||
}
|
||||
|
||||
if (isReplicateRequest()) {
|
||||
return replicate(HttpMethod.POST, userEntity);
|
||||
}
|
||||
|
||||
// handle expects request (usually from the cluster manager)
|
||||
final boolean validationPhase = isValidationPhase(httpServletRequest);
|
||||
if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) {
|
||||
// authorize access
|
||||
serviceFacade.authorizeAccess(lookup -> {
|
||||
final Authorizable users = lookup.getUsersAuthorizable();
|
||||
users.authorize(authorizer, RequestAction.WRITE);
|
||||
});
|
||||
}
|
||||
if (validationPhase) {
|
||||
return generateContinueResponse().build();
|
||||
}
|
||||
|
||||
// set the user id as appropriate
|
||||
userEntity.getComponent().setId(generateUuid());
|
||||
|
||||
// get revision from the config
|
||||
final RevisionDTO revisionDTO = userEntity.getRevision();
|
||||
Revision revision = new Revision(revisionDTO.getVersion(), revisionDTO.getClientId(), userEntity.getComponent().getId());
|
||||
|
||||
// create the user and generate the json
|
||||
final UserEntity entity = serviceFacade.createUser(revision, userEntity.getComponent());
|
||||
populateRemainingUserEntityContent(entity);
|
||||
|
||||
// build the response
|
||||
return clusterContext(generateCreatedResponse(URI.create(entity.getComponent().getUri()), entity)).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the specified user.
|
||||
*
|
||||
* @param id The id of the user to retrieve
|
||||
* @return An userEntity.
|
||||
*/
|
||||
@GET
|
||||
@Consumes(MediaType.WILDCARD)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("{id}")
|
||||
// TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
|
||||
@ApiOperation(
|
||||
value = "Gets a user",
|
||||
response = UserEntity.class,
|
||||
authorizations = {
|
||||
@Authorization(value = "Read Only", type = "ROLE_MONITOR"),
|
||||
@Authorization(value = "Data Flow Manager", type = "ROLE_DFM"),
|
||||
@Authorization(value = "Administrator", type = "ROLE_ADMIN")
|
||||
}
|
||||
)
|
||||
@ApiResponses(
|
||||
value = {
|
||||
@ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
|
||||
@ApiResponse(code = 401, message = "Client could not be authenticated."),
|
||||
@ApiResponse(code = 403, message = "Client is not authorized to make this request."),
|
||||
@ApiResponse(code = 404, message = "The specified resource could not be found."),
|
||||
@ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
|
||||
}
|
||||
)
|
||||
public Response getUser(
|
||||
@ApiParam(
|
||||
value = "The user id.",
|
||||
required = true
|
||||
)
|
||||
@PathParam("id") final String id) {
|
||||
|
||||
if (isReplicateRequest()) {
|
||||
return replicate(HttpMethod.GET);
|
||||
}
|
||||
|
||||
// authorize access
|
||||
serviceFacade.authorizeAccess(lookup -> {
|
||||
final Authorizable users = lookup.getUsersAuthorizable();
|
||||
users.authorize(authorizer, RequestAction.READ);
|
||||
});
|
||||
|
||||
// get the user
|
||||
final UserEntity entity = serviceFacade.getUser(id, true);
|
||||
populateRemainingUserEntityContent(entity);
|
||||
|
||||
return clusterContext(generateOkResponse(entity)).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a user.
|
||||
*
|
||||
* @param httpServletRequest request
|
||||
* @param id The id of the user to update.
|
||||
* @param userEntity An userEntity.
|
||||
* @return An userEntity.
|
||||
*/
|
||||
@PUT
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("{id}")
|
||||
// TODO - @PreAuthorize("hasRole('ROLE_DFM')")
|
||||
@ApiOperation(
|
||||
value = "Updates a user",
|
||||
response = UserEntity.class,
|
||||
authorizations = {
|
||||
@Authorization(value = "Data Flow Manager", type = "ROLE_DFM")
|
||||
}
|
||||
)
|
||||
@ApiResponses(
|
||||
value = {
|
||||
@ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
|
||||
@ApiResponse(code = 401, message = "Client could not be authenticated."),
|
||||
@ApiResponse(code = 403, message = "Client is not authorized to make this request."),
|
||||
@ApiResponse(code = 404, message = "The specified resource could not be found."),
|
||||
@ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
|
||||
}
|
||||
)
|
||||
public Response updateUser(
|
||||
@Context final HttpServletRequest httpServletRequest,
|
||||
@ApiParam(
|
||||
value = "The user id.",
|
||||
required = true
|
||||
)
|
||||
@PathParam("id") final String id,
|
||||
@ApiParam(
|
||||
value = "The user configuration details.",
|
||||
required = true
|
||||
) final UserEntity userEntity) {
|
||||
|
||||
if (userEntity == null || userEntity.getComponent() == null) {
|
||||
throw new IllegalArgumentException("User details must be specified.");
|
||||
}
|
||||
|
||||
if (userEntity.getRevision() == null) {
|
||||
throw new IllegalArgumentException("Revision must be specified.");
|
||||
}
|
||||
|
||||
// ensure the ids are the same
|
||||
final UserDTO userDTO = userEntity.getComponent();
|
||||
if (!id.equals(userDTO.getId())) {
|
||||
throw new IllegalArgumentException(String.format("The user id (%s) in the request body does not equal the "
|
||||
+ "user id of the requested resource (%s).", userDTO.getId(), id));
|
||||
}
|
||||
|
||||
if (isReplicateRequest()) {
|
||||
return replicate(HttpMethod.PUT, userEntity);
|
||||
}
|
||||
|
||||
// Extract the revision
|
||||
final Revision revision = getRevision(userEntity, id);
|
||||
return withWriteLock(
|
||||
serviceFacade,
|
||||
revision,
|
||||
lookup -> {
|
||||
final Authorizable users = lookup.getUsersAuthorizable();
|
||||
users.authorize(authorizer, RequestAction.WRITE);
|
||||
},
|
||||
null,
|
||||
() -> {
|
||||
// update the user
|
||||
final UpdateResult<UserEntity> updateResult = serviceFacade.updateUser(revision, userDTO);
|
||||
|
||||
// get the results
|
||||
final UserEntity entity = updateResult.getResult();
|
||||
populateRemainingUserEntityContent(entity);
|
||||
|
||||
if (updateResult.isNew()) {
|
||||
return clusterContext(generateCreatedResponse(URI.create(entity.getComponent().getUri()), entity)).build();
|
||||
} else {
|
||||
return clusterContext(generateOkResponse(entity)).build();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified user.
|
||||
*
|
||||
* @param httpServletRequest request
|
||||
* @param version The revision is used to verify the client is working with
|
||||
* the latest version of the flow.
|
||||
* @param clientId Optional client id. If the client id is not specified, a
|
||||
* new one will be generated. This value (whether specified or generated) is
|
||||
* included in the response.
|
||||
* @param id The id of the user to remove.
|
||||
* @return A entity containing the client id and an updated revision.
|
||||
*/
|
||||
@DELETE
|
||||
@Consumes(MediaType.WILDCARD)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("{id}")
|
||||
// TODO - @PreAuthorize("hasRole('ROLE_DFM')")
|
||||
@ApiOperation(
|
||||
value = "Deletes a user",
|
||||
response = UserEntity.class,
|
||||
authorizations = {
|
||||
@Authorization(value = "Data Flow Manager", type = "ROLE_DFM")
|
||||
}
|
||||
)
|
||||
@ApiResponses(
|
||||
value = {
|
||||
@ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
|
||||
@ApiResponse(code = 401, message = "Client could not be authenticated."),
|
||||
@ApiResponse(code = 403, message = "Client is not authorized to make this request."),
|
||||
@ApiResponse(code = 404, message = "The specified resource could not be found."),
|
||||
@ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
|
||||
}
|
||||
)
|
||||
public Response removeUser(
|
||||
@Context final HttpServletRequest httpServletRequest,
|
||||
@ApiParam(
|
||||
value = "The revision is used to verify the client is working with the latest version of the flow.",
|
||||
required = false
|
||||
)
|
||||
@QueryParam(VERSION) final LongParameter version,
|
||||
@ApiParam(
|
||||
value = "If the client id is not specified, new one will be generated. This value (whether specified or generated) is included in the response.",
|
||||
required = false
|
||||
)
|
||||
@QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) final ClientIdParameter clientId,
|
||||
@ApiParam(
|
||||
value = "The user id.",
|
||||
required = true
|
||||
)
|
||||
@PathParam("id") final String id) {
|
||||
|
||||
if (isReplicateRequest()) {
|
||||
return replicate(HttpMethod.DELETE);
|
||||
}
|
||||
|
||||
// handle expects request (usually from the cluster manager)
|
||||
final Revision revision = new Revision(version == null ? null : version.getLong(), clientId.getClientId(), id);
|
||||
return withWriteLock(
|
||||
serviceFacade,
|
||||
revision,
|
||||
lookup -> {
|
||||
final Authorizable users = lookup.getUsersAuthorizable();
|
||||
users.authorize(authorizer, RequestAction.READ);
|
||||
},
|
||||
() -> {
|
||||
},
|
||||
() -> {
|
||||
// delete the specified user
|
||||
final UserEntity entity = serviceFacade.deleteUser(revision, id);
|
||||
return clusterContext(generateOkResponse(entity)).build();
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
|
@ -34,9 +34,12 @@ import org.apache.nifi.action.details.PurgeDetails;
|
|||
import org.apache.nifi.annotation.behavior.Stateful;
|
||||
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
||||
import org.apache.nifi.annotation.documentation.Tags;
|
||||
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.Resource;
|
||||
import org.apache.nifi.authorization.User;
|
||||
import org.apache.nifi.authorization.resource.Authorizable;
|
||||
import org.apache.nifi.cluster.coordination.heartbeat.NodeHeartbeat;
|
||||
import org.apache.nifi.cluster.coordination.node.NodeConnectionStatus;
|
||||
|
@ -136,6 +139,8 @@ import org.apache.nifi.web.api.dto.status.ProcessorStatusSnapshotDTO;
|
|||
import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO;
|
||||
import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusSnapshotDTO;
|
||||
import org.apache.nifi.web.api.entity.FlowBreadcrumbEntity;
|
||||
import org.apache.nifi.web.api.entity.UserEntity;
|
||||
import org.apache.nifi.web.api.entity.UserGroupEntity;
|
||||
import org.apache.nifi.web.controller.ControllerFacade;
|
||||
import org.apache.nifi.web.revision.RevisionManager;
|
||||
|
||||
|
@ -675,6 +680,44 @@ public final class DtoFactory {
|
|||
return dto;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link UserDTO} from the specified {@link User}.
|
||||
*
|
||||
* @param user user
|
||||
* @return dto
|
||||
*/
|
||||
public UserDTO createUserDto(final User user, final Set<UserGroupEntity> groups) {
|
||||
if (user == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final UserDTO dto = new UserDTO();
|
||||
dto.setId(user.getIdentifier());
|
||||
dto.setGroups(groups);
|
||||
dto.setIdentity(user.getIdentity());
|
||||
|
||||
return dto;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link UserGroupDTO} from the specified {@link Group}.
|
||||
*
|
||||
* @param userGroup user group
|
||||
* @return dto
|
||||
*/
|
||||
public UserGroupDTO createUserGroupDto(final Group userGroup, Set<UserEntity> users) {
|
||||
if (userGroup == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final UserGroupDTO dto = new UserGroupDTO();
|
||||
dto.setId(userGroup.getIdentifier());
|
||||
dto.setUsers(users);
|
||||
dto.setName(userGroup.getName());
|
||||
|
||||
return dto;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a FunnelDTO from the specified Funnel.
|
||||
*
|
||||
|
@ -1469,6 +1512,23 @@ public final class DtoFactory {
|
|||
return dto;
|
||||
}
|
||||
|
||||
public AccessPolicyDTO createAccessPolicyDto(final AccessPolicy accessPolicy, Set<UserGroupEntity> userGroups, Set<UserEntity> users) {
|
||||
if (accessPolicy == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final AccessPolicyDTO dto = new AccessPolicyDTO();
|
||||
dto.setUserGroups(userGroups);
|
||||
dto.setUsers(users);
|
||||
dto.setId(accessPolicy.getIdentifier());
|
||||
dto.setResource(accessPolicy.getResource());
|
||||
Set<RequestAction> accessPolicyActions = accessPolicy.getActions();
|
||||
dto.setCanRead(accessPolicyActions.contains(RequestAction.READ));
|
||||
dto.setCanWrite(accessPolicyActions.contains(RequestAction.WRITE));
|
||||
|
||||
return dto;
|
||||
|
||||
}
|
||||
/**
|
||||
* Creates the AccessPolicyDTO based on the specified Authorizable.
|
||||
*
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.apache.nifi.web.api.dto.status.PortStatusDTO;
|
|||
import org.apache.nifi.web.api.dto.status.ProcessGroupStatusDTO;
|
||||
import org.apache.nifi.web.api.dto.status.ProcessorStatusDTO;
|
||||
import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO;
|
||||
import org.apache.nifi.web.api.entity.AccessPolicyEntity;
|
||||
import org.apache.nifi.web.api.entity.ConnectionEntity;
|
||||
import org.apache.nifi.web.api.entity.ControllerConfigurationEntity;
|
||||
import org.apache.nifi.web.api.entity.ControllerServiceEntity;
|
||||
|
@ -38,6 +39,8 @@ import org.apache.nifi.web.api.entity.RemoteProcessGroupEntity;
|
|||
import org.apache.nifi.web.api.entity.RemoteProcessGroupPortEntity;
|
||||
import org.apache.nifi.web.api.entity.ReportingTaskEntity;
|
||||
import org.apache.nifi.web.api.entity.SnippetEntity;
|
||||
import org.apache.nifi.web.api.entity.UserEntity;
|
||||
import org.apache.nifi.web.api.entity.UserGroupEntity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -144,6 +147,48 @@ public final class EntityFactory {
|
|||
return entity;
|
||||
}
|
||||
|
||||
public UserEntity createUserEntity(final UserDTO dto, final RevisionDTO revision, final AccessPolicyDTO accessPolicy) {
|
||||
final UserEntity entity = new UserEntity();
|
||||
entity.setRevision(revision);
|
||||
if (dto != null) {
|
||||
entity.setAccessPolicy(accessPolicy);
|
||||
entity.setId(dto.getId());
|
||||
|
||||
if (accessPolicy != null && accessPolicy.getCanRead()) {
|
||||
entity.setComponent(dto);
|
||||
}
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
public UserGroupEntity createUserGroupEntity(final UserGroupDTO dto, final RevisionDTO revision, final AccessPolicyDTO accessPolicy) {
|
||||
final UserGroupEntity entity = new UserGroupEntity();
|
||||
entity.setRevision(revision);
|
||||
if (dto != null) {
|
||||
entity.setAccessPolicy(accessPolicy);
|
||||
entity.setId(dto.getId());
|
||||
|
||||
if (accessPolicy != null && accessPolicy.getCanRead()) {
|
||||
entity.setComponent(dto);
|
||||
}
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
public AccessPolicyEntity createAccessPolicyEntity(final AccessPolicyDTO dto, final RevisionDTO revision, final AccessPolicyDTO accessPolicy) {
|
||||
final AccessPolicyEntity entity = new AccessPolicyEntity();
|
||||
entity.setRevision(revision);
|
||||
if (dto != null) {
|
||||
entity.setAccessPolicy(accessPolicy);
|
||||
entity.setId(dto.getId());
|
||||
|
||||
if (accessPolicy != null && accessPolicy.getCanRead()) {
|
||||
entity.setComponent(dto);
|
||||
}
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
public FunnelEntity createFunnelEntity(final FunnelDTO dto, final RevisionDTO revision, final AccessPolicyDTO accessPolicy) {
|
||||
final FunnelEntity entity = new FunnelEntity();
|
||||
entity.setRevision(revision);
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.web.dao;
|
||||
|
||||
import org.apache.nifi.authorization.AccessPolicy;
|
||||
import org.apache.nifi.web.api.dto.AccessPolicyDTO;
|
||||
|
||||
public interface AccessPolicyDAO {
|
||||
|
||||
/**
|
||||
* @param accessPolicyId access policy ID
|
||||
* @return Determines if the specified access policy exists
|
||||
*/
|
||||
boolean hasAccessPolicy(String accessPolicyId);
|
||||
|
||||
/**
|
||||
* Creates an access policy.
|
||||
*
|
||||
* @param accessPolicyDTO The access policy DTO
|
||||
* @return The access policy transfer object
|
||||
*/
|
||||
AccessPolicy createAccessPolicy(AccessPolicyDTO accessPolicyDTO);
|
||||
|
||||
/**
|
||||
* Gets the acess policy with the specified ID.
|
||||
*
|
||||
* @param accessPolicyId The access policy ID
|
||||
* @return The access policy transfer object
|
||||
*/
|
||||
AccessPolicy getAccessPolicy(String accessPolicyId);
|
||||
|
||||
/**
|
||||
* Updates the specified access policy.
|
||||
*
|
||||
* @param accessPolicyDTO The access policy DTO
|
||||
* @return The access policy transfer object
|
||||
*/
|
||||
AccessPolicy updateAccessPolicy(AccessPolicyDTO accessPolicyDTO);
|
||||
|
||||
/**
|
||||
* Deletes the specified access policy.
|
||||
*
|
||||
* @param accessPolicyId The access policy ID
|
||||
* @return The access policy transfer object of the deleted access policy
|
||||
*/
|
||||
AccessPolicy deleteAccessPolicy(String accessPolicyId);
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.web.dao;
|
||||
|
||||
import org.apache.nifi.authorization.User;
|
||||
import org.apache.nifi.web.api.dto.UserDTO;
|
||||
|
||||
public interface UserDAO {
|
||||
|
||||
/**
|
||||
* @param userId user ID
|
||||
* @return Determines if the specified user exists
|
||||
*/
|
||||
boolean hasUser(String userId);
|
||||
|
||||
/**
|
||||
* Creates a user.
|
||||
*
|
||||
* @param userDTO The user DTO
|
||||
* @return The user transfer object
|
||||
*/
|
||||
User createUser(UserDTO userDTO);
|
||||
|
||||
/**
|
||||
* Gets the user with the specified ID.
|
||||
*
|
||||
* @param userId The user ID
|
||||
* @return The user transfer object
|
||||
*/
|
||||
User getUser(String userId);
|
||||
|
||||
/**
|
||||
* Updates the specified user.
|
||||
*
|
||||
* @param userDTO The user DTO
|
||||
* @return The user transfer object
|
||||
*/
|
||||
User updateUser(UserDTO userDTO);
|
||||
|
||||
/**
|
||||
* Deletes the specified user.
|
||||
*
|
||||
* @param userId The user ID
|
||||
* @return The user transfer object of the deleted user
|
||||
*/
|
||||
User deleteUser(String userId);
|
||||
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.web.dao;
|
||||
|
||||
import org.apache.nifi.authorization.Group;
|
||||
import org.apache.nifi.web.api.dto.UserGroupDTO;
|
||||
|
||||
public interface UserGroupDAO {
|
||||
|
||||
/**
|
||||
* @param userGroupId user group ID
|
||||
* @return Determines if the specified user group exists
|
||||
*/
|
||||
boolean hasUserGroup(String userGroupId);
|
||||
|
||||
/**
|
||||
* Creates a user group.
|
||||
*
|
||||
* @param userGroupDTO The user group DTO
|
||||
* @return The user group transfer object
|
||||
*/
|
||||
Group createUserGroup(UserGroupDTO userGroupDTO);
|
||||
|
||||
/**
|
||||
* Gets the user group with the specified ID.
|
||||
*
|
||||
* @param userGroupId The user group ID
|
||||
* @return The user group transfer object
|
||||
*/
|
||||
Group getUserGroup(String userGroupId);
|
||||
|
||||
/**
|
||||
* Updates the specified user group.
|
||||
*
|
||||
* @param userGroupDTO The user group DTO
|
||||
* @return The user group transfer object
|
||||
*/
|
||||
Group updateUserGroup(UserGroupDTO userGroupDTO);
|
||||
|
||||
/**
|
||||
* Deletes the specified user group.
|
||||
*
|
||||
* @param userGroupId The user group ID
|
||||
* @return The user group transfer object of the deleted user group
|
||||
*/
|
||||
Group deleteUserGroup(String userGroupId);
|
||||
|
||||
}
|
|
@ -0,0 +1,255 @@
|
|||
/*
|
||||
* 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.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.AuthorizerConfigurationContext;
|
||||
import org.apache.nifi.authorization.AuthorizerInitializationContext;
|
||||
import org.apache.nifi.authorization.Group;
|
||||
import org.apache.nifi.authorization.RequestAction;
|
||||
import org.apache.nifi.authorization.User;
|
||||
import org.apache.nifi.authorization.UsersAndAccessPolicies;
|
||||
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.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.ComponentEntity;
|
||||
import org.apache.nifi.web.dao.AccessPolicyDAO;
|
||||
import org.apache.nifi.web.dao.UserDAO;
|
||||
import org.apache.nifi.web.dao.UserGroupDAO;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class StandardPolicyBasedAuthorizerDAO implements AccessPolicyDAO, UserGroupDAO, UserDAO {
|
||||
|
||||
private static final String MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER = "authorizer is not of type AbstractPolicyBasedAuthorizer";
|
||||
private final AbstractPolicyBasedAuthorizer authorizer;
|
||||
|
||||
public StandardPolicyBasedAuthorizerDAO(final Authorizer authorizer) {
|
||||
if (authorizer instanceof AbstractPolicyBasedAuthorizer) {
|
||||
this.authorizer = (AbstractPolicyBasedAuthorizer) authorizer;
|
||||
} else {
|
||||
this.authorizer = new AbstractPolicyBasedAuthorizer() {
|
||||
@Override
|
||||
public Group addGroup(final Group group) throws AuthorizationAccessException {
|
||||
throw new IllegalStateException(MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Group getGroup(final String identifier) throws AuthorizationAccessException {
|
||||
throw new IllegalStateException(MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Group updateGroup(final Group group) throws AuthorizationAccessException {
|
||||
throw new IllegalStateException(MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Group deleteGroup(final Group group) throws AuthorizationAccessException {
|
||||
throw new IllegalStateException(MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Group> getGroups() throws AuthorizationAccessException {
|
||||
throw new IllegalStateException(MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User addUser(final User user) throws AuthorizationAccessException {
|
||||
throw new IllegalStateException(MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getUser(final String identifier) throws AuthorizationAccessException {
|
||||
throw new IllegalStateException(MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getUserByIdentity(final String identity) throws AuthorizationAccessException {
|
||||
throw new IllegalStateException(MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User updateUser(final User user) throws AuthorizationAccessException {
|
||||
throw new IllegalStateException(MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User deleteUser(final User user) throws AuthorizationAccessException {
|
||||
throw new IllegalStateException(MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<User> getUsers() throws AuthorizationAccessException {
|
||||
throw new IllegalStateException(MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccessPolicy addAccessPolicy(final AccessPolicy accessPolicy) throws AuthorizationAccessException {
|
||||
throw new IllegalStateException(MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccessPolicy getAccessPolicy(final String identifier) throws AuthorizationAccessException {
|
||||
throw new IllegalStateException(MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccessPolicy updateAccessPolicy(final AccessPolicy accessPolicy) throws AuthorizationAccessException {
|
||||
throw new IllegalStateException(MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccessPolicy deleteAccessPolicy(final AccessPolicy policy) throws AuthorizationAccessException {
|
||||
throw new IllegalStateException(MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<AccessPolicy> getAccessPolicies() throws AuthorizationAccessException {
|
||||
throw new IllegalStateException(MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UsersAndAccessPolicies getUsersAndAccessPolicies() throws AuthorizationAccessException {
|
||||
throw new IllegalStateException(MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(final AuthorizerInitializationContext initializationContext) throws AuthorizerCreationException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigured(final AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preDestruction() throws AuthorizerDestructionException {
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAccessPolicy(final String accessPolicyId) {
|
||||
return authorizer.getAccessPolicy(accessPolicyId) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccessPolicy createAccessPolicy(final AccessPolicyDTO accessPolicyDTO) {
|
||||
return authorizer.addAccessPolicy(buildAccessPolicy(accessPolicyDTO));
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccessPolicy getAccessPolicy(final String accessPolicyId) {
|
||||
return authorizer.getAccessPolicy(accessPolicyId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccessPolicy updateAccessPolicy(final AccessPolicyDTO accessPolicyDTO) {
|
||||
return authorizer.updateAccessPolicy(buildAccessPolicy(accessPolicyDTO));
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccessPolicy deleteAccessPolicy(final String accessPolicyId) {
|
||||
return authorizer.deleteAccessPolicy(authorizer.getAccessPolicy(accessPolicyId));
|
||||
}
|
||||
|
||||
private AccessPolicy buildAccessPolicy(final AccessPolicyDTO accessPolicyDTO) {
|
||||
final AccessPolicy.Builder builder = new AccessPolicy.Builder()
|
||||
.identifier(accessPolicyDTO.getId())
|
||||
.addGroups(accessPolicyDTO.getUserGroups().stream().map(ComponentEntity::getId).collect(Collectors.toSet()))
|
||||
.addUsers(accessPolicyDTO.getUsers().stream().map(ComponentEntity::getId).collect(Collectors.toSet()))
|
||||
.resource(accessPolicyDTO.getResource());
|
||||
if (accessPolicyDTO.getCanRead()) {
|
||||
builder.addAction(RequestAction.READ);
|
||||
}
|
||||
if (accessPolicyDTO.getCanWrite()) {
|
||||
builder.addAction(RequestAction.WRITE);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasUserGroup(final String userGroupId) {
|
||||
return authorizer.getGroup(userGroupId) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Group createUserGroup(final UserGroupDTO userGroupDTO) {
|
||||
return authorizer.addGroup(buildUserGroup(userGroupDTO));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Group getUserGroup(final String userGroupId) {
|
||||
return authorizer.getGroup(userGroupId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Group updateUserGroup(final UserGroupDTO userGroupDTO) {
|
||||
return authorizer.updateGroup(buildUserGroup(userGroupDTO));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Group deleteUserGroup(final String userGroupId) {
|
||||
return authorizer.deleteGroup(authorizer.getGroup(userGroupId));
|
||||
}
|
||||
|
||||
private Group buildUserGroup(final UserGroupDTO userGroupDTO) {
|
||||
return new Group.Builder()
|
||||
.addUsers(userGroupDTO.getUsers().stream().map(ComponentEntity::getId).collect(Collectors.toSet()))
|
||||
.identifier(userGroupDTO.getId()).name(userGroupDTO.getName()).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasUser(final String userId) {
|
||||
return authorizer.getUser(userId) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public User createUser(final UserDTO userDTO) {
|
||||
final User user = buildUser(userDTO);
|
||||
return authorizer.addUser(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getUser(final String userId) {
|
||||
return authorizer.getUser(userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User updateUser(final UserDTO userDTO) {
|
||||
return authorizer.updateUser(buildUser(userDTO));
|
||||
}
|
||||
|
||||
@Override
|
||||
public User deleteUser(final String userId) {
|
||||
return authorizer.deleteUser(authorizer.getUser(userId));
|
||||
}
|
||||
|
||||
private User buildUser(final UserDTO userDTO) {
|
||||
return new User.Builder()
|
||||
.addGroups(userDTO.getGroups().stream().map(ComponentEntity::getId).collect(Collectors.toSet()))
|
||||
.identifier(userDTO.getIdentity()).identity(userDTO.getIdentity()).build();
|
||||
}
|
||||
|
||||
}
|
|
@ -108,6 +108,9 @@
|
|||
<property name="flowController" ref="flowController"/>
|
||||
<property name="snippetUtils" ref="snippetUtils"/>
|
||||
</bean>
|
||||
<bean id="policyBasedAuthorizerDAO" class="org.apache.nifi.web.dao.impl.StandardPolicyBasedAuthorizerDAO">
|
||||
<constructor-arg ref="authorizer"/>
|
||||
</bean>
|
||||
<bean id="controllerFacade" class="org.apache.nifi.web.controller.ControllerFacade">
|
||||
<property name="properties" ref="nifiProperties"/>
|
||||
<property name="flowController" ref="flowController"/>
|
||||
|
@ -117,7 +120,24 @@
|
|||
<property name="dtoFactory" ref="dtoFactory"/>
|
||||
<property name="bulletinRepository" ref="bulletinRepository"/>
|
||||
</bean>
|
||||
<bean id="authorizableLookup" class="org.apache.nifi.web.StandardAuthorizableLookup">
|
||||
<property name="controllerFacade" ref="controllerFacade"/>
|
||||
<property name="processorDAO" ref="processorDAO"/>
|
||||
<property name="inputPortDAO" ref="inputPortDAO"/>
|
||||
<property name="outputPortDAO" ref="outputPortDAO"/>
|
||||
<property name="processGroupDAO" ref="processGroupDAO"/>
|
||||
<property name="remoteProcessGroupDAO" ref="remoteProcessGroupDAO"/>
|
||||
<property name="labelDAO" ref="labelDAO"/>
|
||||
<property name="funnelDAO" ref="funnelDAO"/>
|
||||
<property name="connectionDAO" ref="connectionDAO"/>
|
||||
<property name="controllerServiceDAO" ref="controllerServiceDAO"/>
|
||||
<property name="reportingTaskDAO" ref="reportingTaskDAO"/>
|
||||
<property name="templateDAO" ref="templateDAO"/>
|
||||
<property name="snippetDAO" ref="snippetDAO"/>
|
||||
<property name="accessPolicyDAO" ref="policyBasedAuthorizerDAO"/>
|
||||
</bean>
|
||||
<bean id="serviceFacade" class="org.apache.nifi.web.StandardNiFiServiceFacade">
|
||||
<property name="authorizableLookup" ref="authorizableLookup" />
|
||||
<property name="properties" ref="nifiProperties"/>
|
||||
<property name="authorizer" ref="authorizer"/>
|
||||
<property name="controllerFacade" ref="controllerFacade"/>
|
||||
|
@ -133,6 +153,9 @@
|
|||
<property name="reportingTaskDAO" ref="reportingTaskDAO"/>
|
||||
<property name="templateDAO" ref="templateDAO"/>
|
||||
<property name="snippetDAO" ref="snippetDAO"/>
|
||||
<property name="accessPolicyDAO" ref="policyBasedAuthorizerDAO"/>
|
||||
<property name="userGroupDAO" ref="policyBasedAuthorizerDAO"/>
|
||||
<property name="userDAO" ref="policyBasedAuthorizerDAO"/>
|
||||
<property name="auditService" ref="auditService"/>
|
||||
<property name="keyService" ref="keyService"/>
|
||||
<property name="snippetUtils" ref="snippetUtils"/>
|
||||
|
@ -342,6 +365,27 @@
|
|||
<property name="clusterCoordinator" ref="clusterCoordinator"/>
|
||||
<property name="requestReplicator" ref="requestReplicator" />
|
||||
</bean>
|
||||
<bean id="accessPolicyResource" class="org.apache.nifi.web.api.AccessPolicyResource" scope="singleton">
|
||||
<constructor-arg ref="serviceFacade"/>
|
||||
<constructor-arg ref="authorizer"/>
|
||||
<constructor-arg ref="nifiProperties"/>
|
||||
<constructor-arg ref="clusterCoordinator"/>
|
||||
<constructor-arg ref="requestReplicator" />
|
||||
</bean>
|
||||
<bean id="userGroupsResource" class="org.apache.nifi.web.api.UserGroupsResource" scope="singleton">
|
||||
<constructor-arg ref="serviceFacade"/>
|
||||
<constructor-arg ref="authorizer"/>
|
||||
<constructor-arg ref="nifiProperties"/>
|
||||
<constructor-arg ref="clusterCoordinator"/>
|
||||
<constructor-arg ref="requestReplicator" />
|
||||
</bean>
|
||||
<bean id="usersResource" class="org.apache.nifi.web.api.UsersResource" scope="singleton">
|
||||
<constructor-arg ref="serviceFacade"/>
|
||||
<constructor-arg ref="authorizer"/>
|
||||
<constructor-arg ref="nifiProperties"/>
|
||||
<constructor-arg ref="clusterCoordinator"/>
|
||||
<constructor-arg ref="requestReplicator" />
|
||||
</bean>
|
||||
|
||||
<!-- configuration for jaxb serialization -->
|
||||
<bean class="org.apache.nifi.web.util.ObjectMapperResolver" scope="singleton"/>
|
||||
|
|
|
@ -0,0 +1,896 @@
|
|||
/*
|
||||
* 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.web
|
||||
|
||||
import org.apache.nifi.authorization.*
|
||||
import org.apache.nifi.authorization.resource.Authorizable
|
||||
import org.apache.nifi.authorization.resource.ResourceFactory
|
||||
import org.apache.nifi.authorization.user.NiFiUser
|
||||
import org.apache.nifi.controller.service.ControllerServiceProvider
|
||||
import org.apache.nifi.web.api.dto.*
|
||||
import org.apache.nifi.web.api.entity.UserEntity
|
||||
import org.apache.nifi.web.controller.ControllerFacade
|
||||
import org.apache.nifi.web.dao.AccessPolicyDAO
|
||||
import org.apache.nifi.web.dao.UserDAO
|
||||
import org.apache.nifi.web.dao.UserGroupDAO
|
||||
import org.apache.nifi.web.revision.*
|
||||
import spock.lang.Specification
|
||||
import spock.lang.Unroll
|
||||
|
||||
class StandardNiFiServiceFacadeSpec extends Specification {
|
||||
|
||||
@Unroll
|
||||
def "CreateUser: isAuthorized: #isAuthorized"() {
|
||||
given:
|
||||
def userDao = Mock UserDAO
|
||||
def entityFactory = new EntityFactory()
|
||||
def dtoFactory = new DtoFactory()
|
||||
def authorizableLookup = Mock AuthorizableLookup
|
||||
def niFiServiceFacade = new StandardNiFiServiceFacade()
|
||||
niFiServiceFacade.setAuthorizableLookup authorizableLookup
|
||||
niFiServiceFacade.setDtoFactory dtoFactory
|
||||
niFiServiceFacade.setUserDAO userDao
|
||||
niFiServiceFacade.setEntityFactory entityFactory
|
||||
def newUser = new User.Builder().identifier(userDto.id).identity(userDto.identity).build()
|
||||
|
||||
when:
|
||||
def userEntity = niFiServiceFacade.createUser(new Revision(0L, 'client-1'), userDto)
|
||||
|
||||
then:
|
||||
1 * userDao.createUser(_) >> newUser
|
||||
1 * authorizableLookup.getUsersAuthorizable() >> new SimpleAuthorizable(parentAuthorizable, resource, isAuthorized, authorizationResult)
|
||||
0 * _
|
||||
userEntity != null
|
||||
if (isAuthorized) {
|
||||
assert userEntity?.component?.id == userDto.id
|
||||
assert userEntity?.component?.identity?.equals(userDto.identity)
|
||||
assert userEntity?.accessPolicy?.canRead
|
||||
assert userEntity?.accessPolicy?.canWrite
|
||||
} else {
|
||||
assert userEntity.component == null
|
||||
}
|
||||
|
||||
|
||||
where:
|
||||
userDto | parentAuthorizable | resource | isAuthorized | authorizationResult
|
||||
createUserDTO() | null | ResourceFactory.usersResource | true | AuthorizationResult.approved()
|
||||
createUserDTO() | null | ResourceFactory.usersResource | false | AuthorizationResult.denied()
|
||||
}
|
||||
|
||||
@Unroll
|
||||
def "GetUser: isAuthorized: #isAuthorized"() {
|
||||
given:
|
||||
def userDao = Mock UserDAO
|
||||
def revisionManager = Mock RevisionManager
|
||||
def authorizableLookup = Mock AuthorizableLookup
|
||||
def dtoFactory = new DtoFactory()
|
||||
def entityFactory = new EntityFactory()
|
||||
def niFiServiceFacade = new StandardNiFiServiceFacade()
|
||||
niFiServiceFacade.setAuthorizableLookup authorizableLookup
|
||||
niFiServiceFacade.setRevisionManager revisionManager
|
||||
niFiServiceFacade.setDtoFactory dtoFactory
|
||||
niFiServiceFacade.setEntityFactory entityFactory
|
||||
niFiServiceFacade.setUserDAO userDao
|
||||
def requestedUser = new User.Builder().identifier(userDto.id).identity(userDto.identity).build()
|
||||
def exception = null
|
||||
def userEntity = null
|
||||
|
||||
when:
|
||||
try {
|
||||
userEntity = niFiServiceFacade.getUser(userDto.id, true)
|
||||
} catch (AccessDeniedException e) {
|
||||
exception = e
|
||||
}
|
||||
|
||||
then:
|
||||
if (isAuthorized) {
|
||||
1 * userDao.getUser(userDto.id) >> requestedUser
|
||||
}
|
||||
1 * revisionManager.get(_, _) >> { String id, ReadOnlyRevisionCallback callback ->
|
||||
callback.withRevision(new Revision(1L, 'client1', 'root'))
|
||||
}
|
||||
1 * authorizableLookup.getUsersAuthorizable() >> new SimpleAuthorizable(null, ResourceFactory.getUsersResource(),
|
||||
isAuthorized, authorizationResult)
|
||||
0 * _
|
||||
if (isAuthorized) {
|
||||
assert userEntity?.component?.id?.equals(userDto.id)
|
||||
} else {
|
||||
assert exception instanceof AccessDeniedException
|
||||
}
|
||||
|
||||
where:
|
||||
userDto | isAuthorized | authorizationResult
|
||||
createUserDTO() | true | AuthorizationResult.approved()
|
||||
createUserDTO() | false | AuthorizationResult.denied()
|
||||
}
|
||||
|
||||
@Unroll
|
||||
def "UpdateUser: isAuthorized: #isAuthorized, policy exists: #userExists"() {
|
||||
given:
|
||||
def userDao = Mock UserDAO
|
||||
def revisionManager = Mock RevisionManager
|
||||
def entityFactory = new EntityFactory()
|
||||
def dtoFactory = new DtoFactory()
|
||||
def authorizableLookup = Mock AuthorizableLookup
|
||||
def controllerFacade = Mock ControllerFacade
|
||||
def niFiServiceFacade = new StandardNiFiServiceFacade()
|
||||
niFiServiceFacade.setAuthorizableLookup authorizableLookup
|
||||
niFiServiceFacade.setRevisionManager revisionManager
|
||||
niFiServiceFacade.setDtoFactory dtoFactory
|
||||
niFiServiceFacade.setUserDAO userDao
|
||||
niFiServiceFacade.setEntityFactory entityFactory
|
||||
niFiServiceFacade.setControllerFacade controllerFacade
|
||||
def user = new User.Builder().identifier(userDto.id).identity(userDto.identity).build()
|
||||
|
||||
when:
|
||||
def userEntityUpdateResult = niFiServiceFacade.updateUser(currentRevision, userDto)
|
||||
|
||||
then:
|
||||
1 * userDao.hasUser(userDto.id) >> userExists
|
||||
if (!userExists) {
|
||||
1 * userDao.createUser(userDto) >> user
|
||||
} else {
|
||||
1 * controllerFacade.save()
|
||||
1 * userDao.updateUser(userDto) >> user
|
||||
1 * revisionManager.updateRevision(_, _, _) >> { RevisionClaim revisionClaim, NiFiUser niFiUser, UpdateRevisionTask callback ->
|
||||
callback.update()
|
||||
}
|
||||
}
|
||||
1 * authorizableLookup.getUsersAuthorizable() >> new SimpleAuthorizable(null, ResourceFactory.getUsersResource(),
|
||||
isAuthorized, authorizationResult)
|
||||
0 * _
|
||||
userEntityUpdateResult != null
|
||||
def userEntity = userEntityUpdateResult?.result
|
||||
if (isAuthorized) {
|
||||
assert userEntity?.component?.id?.equals(userDto.id)
|
||||
assert userEntity?.accessPolicy?.canRead
|
||||
assert userEntity?.accessPolicy?.canWrite
|
||||
} else {
|
||||
assert userEntity.component == null
|
||||
}
|
||||
|
||||
where:
|
||||
userExists | currentRevision | userDto | isAuthorized | authorizationResult
|
||||
false | new Revision(0L, 'client1', 'root') | createUserDTO() | true | AuthorizationResult.approved()
|
||||
true | new Revision(1L, 'client1', 'root') | createUserDTO() | true | AuthorizationResult.approved()
|
||||
false | new Revision(0L, 'client1', 'root') | createUserDTO() | false | AuthorizationResult.denied()
|
||||
true | new Revision(1L, 'client1', 'root') | createUserDTO() | false | AuthorizationResult.denied()
|
||||
}
|
||||
|
||||
@Unroll
|
||||
def "DeleteUser: isAuthorized: #isAuthorized, user exists: #userExists"() {
|
||||
given:
|
||||
def userDao = Mock UserDAO
|
||||
def revisionManager = Mock RevisionManager
|
||||
def authorizableLookup = Mock AuthorizableLookup
|
||||
def dtoFactory = new DtoFactory()
|
||||
def entityFactory = new EntityFactory()
|
||||
def controllerFacade = Mock ControllerFacade
|
||||
def niFiServiceFacade = new StandardNiFiServiceFacade()
|
||||
niFiServiceFacade.setAuthorizableLookup authorizableLookup
|
||||
niFiServiceFacade.setRevisionManager revisionManager
|
||||
niFiServiceFacade.setDtoFactory dtoFactory
|
||||
niFiServiceFacade.setEntityFactory entityFactory
|
||||
niFiServiceFacade.setUserDAO userDao
|
||||
niFiServiceFacade.setControllerFacade controllerFacade
|
||||
def user = new User.Builder().identifier(userDto.id).identity(userDto.identity).build()
|
||||
|
||||
when:
|
||||
def userEntity = niFiServiceFacade.deleteUser(currentRevision, userDto.id)
|
||||
|
||||
then:
|
||||
if (userExists) {
|
||||
1 * userDao.getUser(userDto.id) >> user
|
||||
1 * userDao.deleteUser(userDto.id) >> user
|
||||
} else {
|
||||
1 * userDao.getUser(userDto.id) >> null
|
||||
1 * userDao.deleteUser(userDto.id) >> null
|
||||
}
|
||||
1 * controllerFacade.save()
|
||||
1 * revisionManager.deleteRevision(_, _, _) >> { RevisionClaim revisionClaim, NiFiUser nifiUser, DeleteRevisionTask task ->
|
||||
task.performTask()
|
||||
}
|
||||
1 * authorizableLookup.getUsersAuthorizable() >> new SimpleAuthorizable(null, ResourceFactory.usersResource,
|
||||
isAuthorized, authorizationResult)
|
||||
0 * _
|
||||
userEntity?.component?.id == null
|
||||
if (userExists) {
|
||||
assert userEntity?.id?.equals(userDto.id)
|
||||
} else {
|
||||
assert userEntity?.id == null
|
||||
}
|
||||
|
||||
where:
|
||||
userExists | currentRevision | userDto | isAuthorized | authorizationResult
|
||||
true | new Revision(1L, 'client1') | createUserDTO() | true | AuthorizationResult.approved()
|
||||
false | null | createUserDTO() | true | AuthorizationResult.approved()
|
||||
true | new Revision(1L, 'client1') | createUserDTO() | false | AuthorizationResult.denied()
|
||||
false | null | createUserDTO() | false | AuthorizationResult.denied()
|
||||
}
|
||||
|
||||
@Unroll
|
||||
def "CreateUserGroup: isAuthorized: #isAuthorized"() {
|
||||
given:
|
||||
def userGroupDao = Mock UserGroupDAO
|
||||
def userDao = Mock UserDAO
|
||||
def revisionManager = Mock RevisionManager
|
||||
def controllerServiceProvider = Mock ControllerServiceProvider
|
||||
def entityFactory = new EntityFactory()
|
||||
def dtoFactory = new DtoFactory()
|
||||
dtoFactory.setControllerServiceProvider controllerServiceProvider
|
||||
dtoFactory.setEntityFactory entityFactory
|
||||
def authorizableLookup = Mock AuthorizableLookup
|
||||
def controllerFacade = Mock ControllerFacade
|
||||
def niFiServiceFacade = new StandardNiFiServiceFacade()
|
||||
niFiServiceFacade.setAuthorizableLookup authorizableLookup
|
||||
niFiServiceFacade.setRevisionManager revisionManager
|
||||
niFiServiceFacade.setDtoFactory dtoFactory
|
||||
niFiServiceFacade.setUserGroupDAO userGroupDao
|
||||
niFiServiceFacade.setUserDAO userDao
|
||||
niFiServiceFacade.setEntityFactory entityFactory
|
||||
niFiServiceFacade.setControllerFacade controllerFacade
|
||||
def newUserGroup = new Group.Builder().identifier(userGroupDto.id).name(userGroupDto.name).addUsers(userGroupDto.users.collect { it.id } as Set).build()
|
||||
def exception = null
|
||||
def userGroupEntity = null
|
||||
|
||||
when:
|
||||
try {
|
||||
userGroupEntity = niFiServiceFacade.createUserGroup(new Revision(0L, 'client-1'), userGroupDto)
|
||||
} catch (AccessDeniedException e) {
|
||||
exception = e
|
||||
}
|
||||
|
||||
then:
|
||||
if (isAuthorized) {
|
||||
1 * authorizableLookup.getUserGroupsAuthorizable() >>
|
||||
new SimpleAuthorizable(null, ResourceFactory.userGroupsResource, isAuthorized, authorizationResult.get(ResourceFactory.userGroupsResource))
|
||||
}
|
||||
1 * authorizableLookup.getUsersAuthorizable() >> new SimpleAuthorizable(null, ResourceFactory.usersResource, isAuthorized, authorizationResult.get(ResourceFactory.usersResource))
|
||||
1 * userGroupDao.createUserGroup(_) >> newUserGroup
|
||||
if (authorizationResult.get(ResourceFactory.usersResource) == AuthorizationResult.approved()) {
|
||||
1 * userDao.getUser(_) >> { String userId ->
|
||||
def userEntity = userGroupDto.users.find { it.id.equals(userId) }?.component
|
||||
assert userEntity != null
|
||||
new User.Builder().identifier(userEntity.id).identity(userEntity.identity)
|
||||
.addGroups(userEntity.groups.collect { it.id } as Set)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
userGroupDto.users.size() * revisionManager.get(_, _) >> { String id, ReadOnlyRevisionCallback callback ->
|
||||
assert userGroupDto.users.collect { it.id }.contains(id)
|
||||
def revisionDTO = userGroupDto.users.find { it.id.equals(id) }.revision
|
||||
callback.withRevision new Revision(revisionDTO.version, revisionDTO.clientId, id)
|
||||
}
|
||||
0 * _
|
||||
if (isAuthorized) {
|
||||
assert userGroupEntity?.component?.id == userGroupDto.id
|
||||
assert userGroupEntity?.component?.users?.equals(userGroupDto.users)
|
||||
assert userGroupEntity?.accessPolicy?.canRead
|
||||
assert userGroupEntity?.accessPolicy?.canWrite
|
||||
} else {
|
||||
assert userGroupEntity?.component == null
|
||||
assert exception instanceof AccessDeniedException
|
||||
}
|
||||
|
||||
|
||||
where: // TODO add more use cases, specifically with varied authorization results, and the assertions to check them, to all spec methods that use AuthorizationResult
|
||||
userGroupDto | isAuthorized | authorizationResult
|
||||
createUserGroupDTO() | true | [(ResourceFactory.userGroupsResource): AuthorizationResult.approved(), (ResourceFactory.usersResource): AuthorizationResult.approved()]
|
||||
createUserGroupDTO() | false | [(ResourceFactory.userGroupsResource): AuthorizationResult.denied(), (ResourceFactory.usersResource): AuthorizationResult.denied()]
|
||||
}
|
||||
|
||||
@Unroll
|
||||
def "GetUserGroup: isAuthorized: #isAuthorized"() {
|
||||
given:
|
||||
def userGroupDao = Mock UserGroupDAO
|
||||
def userDao = Mock UserDAO
|
||||
def revisionManager = Mock RevisionManager
|
||||
def authorizableLookup = Mock AuthorizableLookup
|
||||
def dtoFactory = new DtoFactory()
|
||||
def entityFactory = new EntityFactory()
|
||||
def niFiServiceFacade = new StandardNiFiServiceFacade()
|
||||
niFiServiceFacade.setAuthorizableLookup authorizableLookup
|
||||
niFiServiceFacade.setRevisionManager revisionManager
|
||||
niFiServiceFacade.setDtoFactory dtoFactory
|
||||
niFiServiceFacade.setEntityFactory entityFactory
|
||||
niFiServiceFacade.setUserGroupDAO userGroupDao
|
||||
niFiServiceFacade.setUserDAO userDao
|
||||
def requestedUserGroup = new Group.Builder().identifier(userGroupDto.id).name(userGroupDto.name)
|
||||
.addUsers(userGroupDto.users.collect { it.id } as Set).build()
|
||||
def exception = null
|
||||
def userGroupEntity = null
|
||||
|
||||
when:
|
||||
try {
|
||||
userGroupEntity = niFiServiceFacade.getUserGroup(userGroupDto.id, true)
|
||||
} catch (AccessDeniedException e) {
|
||||
exception = e
|
||||
}
|
||||
|
||||
then:
|
||||
if (isAuthorized) {
|
||||
1 * userGroupDao.getUserGroup(userGroupDto.id) >> requestedUserGroup
|
||||
1 * authorizableLookup.getUsersAuthorizable() >> new SimpleAuthorizable(null, ResourceFactory.usersResource, isAuthorized, authorizationResult)
|
||||
}
|
||||
1 * authorizableLookup.getUserGroupsAuthorizable() >> new SimpleAuthorizable(null, ResourceFactory.getUserGroupsResource(),
|
||||
isAuthorized, authorizationResult)
|
||||
_ * revisionManager.get(_, _) >> { String id, ReadOnlyRevisionCallback callback ->
|
||||
callback.withRevision(new Revision(1L, 'client1', 'root'))
|
||||
}
|
||||
if (authorizationResult == AuthorizationResult.approved()) {
|
||||
1 * userDao.getUser(_) >> { String userId ->
|
||||
def userEntity = userGroupDto.users.find { it.id.equals(userId) }?.component
|
||||
assert userEntity != null
|
||||
new User.Builder().identifier(userEntity.id).identity(userEntity.identity).build()
|
||||
}
|
||||
}
|
||||
0 * _
|
||||
if (isAuthorized) {
|
||||
assert userGroupEntity?.component?.id?.equals(userGroupDto.id)
|
||||
} else {
|
||||
assert exception instanceof AccessDeniedException
|
||||
}
|
||||
|
||||
where:
|
||||
userGroupDto | isAuthorized | authorizationResult
|
||||
new UserGroupDTO(id: '1', name: 'test group', users: [createUserEntity()]) | true | AuthorizationResult.approved()
|
||||
new UserGroupDTO(id: '1', name: 'test group', users: [createUserEntity()]) | false | AuthorizationResult.denied()
|
||||
}
|
||||
|
||||
@Unroll
|
||||
def "UpdateUserGroup: isAuthorized: #isAuthorized, userGroupExists exists: #userGroupExists"() {
|
||||
given:
|
||||
def userGroupDao = Mock UserGroupDAO
|
||||
def userDao = Mock UserDAO
|
||||
def revisionManager = Mock RevisionManager
|
||||
def entityFactory = new EntityFactory()
|
||||
def dtoFactory = new DtoFactory()
|
||||
def authorizableLookup = Mock AuthorizableLookup
|
||||
def controllerFacade = Mock ControllerFacade
|
||||
def niFiServiceFacade = new StandardNiFiServiceFacade()
|
||||
niFiServiceFacade.setAuthorizableLookup authorizableLookup
|
||||
niFiServiceFacade.setRevisionManager revisionManager
|
||||
niFiServiceFacade.setDtoFactory dtoFactory
|
||||
niFiServiceFacade.setUserGroupDAO userGroupDao
|
||||
niFiServiceFacade.setEntityFactory entityFactory
|
||||
niFiServiceFacade.setControllerFacade controllerFacade
|
||||
niFiServiceFacade.setUserDAO userDao
|
||||
def userGroup = new Group.Builder().identifier(userGroupDto.id).name(userGroupDto.name)
|
||||
.addUsers(userGroupDto.users.collect { it.id } as Set).build()
|
||||
def userGroupsEntityUpdateResult = null
|
||||
def exception = null
|
||||
|
||||
when:
|
||||
try {
|
||||
userGroupsEntityUpdateResult = niFiServiceFacade.updateUserGroup(currentRevision, userGroupDto)
|
||||
} catch (AccessDeniedException e) {
|
||||
exception = e
|
||||
}
|
||||
|
||||
then:
|
||||
1 * userGroupDao.hasUserGroup(userGroupDto.id) >> userGroupExists
|
||||
if (!userGroupExists) {
|
||||
1 * userGroupDao.createUserGroup(userGroupDto) >> userGroup
|
||||
1 * authorizableLookup.getUsersAuthorizable() >> new SimpleAuthorizable(null, ResourceFactory.getUsersResource(),
|
||||
isAuthorized, authorizationResult.get(ResourceFactory.getUsersResource()))
|
||||
} else {
|
||||
1 * controllerFacade.save()
|
||||
1 * userGroupDao.updateUserGroup(userGroupDto) >> userGroup
|
||||
1 * revisionManager.updateRevision(_, _, _) >> { RevisionClaim revisionClaim, NiFiUser niFiUser, UpdateRevisionTask callback ->
|
||||
callback.update()
|
||||
}
|
||||
1 * authorizableLookup.getUsersAuthorizable() >> new SimpleAuthorizable(null, ResourceFactory.usersResource,
|
||||
isAuthorized, authorizationResult.get(ResourceFactory.usersResource))
|
||||
}
|
||||
if (isAuthorized || userGroupExists) {
|
||||
1 * authorizableLookup.getUserGroupsAuthorizable() >> new SimpleAuthorizable(null, ResourceFactory.userGroupsResource,
|
||||
isAuthorized, authorizationResult.get(ResourceFactory.userGroupsResource))
|
||||
}
|
||||
_ * revisionManager.get(_, _) >> { String id, ReadOnlyRevisionCallback callback ->
|
||||
callback.withRevision(new Revision(1L, 'client1', 'root'))
|
||||
}
|
||||
if (authorizationResult.get(ResourceFactory.userGroupsResource) == AuthorizationResult.approved()) {
|
||||
1 * userDao.getUser(_) >> { String userId ->
|
||||
def userEntity = userGroupDto.users.find { it.id.equals(userId) }?.component
|
||||
assert userEntity != null
|
||||
new User.Builder().identifier(userEntity.id).identity(userEntity.identity).build()
|
||||
}
|
||||
}
|
||||
0 * _
|
||||
def userGroupEntity = userGroupsEntityUpdateResult?.result
|
||||
if (isAuthorized) {
|
||||
assert userGroupEntity?.component?.id?.equals(userGroupDto.id)
|
||||
assert userGroupEntity?.accessPolicy?.canRead
|
||||
assert userGroupEntity?.accessPolicy?.canWrite
|
||||
} else {
|
||||
assert userGroupEntity?.component == null
|
||||
assert exception instanceof AccessDeniedException
|
||||
}
|
||||
|
||||
where:
|
||||
userGroupExists | currentRevision | userGroupDto | isAuthorized |
|
||||
authorizationResult
|
||||
false | new Revision(0L, 'client1', 'root') | new UserGroupDTO(id: '1', name: 'test group', users: [createUserEntity()]) | true |
|
||||
[(ResourceFactory.userGroupsResource): AuthorizationResult.approved(), (ResourceFactory.usersResource): AuthorizationResult.approved()]
|
||||
true | new Revision(1L, 'client1', 'root') | new UserGroupDTO(id: '1', name: 'test group', users: [createUserEntity()]) | true |
|
||||
[(ResourceFactory.userGroupsResource): AuthorizationResult.approved(), (ResourceFactory.usersResource): AuthorizationResult.approved()]
|
||||
false | new Revision(0L, 'client1', 'root') | new UserGroupDTO(id: '1', name: 'test group', users: [createUserEntity()]) | false |
|
||||
[(ResourceFactory.userGroupsResource): AuthorizationResult.denied(), (ResourceFactory.usersResource): AuthorizationResult.denied()]
|
||||
true | new Revision(1L, 'client1', 'root') | new UserGroupDTO(id: '1', name: 'test group', users: [createUserEntity()]) | false |
|
||||
[(ResourceFactory.userGroupsResource): AuthorizationResult.denied(), (ResourceFactory.usersResource): AuthorizationResult.denied()]
|
||||
}
|
||||
|
||||
@Unroll
|
||||
def "DeleteUserGroup: isAuthorized: #isAuthorized, userGroup exists: #userGroupExists"() {
|
||||
given:
|
||||
def userGroupDao = Mock UserGroupDAO
|
||||
def userDao = Mock UserDAO
|
||||
def revisionManager = Mock RevisionManager
|
||||
def authorizableLookup = Mock AuthorizableLookup
|
||||
def dtoFactory = new DtoFactory()
|
||||
def entityFactory = new EntityFactory()
|
||||
def controllerFacade = Mock ControllerFacade
|
||||
def niFiServiceFacade = new StandardNiFiServiceFacade()
|
||||
niFiServiceFacade.setAuthorizableLookup authorizableLookup
|
||||
niFiServiceFacade.setRevisionManager revisionManager
|
||||
niFiServiceFacade.setDtoFactory dtoFactory
|
||||
niFiServiceFacade.setEntityFactory entityFactory
|
||||
niFiServiceFacade.setUserGroupDAO userGroupDao
|
||||
niFiServiceFacade.setControllerFacade controllerFacade
|
||||
niFiServiceFacade.setUserDAO userDao
|
||||
def userGroup = new Group.Builder().identifier(userGroupDto.id).name(userGroupDto.name)
|
||||
.addUsers(userGroupDto.users.collect { it.id } as Set).build()
|
||||
def userGroupEntity = null
|
||||
def exception = null
|
||||
|
||||
when:
|
||||
try {
|
||||
userGroupEntity = niFiServiceFacade.deleteUserGroup(currentRevision, userGroupDto.id)
|
||||
} catch (AccessDeniedException e) {
|
||||
exception = e
|
||||
}
|
||||
|
||||
then:
|
||||
if (userGroupExists) {
|
||||
1 * userGroupDao.getUserGroup(userGroupDto.id) >> userGroup
|
||||
if (isAuthorized) {
|
||||
1 * userGroupDao.deleteUserGroup(userGroupDto.id) >> userGroup
|
||||
}
|
||||
1 * authorizableLookup.getUsersAuthorizable() >> new SimpleAuthorizable(null, ResourceFactory.getUsersResource(),
|
||||
isAuthorized, authorizationResult.get(ResourceFactory.getUsersResource()))
|
||||
} else {
|
||||
1 * userGroupDao.getUserGroup(userGroupDto.id) >> null
|
||||
1 * userGroupDao.deleteUserGroup(userGroupDto.id) >> null
|
||||
}
|
||||
if (!(!isAuthorized && userGroupExists)) {
|
||||
1 * authorizableLookup.getUserGroupsAuthorizable() >> new SimpleAuthorizable(null, ResourceFactory.userGroupsResource,
|
||||
isAuthorized, authorizationResult.get(ResourceFactory.userGroupsResource))
|
||||
1 * revisionManager.deleteRevision(_, _, _) >> { RevisionClaim revisionClaim, NiFiUser nifiUser, DeleteRevisionTask task ->
|
||||
task.performTask()
|
||||
}
|
||||
1 * controllerFacade.save()
|
||||
}
|
||||
_ * revisionManager.get(_, _) >> { String id, ReadOnlyRevisionCallback callback ->
|
||||
callback.withRevision(new Revision(1L, 'client1', 'root'))
|
||||
}
|
||||
if (authorizationResult.get(ResourceFactory.userGroupsResource) == AuthorizationResult.approved() && userGroupExists) {
|
||||
1 * userDao.getUser(_) >> { String userId ->
|
||||
def userEntity = userGroupDto.users.find { it.id.equals(userId) }?.component
|
||||
assert userEntity != null
|
||||
new User.Builder().identifier(userEntity.id).identity(userEntity.identity).build()
|
||||
}
|
||||
}
|
||||
0 * _
|
||||
userGroupEntity?.component?.id == null
|
||||
if (userGroupExists && isAuthorized) {
|
||||
assert userGroupEntity?.id?.equals(userGroupDto.id)
|
||||
} else {
|
||||
assert userGroupEntity?.id == null
|
||||
}
|
||||
if (authorizationResult.get(ResourceFactory.usersResource) == AuthorizationResult.denied()) {
|
||||
assert exception instanceof AccessDeniedException
|
||||
}
|
||||
|
||||
where:
|
||||
userGroupExists | currentRevision | userGroupDto | isAuthorized |
|
||||
authorizationResult
|
||||
true | new Revision(1L, 'client1', 'root') | new UserGroupDTO(id: '1', name: 'test group', users: [createUserEntity()]) | true |
|
||||
[(ResourceFactory.userGroupsResource): AuthorizationResult.approved(), (ResourceFactory.usersResource): AuthorizationResult.approved()]
|
||||
false | null | new UserGroupDTO(id: '1', name: 'test group', users: [createUserEntity()]) | true |
|
||||
[(ResourceFactory.userGroupsResource): AuthorizationResult.approved(), (ResourceFactory.usersResource): AuthorizationResult.approved()]
|
||||
true | new Revision(1L, 'client1', 'root') | new UserGroupDTO(id: '1', name: 'test group', users: [createUserEntity()]) | false |
|
||||
[(ResourceFactory.userGroupsResource): AuthorizationResult.denied(), (ResourceFactory.usersResource): AuthorizationResult.denied()]
|
||||
false | null | new UserGroupDTO(id: '1', name: 'test group', users: [createUserEntity()]) | false |
|
||||
[(ResourceFactory.userGroupsResource): AuthorizationResult.denied(), (ResourceFactory.usersResource): AuthorizationResult.denied()]
|
||||
}
|
||||
|
||||
@Unroll
|
||||
def "CreateAccessPolicy: #isAuthorized"() {
|
||||
given:
|
||||
def accessPolicyDao = Mock AccessPolicyDAO
|
||||
def userDao = Mock UserDAO
|
||||
def revisionManager = Mock RevisionManager
|
||||
def entityFactory = new EntityFactory()
|
||||
def dtoFactory = new DtoFactory()
|
||||
dtoFactory.setEntityFactory entityFactory
|
||||
def authorizableLookup = Mock AuthorizableLookup
|
||||
def niFiServiceFacade = new StandardNiFiServiceFacade()
|
||||
niFiServiceFacade.setAuthorizableLookup authorizableLookup
|
||||
niFiServiceFacade.setDtoFactory dtoFactory
|
||||
niFiServiceFacade.setAccessPolicyDAO accessPolicyDao
|
||||
niFiServiceFacade.setUserDAO userDao
|
||||
niFiServiceFacade.setEntityFactory entityFactory
|
||||
niFiServiceFacade.setRevisionManager revisionManager
|
||||
def builder = new AccessPolicy.Builder().identifier(accessPolicyDto.id).resource(accessPolicyDto.resource)
|
||||
.addUsers(accessPolicyDto.users.collect { it.id } as Set)
|
||||
.addGroups(accessPolicyDto.userGroups.collect { it.id } as Set)
|
||||
if (accessPolicyDto.canRead) {
|
||||
builder.addAction(RequestAction.READ)
|
||||
}
|
||||
if (accessPolicyDto.canWrite) {
|
||||
builder.addAction(RequestAction.WRITE)
|
||||
}
|
||||
def newAccessPolicy = builder.build()
|
||||
def accessPolicyEntity = null
|
||||
def exception = null
|
||||
|
||||
when:
|
||||
try {
|
||||
accessPolicyEntity = niFiServiceFacade.createAccessPolicy(new Revision(0L, 'client-1'), accessPolicyDto)
|
||||
} catch (AccessDeniedException e) {
|
||||
exception = e
|
||||
}
|
||||
|
||||
then:
|
||||
1 * accessPolicyDao.createAccessPolicy(accessPolicyDto) >> newAccessPolicy
|
||||
if (isAuthorized) {
|
||||
1 * authorizableLookup.getAccessPolicyAuthorizable(accessPolicyDto.id) >> new SimpleAuthorizable(null, ResourceFactory.getPolicyResource(accessPolicyDto.id),
|
||||
isAuthorized, authorizationResult)
|
||||
}
|
||||
1 * authorizableLookup.getUsersAuthorizable() >> new SimpleAuthorizable(null, ResourceFactory.getUsersResource(),
|
||||
isAuthorized, authorizationResult)
|
||||
if (authorizationResult == AuthorizationResult.approved()) {
|
||||
1 * userDao.getUser(_) >> { String userId ->
|
||||
def userEntity = accessPolicyDto.users.find { it.id.equals(userId) }?.component
|
||||
assert userEntity != null
|
||||
new User.Builder().identifier(userEntity.id).identity(userEntity.identity).build()
|
||||
}
|
||||
}
|
||||
1 * revisionManager.get(_, _) >> { String id, ReadOnlyRevisionCallback callback ->
|
||||
callback.withRevision(new Revision(1L, 'client1', 'root'))
|
||||
}
|
||||
0 * _
|
||||
if (isAuthorized) {
|
||||
assert accessPolicyEntity?.component?.id?.equals(accessPolicyDto.id)
|
||||
assert accessPolicyEntity?.accessPolicy?.canRead
|
||||
assert accessPolicyEntity?.accessPolicy?.canWrite
|
||||
} else {
|
||||
assert accessPolicyEntity?.component == null
|
||||
assert exception instanceof AccessDeniedException
|
||||
}
|
||||
|
||||
where:
|
||||
accessPolicyDto | isAuthorized | authorizationResult
|
||||
new AccessPolicyDTO(id: '1', resource: ResourceFactory.flowResource.identifier, users: [createUserEntity()], canRead: true) | true | AuthorizationResult.approved()
|
||||
new AccessPolicyDTO(id: '1', resource: ResourceFactory.flowResource.identifier, users: [createUserEntity()], canRead: true) | false | AuthorizationResult.denied()
|
||||
}
|
||||
|
||||
@Unroll
|
||||
def "GetAccessPolicy: isAuthorized: #isAuthorized"() {
|
||||
given:
|
||||
def accessPolicyDao = Mock AccessPolicyDAO
|
||||
def userDao = Mock UserDAO
|
||||
def revisionManager = Mock RevisionManager
|
||||
def authorizableLookup = Mock AuthorizableLookup
|
||||
def dtoFactory = new DtoFactory()
|
||||
def entityFactory = new EntityFactory()
|
||||
def niFiServiceFacade = new StandardNiFiServiceFacade()
|
||||
niFiServiceFacade.setAuthorizableLookup authorizableLookup
|
||||
niFiServiceFacade.setRevisionManager revisionManager
|
||||
niFiServiceFacade.setDtoFactory dtoFactory
|
||||
niFiServiceFacade.setEntityFactory entityFactory
|
||||
niFiServiceFacade.setAccessPolicyDAO accessPolicyDao
|
||||
niFiServiceFacade.setUserDAO userDao
|
||||
def builder = new AccessPolicy.Builder().identifier(accessPolicyDto.id).resource(accessPolicyDto.resource)
|
||||
.addUsers(accessPolicyDto.users.collect { it.id } as Set)
|
||||
.addGroups(accessPolicyDto.userGroups.collect { it.id } as Set)
|
||||
if (accessPolicyDto.canRead) {
|
||||
builder.addAction(RequestAction.READ)
|
||||
}
|
||||
if (accessPolicyDto.canWrite) {
|
||||
builder.addAction(RequestAction.WRITE)
|
||||
}
|
||||
def requestedAccessPolicy = builder.build()
|
||||
def exception = null
|
||||
def accessPolicyEntity = null
|
||||
|
||||
when:
|
||||
try {
|
||||
accessPolicyEntity = niFiServiceFacade.getAccessPolicy(accessPolicyDto.id)
|
||||
} catch (AccessDeniedException e) {
|
||||
exception = e
|
||||
}
|
||||
|
||||
then:
|
||||
if (isAuthorized) {
|
||||
1 * accessPolicyDao.getAccessPolicy(accessPolicyDto.id) >> requestedAccessPolicy
|
||||
1 * authorizableLookup.getUsersAuthorizable() >> new SimpleAuthorizable(null, ResourceFactory.getUsersResource(),
|
||||
isAuthorized, authorizationResult)
|
||||
}
|
||||
_ * revisionManager.get(_, _) >> { String id, ReadOnlyRevisionCallback callback ->
|
||||
callback.withRevision(new Revision(1L, 'client1', 'root'))
|
||||
}
|
||||
1 * authorizableLookup.getAccessPolicyAuthorizable(accessPolicyDto.id) >> new SimpleAuthorizable(null, ResourceFactory.getPolicyResource(accessPolicyDto.id),
|
||||
isAuthorized, authorizationResult)
|
||||
if (authorizationResult == AuthorizationResult.approved()) {
|
||||
1 * userDao.getUser(_) >> { String userId ->
|
||||
def userEntity = accessPolicyDto.users.find { it.id.equals(userId) }?.component
|
||||
assert userEntity != null
|
||||
new User.Builder().identifier(userEntity.id).identity(userEntity.identity).build()
|
||||
}
|
||||
}
|
||||
0 * _
|
||||
if (isAuthorized) {
|
||||
assert accessPolicyEntity?.component?.id?.equals(accessPolicyDto.id)
|
||||
} else {
|
||||
assert exception instanceof AccessDeniedException
|
||||
}
|
||||
|
||||
where:
|
||||
accessPolicyDto | isAuthorized | authorizationResult
|
||||
new AccessPolicyDTO(id: '1', resource: ResourceFactory.flowResource.identifier, users: [createUserEntity()], canRead: true) | true | AuthorizationResult.approved()
|
||||
new AccessPolicyDTO(id: '1', resource: ResourceFactory.flowResource.identifier, users: [createUserEntity()], canRead: true) | false | AuthorizationResult.denied()
|
||||
}
|
||||
|
||||
@Unroll
|
||||
def "UpdateAccessPolicy: isAuthorized: #isAuthorized, policy exists: #hasPolicy"() {
|
||||
given:
|
||||
def accessPolicyDao = Mock AccessPolicyDAO
|
||||
def userDao = Mock UserDAO
|
||||
def revisionManager = Mock RevisionManager
|
||||
def entityFactory = new EntityFactory()
|
||||
def dtoFactory = new DtoFactory()
|
||||
def authorizableLookup = Mock AuthorizableLookup
|
||||
def controllerFacade = Mock ControllerFacade
|
||||
def niFiServiceFacade = new StandardNiFiServiceFacade()
|
||||
niFiServiceFacade.setAuthorizableLookup authorizableLookup
|
||||
niFiServiceFacade.setRevisionManager revisionManager
|
||||
niFiServiceFacade.setDtoFactory dtoFactory
|
||||
niFiServiceFacade.setAccessPolicyDAO accessPolicyDao
|
||||
niFiServiceFacade.setEntityFactory entityFactory
|
||||
niFiServiceFacade.setControllerFacade controllerFacade
|
||||
niFiServiceFacade.setUserDAO userDao
|
||||
def builder = new AccessPolicy.Builder().identifier(accessPolicyDto.id).resource(accessPolicyDto.resource)
|
||||
.addUsers(accessPolicyDto.users.collect { it.id } as Set)
|
||||
.addGroups(accessPolicyDto.userGroups.collect { it.id } as Set)
|
||||
if (accessPolicyDto.canRead) {
|
||||
builder.addAction(RequestAction.READ)
|
||||
}
|
||||
if (accessPolicyDto.canWrite) {
|
||||
builder.addAction(RequestAction.WRITE)
|
||||
}
|
||||
def accessPolicy = builder.build()
|
||||
def accessPolicyEntityUpdateResult = null
|
||||
def exception = null
|
||||
|
||||
when:
|
||||
try {
|
||||
accessPolicyEntityUpdateResult = niFiServiceFacade.updateAccessPolicy(currentRevision, accessPolicyDto)
|
||||
} catch (AccessDeniedException e) {
|
||||
exception = e
|
||||
}
|
||||
|
||||
then:
|
||||
1 * accessPolicyDao.hasAccessPolicy(accessPolicyDto.id) >> hasPolicy
|
||||
if (!hasPolicy) {
|
||||
1 * accessPolicyDao.createAccessPolicy(accessPolicyDto) >> accessPolicy
|
||||
} else {
|
||||
1 * controllerFacade.save()
|
||||
1 * accessPolicyDao.updateAccessPolicy(accessPolicyDto) >> accessPolicy
|
||||
1 * revisionManager.updateRevision(_, _, _) >> { RevisionClaim revisionClaim, NiFiUser niFiUser, UpdateRevisionTask callback ->
|
||||
callback.update()
|
||||
}
|
||||
}
|
||||
1 * authorizableLookup.getUsersAuthorizable() >> new SimpleAuthorizable(null, ResourceFactory.getUsersResource(),
|
||||
isAuthorized, authorizationResult)
|
||||
if (isAuthorized || hasPolicy) {
|
||||
1 * authorizableLookup.getAccessPolicyAuthorizable(accessPolicyDto.id) >> new SimpleAuthorizable(null, ResourceFactory.getPolicyResource(accessPolicyDto.id),
|
||||
isAuthorized, authorizationResult)
|
||||
}
|
||||
if (authorizationResult == AuthorizationResult.approved()) {
|
||||
1 * userDao.getUser(_) >> { String userId ->
|
||||
def userEntity = accessPolicyDto.users.find { it.id.equals(userId) }?.component
|
||||
assert userEntity != null
|
||||
new User.Builder().identifier(userEntity.id).identity(userEntity.identity).build()
|
||||
}
|
||||
}
|
||||
1 * revisionManager.get(_, _) >> { String id, ReadOnlyRevisionCallback callback ->
|
||||
callback.withRevision(new Revision(1L, 'client1', 'root'))
|
||||
}
|
||||
0 * _
|
||||
def accessPolicyEntity = accessPolicyEntityUpdateResult?.result
|
||||
if (isAuthorized) {
|
||||
assert accessPolicyEntity?.component?.id?.equals(accessPolicyDto.id)
|
||||
assert accessPolicyEntity?.accessPolicy?.canRead
|
||||
assert accessPolicyEntity?.accessPolicy?.canWrite
|
||||
} else {
|
||||
assert accessPolicyEntity?.component == null
|
||||
assert exception instanceof AccessDeniedException
|
||||
}
|
||||
|
||||
where:
|
||||
hasPolicy | currentRevision | accessPolicyDto | isAuthorized |
|
||||
authorizationResult
|
||||
false | new Revision(0L, 'client1', 'root') | new AccessPolicyDTO(id: '1', resource: ResourceFactory.flowResource.identifier, users: [createUserEntity()], canRead: true) | true |
|
||||
AuthorizationResult.approved()
|
||||
true | new Revision(1L, 'client1', 'root') | new AccessPolicyDTO(id: '1', resource: ResourceFactory.flowResource.identifier, users: [createUserEntity()], canRead: true) | true |
|
||||
AuthorizationResult.approved()
|
||||
false | new Revision(0L, 'client1', 'root') | new AccessPolicyDTO(id: '1', resource: ResourceFactory.flowResource.identifier, users: [createUserEntity()], canRead: true) | false |
|
||||
AuthorizationResult.denied()
|
||||
true | new Revision(1L, 'client1', 'root') | new AccessPolicyDTO(id: '1', resource: ResourceFactory.flowResource.identifier, users: [createUserEntity()], canRead: true) | false |
|
||||
AuthorizationResult.denied()
|
||||
}
|
||||
|
||||
@Unroll
|
||||
def "DeleteAccessPolicy: isAuthorized: #isAuthorized, hasPolicy: #hasPolicy"() {
|
||||
given:
|
||||
def accessPolicyDao = Mock AccessPolicyDAO
|
||||
def userDao = Mock UserDAO
|
||||
def revisionManager = Mock RevisionManager
|
||||
def authorizableLookup = Mock AuthorizableLookup
|
||||
def dtoFactory = new DtoFactory()
|
||||
def entityFactory = new EntityFactory()
|
||||
def controllerFacade = Mock ControllerFacade
|
||||
def niFiServiceFacade = new StandardNiFiServiceFacade()
|
||||
niFiServiceFacade.setAuthorizableLookup authorizableLookup
|
||||
niFiServiceFacade.setRevisionManager revisionManager
|
||||
niFiServiceFacade.setDtoFactory dtoFactory
|
||||
niFiServiceFacade.setEntityFactory entityFactory
|
||||
niFiServiceFacade.setAccessPolicyDAO accessPolicyDao
|
||||
niFiServiceFacade.setControllerFacade controllerFacade
|
||||
niFiServiceFacade.setUserDAO userDao
|
||||
def builder = new AccessPolicy.Builder()
|
||||
builder.identifier(accessPolicyDto.id).resource(accessPolicyDto.resource)
|
||||
.addUsers(accessPolicyDto.users.collect { it.id } as Set)
|
||||
.addGroups(accessPolicyDto.userGroups.collect { it.id } as Set)
|
||||
if (accessPolicyDto.canRead) {
|
||||
builder.addAction(RequestAction.READ)
|
||||
}
|
||||
if (accessPolicyDto.canWrite) {
|
||||
builder.addAction(RequestAction.WRITE)
|
||||
}
|
||||
def accessPolicy = builder.build()
|
||||
def accessPolicyEntity = null
|
||||
def exception = null
|
||||
|
||||
when:
|
||||
try {
|
||||
accessPolicyEntity = niFiServiceFacade.deleteAccessPolicy(currentRevision, accessPolicyDto.id)
|
||||
} catch (AccessDeniedException e) {
|
||||
exception = e
|
||||
}
|
||||
|
||||
then:
|
||||
if (hasPolicy) {
|
||||
1 * accessPolicyDao.getAccessPolicy(accessPolicyDto.id) >> accessPolicy
|
||||
if (isAuthorized) {
|
||||
1 * accessPolicyDao.deleteAccessPolicy(accessPolicyDto.id) >> accessPolicy
|
||||
}
|
||||
1 * authorizableLookup.getUsersAuthorizable() >> new SimpleAuthorizable(null, ResourceFactory.usersResource,
|
||||
isAuthorized, authorizationResult)
|
||||
} else {
|
||||
1 * accessPolicyDao.getAccessPolicy(accessPolicyDto.id) >> null
|
||||
1 * accessPolicyDao.deleteAccessPolicy(accessPolicyDto.id) >> null
|
||||
}
|
||||
if (!(!isAuthorized && hasPolicy)) {
|
||||
1 * authorizableLookup.getAccessPolicyAuthorizable(accessPolicyDto.id) >> new SimpleAuthorizable(null, ResourceFactory.getPolicyResource(accessPolicyDto.id),
|
||||
isAuthorized, authorizationResult)
|
||||
1 * revisionManager.deleteRevision(_, _, _) >> { RevisionClaim revisionClaim, NiFiUser nifiUser, DeleteRevisionTask task ->
|
||||
task.performTask()
|
||||
}
|
||||
1 * controllerFacade.save()
|
||||
}
|
||||
_ * revisionManager.get(_, _) >> { String id, ReadOnlyRevisionCallback callback ->
|
||||
callback.withRevision(new Revision(1L, 'client1', 'root'))
|
||||
}
|
||||
if (authorizationResult == AuthorizationResult.approved() && hasPolicy) {
|
||||
1 * userDao.getUser(_) >> { String userId ->
|
||||
def userEntity = accessPolicyDto.users.find { it.id.equals(userId) }?.component
|
||||
assert userEntity != null
|
||||
new User.Builder().identifier(userEntity.id).identity(userEntity.identity).build()
|
||||
}
|
||||
}
|
||||
0 * _
|
||||
if (hasPolicy && isAuthorized) {
|
||||
assert accessPolicyEntity?.id?.equals(accessPolicyDto.id)
|
||||
} else {
|
||||
assert accessPolicyEntity?.id == null
|
||||
}
|
||||
if (!isAuthorized && hasPolicy) {
|
||||
assert exception instanceof AccessDeniedException
|
||||
}
|
||||
|
||||
where:
|
||||
hasPolicy | currentRevision | accessPolicyDto | isAuthorized |
|
||||
authorizationResult
|
||||
true | new Revision(1L, 'client1', 'root') | new AccessPolicyDTO(id: '1', resource: ResourceFactory.flowResource.identifier, users: [createUserEntity()], canRead: true) | true |
|
||||
AuthorizationResult.approved()
|
||||
false | null | new AccessPolicyDTO(id: '1', resource: ResourceFactory.flowResource.identifier, users: [createUserEntity()], canRead: true) | true |
|
||||
AuthorizationResult.approved()
|
||||
true | new Revision(1L, 'client1', 'root') | new AccessPolicyDTO(id: '1', resource: ResourceFactory.flowResource.identifier, users: [createUserEntity()], canRead: true) | false |
|
||||
AuthorizationResult.denied()
|
||||
false | null | new AccessPolicyDTO(id: '1', resource: ResourceFactory.flowResource.identifier, users: [createUserEntity()], canRead: true) | false |
|
||||
AuthorizationResult.denied()
|
||||
}
|
||||
|
||||
private UserGroupDTO createUserGroupDTO() {
|
||||
new UserGroupDTO(id: 'group-1', name: 'test group', users: [createUserEntity()] as Set)
|
||||
}
|
||||
|
||||
private UserEntity createUserEntity() {
|
||||
new UserEntity(id: 'user-1', component: createUserDTO(), revision: createRevisionDTO())
|
||||
}
|
||||
|
||||
private UserDTO createUserDTO() {
|
||||
new UserDTO(id: 'user-1', identity: 'user-1')
|
||||
}
|
||||
|
||||
private RevisionDTO createRevisionDTO() {
|
||||
new RevisionDTO(version: 0L, clientId: 'client-1', lastModifier: 'user-1')
|
||||
}
|
||||
|
||||
private class SimpleAuthorizable implements Authorizable {
|
||||
final private Authorizable parentAuthorizable
|
||||
final private Resource resource
|
||||
final private boolean isAuthorized
|
||||
final private AuthorizationResult authorizationResult;
|
||||
|
||||
SimpleAuthorizable(Authorizable parentAuthorizable, Resource resource, boolean isAuthorized, AuthorizationResult authorizationResult) {
|
||||
this.parentAuthorizable = parentAuthorizable
|
||||
this.resource = resource
|
||||
this.isAuthorized = isAuthorized
|
||||
this.authorizationResult = authorizationResult
|
||||
}
|
||||
|
||||
@Override
|
||||
Authorizable getParentAuthorizable() {
|
||||
return parentAuthorizable
|
||||
}
|
||||
|
||||
@Override
|
||||
Resource getResource() {
|
||||
return resource
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isAuthorized(Authorizer authorzr, RequestAction action) {
|
||||
return isAuthorized
|
||||
}
|
||||
|
||||
@Override
|
||||
AuthorizationResult checkAuthorization(Authorizer authorzr, RequestAction action) {
|
||||
return authorizationResult
|
||||
}
|
||||
|
||||
@Override
|
||||
void authorize(Authorizer authorzr, RequestAction action) throws AccessDeniedException {
|
||||
if (!isAuthorized) {
|
||||
throw new AccessDeniedException("test exception, access denied")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -44,7 +44,6 @@ import org.apache.nifi.web.api.entity.ProcessGroupsEntity;
|
|||
import org.apache.nifi.web.api.entity.ProcessorEntity;
|
||||
import org.apache.nifi.web.api.entity.ProcessorTypesEntity;
|
||||
import org.apache.nifi.web.api.entity.ProcessorsEntity;
|
||||
import org.apache.nifi.web.api.entity.UserEntity;
|
||||
import org.apache.nifi.web.api.entity.UsersEntity;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
|
@ -993,7 +992,7 @@ public class AdminAccessControlTest {
|
|||
|
||||
// ensure the request succeeded
|
||||
Assert.assertEquals(200, putResponse.getStatus());
|
||||
Assert.assertEquals("ACTIVE", putResponse.getEntity(UserEntity.class).getUser().getStatus());
|
||||
Assert.assertEquals("ACTIVE", null); // FIXME test should fail, needs to be updated to test updating user by changing the groups the user is in and the name of the user
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
|
|
Loading…
Reference in New Issue