http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/785cb81f/nifi-registry-framework/src/main/java/org/apache/nifi/registry/authorization/user/StandardNiFiUser.java ---------------------------------------------------------------------- diff --git a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/authorization/user/StandardNiFiUser.java b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/authorization/user/StandardNiFiUser.java new file mode 100644 index 0000000..3a8a8bc --- /dev/null +++ b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/authorization/user/StandardNiFiUser.java @@ -0,0 +1,189 @@ +/* + * 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.registry.authorization.user; + +import org.apache.commons.lang3.StringUtils; + +import java.util.Collections; +import java.util.Objects; +import java.util.Set; + +/** + * An implementation of NiFiUser. + */ +public class StandardNiFiUser implements NiFiUser { + + public static final String ANONYMOUS_IDENTITY = "anonymous"; + public static final StandardNiFiUser ANONYMOUS = new Builder().identity(ANONYMOUS_IDENTITY).anonymous(true).build(); + + private final String identity; + private final Set<String> groups; + private final NiFiUser chain; + private final String clientAddress; + private final boolean isAnonymous; + + private StandardNiFiUser(final Builder builder) { + this.identity = builder.identity; + this.groups = builder.groups == null ? null : Collections.unmodifiableSet(builder.groups); + this.chain = builder.chain; + this.clientAddress = builder.clientAddress; + this.isAnonymous = builder.isAnonymous; + } + + /** + * This static builder allows the chain and clientAddress to be populated without allowing calling code to provide a non-anonymous identity of the anonymous user. + * + * @param chain the proxied entities in {@see NiFiUser} form + * @param clientAddress the address the request originated from + * @return an anonymous user instance with the identity "anonymous" + */ + public static StandardNiFiUser populateAnonymousUser(NiFiUser chain, String clientAddress) { + return new Builder().identity(ANONYMOUS_IDENTITY).chain(chain).clientAddress(clientAddress).anonymous(true).build(); + } + + @Override + public String getIdentity() { + return identity; + } + + @Override + public Set<String> getGroups() { + return groups; + } + + @Override + public NiFiUser getChain() { + return chain; + } + + @Override + public boolean isAnonymous() { + return isAnonymous; + } + + @Override + public String getClientAddress() { + return clientAddress; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + + if (!(obj instanceof NiFiUser)) { + return false; + } + + final NiFiUser other = (NiFiUser) obj; + return Objects.equals(this.identity, other.getIdentity()); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 53 * hash + Objects.hashCode(this.identity); + return hash; + } + + @Override + public String toString() { + final String formattedGroups; + if (groups == null) { + formattedGroups = "none"; + } else { + formattedGroups = StringUtils.join(groups, ", "); + } + + return String.format("identity[%s], groups[%s]", getIdentity(), formattedGroups); + } + + /** + * Builder for a StandardNiFiUser + */ + public static class Builder { + + private String identity; + private Set<String> groups; + private NiFiUser chain; + private String clientAddress; + private boolean isAnonymous = false; + + /** + * Sets the identity. + * + * @param identity the identity string for the user (i.e. "Andy" or "CN=alopresto, OU=Apache NiFi") + * @return the builder + */ + public Builder identity(final String identity) { + this.identity = identity; + return this; + } + + /** + * Sets the groups. + * + * @param groups the user groups + * @return the builder + */ + public Builder groups(final Set<String> groups) { + this.groups = groups; + return this; + } + + /** + * Sets the chain. + * + * @param chain the proxy chain that leads to this users + * @return the builder + */ + public Builder chain(final NiFiUser chain) { + this.chain = chain; + return this; + } + + /** + * Sets the client address. + * + * @param clientAddress the source address of the request + * @return the builder + */ + public Builder clientAddress(final String clientAddress) { + this.clientAddress = clientAddress; + return this; + } + + /** + * Sets whether this user is the canonical "anonymous" user + * + * @param isAnonymous true to represent the canonical "anonymous" user + * @return the builder + */ + private Builder anonymous(final boolean isAnonymous) { + this.isAnonymous = isAnonymous; + return this; + } + + /** + * @return builds a StandardNiFiUser from the current state of the builder + */ + public StandardNiFiUser build() { + return new StandardNiFiUser(this); + } + } +}
http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/785cb81f/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/DatabaseMetadataService.java ---------------------------------------------------------------------- diff --git a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/DatabaseMetadataService.java b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/DatabaseMetadataService.java index 35c6b55..0fc10a4 100644 --- a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/DatabaseMetadataService.java +++ b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/DatabaseMetadataService.java @@ -42,6 +42,7 @@ import javax.persistence.metamodel.Metamodel; import java.util.ArrayList; import java.util.Collections; import java.util.Date; +import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.stream.Collectors; @@ -166,6 +167,10 @@ public class DatabaseMetadataService implements MetadataService { return buckets; } + private Set<BucketEntity> getBuckets(Set<String> bucketIds) { + return new HashSet<>(bucketRepository.findByIdIn(bucketIds)); + } + // ------------------------------------------------------------------------------------ @Override @@ -218,6 +223,18 @@ public class DatabaseMetadataService implements MetadataService { } } + @Override + public List<BucketItemEntity> getBucketItems(final QueryParameters params, final Set<String> bucketIds) { + Set<BucketEntity> filterBuckets = getBuckets(bucketIds); + if (params.getNumRows() != null && params.getPageNum() != null) { + return getPagedBucketItems(params, filterBuckets); + } else if (params.getSortParameters() != null && params.getSortParameters().size() > 0) { + return getSortedBucketItems(params, filterBuckets); + } else { + return getBucketItems(filterBuckets); + } + } + private List<BucketItemEntity> getBucketItems(final BucketEntity bucket) { final List<BucketItemEntity> bucketItems = new ArrayList<>(); for (BucketItemEntity item : itemRepository.findByBucket(bucket)) { @@ -244,6 +261,32 @@ public class DatabaseMetadataService implements MetadataService { return items; } + private List<BucketItemEntity> getBucketItems(final Set<BucketEntity> buckets) { + final List<BucketItemEntity> bucketItems = new ArrayList<>(); + for (BucketItemEntity item : itemRepository.findByBucketIn(buckets)) { + bucketItems.add(item); + } + return bucketItems; + } + + private List<BucketItemEntity> getPagedBucketItems(final QueryParameters params, final Set<BucketEntity> buckets) { + final Pageable pageable = getPageRequest(params); + final List<BucketItemEntity> items = new ArrayList<>(); + for (BucketItemEntity item : itemRepository.findByBucketIn(buckets, pageable)) { + items.add(item); + } + return items; + } + + private List<BucketItemEntity> getSortedBucketItems(final QueryParameters params, final Set<BucketEntity> buckets) { + final Sort sort = getSort(params); + final List<BucketItemEntity> items = new ArrayList<>(); + for (BucketItemEntity item : itemRepository.findByBucketIn(buckets, sort)) { + items.add(item); + } + return items; + } + // ------------------------------------------------------------------------------------ @Override @@ -254,8 +297,14 @@ public class DatabaseMetadataService implements MetadataService { } @Override - public FlowEntity getFlowById(final String flowIdentifier) { - return flowRepository.findOne(flowIdentifier); + public FlowEntity getFlowById(final String bucketIdentifier, final String flowIdentifier) { + FlowEntity flow = flowRepository.findOne(flowIdentifier); + + if (flow.getBucket() == null || !bucketIdentifier.equals(flow.getBucket().getId())) { + return null; + } + + return flow; } @Override @@ -285,12 +334,18 @@ public class DatabaseMetadataService implements MetadataService { @Override public List<FlowEntity> getFlows(final QueryParameters params) { + return getFlows(params, null); + } + + @Override + public List<FlowEntity> getFlows(final QueryParameters params, Set<String> bucketIds) { + Set<BucketEntity> filterBuckets = getBuckets(bucketIds); if (params.getNumRows() != null && params.getPageNum() != null) { - return getPagedFlows(params); + return getPagedFlows(params, filterBuckets); } else if (params.getSortParameters() != null && params.getSortParameters().size() > 0) { - return getSortedFlows(params); + return getSortedFlows(params, filterBuckets); } else { - return getAllFlows(); + return getAllFlows(filterBuckets); } } @@ -320,6 +375,20 @@ public class DatabaseMetadataService implements MetadataService { return flows; } + private List<FlowEntity> getAllFlows(Set<BucketEntity> buckets) { + return flowRepository.findByBucketIn(buckets); + } + + private List<FlowEntity> getPagedFlows(final QueryParameters params, Set<BucketEntity> buckets) { + final Pageable pageable = getPageRequest(params); + return flowRepository.findByBucketIn(buckets, pageable); + } + + private List<FlowEntity> getSortedFlows(final QueryParameters params, Set<BucketEntity> buckets) { + final Sort sort = getSort(params); + return flowRepository.findByBucketIn(buckets, sort); + } + // ------------------------------------------------------------------------------------ @Override @@ -329,9 +398,18 @@ public class DatabaseMetadataService implements MetadataService { } @Override - public FlowSnapshotEntity getFlowSnapshot(final String flowIdentifier, final Integer version) { + public FlowSnapshotEntity getFlowSnapshot(final String bucketIdentifier, final String flowIdentifier, final Integer version) { final FlowSnapshotEntityKey key = new FlowSnapshotEntityKey(flowIdentifier, version); - return flowSnapshotRepository.findOne(key); + FlowSnapshotEntity flowSnapshot = flowSnapshotRepository.findOne(key); + + if (flowSnapshot == null + || flowSnapshot.getFlow() == null + || flowSnapshot.getFlow().getBucket() == null + || !bucketIdentifier.equals(flowSnapshot.getFlow().getBucket().getId())) { + return null; + } + + return flowSnapshot; } @Override http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/785cb81f/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/repository/BucketItemRepository.java ---------------------------------------------------------------------- diff --git a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/repository/BucketItemRepository.java b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/repository/BucketItemRepository.java index 85d98ad..2f188e1 100644 --- a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/repository/BucketItemRepository.java +++ b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/repository/BucketItemRepository.java @@ -24,6 +24,7 @@ import org.springframework.data.domain.Sort; import org.springframework.data.repository.Repository; import java.util.List; +import java.util.Set; /** * Repository for BucketItems that exposes only the methods from PagingAndSortingRepository. @@ -81,4 +82,30 @@ public interface BucketItemRepository extends Repository<BucketItemEntity,String */ List<BucketItemEntity> findByBucket(BucketEntity bucket, Pageable pageable); + /** + * Find all items by buckets. + * + * @param buckets the buckets to find items for + * @return the list of items for the buckets + */ + List<BucketItemEntity> findByBucketIn(Set<BucketEntity> buckets); + + /** + * Find all items by buckets with sorting. + * + * @param buckets the buckets to find items for + * @param sort the sort params + * @return the list of items for the buckets + */ + List<BucketItemEntity> findByBucketIn(Set<BucketEntity> buckets, Sort sort); + + /** + * Find all items by buckets with paging/sorting. + * + * @param buckets the buckets to find items for + * @param pageable the pageable params + * @return the list of items for the buckets based on the pageable params + */ + List<BucketItemEntity> findByBucketIn(Set<BucketEntity> buckets, Pageable pageable); + } http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/785cb81f/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/repository/BucketRepository.java ---------------------------------------------------------------------- diff --git a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/repository/BucketRepository.java b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/repository/BucketRepository.java index e917c2d..f7fb7fb 100644 --- a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/repository/BucketRepository.java +++ b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/repository/BucketRepository.java @@ -20,6 +20,7 @@ import org.apache.nifi.registry.db.entity.BucketEntity; import org.springframework.data.repository.PagingAndSortingRepository; import java.util.List; +import java.util.Set; /** * Spring Data Repository for BucketEntity. @@ -28,4 +29,6 @@ public interface BucketRepository extends PagingAndSortingRepository<BucketEntit List<BucketEntity> findByNameIgnoreCase(String name); + List<BucketEntity> findByIdIn(Set<String> id); + } http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/785cb81f/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/repository/FlowRepository.java ---------------------------------------------------------------------- diff --git a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/repository/FlowRepository.java b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/repository/FlowRepository.java index ac20f81..bfda5d0 100644 --- a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/repository/FlowRepository.java +++ b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/repository/FlowRepository.java @@ -16,10 +16,14 @@ */ package org.apache.nifi.registry.db.repository; +import org.apache.nifi.registry.db.entity.BucketEntity; import org.apache.nifi.registry.db.entity.FlowEntity; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; import org.springframework.data.repository.PagingAndSortingRepository; import java.util.List; +import java.util.Set; /** * Spring Data Repository for FlowEntity. @@ -28,4 +32,30 @@ public interface FlowRepository extends PagingAndSortingRepository<FlowEntity,St List<FlowEntity> findByNameIgnoreCase(String name); + /** + * Find all flows by buckets. + * + * @param buckets the buckets to find items for + * @return the list of items for the buckets + */ + List<FlowEntity> findByBucketIn(Set<BucketEntity> buckets); + + /** + * Find all flows by buckets with sorting. + * + * @param buckets the buckets to find flows for + * @param sort the sort params + * @return the list of flows for the buckets + */ + List<FlowEntity> findByBucketIn(Set<BucketEntity> buckets, Sort sort); + + /** + * Find all flows by buckets with paging/sorting. + * + * @param buckets the buckets to find flows for + * @param pageable the pageable params + * @return the list of flows for the buckets based on the pageable params + */ + List<FlowEntity> findByBucketIn(Set<BucketEntity> buckets, Pageable pageable); + } http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/785cb81f/nifi-registry-framework/src/main/java/org/apache/nifi/registry/exception/AdministrationException.java ---------------------------------------------------------------------- diff --git a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/exception/AdministrationException.java b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/exception/AdministrationException.java new file mode 100644 index 0000000..8f9180c --- /dev/null +++ b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/exception/AdministrationException.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.registry.exception; + +/** + * + */ +public class AdministrationException extends RuntimeException { + + public AdministrationException(Throwable cause) { + super(cause); + } + + public AdministrationException(String message, Throwable cause) { + super(message, cause); + } + + public AdministrationException(String message) { + super(message); + } + + public AdministrationException() { + } + +} http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/785cb81f/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/AuthorizationService.java ---------------------------------------------------------------------- diff --git a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/AuthorizationService.java b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/AuthorizationService.java new file mode 100644 index 0000000..c62d170 --- /dev/null +++ b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/AuthorizationService.java @@ -0,0 +1,695 @@ +/* + * 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.registry.service; + +import org.apache.nifi.registry.authorization.AccessPolicyProvider; +import org.apache.nifi.registry.authorization.AccessPolicyProviderInitializationContext; +import org.apache.nifi.registry.authorization.AuthorizableLookup; +import org.apache.nifi.registry.authorization.exception.AccessDeniedException; +import org.apache.nifi.registry.authorization.exception.AuthorizationAccessException; +import org.apache.nifi.registry.authorization.AuthorizeAccess; +import org.apache.nifi.registry.authorization.Authorizer; +import org.apache.nifi.registry.authorization.AuthorizerCapabilityDetection; +import org.apache.nifi.registry.authorization.AuthorizerConfigurationContext; +import org.apache.nifi.registry.authorization.exception.AuthorizerCreationException; +import org.apache.nifi.registry.authorization.exception.AuthorizerDestructionException; +import org.apache.nifi.registry.authorization.ConfigurableAccessPolicyProvider; +import org.apache.nifi.registry.authorization.ConfigurableUserGroupProvider; +import org.apache.nifi.registry.authorization.Group; +import org.apache.nifi.registry.authorization.ManagedAuthorizer; +import org.apache.nifi.registry.authorization.RequestAction; +import org.apache.nifi.registry.authorization.UserAndGroups; +import org.apache.nifi.registry.authorization.UserGroupProvider; +import org.apache.nifi.registry.authorization.UserGroupProviderInitializationContext; +import org.apache.nifi.registry.authorization.resource.ResourceFactory; +import org.apache.nifi.registry.authorization.resource.ResourceType; +import org.apache.nifi.registry.authorization.user.NiFiUserUtils; +import org.apache.nifi.registry.bucket.Bucket; +import org.apache.nifi.registry.model.authorization.AccessPolicy; +import org.apache.nifi.registry.model.authorization.AccessPolicySummary; +import org.apache.nifi.registry.model.authorization.Resource; +import org.apache.nifi.registry.model.authorization.Tenant; +import org.apache.nifi.registry.model.authorization.User; +import org.apache.nifi.registry.model.authorization.UserGroup; +import org.apache.nifi.registry.service.params.QueryParameters; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.stream.Collectors; + +@Service +public class AuthorizationService { + + public static final String MSG_NON_MANAGED_AUTHORIZER = "This NiFi Registry is not configured to internally manage users, groups, or policies. Please contact your system administrator."; + public static final String MSG_NON_CONFIGURABLE_POLICIES = "This NiFi Registry is not configured to allow configurable policies. Please contact your system administrator."; + public static final String MSG_NON_CONFIGURABLE_USERS = "This NiFi Registry is not configured to allow configurable users and groups. Please contact your system administrator."; + + private AuthorizableLookup authorizableLookup; + private Authorizer authorizer; + private RegistryService registryService; + private UserGroupProvider userGroupProvider; + private AccessPolicyProvider accessPolicyProvider; + + private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + private final Lock readLock = lock.readLock(); + private final Lock writeLock = lock.writeLock(); + + @Autowired + public AuthorizationService( + final AuthorizableLookup authorizableLookup, + final Authorizer authorizer, + final RegistryService registryService) { + this.authorizableLookup = authorizableLookup; + this.authorizer = authorizer; + this.registryService = registryService; + + if (AuthorizerCapabilityDetection.isManagedAuthorizer(this.authorizer)) { + this.accessPolicyProvider = ((ManagedAuthorizer) authorizer).getAccessPolicyProvider(); + } else { + this.accessPolicyProvider = createExceptionThrowingAccessPolicyProvider(); + } + this.userGroupProvider = accessPolicyProvider.getUserGroupProvider(); + } + + + // ---------------------- Authorization methods ------------------------------------- + + public void authorizeAccess(final AuthorizeAccess authorizeAccess) { + authorizeAccess.authorize(authorizableLookup); + } + + + // ---------------------- Tenant methods -------------------------------------------- + + public Tenant getTenant(String identifier) { + this.readLock.lock(); + try { + org.apache.nifi.registry.authorization.User user = userGroupProvider.getUser(identifier); + if (user != null) { + return tenantToDTO(user); + } else { + org.apache.nifi.registry.authorization.Group group = userGroupProvider.getGroup(identifier); + return tenantToDTO(group); + } + } finally { + this.readLock.unlock(); + } + } + + + // ---------------------- User methods ---------------------------------------------- + + public User createUser(User user) { + verifyUserGroupProviderIsConfigurable(); + writeLock.lock(); + try { + final org.apache.nifi.registry.authorization.User createdUser = + ((ConfigurableUserGroupProvider) userGroupProvider).addUser(userFromDTO(user)); + return userToDTO(createdUser); + } finally { + writeLock.unlock(); + } + } + + public List<User> getUsers() { + this.readLock.lock(); + try { + return userGroupProvider.getUsers().stream().map(this::userToDTO).collect(Collectors.toList()); + } finally { + this.readLock.unlock(); + } + } + + public User getUser(String identifier) { + this.readLock.lock(); + try { + return userToDTO(userGroupProvider.getUser(identifier)); + } finally { + this.readLock.unlock(); + } + } + + public User updateUser(User user) { + verifyUserGroupProviderIsConfigurable(); + this.writeLock.lock(); + try { + final org.apache.nifi.registry.authorization.User updatedUser = + ((ConfigurableUserGroupProvider) userGroupProvider).updateUser(userFromDTO(user)); + return userToDTO(updatedUser); + } finally { + this.writeLock.unlock(); + } + } + + public User deleteUser(String identifier) { + verifyUserGroupProviderIsConfigurable(); + this.writeLock.lock(); + try { + User deletedUserDTO = getUser(identifier); + ((ConfigurableUserGroupProvider) userGroupProvider).deleteUser(identifier); + return deletedUserDTO; + } finally { + this.writeLock.unlock(); + } + } + + + // ---------------------- User Group methods -------------------------------------- + + public UserGroup createUserGroup(UserGroup userGroup) { + verifyUserGroupProviderIsConfigurable(); + writeLock.lock(); + try { + final org.apache.nifi.registry.authorization.Group createdGroup = + ((ConfigurableUserGroupProvider) userGroupProvider).addGroup(userGroupFromDTO(userGroup)); + return userGroupToDTO(createdGroup); + } finally { + writeLock.unlock(); + } + } + + public List<UserGroup> getUserGroups() { + this.readLock.lock(); + try { + return userGroupProvider.getGroups().stream().map(this::userGroupToDTO).collect(Collectors.toList()); + } finally { + this.readLock.unlock(); + } + } + + public List<UserGroup> getUserGroupsForUser(String userIdentifier) { + this.readLock.lock(); + try { + return userGroupProvider.getGroups() + .stream() + .filter(group -> group.getUsers().contains(userIdentifier)) + .map(this::userGroupToDTO) + .collect(Collectors.toList()); + } finally { + this.readLock.unlock(); + } + } + + public UserGroup getUserGroup(String identifier) { + this.readLock.lock(); + try { + return userGroupToDTO(userGroupProvider.getGroup(identifier)); + } finally { + this.readLock.unlock(); + } + } + + public UserGroup updateUserGroup(UserGroup userGroup) { + verifyUserGroupProviderIsConfigurable(); + writeLock.lock(); + try { + final org.apache.nifi.registry.authorization.Group updatedGroup = + ((ConfigurableUserGroupProvider) userGroupProvider).updateGroup(userGroupFromDTO(userGroup)); + return userGroupToDTO(updatedGroup); + } finally { + writeLock.unlock(); + } + } + + public UserGroup deleteUserGroup(String identifier) { + verifyUserGroupProviderIsConfigurable(); + writeLock.lock(); + try { + final UserGroup userGroupDTO = getUserGroup(identifier); + ((ConfigurableUserGroupProvider) userGroupProvider).deleteGroup(identifier); + return userGroupDTO; + } finally { + writeLock.unlock(); + } + } + + + // ---------------------- Access Policy methods ---------------------------------------- + + public AccessPolicy createAccessPolicy(AccessPolicy accessPolicy) { + verifyAccessPolicyProviderIsConfigurable(); + writeLock.lock(); + try { + org.apache.nifi.registry.authorization.AccessPolicy createdAccessPolicy = + ((ConfigurableAccessPolicyProvider) accessPolicyProvider).addAccessPolicy(accessPolicyFromDTO(accessPolicy)); + return accessPolicyToDTO(createdAccessPolicy); + } finally { + writeLock.unlock(); + } + } + + public AccessPolicy getAccessPolicy(String identifier) { + readLock.lock(); + try { + return accessPolicyToDTO(accessPolicyProvider.getAccessPolicy(identifier)); + } finally { + readLock.unlock(); + } + } + + public AccessPolicy getAccessPolicy(String resource, RequestAction action) { + readLock.lock(); + try { + return accessPolicyToDTO(accessPolicyProvider.getAccessPolicy(resource, action)); + } finally { + readLock.unlock(); + } + } + + public List<AccessPolicy> getAccessPolicies() { + readLock.lock(); + try { + return accessPolicyProvider.getAccessPolicies().stream().map(this::accessPolicyToDTO).collect(Collectors.toList()); + } finally { + readLock.unlock(); + } + } + + public List<AccessPolicySummary> getAccessPolicySummaries() { + readLock.lock(); + try { + return accessPolicyProvider.getAccessPolicies().stream().map(this::accessPolicyToSummaryDTO).collect(Collectors.toList()); + } finally { + readLock.unlock(); + } + } + + public List<AccessPolicy> getAccessPoliciesForUser(String userIdentifier) { + readLock.lock(); + try { + return accessPolicyProvider.getAccessPolicies().stream() + .filter(accessPolicy -> accessPolicy.getUsers().contains(userIdentifier)) + .map(this::accessPolicyToDTO) + .collect(Collectors.toList()); + } finally { + readLock.unlock(); + } + } + + public List<AccessPolicySummary> getAccessPolicySummariesForUser(String userIdentifier) { + readLock.lock(); + try { + return accessPolicyProvider.getAccessPolicies().stream() + .filter(accessPolicy -> accessPolicy.getUsers().contains(userIdentifier)) + .map(this::accessPolicyToSummaryDTO) + .collect(Collectors.toList()); + } finally { + readLock.unlock(); + } + } + + public List<AccessPolicySummary> getAccessPolicySummariesForUserGroup(String userGroupIdentifier) { + readLock.lock(); + try { + return accessPolicyProvider.getAccessPolicies().stream() + .filter(accessPolicy -> accessPolicy.getGroups().contains(userGroupIdentifier)) + .map(this::accessPolicyToSummaryDTO) + .collect(Collectors.toList()); + } finally { + readLock.unlock(); + } + } + + public AccessPolicy updateAccessPolicy(AccessPolicy accessPolicy) { + verifyAccessPolicyProviderIsConfigurable(); + writeLock.lock(); + try { + // Don't allow changing action or resource of existing policy (should only be adding/removing users/groups) + org.apache.nifi.registry.authorization.AccessPolicy currentAccessPolicy = + accessPolicyProvider.getAccessPolicy(accessPolicy.getIdentifier()); + accessPolicy.setResource(currentAccessPolicy.getResource()); + accessPolicy.setAction(currentAccessPolicy.getAction().toString()); + + org.apache.nifi.registry.authorization.AccessPolicy updateAccessPolicy = + ((ConfigurableAccessPolicyProvider) accessPolicyProvider).updateAccessPolicy(accessPolicyFromDTO(accessPolicy)); + return accessPolicyToDTO(updateAccessPolicy); + } finally { + writeLock.unlock(); + } + } + + public AccessPolicy deleteAccessPolicy(String identifier) { + verifyAccessPolicyProviderIsConfigurable(); + writeLock.lock(); + try { + AccessPolicy deletedAccessPolicyDTO = getAccessPolicy(identifier); + ((ConfigurableAccessPolicyProvider) accessPolicyProvider).deleteAccessPolicy(identifier); + return deletedAccessPolicyDTO; + } finally { + writeLock.unlock(); + } + } + + + // ---------------------- Resource Lookup methods -------------------------------------- + + public List<Resource> getAuthorizedResources(RequestAction actionType, ResourceType resourceType) { + final List<Resource> authorizedResources = + getAllAuthorizableResources() + .stream() + .filter(resource -> { + String resourceId = resource.getIdentifier(); + if (resourceType != null) { + if (!resourceId.startsWith(resourceType.getValue())) { + return false; + } + } + try { + authorizableLookup + .getAuthorizableByResource(resource.getIdentifier()) + .authorize(authorizer, actionType, NiFiUserUtils.getNiFiUser()); + } catch (AccessDeniedException e) { + return false; + } + return true; + + }) + .map(AuthorizationService::resourceToDTO) + .collect(Collectors.toList()); + + return authorizedResources; + } + + public List<Resource> getAuthorizedResources(RequestAction actionType) { + return getAuthorizedResources(actionType, null); + } + + public List<Resource> getResources() { + final List<Resource> dtoResources = + getAllAuthorizableResources() + .stream() + .map(AuthorizationService::resourceToDTO) + .collect(Collectors.toList()); + return dtoResources; + } + + + // ---------------------- Private Helper methods -------------------------------------- + + private void verifyUserGroupProviderIsConfigurable() { + if (!(userGroupProvider instanceof ConfigurableUserGroupProvider)) { + throw new IllegalStateException(MSG_NON_CONFIGURABLE_USERS); + } + } + + private void verifyAccessPolicyProviderIsConfigurable() { + if (!(accessPolicyProvider instanceof ConfigurableAccessPolicyProvider)) { + throw new IllegalStateException(MSG_NON_CONFIGURABLE_POLICIES); + } + } + + private List<org.apache.nifi.registry.authorization.Resource> getAllAuthorizableResources() { + final List<org.apache.nifi.registry.authorization.Resource> resources = new ArrayList<>(); + resources.add(ResourceFactory.getPoliciesResource()); + resources.add(ResourceFactory.getTenantResource()); + resources.add(ResourceFactory.getProxyResource()); + resources.add(ResourceFactory.getResourceResource()); + + // add all buckets + resources.add(ResourceFactory.getBucketsResource()); + for (final Bucket bucket : registryService.getBuckets(QueryParameters.EMPTY_PARAMETERS)) { + resources.add(ResourceFactory.getChildResource(ResourceType.Bucket, bucket.getIdentifier(), bucket.getName())); + } + + return resources; + } + + private org.apache.nifi.registry.model.authorization.User userToDTO( + final org.apache.nifi.registry.authorization.User user) { + if (user == null) { + return null; + } + String userIdentifier = user.getIdentifier(); + Collection<UserGroup> userGroups = getUserGroupsForUser(userIdentifier); + Collection<AccessPolicySummary> accessPolicySummaries = getAccessPolicySummariesForUser(userIdentifier); + + return userToDTO(user, userGroups, accessPolicySummaries); + } + + private org.apache.nifi.registry.model.authorization.UserGroup userGroupToDTO( + final org.apache.nifi.registry.authorization.Group userGroup) { + if (userGroup == null) { + return null; + } + Collection<Tenant> userTenants = userGroup.getUsers() != null + ? userGroup.getUsers().stream().map(this::getTenant).collect(Collectors.toSet()) : null; + Collection<AccessPolicySummary> accessPolicySummaries = getAccessPolicySummariesForUserGroup(userGroup.getIdentifier()); + + return userGroupToDTO(userGroup, userTenants, accessPolicySummaries); + } + + private org.apache.nifi.registry.model.authorization.AccessPolicy accessPolicyToDTO( + final org.apache.nifi.registry.authorization.AccessPolicy accessPolicy) { + if (accessPolicy == null) { + return null; + } + + Collection<Tenant> users = accessPolicy.getUsers() != null + ? accessPolicy.getUsers().stream().map(this::getTenant).collect(Collectors.toList()) : null; + Collection<Tenant> userGroups = accessPolicy.getGroups() != null + ? accessPolicy.getGroups().stream().map(this::getTenant).collect(Collectors.toList()) : null; + + Boolean isConfigurable = AuthorizerCapabilityDetection.isAccessPolicyConfigurable(authorizer, accessPolicy); + + return accessPolicyToDTO(accessPolicy, userGroups, users, isConfigurable); + } + + private org.apache.nifi.registry.model.authorization.AccessPolicySummary accessPolicyToSummaryDTO( + final org.apache.nifi.registry.authorization.AccessPolicy accessPolicy) { + if (accessPolicy == null) { + return null; + } + + Boolean isConfigurable = AuthorizerCapabilityDetection.isAccessPolicyConfigurable(authorizer, accessPolicy); + + final AccessPolicySummary accessPolicySummaryDTO = new AccessPolicySummary(); + accessPolicySummaryDTO.setIdentifier(accessPolicy.getIdentifier()); + accessPolicySummaryDTO.setAction(accessPolicy.getAction().toString()); + accessPolicySummaryDTO.setResource(accessPolicy.getResource()); + accessPolicySummaryDTO.setConfigurable(isConfigurable); + return accessPolicySummaryDTO; + } + + private static Resource resourceToDTO(org.apache.nifi.registry.authorization.Resource resource) { + if (resource == null) { + return null; + } + Resource resourceDto = new Resource(); + resourceDto.setIdentifier(resource.getIdentifier()); + resourceDto.setName(resource.getName()); + return resourceDto; + } + + private static Tenant tenantToDTO(org.apache.nifi.registry.authorization.User user) { + if (user == null) { + return null; + } + return new Tenant(user.getIdentifier(), user.getIdentity()); + } + + private static Tenant tenantToDTO(org.apache.nifi.registry.authorization.Group group) { + if (group == null) { + return null; + } + return new Tenant(group.getIdentifier(), group.getName()); + } + + private static org.apache.nifi.registry.authorization.User userFromDTO( + final org.apache.nifi.registry.model.authorization.User userDTO) { + if (userDTO == null) { + return null; + } + return new org.apache.nifi.registry.authorization.User.Builder() + .identifier(userDTO.getIdentifier() != null ? userDTO.getIdentifier() : UUID.randomUUID().toString()) + .identity(userDTO.getIdentity()) + .build(); + } + + private static org.apache.nifi.registry.model.authorization.User userToDTO( + final org.apache.nifi.registry.authorization.User user, + final Collection<? extends Tenant> userGroups, + final Collection<? extends AccessPolicySummary> accessPolicies) { + + if (user == null) { + return null; + } + User userDTO = new User(user.getIdentifier(), user.getIdentity()); + userDTO.addUserGroups(userGroups); + userDTO.addAccessPolicies(accessPolicies); + return userDTO; + } + + private static org.apache.nifi.registry.authorization.Group userGroupFromDTO( + final org.apache.nifi.registry.model.authorization.UserGroup userGroupDTO) { + if (userGroupDTO == null) { + return null; + } + org.apache.nifi.registry.authorization.Group.Builder groupBuilder = new org.apache.nifi.registry.authorization.Group.Builder() + .identifier(userGroupDTO.getIdentifier() != null ? userGroupDTO.getIdentifier() : UUID.randomUUID().toString()) + .name(userGroupDTO.getIdentity()); + Set<Tenant> users = userGroupDTO.getUsers(); + if (users != null) { + groupBuilder.addUsers(users.stream().map(Tenant::getIdentifier).collect(Collectors.toSet())); + } + return groupBuilder.build(); + } + + private static org.apache.nifi.registry.model.authorization.UserGroup userGroupToDTO( + final org.apache.nifi.registry.authorization.Group userGroup, + final Collection<? extends Tenant> users, + final Collection<? extends AccessPolicySummary> accessPolicies) { + if (userGroup == null) { + return null; + } + UserGroup userGroupDTO = new UserGroup(userGroup.getIdentifier(), userGroup.getName()); + userGroupDTO.addUsers(users); + userGroupDTO.addAccessPolicies(accessPolicies); + return userGroupDTO; + } + + private static org.apache.nifi.registry.authorization.AccessPolicy accessPolicyFromDTO( + final org.apache.nifi.registry.model.authorization.AccessPolicy accessPolicyDTO) { + org.apache.nifi.registry.authorization.AccessPolicy.Builder accessPolicyBuilder = + new org.apache.nifi.registry.authorization.AccessPolicy.Builder() + .identifier(accessPolicyDTO.getIdentifier() != null ? accessPolicyDTO.getIdentifier() : UUID.randomUUID().toString()) + .resource(accessPolicyDTO.getResource()) + .action(RequestAction.valueOfValue(accessPolicyDTO.getAction())); + + Set<Tenant> dtoUsers = accessPolicyDTO.getUsers(); + if (accessPolicyDTO.getUsers() != null) { + accessPolicyBuilder.addUsers(dtoUsers.stream().map(Tenant::getIdentifier).collect(Collectors.toSet())); + } + + Set<Tenant> dtoUserGroups = accessPolicyDTO.getUserGroups(); + if (dtoUserGroups != null) { + accessPolicyBuilder.addGroups(dtoUserGroups.stream().map(Tenant::getIdentifier).collect(Collectors.toSet())); + } + + return accessPolicyBuilder.build(); + } + + private static org.apache.nifi.registry.model.authorization.AccessPolicy accessPolicyToDTO( + final org.apache.nifi.registry.authorization.AccessPolicy accessPolicy, + final Collection<? extends Tenant> userGroups, + final Collection<? extends Tenant> users, + final Boolean isConfigurable) { + + if (accessPolicy == null) { + return null; + } + + final AccessPolicy accessPolicyDTO = new AccessPolicy(); + accessPolicyDTO.setIdentifier(accessPolicy.getIdentifier()); + accessPolicyDTO.setAction(accessPolicy.getAction().toString()); + accessPolicyDTO.setResource(accessPolicy.getResource()); + accessPolicyDTO.setConfigurable(isConfigurable); + accessPolicyDTO.addUsers(users); + accessPolicyDTO.addUserGroups(userGroups); + return accessPolicyDTO; + } + + private static AccessPolicyProvider createExceptionThrowingAccessPolicyProvider() { + + return new AccessPolicyProvider() { + @Override + public Set<org.apache.nifi.registry.authorization.AccessPolicy> getAccessPolicies() throws AuthorizationAccessException { + throw new IllegalStateException(MSG_NON_MANAGED_AUTHORIZER); + } + + @Override + public org.apache.nifi.registry.authorization.AccessPolicy getAccessPolicy(String identifier) throws AuthorizationAccessException { + throw new IllegalStateException(MSG_NON_MANAGED_AUTHORIZER); + } + + @Override + public org.apache.nifi.registry.authorization.AccessPolicy getAccessPolicy(String resourceIdentifier, RequestAction action) throws AuthorizationAccessException { + throw new IllegalStateException(MSG_NON_MANAGED_AUTHORIZER); + } + + @Override + public UserGroupProvider getUserGroupProvider() { + return new UserGroupProvider() { + @Override + public Set<org.apache.nifi.registry.authorization.User> getUsers() throws AuthorizationAccessException { + throw new IllegalStateException(MSG_NON_MANAGED_AUTHORIZER); + } + + @Override + public org.apache.nifi.registry.authorization.User getUser(String identifier) throws AuthorizationAccessException { + throw new IllegalStateException(MSG_NON_MANAGED_AUTHORIZER); + } + + @Override + public org.apache.nifi.registry.authorization.User getUserByIdentity(String identity) throws AuthorizationAccessException { + throw new IllegalStateException(MSG_NON_MANAGED_AUTHORIZER); + } + + @Override + public Set<Group> getGroups() throws AuthorizationAccessException { + throw new IllegalStateException(MSG_NON_MANAGED_AUTHORIZER); + } + + @Override + public Group getGroup(String identifier) throws AuthorizationAccessException { + throw new IllegalStateException(MSG_NON_MANAGED_AUTHORIZER); + } + + @Override + public UserAndGroups getUserAndGroups(String identity) throws AuthorizationAccessException { + throw new IllegalStateException(MSG_NON_MANAGED_AUTHORIZER); + } + + @Override + public void initialize(UserGroupProviderInitializationContext initializationContext) throws AuthorizerCreationException { + + } + + @Override + public void onConfigured(AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException { + + } + + @Override + public void preDestruction() throws AuthorizerDestructionException { + + } + }; + } + + @Override + public void initialize(AccessPolicyProviderInitializationContext initializationContext) throws AuthorizerCreationException { + } + + @Override + public void onConfigured(AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException { + } + + @Override + public void preDestruction() throws AuthorizerDestructionException { + } + }; + + } + +} http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/785cb81f/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/MetadataService.java ---------------------------------------------------------------------- diff --git a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/MetadataService.java b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/MetadataService.java index 3c17cee..2a85c84 100644 --- a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/MetadataService.java +++ b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/MetadataService.java @@ -96,6 +96,15 @@ public interface MetadataService { List<BucketItemEntity> getBucketItems(QueryParameters queryParameters, BucketEntity bucket); /** + * Retrieves items for the given buckets. + * + * @param bucketIds the ids of buckets to retrieve items for + * @param queryParameters the parameters for retrieving the items, or null + * @return the set of items for the bucket + */ + List<BucketItemEntity> getBucketItems(QueryParameters queryParameters, Set<String> bucketIds); + + /** * Creates a versioned flow in the given bucket. * * @param flow the versioned flow to create @@ -107,10 +116,11 @@ public interface MetadataService { /** * Retrieves the versioned flow with the given id. * + * @param bucketIdentifier the identifier of the bucket storing the flow * @param flowIdentifier the identifier of the flow to retrieve * @return the versioned flow with the given id, or null if no flow with the given id exists */ - FlowEntity getFlowById(String flowIdentifier); + FlowEntity getFlowById(String bucketIdentifier, String flowIdentifier); /** * Retrieves the versioned flows with the given name. The name comparison must be case-insensitive. @@ -144,6 +154,15 @@ public interface MetadataService { List<FlowEntity> getFlows(QueryParameters queryParameters); /** + * Retrieves items for the given buckets. + * + * @param bucketIds the ids of buckets to retrieve items for + * @param queryParameters the parameters for retrieving the items, or null + * @return the set of items for the bucket + */ + List<FlowEntity> getFlows(QueryParameters queryParameters, Set<String> bucketIds); + + /** * Creates a versioned flow snapshot. * * @param flowSnapshot the snapshot to create @@ -155,11 +174,12 @@ public interface MetadataService { /** * Retrieves the snapshot for the given flow identifier and snapshot version. * + * @param bucketIdentifier the identifier of the bucket storign the flow * @param flowIdentifier the identifier of the flow the snapshot belongs to * @param version the version of the snapshot * @return the versioned flow snapshot for the given flow identifier and version, or null if none exists */ - FlowSnapshotEntity getFlowSnapshot(String flowIdentifier, Integer version); + FlowSnapshotEntity getFlowSnapshot(String bucketIdentifier, String flowIdentifier, Integer version); /** * Deletes the flow snapshot. http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/785cb81f/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/RegistryService.java ---------------------------------------------------------------------- diff --git a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/RegistryService.java b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/RegistryService.java index fc067e6..f0fc927 100644 --- a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/RegistryService.java +++ b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/RegistryService.java @@ -261,6 +261,21 @@ public class RegistryService { } } + public List<BucketItem> getBucketItems(final QueryParameters queryParameters, final Set<String> bucketIdentifiers) { + if (bucketIdentifiers == null || bucketIdentifiers.isEmpty()) { + throw new IllegalArgumentException("Bucket Identifiers cannot be null or empty"); + } + + readLock.lock(); + try { + final List<BucketItem> bucketItems = new ArrayList<>(); + metadataService.getBucketItems(queryParameters, bucketIdentifiers).stream().forEach(b -> addBucketItem(bucketItems, b)); + return bucketItems; + } finally { + readLock.unlock(); + } + } + private void addBucketItem(final List<BucketItem> bucketItems, final BucketItemEntity itemEntity) { if (itemEntity instanceof FlowEntity) { final FlowEntity flowEntity = (FlowEntity) itemEntity; @@ -326,14 +341,14 @@ public class RegistryService { } } - public VersionedFlow getFlow(final String flowIdentifier, final boolean verbose) { + public VersionedFlow getFlow(final String bucketIdentifier, final String flowIdentifier, final boolean verbose) { if (StringUtils.isBlank(flowIdentifier)) { throw new IllegalArgumentException("Flow Identifier cannot be null or blank"); } readLock.lock(); try { - final FlowEntity flowEntity = metadataService.getFlowById(flowIdentifier); + final FlowEntity flowEntity = metadataService.getFlowById(bucketIdentifier, flowIdentifier); if (flowEntity == null) { throw new ResourceNotFoundException("VersionedFlow does not exist for identifier: " + flowIdentifier); } @@ -375,6 +390,17 @@ public class RegistryService { } } + public List<VersionedFlow> getFlows(final QueryParameters queryParameters, final Set<String> bucketIds) { + readLock.lock(); + try { + // return non-verbose set of all flows + final List<FlowEntity> flows = metadataService.getFlows(queryParameters, bucketIds); + return flows.stream().map(f -> DataModelMapper.map(f, false)).collect(Collectors.toList()); + } finally { + readLock.unlock(); + } + } + public VersionedFlow updateFlow(final VersionedFlow versionedFlow) { if (versionedFlow == null) { throw new IllegalArgumentException("VersionedFlow cannot be null"); @@ -384,10 +410,14 @@ public class RegistryService { throw new IllegalArgumentException("VersionedFlow identifier cannot be null or blank"); } + if (StringUtils.isBlank(versionedFlow.getBucketIdentifier())) { + throw new IllegalArgumentException("VersionedFlow bucket identifier cannot be null or blank"); + } + writeLock.lock(); try { // ensure a flow with the given id exists - final FlowEntity existingFlow = metadataService.getFlowById(versionedFlow.getIdentifier()); + final FlowEntity existingFlow = metadataService.getFlowById(versionedFlow.getBucketIdentifier(), versionedFlow.getIdentifier()); if (existingFlow == null) { throw new ResourceNotFoundException("VersionedFlow does not exist for identifier: " + versionedFlow.getIdentifier()); } @@ -422,7 +452,10 @@ public class RegistryService { } } - public VersionedFlow deleteFlow(final String flowIdentifier) { + public VersionedFlow deleteFlow(final String bucketIdentifier, final String flowIdentifier) { + if (StringUtils.isBlank(bucketIdentifier)) { + throw new IllegalArgumentException("Bucket Identifier cannot be null or blank"); + } if (StringUtils.isBlank(flowIdentifier)) { throw new IllegalArgumentException("Flow Identifier cannot be null or blank"); } @@ -430,7 +463,7 @@ public class RegistryService { writeLock.lock(); try { // ensure the flow exists - final FlowEntity existingFlow = metadataService.getFlowById(flowIdentifier); + final FlowEntity existingFlow = metadataService.getFlowById(bucketIdentifier, flowIdentifier); if (existingFlow == null) { throw new ResourceNotFoundException("VersionedFlow does not exist for identifier: " + flowIdentifier); } @@ -472,7 +505,7 @@ public class RegistryService { } // ensure the flow exists - final FlowEntity existingFlow = metadataService.getFlowById(snapshotMetadata.getFlowIdentifier()); + final FlowEntity existingFlow = metadataService.getFlowById(snapshotMetadata.getBucketIdentifier(), snapshotMetadata.getFlowIdentifier()); if (existingFlow == null) { throw new ResourceNotFoundException("VersionedFlow does not exist for identifier: " + snapshotMetadata.getFlowIdentifier()); } @@ -518,9 +551,13 @@ public class RegistryService { } } - public VersionedFlowSnapshot getFlowSnapshot(final String flowIdentifier, final Integer version) { + public VersionedFlowSnapshot getFlowSnapshot(final String bucketIdentifier, final String flowIdentifier, final Integer version) { + if (StringUtils.isBlank(bucketIdentifier)) { + throw new IllegalArgumentException("Bucket identifier cannot be null or blank"); + } + if (StringUtils.isBlank(flowIdentifier)) { - throw new IllegalArgumentException("Flow Identifier cannot be null or blank"); + throw new IllegalArgumentException("Flow identifier cannot be null or blank"); } if (version == null) { @@ -530,17 +567,13 @@ public class RegistryService { readLock.lock(); try { // ensure the snapshot exists - final FlowSnapshotEntity snapshotEntity = metadataService.getFlowSnapshot(flowIdentifier, version); + final FlowSnapshotEntity snapshotEntity = metadataService.getFlowSnapshot(bucketIdentifier, flowIdentifier, version); if (snapshotEntity == null) { throw new ResourceNotFoundException("VersionedFlowSnapshot does not exist for flow " + flowIdentifier + " and version " + version); } - final FlowEntity flow = snapshotEntity.getFlow(); - final String flowId = flow.getId(); - final String bucketId = flow.getBucket().getId(); - // get the serialized bytes of the snapshot - final byte[] serializedSnapshot = flowPersistenceProvider.getSnapshot(bucketId, flowId, version); + final byte[] serializedSnapshot = flowPersistenceProvider.getSnapshot(bucketIdentifier, flowIdentifier, version); if (serializedSnapshot == null || serializedSnapshot.length == 0) { throw new IllegalStateException("No serialized content found for snapshot with flow identifier " @@ -554,9 +587,13 @@ public class RegistryService { } } - public VersionedFlowSnapshotMetadata deleteFlowSnapshot(final String flowIdentifier, final Integer version) { + public VersionedFlowSnapshotMetadata deleteFlowSnapshot(final String bucketIdentifier, final String flowIdentifier, final Integer version) { + if (StringUtils.isBlank(bucketIdentifier)) { + throw new IllegalArgumentException("Bucket identifier cannot be null or blank"); + } + if (StringUtils.isBlank(flowIdentifier)) { - throw new IllegalArgumentException("Flow Identifier cannot be null or blank"); + throw new IllegalArgumentException("Flow identifier cannot be null or blank"); } if (version == null) { @@ -566,18 +603,14 @@ public class RegistryService { writeLock.lock(); try { // ensure the snapshot exists - final FlowSnapshotEntity snapshotEntity = metadataService.getFlowSnapshot(flowIdentifier, version); + final FlowSnapshotEntity snapshotEntity = metadataService.getFlowSnapshot(bucketIdentifier, flowIdentifier, version); if (snapshotEntity == null) { throw new ResourceNotFoundException("VersionedFlowSnapshot does not exist for flow " + flowIdentifier + " and version " + version); } - final FlowEntity flow = snapshotEntity.getFlow(); - final String flowId = flow.getId(); - final String bucketId = flow.getBucket().getId(); - // delete the content of the snapshot - flowPersistenceProvider.deleteSnapshot(bucketId, flowId, version); + flowPersistenceProvider.deleteSnapshot(bucketIdentifier, flowIdentifier, version); // delete the snapshot itself metadataService.deleteFlowSnapshot(snapshotEntity); http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/785cb81f/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/params/QueryParameters.java ---------------------------------------------------------------------- diff --git a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/params/QueryParameters.java b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/params/QueryParameters.java index 3c62a9d..9f30f75 100644 --- a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/params/QueryParameters.java +++ b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/params/QueryParameters.java @@ -26,6 +26,8 @@ import java.util.List; */ public class QueryParameters { + public static final QueryParameters EMPTY_PARAMETERS = new QueryParameters.Builder().build(); + private final Integer pageNum; private final Integer numRows; http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/785cb81f/nifi-registry-framework/src/main/xsd/authorizers.xsd ---------------------------------------------------------------------- diff --git a/nifi-registry-framework/src/main/xsd/authorizers.xsd b/nifi-registry-framework/src/main/xsd/authorizers.xsd new file mode 100644 index 0000000..278ff09 --- /dev/null +++ b/nifi-registry-framework/src/main/xsd/authorizers.xsd @@ -0,0 +1,67 @@ +<?xml version="1.0"?> +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one or more + ~ contributor license agreements. See the NOTICE file distributed with + ~ this work for additional information regarding copyright ownership. + ~ The ASF licenses this file to You under the Apache License, Version 2.0 + ~ (the "License"); you may not use this file except in compliance with + ~ the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + + <!-- user group providers type --> + <xs:complexType name="UserGroupProvider"> + <xs:sequence> + <xs:element name="identifier" type="xs:string"/> + <xs:element name="class" type="xs:string"/> + <xs:element name="property" type="Prop" minOccurs="0" maxOccurs="unbounded" /> + </xs:sequence> + </xs:complexType> + + <!-- access policy provider type --> + <xs:complexType name="AccessPolicyProvider"> + <xs:sequence> + <xs:element name="identifier" type="xs:string"/> + <xs:element name="class" type="xs:string"/> + <xs:element name="property" type="Prop" minOccurs="0" maxOccurs="unbounded" /> + </xs:sequence> + </xs:complexType> + + <!-- authorizers type --> + <xs:complexType name="Authorizer"> + <xs:sequence> + <xs:element name="identifier" type="xs:string"/> + <xs:element name="class" type="xs:string"/> + <xs:element name="classpath" type="xs:string" minOccurs="0"/> + <xs:element name="property" type="Prop" minOccurs="0" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + + <!-- Name/Value properties--> + <xs:complexType name="Prop"> + <xs:simpleContent> + <xs:extension base="xs:string"> + <xs:attribute name="name" type="xs:string"></xs:attribute> + </xs:extension> + </xs:simpleContent> + </xs:complexType> + + <!-- authorizers --> + <xs:element name="authorizers"> + <xs:complexType> + <xs:sequence> + <xs:element name="userGroupProvider" type="UserGroupProvider" minOccurs="0" maxOccurs="unbounded"/> + <xs:element name="accessPolicyProvider" type="AccessPolicyProvider" minOccurs="0" maxOccurs="unbounded"/> + <xs:element name="authorizer" type="Authorizer" minOccurs="0" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> +</xs:schema> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/785cb81f/nifi-registry-framework/src/test/java/org/apache/nifi/registry/service/TestRegistryService.java ---------------------------------------------------------------------- diff --git a/nifi-registry-framework/src/test/java/org/apache/nifi/registry/service/TestRegistryService.java b/nifi-registry-framework/src/test/java/org/apache/nifi/registry/service/TestRegistryService.java index d4b42cf..2efa320 100644 --- a/nifi-registry-framework/src/test/java/org/apache/nifi/registry/service/TestRegistryService.java +++ b/nifi-registry-framework/src/test/java/org/apache/nifi/registry/service/TestRegistryService.java @@ -356,8 +356,8 @@ public class TestRegistryService { @Test(expected = ResourceNotFoundException.class) public void testGetFlowDoesNotExist() { - when(metadataService.getFlowById(any(String.class))).thenReturn(null); - registryService.getFlow("flow1", false); + when(metadataService.getFlowById(any(String.class), any(String.class))).thenReturn(null); + registryService.getFlow("bucket1","flow1", false); } @Test @@ -376,9 +376,9 @@ public class TestRegistryService { flowEntity.setModified(new Date()); flowEntity.setBucket(existingBucket); - when(metadataService.getFlowById(flowEntity.getId())).thenReturn(flowEntity); + when(metadataService.getFlowById(existingBucket.getId(), flowEntity.getId())).thenReturn(flowEntity); - final VersionedFlow versionedFlow = registryService.getFlow(flowEntity.getId(), false); + final VersionedFlow versionedFlow = registryService.getFlow(existingBucket.getId(), flowEntity.getId(), false); assertNotNull(versionedFlow); assertEquals(flowEntity.getId(), versionedFlow.getIdentifier()); assertEquals(flowEntity.getName(), versionedFlow.getName()); @@ -475,9 +475,10 @@ public class TestRegistryService { @Test(expected = ResourceNotFoundException.class) public void testUpdateFlowDoesNotExist() { final VersionedFlow versionedFlow = new VersionedFlow(); + versionedFlow.setBucketIdentifier("b1"); versionedFlow.setIdentifier("flow1"); - when(metadataService.getFlowById(versionedFlow.getIdentifier())).thenReturn(null); + when(metadataService.getFlowById(versionedFlow.getBucketIdentifier(), versionedFlow.getIdentifier())).thenReturn(null); registryService.updateFlow(versionedFlow); } @@ -498,7 +499,7 @@ public class TestRegistryService { flowToUpdate.setModified(new Date()); flowToUpdate.setBucket(existingBucket); - when(metadataService.getFlowById(flowToUpdate.getId())).thenReturn(flowToUpdate); + when(metadataService.getFlowById(existingBucket.getId(), flowToUpdate.getId())).thenReturn(flowToUpdate); final FlowEntity otherFlow = new FlowEntity(); otherFlow.setId("flow2"); @@ -512,6 +513,7 @@ public class TestRegistryService { final VersionedFlow versionedFlow = new VersionedFlow(); versionedFlow.setIdentifier(flowToUpdate.getId()); + versionedFlow.setBucketIdentifier(existingBucket.getId()); versionedFlow.setName(otherFlow.getName()); registryService.updateFlow(versionedFlow); @@ -533,12 +535,13 @@ public class TestRegistryService { flowToUpdate.setModified(new Date()); flowToUpdate.setBucket(existingBucket); - when(metadataService.getFlowById(flowToUpdate.getId())).thenReturn(flowToUpdate); + when(metadataService.getFlowById(existingBucket.getId(), flowToUpdate.getId())).thenReturn(flowToUpdate); when(metadataService.getFlowsByName(flowToUpdate.getName())).thenReturn(Collections.singletonList(flowToUpdate)); doAnswer(updateFlowAnswer()).when(metadataService).updateFlow(any(FlowEntity.class)); final VersionedFlow versionedFlow = new VersionedFlow(); + versionedFlow.setBucketIdentifier(flowToUpdate.getBucket().getId()); versionedFlow.setIdentifier(flowToUpdate.getId()); versionedFlow.setName("New Flow Name"); versionedFlow.setDescription("This is a new description"); @@ -560,8 +563,8 @@ public class TestRegistryService { @Test(expected = ResourceNotFoundException.class) public void testDeleteFlowDoesNotExist() { - when(metadataService.getFlowById(any(String.class))).thenReturn(null); - registryService.deleteFlow("flow1"); + when(metadataService.getFlowById(any(String.class), any(String.class))).thenReturn(null); + registryService.deleteFlow("b1", "flow1"); } @Test @@ -580,10 +583,10 @@ public class TestRegistryService { flowToDelete.setModified(new Date()); flowToDelete.setBucket(existingBucket); - when(metadataService.getFlowById(flowToDelete.getId())).thenReturn(flowToDelete); + when(metadataService.getFlowById(existingBucket.getId(), flowToDelete.getId())).thenReturn(flowToDelete); when(metadataService.getFlowsByName(flowToDelete.getName())).thenReturn(Collections.singletonList(flowToDelete)); - final VersionedFlow deletedFlow = registryService.deleteFlow(flowToDelete.getId()); + final VersionedFlow deletedFlow = registryService.deleteFlow(existingBucket.getId(), flowToDelete.getId()); assertNotNull(deletedFlow); assertEquals(flowToDelete.getId(), deletedFlow.getIdentifier()); @@ -662,7 +665,7 @@ public class TestRegistryService { when(metadataService.getBucketById(existingBucket.getId())).thenReturn(existingBucket); - when(metadataService.getFlowById(snapshot.getSnapshotMetadata().getFlowIdentifier())).thenReturn(null); + when(metadataService.getFlowById(existingBucket.getId(), snapshot.getSnapshotMetadata().getFlowIdentifier())).thenReturn(null); registryService.createFlowSnapshot(snapshot); } @@ -701,7 +704,7 @@ public class TestRegistryService { existingFlow.setSnapshots(Collections.singleton(existingSnapshot)); - when(metadataService.getFlowById(existingFlow.getId())).thenReturn(existingFlow); + when(metadataService.getFlowById(existingBucket.getId(), existingFlow.getId())).thenReturn(existingFlow); registryService.createFlowSnapshot(snapshot); } @@ -740,7 +743,7 @@ public class TestRegistryService { existingFlow.setSnapshots(Collections.singleton(existingSnapshot)); - when(metadataService.getFlowById(existingFlow.getId())).thenReturn(existingFlow); + when(metadataService.getFlowById(existingBucket.getId(), existingFlow.getId())).thenReturn(existingFlow); // set the version to something that is not the next one-up version snapshot.getSnapshotMetadata().setVersion(100); @@ -768,7 +771,7 @@ public class TestRegistryService { existingFlow.setModified(new Date()); existingFlow.setBucket(existingBucket); - when(metadataService.getFlowById(existingFlow.getId())).thenReturn(existingFlow); + when(metadataService.getFlowById(existingBucket.getId(), existingFlow.getId())).thenReturn(existingFlow); final VersionedFlowSnapshot createdSnapshot = registryService.createFlowSnapshot(snapshot); assertNotNull(createdSnapshot); @@ -799,7 +802,7 @@ public class TestRegistryService { existingFlow.setModified(new Date()); existingFlow.setBucket(existingBucket); - when(metadataService.getFlowById(existingFlow.getId())).thenReturn(existingFlow); + when(metadataService.getFlowById(existingBucket.getId(), existingFlow.getId())).thenReturn(existingFlow); // set the first version to something other than 1 snapshot.getSnapshotMetadata().setVersion(100); @@ -808,18 +811,20 @@ public class TestRegistryService { @Test(expected = ResourceNotFoundException.class) public void testGetSnapshotDoesNotExistInMetadataProvider() { + final String bucketId = "b1"; final String flowId = "flow1"; final Integer version = 1; - when(metadataService.getFlowSnapshot(flowId, version)).thenReturn(null); - registryService.getFlowSnapshot(flowId, version); + when(metadataService.getFlowSnapshot(bucketId, flowId, version)).thenReturn(null); + registryService.getFlowSnapshot(bucketId, flowId, version); } @Test(expected = IllegalStateException.class) public void testGetSnapshotDoesNotExistInPersistenceProvider() { final FlowSnapshotEntity existingSnapshot = createFlowSnapshotEntity(); final FlowSnapshotEntityKey key = existingSnapshot.getId(); + final String bucketId = existingSnapshot.getFlow().getBucket().getId(); - when(metadataService.getFlowSnapshot(key.getFlowId(), key.getVersion())).thenReturn(existingSnapshot); + when(metadataService.getFlowSnapshot(bucketId, key.getFlowId(), key.getVersion())).thenReturn(existingSnapshot); when(flowPersistenceProvider.getSnapshot( existingSnapshot.getFlow().getBucket().getId(), @@ -827,15 +832,16 @@ public class TestRegistryService { existingSnapshot.getId().getVersion() )).thenReturn(null); - registryService.getFlowSnapshot(existingSnapshot.getFlow().getId(), existingSnapshot.getId().getVersion()); + registryService.getFlowSnapshot(bucketId, existingSnapshot.getFlow().getId(), existingSnapshot.getId().getVersion()); } @Test public void testGetSnapshotExists() { final FlowSnapshotEntity existingSnapshot = createFlowSnapshotEntity(); final FlowSnapshotEntityKey key = existingSnapshot.getId(); + final String bucketId = existingSnapshot.getFlow().getBucket().getId(); - when(metadataService.getFlowSnapshot(key.getFlowId(), key.getVersion())) + when(metadataService.getFlowSnapshot(bucketId, key.getFlowId(), key.getVersion())) .thenReturn(existingSnapshot); // return a non-null, non-zero-length array so something gets passed to the serializer @@ -849,27 +855,29 @@ public class TestRegistryService { when(snapshotSerializer.deserialize(any(InputStream.class))).thenReturn(snapshotToDeserialize); final VersionedFlowSnapshot returnedSnapshot = registryService.getFlowSnapshot( - existingSnapshot.getFlow().getId(), existingSnapshot.getId().getVersion()); + bucketId, existingSnapshot.getFlow().getId(), existingSnapshot.getId().getVersion()); assertNotNull(returnedSnapshot); } @Test(expected = ResourceNotFoundException.class) public void testDeleteSnapshotDoesNotExist() { + final String bucketId = "b1"; final String flowId = "flow1"; final Integer version = 1; - when(metadataService.getFlowSnapshot(flowId, version)).thenReturn(null); - registryService.deleteFlowSnapshot(flowId, version); + when(metadataService.getFlowSnapshot(bucketId, flowId, version)).thenReturn(null); + registryService.deleteFlowSnapshot(bucketId, flowId, version); } @Test public void testDeleteSnapshotExists() { final FlowSnapshotEntity existingSnapshot = createFlowSnapshotEntity(); final FlowSnapshotEntityKey key = existingSnapshot.getId(); + final String bucketId = existingSnapshot.getFlow().getBucket().getId(); - when(metadataService.getFlowSnapshot(key.getFlowId(), key.getVersion())) + when(metadataService.getFlowSnapshot(bucketId, key.getFlowId(), key.getVersion())) .thenReturn(existingSnapshot); - final VersionedFlowSnapshotMetadata deletedSnapshot = registryService.deleteFlowSnapshot(key.getFlowId(), key.getVersion()); + final VersionedFlowSnapshotMetadata deletedSnapshot = registryService.deleteFlowSnapshot(bucketId, key.getFlowId(), key.getVersion()); assertNotNull(deletedSnapshot); assertEquals(existingSnapshot.getId().getFlowId(), deletedSnapshot.getFlowIdentifier()); http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/785cb81f/nifi-registry-jetty/pom.xml ---------------------------------------------------------------------- diff --git a/nifi-registry-jetty/pom.xml b/nifi-registry-jetty/pom.xml index e47a354..8961ae1 100644 --- a/nifi-registry-jetty/pom.xml +++ b/nifi-registry-jetty/pom.xml @@ -30,11 +30,6 @@ <version>0.0.1-SNAPSHOT</version> </dependency> <dependency> - <groupId>org.apache.nifi.registry</groupId> - <artifactId>nifi-registry-security</artifactId> - <version>0.0.1-SNAPSHOT</version> - </dependency> - <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-server</artifactId> </dependency> http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/785cb81f/nifi-registry-properties/src/main/java/org/apache/nifi/registry/properties/NiFiRegistryProperties.java ---------------------------------------------------------------------- diff --git a/nifi-registry-properties/src/main/java/org/apache/nifi/registry/properties/NiFiRegistryProperties.java b/nifi-registry-properties/src/main/java/org/apache/nifi/registry/properties/NiFiRegistryProperties.java index 6aac4a6..b3ebf9d 100644 --- a/nifi-registry-properties/src/main/java/org/apache/nifi/registry/properties/NiFiRegistryProperties.java +++ b/nifi-registry-properties/src/main/java/org/apache/nifi/registry/properties/NiFiRegistryProperties.java @@ -17,7 +17,11 @@ package org.apache.nifi.registry.properties; import java.io.File; +import java.util.Enumeration; +import java.util.HashSet; import java.util.Properties; +import java.util.Set; + import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,7 +47,11 @@ public class NiFiRegistryProperties extends Properties { public static final String SECURITY_TRUSTSTORE_TYPE = "nifi.registry.security.truststoreType"; public static final String SECURITY_TRUSTSTORE_PASSWD = "nifi.registry.security.truststorePasswd"; public static final String SECURITY_NEED_CLIENT_AUTH = "nifi.registry.security.needClientAuth"; - public static final String SECURITY_AUTHORIZED_USERS = "nifi.registry.security.authorized.users"; + public static final String SECURITY_AUTHORIZERS_CONFIGURATION_FILE = "nifi.registry.security.authorizers.configuration.file"; + public static final String SECURITY_AUTHORIZER = "nifi.registry.security.authorizer"; + public static final String SECURITY_IDENTITY_MAPPING_PATTERN_PREFIX = "nifi.registry.security.identity.mapping.pattern."; + public static final String SECURITY_IDENTITY_MAPPING_VALUE_PREFIX = "nifi.registry.security.identity.mapping.value."; + public static final String PROVIDERS_CONFIGURATION_FILE = "nifi.registry.providers.configuration.file"; @@ -54,6 +62,7 @@ public class NiFiRegistryProperties extends Properties { public static final String DEFAULT_WEB_WORKING_DIR = "./work/jetty"; public static final String DEFAULT_WAR_DIR = "./lib"; public static final String DEFAULT_PROVIDERS_CONFIGURATION_FILE = "./conf/providers.xml"; + public static final String DEFAULT_SECURITY_AUTHORIZERS_CONFIGURATION_FILE = "./conf/authorizers.xml"; public int getWebThreads() { int webThreads = 200; @@ -142,14 +151,6 @@ public class NiFiRegistryProperties extends Properties { return new File(getProperty(WEB_WORKING_DIR, DEFAULT_WEB_WORKING_DIR)); } - public File getAuthorizedUsersFile() { - final String authorizedUsersFile = getProperty(SECURITY_AUTHORIZED_USERS); - if (StringUtils.isBlank(authorizedUsersFile)) { - return null; - } - return new File(authorizedUsersFile); - } - public File getProvidersConfigurationFile() { final String value = getProperty(PROVIDERS_CONFIGURATION_FILE); if (StringUtils.isBlank(value)) { @@ -167,4 +168,28 @@ public class NiFiRegistryProperties extends Properties { return getProperty(DATABASE_URL_APPEND); } + + public File getAuthorizersConfigurationFile() { + final String value = getProperty(SECURITY_AUTHORIZERS_CONFIGURATION_FILE); + if (StringUtils.isBlank(value)) { + return new File(DEFAULT_SECURITY_AUTHORIZERS_CONFIGURATION_FILE); + } else { + return new File(value); + } + } + + /** + * Retrieves all known property keys. + * + * @return all known property keys + */ + public Set<String> getPropertyKeys() { + Set<String> propertyNames = new HashSet<>(); + Enumeration e = this.propertyNames(); + for (; e.hasMoreElements(); ){ + propertyNames.add((String) e.nextElement()); + } + + return propertyNames; + } } http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/785cb81f/nifi-registry-properties/src/main/java/org/apache/nifi/registry/properties/util/IdentityMapping.java ---------------------------------------------------------------------- diff --git a/nifi-registry-properties/src/main/java/org/apache/nifi/registry/properties/util/IdentityMapping.java b/nifi-registry-properties/src/main/java/org/apache/nifi/registry/properties/util/IdentityMapping.java new file mode 100644 index 0000000..df3bbe6 --- /dev/null +++ b/nifi-registry-properties/src/main/java/org/apache/nifi/registry/properties/util/IdentityMapping.java @@ -0,0 +1,48 @@ +/* + * 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.registry.properties.util; + +import java.util.regex.Pattern; + +/** + * Holder to pass around the key, pattern, and replacement from an identity mapping in NiFiProperties. + */ +public class IdentityMapping { + + private final String key; + private final Pattern pattern; + private final String replacementValue; + + public IdentityMapping(String key, Pattern pattern, String replacementValue) { + this.key = key; + this.pattern = pattern; + this.replacementValue = replacementValue; + } + + public String getKey() { + return key; + } + + public Pattern getPattern() { + return pattern; + } + + public String getReplacementValue() { + return replacementValue; + } + +}
