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

ASF GitHub Bot commented on NIFI-1952:
--------------------------------------

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

    https://github.com/apache/nifi/pull/526#discussion_r66966699
  
    --- Diff: 
nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/UserGroupsResource.java
 ---
    @@ -0,0 +1,373 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +package org.apache.nifi.web.api;
    +
    +import com.wordnik.swagger.annotations.Api;
    +import com.wordnik.swagger.annotations.ApiOperation;
    +import com.wordnik.swagger.annotations.ApiParam;
    +import com.wordnik.swagger.annotations.ApiResponse;
    +import com.wordnik.swagger.annotations.ApiResponses;
    +import com.wordnik.swagger.annotations.Authorization;
    +import org.apache.commons.lang3.StringUtils;
    +import org.apache.nifi.authorization.Authorizer;
    +import org.apache.nifi.authorization.RequestAction;
    +import org.apache.nifi.authorization.resource.Authorizable;
    +import org.apache.nifi.web.NiFiServiceFacade;
    +import org.apache.nifi.web.Revision;
    +import org.apache.nifi.web.UpdateResult;
    +import org.apache.nifi.web.api.dto.UserGroupDTO;
    +import org.apache.nifi.web.api.entity.UserGroupEntity;
    +import org.apache.nifi.web.api.request.ClientIdParameter;
    +import org.apache.nifi.web.api.request.LongParameter;
    +
    +import javax.servlet.http.HttpServletRequest;
    +import javax.ws.rs.Consumes;
    +import javax.ws.rs.DELETE;
    +import javax.ws.rs.DefaultValue;
    +import javax.ws.rs.GET;
    +import javax.ws.rs.HttpMethod;
    +import javax.ws.rs.POST;
    +import javax.ws.rs.PUT;
    +import javax.ws.rs.Path;
    +import javax.ws.rs.PathParam;
    +import javax.ws.rs.Produces;
    +import javax.ws.rs.QueryParam;
    +import javax.ws.rs.core.Context;
    +import javax.ws.rs.core.MediaType;
    +import javax.ws.rs.core.Response;
    +import java.net.URI;
    +
    +@Path("/usergroups")
    +@Api(
    +        value = "/usergroups",
    +        description = "Endpoint for managing user groups."
    +)
    +public class UserGroupsResource extends ApplicationResource {
    +
    +    final private NiFiServiceFacade serviceFacade;
    +    final private Authorizer authorizer;
    +
    +    public UserGroupsResource(NiFiServiceFacade serviceFacade, Authorizer 
authorizer) {
    +        this.serviceFacade = serviceFacade;
    +        this.authorizer = authorizer;
    +    }
    +
    +    /**
    +     * Populates the uri for the specified user group.
    +     *
    +     * @param userGroupEntity userGroupEntity
    +     * @return userGroupEntity
    +     */
    +    public UserGroupEntity 
populateRemainingUserGroupEntityContent(UserGroupEntity userGroupEntity) {
    +        if (userGroupEntity.getComponent() != null) {
    +            
populateRemainingUserGroupContent(userGroupEntity.getComponent());
    +        }
    +        return userGroupEntity;
    +    }
    +
    +    /**
    +     * Populates the uri for the specified userGroup.
    +     */
    +    public UserGroupDTO populateRemainingUserGroupContent(UserGroupDTO 
userGroup) {
    +        // populate the user group href
    +        userGroup.setUri(generateResourceUri("usergroups", 
userGroup.getId()));
    +        return userGroup;
    +    }
    +
    +    /**
    +     * Creates a new user group.
    +     *
    +     * @param httpServletRequest request
    +     * @param userGroupEntity An userGroupEntity.
    +     * @return An userGroupEntity.
    +     */
    +    @POST
    +    @Consumes(MediaType.APPLICATION_JSON)
    +    @Produces(MediaType.APPLICATION_JSON)
    +    // TODO - @PreAuthorize("hasRole('ROLE_DFM')")
    +    @ApiOperation(
    +            value = "Creates a user group",
    +            response = UserGroupEntity.class,
    +            authorizations = {
    +                    @Authorization(value = "Data Flow Manager", type = 
"ROLE_DFM")
    +            }
    +    )
    +    @ApiResponses(
    +            value = {
    +                    @ApiResponse(code = 400, message = "NiFi was unable to 
complete the request because it was invalid. The request should not be retried 
without modification."),
    +                    @ApiResponse(code = 401, message = "Client could not 
be authenticated."),
    +                    @ApiResponse(code = 403, message = "Client is not 
authorized to make this request."),
    +                    @ApiResponse(code = 404, message = "The specified 
resource could not be found."),
    +                    @ApiResponse(code = 409, message = "The request was 
valid but NiFi was not in the appropriate state to process it. Retrying the 
same request later may be successful.")
    +            }
    +    )
    +    public Response createUserGroup(
    +            @Context final HttpServletRequest httpServletRequest,
    +            @ApiParam(
    +                    value = "The user group configuration details.",
    +                    required = true
    +            ) final UserGroupEntity userGroupEntity) {
    +
    +        if (userGroupEntity == null || userGroupEntity.getComponent() == 
null) {
    +            throw new IllegalArgumentException("User group details must be 
specified.");
    +        }
    +
    +        if (userGroupEntity.getComponent().getId() != null) {
    +            throw new IllegalArgumentException("User group ID cannot be 
specified.");
    +        }
    +
    +        if (isReplicateRequest()) {
    +            return replicate(HttpMethod.POST, userGroupEntity);
    +        }
    +
    +        // handle expects request (usually from the cluster manager)
    +        final boolean validationPhase = 
isValidationPhase(httpServletRequest);
    +        if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) {
    +            // authorize access
    +            serviceFacade.authorizeAccess(lookup -> {
    +                final Authorizable userGroups = 
lookup.getUserGroupsAuthorizable();
    +                userGroups.authorize(authorizer, RequestAction.WRITE);
    +            });
    +        }
    +        if (validationPhase) {
    +            return generateContinueResponse().build();
    +        }
    +
    +        // set the user group id as appropriate
    +        userGroupEntity.getComponent().setId(generateUuid());
    +
    +        // create the user group and generate the json
    +        final UserGroupEntity entity = 
serviceFacade.createUserGroup(userGroupEntity.getComponent());
    +        populateRemainingUserGroupEntityContent(entity);
    +
    +        // build the response
    +        return 
clusterContext(generateCreatedResponse(URI.create(entity.getComponent().getUri()),
 entity)).build();
    +    }
    +
    +    /**
    +     * Retrieves the specified user group.
    +     *
    +     * @param id The id of the user group to retrieve
    +     * @return An userGroupEntity.
    +     */
    +    @GET
    +    @Consumes(MediaType.WILDCARD)
    +    @Produces(MediaType.APPLICATION_JSON)
    +    @Path("{id}")
    +    // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 
'ROLE_ADMIN')")
    +    @ApiOperation(
    +            value = "Gets a user group",
    +            response = UserGroupEntity.class,
    +            authorizations = {
    +                    @Authorization(value = "Read Only", type = 
"ROLE_MONITOR"),
    +                    @Authorization(value = "Data Flow Manager", type = 
"ROLE_DFM"),
    +                    @Authorization(value = "Administrator", type = 
"ROLE_ADMIN")
    +            }
    +    )
    +    @ApiResponses(
    +            value = {
    +                    @ApiResponse(code = 400, message = "NiFi was unable to 
complete the request because it was invalid. The request should not be retried 
without modification."),
    +                    @ApiResponse(code = 401, message = "Client could not 
be authenticated."),
    +                    @ApiResponse(code = 403, message = "Client is not 
authorized to make this request."),
    +                    @ApiResponse(code = 404, message = "The specified 
resource could not be found."),
    +                    @ApiResponse(code = 409, message = "The request was 
valid but NiFi was not in the appropriate state to process it. Retrying the 
same request later may be successful.")
    +            }
    +    )
    +    public Response getUserGroup(
    +            @ApiParam(
    +                    value = "The user group id.",
    +                    required = true
    +            )
    +            @PathParam("id") final String id) {
    +
    +        if (isReplicateRequest()) {
    +            return replicate(HttpMethod.GET);
    +        }
    +
    +        // authorize access
    +        serviceFacade.authorizeAccess(lookup -> {
    +            final Authorizable userGroups = 
lookup.getUserGroupsAuthorizable();
    +            userGroups.authorize(authorizer, RequestAction.READ);
    +        });
    +
    +        // get the user group
    +        final UserGroupEntity entity = serviceFacade.getUserGroup(id);
    +        populateRemainingUserGroupEntityContent(entity);
    +
    +        return clusterContext(generateOkResponse(entity)).build();
    +    }
    +
    +    /**
    +     * Updates a user group.
    +     *
    +     * @param httpServletRequest request
    +     * @param id The id of the user group to update.
    +     * @param userGroupEntity An userGroupEntity.
    +     * @return An userGroupEntity.
    +     */
    +    @PUT
    +    @Consumes(MediaType.APPLICATION_JSON)
    +    @Produces(MediaType.APPLICATION_JSON)
    +    @Path("{id}")
    +    // TODO - @PreAuthorize("hasRole('ROLE_DFM')")
    +    @ApiOperation(
    +            value = "Updates a user group",
    +            response = UserGroupEntity.class,
    +            authorizations = {
    +                    @Authorization(value = "Data Flow Manager", type = 
"ROLE_DFM")
    +            }
    +    )
    +    @ApiResponses(
    +            value = {
    +                    @ApiResponse(code = 400, message = "NiFi was unable to 
complete the request because it was invalid. The request should not be retried 
without modification."),
    +                    @ApiResponse(code = 401, message = "Client could not 
be authenticated."),
    +                    @ApiResponse(code = 403, message = "Client is not 
authorized to make this request."),
    +                    @ApiResponse(code = 404, message = "The specified 
resource could not be found."),
    +                    @ApiResponse(code = 409, message = "The request was 
valid but NiFi was not in the appropriate state to process it. Retrying the 
same request later may be successful.")
    +            }
    +    )
    +    public Response updateUserGroup(
    +            @Context final HttpServletRequest httpServletRequest,
    +            @ApiParam(
    +                    value = "The user group id.",
    +                    required = true
    +            )
    +            @PathParam("id") final String id,
    +            @ApiParam(
    +                    value = "The user group configuration details.",
    +                    required = true
    +            ) final UserGroupEntity userGroupEntity) {
    +
    +        if (userGroupEntity == null || userGroupEntity.getComponent() == 
null) {
    +            throw new IllegalArgumentException("User group details must be 
specified.");
    +        }
    +
    +        if (userGroupEntity.getRevision() == null) {
    +            throw new IllegalArgumentException("Revision must be 
specified.");
    +        }
    +
    +        // ensure the ids are the same
    +        final UserGroupDTO userGroupDTO = userGroupEntity.getComponent();
    +        if (!id.equals(userGroupDTO.getId())) {
    +            throw new IllegalArgumentException(String.format("The user 
group id (%s) in the request body does not equal the "
    +                    + "user group id of the requested resource (%s).", 
userGroupDTO.getId(), id));
    +        }
    +
    +        if (isReplicateRequest()) {
    +            return replicate(HttpMethod.PUT, userGroupEntity);
    +        }
    +
    +        // Extract the revision
    +        final Revision revision = getRevision(userGroupEntity, id);
    +        return withWriteLock(
    +                serviceFacade,
    +                revision,
    +                lookup -> {
    +                    final Authorizable userGroups = 
lookup.getUserGroupsAuthorizable();
    +                    userGroups.authorize(authorizer, RequestAction.WRITE);
    +                },
    +                null,
    +                () -> {
    +                    // update the user group
    +                    final UpdateResult<UserGroupEntity> updateResult = 
serviceFacade.updateUserGroup(revision, userGroupDTO);
    +
    +                    // get the results
    +                    final UserGroupEntity entity = 
updateResult.getResult();
    +                    populateRemainingUserGroupEntityContent(entity);
    +
    +                    if (updateResult.isNew()) {
    +                        return 
clusterContext(generateCreatedResponse(URI.create(entity.getComponent().getUri()),
 entity)).build();
    +                    } else {
    +                        return 
clusterContext(generateOkResponse(entity)).build();
    +                    }
    +                }
    +        );
    +    }
    +
    +    /**
    +     * Removes the specified user group.
    +     *
    +     * @param httpServletRequest request
    +     * @param version The revision is used to verify the client is working 
with
    +     * the latest version of the flow.
    +     * @param clientId Optional client id. If the client id is not 
specified, a
    +     * new one will be generated. This value (whether specified or 
generated) is
    +     * included in the response.
    +     * @param id The id of the user group to remove.
    +     * @return A entity containing the client id and an updated revision.
    +     */
    +    @DELETE
    +    @Consumes(MediaType.WILDCARD)
    +    @Produces(MediaType.APPLICATION_JSON)
    +    @Path("{id}")
    +    // TODO - @PreAuthorize("hasRole('ROLE_DFM')")
    +    @ApiOperation(
    +            value = "Deletes a user group",
    +            response = UserGroupEntity.class,
    +            authorizations = {
    +                    @Authorization(value = "Data Flow Manager", type = 
"ROLE_DFM")
    +            }
    +    )
    +    @ApiResponses(
    +            value = {
    +                    @ApiResponse(code = 400, message = "NiFi was unable to 
complete the request because it was invalid. The request should not be retried 
without modification."),
    +                    @ApiResponse(code = 401, message = "Client could not 
be authenticated."),
    +                    @ApiResponse(code = 403, message = "Client is not 
authorized to make this request."),
    +                    @ApiResponse(code = 404, message = "The specified 
resource could not be found."),
    +                    @ApiResponse(code = 409, message = "The request was 
valid but NiFi was not in the appropriate state to process it. Retrying the 
same request later may be successful.")
    +            }
    +    )
    +    public Response removeUserGroup(
    +            @Context final HttpServletRequest httpServletRequest,
    +            @ApiParam(
    +                    value = "The revision is used to verify the client is 
working with the latest version of the flow.",
    +                    required = false
    +            )
    +            @QueryParam(VERSION) final LongParameter version,
    +            @ApiParam(
    +                    value = "If the client id is not specified, new one 
will be generated. This value (whether specified or generated) is included in 
the response.",
    +                    required = false
    +            )
    +            @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) final 
ClientIdParameter clientId,
    +            @ApiParam(
    +                    value = "The user group id.",
    +                    required = true
    +            )
    +            @PathParam("id") final String id) {
    +
    +        if (isReplicateRequest()) {
    +            return replicate(HttpMethod.DELETE);
    +        }
    +
    +        // handle expects request (usually from the cluster manager)
    +        final Revision revision = new Revision(version == null ? null : 
version.getLong(), clientId.getClientId(), id);
    +        return withWriteLock(
    +                serviceFacade,
    +                revision,
    +                lookup -> {
    +                    final Authorizable userGroups = 
lookup.getUserGroupsAuthorizable();
    +                    userGroups.authorize(authorizer, RequestAction.READ);
    +                },
    +                () -> {},
    --- End diff --
    
    Will update this with null, as well.


> Create REST endpoints for user/group/policy management
> ------------------------------------------------------
>
>                 Key: NIFI-1952
>                 URL: https://issues.apache.org/jira/browse/NIFI-1952
>             Project: Apache NiFi
>          Issue Type: Sub-task
>          Components: Core Framework
>    Affects Versions: 1.0.0
>            Reporter: Jeff Storck
>            Assignee: Jeff Storck
>             Fix For: 1.0.0
>
>
> REST endpoints are needed to provide CRUD capability for mutable authorizers 
> (extensions of AbstractPolicyBasedAuthorizer) to manage users, groups, and 
> policies.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to