[ 
https://issues.apache.org/jira/browse/NIFIREG-9?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16190327#comment-16190327
 ] 

ASF GitHub Bot commented on NIFIREG-9:
--------------------------------------

Github user kevdoran commented on a diff in the pull request:

    https://github.com/apache/nifi-registry/pull/14#discussion_r142518769
  
    --- Diff: 
nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/AuthorizationService.java
 ---
    @@ -0,0 +1,696 @@
    +/*
    + * 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.AccessDeniedException;
    +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.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.AuthorizerCreationException;
    +import 
org.apache.nifi.registry.authorization.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();
    +
    +        // Don't allow changing action or resource of existing policy 
(should only be adding/removing users/groups)
    +        org.apache.nifi.registry.authorization.AccessPolicy 
currentAccessPolicy =
    --- End diff --
    
    The idea here is that no user can change the accessPolicy identifier, 
resource, or action fields on update. They can only change groups or users that 
have an access policy. To change resource or action, they would have to delete 
and create a new access policy.
    
    So in your example, user1 and user2 both get the initial version, but those 
should be guaranteed to match. Unless I'm making a mistake in my logic...
    
    That said, I think I'll move it to inside the write lock anyway, as it 
won't hurt and would protect  this code block from future changes that break 
the expectation I had.


> Define web REST API endpoints for user, group, and policy management
> --------------------------------------------------------------------
>
>                 Key: NIFIREG-9
>                 URL: https://issues.apache.org/jira/browse/NIFIREG-9
>             Project: NiFi Registry
>          Issue Type: New Feature
>            Reporter: Kevin Doran
>            Assignee: Kevin Doran
>             Fix For: 0.0.1
>
>
> NIFIREG-8 defined web REST API endpoints for domain objects such as buckets 
> and flows.
> This ticket scopes work to build on that by adding endpoints for additional 
> resources to facilitate user, group, and policy management.
> The interface for user, group, and policy management will be based on the 
> NiFi API so as to minimize the effort for NiFi API clients to be reused for 
> NiFi Registry.



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)

Reply via email to