org.camunda.bpm.admin.impl.web.SetupResource.java Source code

Java tutorial

Introduction

Here is the source code for org.camunda.bpm.admin.impl.web.SetupResource.java

Source

/* Licensed 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.camunda.bpm.admin.impl.web;

import static org.camunda.bpm.engine.authorization.Authorization.ANY;
import static org.camunda.bpm.engine.authorization.Authorization.AUTH_TYPE_GRANT;
import static org.camunda.bpm.engine.authorization.Permissions.ALL;

import java.util.Iterator;
import java.util.ServiceLoader;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.ext.Providers;

import org.camunda.bpm.engine.AuthorizationService;
import org.camunda.bpm.engine.IdentityService;
import org.camunda.bpm.engine.ProcessEngine;
import org.camunda.bpm.engine.authorization.Groups;
import org.camunda.bpm.engine.authorization.Resource;
import org.camunda.bpm.engine.authorization.Resources;
import org.camunda.bpm.engine.identity.Group;
import org.camunda.bpm.engine.impl.persistence.entity.AuthorizationEntity;
import org.camunda.bpm.engine.rest.dto.identity.UserDto;
import org.camunda.bpm.engine.rest.exception.InvalidRequestException;
import org.camunda.bpm.engine.rest.exception.RestException;
import org.camunda.bpm.engine.rest.impl.UserRestServiceImpl;
import org.camunda.bpm.engine.rest.spi.ProcessEngineProvider;
import org.camunda.bpm.engine.rest.util.ProvidersUtil;
import org.camunda.bpm.webapp.impl.security.SecurityActions;
import org.camunda.bpm.webapp.impl.security.SecurityActions.SecurityAction;

import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * <p>Jax RS resource allowing to perform the setup steps.</p>
 *
 * <p>All methods of this class must throw Status.FORBIDDEN exception if
 * setup actions are unavailable.</p>
 *
 * @author Daniel Meyer
 *
 */
@Path("/setup/{engine}")
public class SetupResource {

    @Context
    protected Providers providers;

    @Path("/user/create")
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public void createInitialUser(final @PathParam("engine") String processEngineName, final UserDto user) {

        final ProcessEngine processEngine = lookupProcessEngine(processEngineName);
        if (processEngine == null) {
            throw new InvalidRequestException(Status.BAD_REQUEST,
                    "Process Engine '" + processEngineName + "' does not exist.");
        }

        SecurityActions.runWithoutAuthentication(new SecurityAction<Void>() {
            public Void execute() {
                createInitialUserInternal(processEngineName, user, processEngine);
                return null;
            }
        }, processEngine);

    }

    protected void createInitialUserInternal(String processEngineName, UserDto user, ProcessEngine processEngine) {

        ObjectMapper objectMapper = getObjectMapper();

        // make sure we can process this request at this time
        ensureSetupAvailable(processEngine);

        // reuse logic from rest api implementation
        UserRestServiceImpl userRestServiceImpl = new UserRestServiceImpl(processEngineName, objectMapper);
        userRestServiceImpl.createUser(user);

        // crate the camunda admin group
        ensureCamundaAdminGroupExists(processEngine);

        // create group membership (add new user to admin group)
        processEngine.getIdentityService().createMembership(user.getProfile().getId(), Groups.CAMUNDA_ADMIN);
    }

    protected ObjectMapper getObjectMapper() {
        if (providers != null) {
            return ProvidersUtil.resolveFromContext(providers, ObjectMapper.class, MediaType.APPLICATION_JSON_TYPE,
                    this.getClass());
        } else {
            return null;
        }
    }

    protected void ensureCamundaAdminGroupExists(ProcessEngine processEngine) {

        final IdentityService identityService = processEngine.getIdentityService();
        final AuthorizationService authorizationService = processEngine.getAuthorizationService();

        // create group
        if (identityService.createGroupQuery().groupId(Groups.CAMUNDA_ADMIN).count() == 0) {
            Group camundaAdminGroup = identityService.newGroup(Groups.CAMUNDA_ADMIN);
            camundaAdminGroup.setName("camunda BPM Administrators");
            camundaAdminGroup.setType(Groups.GROUP_TYPE_SYSTEM);
            identityService.saveGroup(camundaAdminGroup);
        }

        // create ADMIN authorizations on all built-in resources
        for (Resource resource : Resources.values()) {
            if (authorizationService.createAuthorizationQuery().groupIdIn(Groups.CAMUNDA_ADMIN)
                    .resourceType(resource).resourceId(ANY).count() == 0) {
                AuthorizationEntity userAdminAuth = new AuthorizationEntity(AUTH_TYPE_GRANT);
                userAdminAuth.setGroupId(Groups.CAMUNDA_ADMIN);
                userAdminAuth.setResource(resource);
                userAdminAuth.setResourceId(ANY);
                userAdminAuth.addPermission(ALL);
                authorizationService.saveAuthorization(userAdminAuth);
            }
        }

    }

    protected void ensureSetupAvailable(ProcessEngine processEngine) {
        if (processEngine.getIdentityService().isReadOnly() || (processEngine.getIdentityService().createUserQuery()
                .memberOfGroup(Groups.CAMUNDA_ADMIN).count() > 0)) {

            throw new InvalidRequestException(Status.FORBIDDEN, "Setup action not available");
        }
    }

    protected ProcessEngine lookupProcessEngine(String engineName) {

        ServiceLoader<ProcessEngineProvider> serviceLoader = ServiceLoader.load(ProcessEngineProvider.class);
        Iterator<ProcessEngineProvider> iterator = serviceLoader.iterator();

        if (iterator.hasNext()) {
            ProcessEngineProvider provider = iterator.next();
            return provider.getProcessEngine(engineName);

        } else {
            throw new RestException(Status.BAD_REQUEST,
                    "Could not find an implementation of the " + ProcessEngineProvider.class + "- SPI");

        }

    }

}