All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.marvelution.jira.plugins.sonar.rest.SonarLayoutRestResource Maven / Gradle / Ivy

/*
 * Licensed to Marvelution under one or more contributor license 
 * agreements.  See the NOTICE file distributed with this work 
 * for additional information regarding copyright ownership.
 * Marvelution 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 com.marvelution.jira.plugins.sonar.rest;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
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;

import org.apache.log4j.Logger;

import com.atlassian.crowd.embedded.api.User;
import com.atlassian.jira.project.Project;
import com.atlassian.jira.project.ProjectManager;
import com.atlassian.jira.security.PermissionManager;
import com.atlassian.jira.security.Permissions;
import com.atlassian.jira.user.util.UserUtil;
import com.atlassian.plugins.rest.common.security.AnonymousAllowed;
import com.atlassian.plugins.rest.common.security.AuthenticationContext;
import com.marvelution.jira.plugins.sonar.rest.exceptions.InvalidGadgetException;
import com.marvelution.jira.plugins.sonar.rest.exceptions.InvalidLayoutException;
import com.marvelution.jira.plugins.sonar.rest.exceptions.NotAuthorisedWebException;
import com.marvelution.jira.plugins.sonar.rest.model.Layout;
import com.marvelution.jira.plugins.sonar.rest.model.Gadgets;
import com.marvelution.jira.plugins.sonar.rest.model.Types;
import com.marvelution.jira.plugins.sonar.services.layout.Gadget;
import com.marvelution.jira.plugins.sonar.services.layout.SonarPanelLayoutManager;

/**
 * REST API for Sonar Layouts
 * 
 * @author Mark Rekveld
 */
@Path("/layout")
@AnonymousAllowed
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public class SonarLayoutRestResource {

	private final Logger logger = Logger.getLogger(SonarLayoutRestResource.class);

	private SonarPanelLayoutManager panelLayoutManager;
	private UserUtil userUtil;
	private PermissionManager permissionManager;
	private ProjectManager projectManager;

	/**
	 * Constructor
	 *
	 * @param panelLayoutManager the {@link SonarPanelLayoutManager} implementation
	 * @param userUtil the {@link UserUtil} implementation
	 * @param permissionManager the {@link PermissionManager} implementation
	 * @param projectManager the {@link ProjectManager} implementation
	 */
	public SonarLayoutRestResource(SonarPanelLayoutManager panelLayoutManager, UserUtil userUtil,
			PermissionManager permissionManager, ProjectManager projectManager) {
		this.panelLayoutManager = panelLayoutManager;
		this.userUtil = userUtil;
		this.permissionManager = permissionManager;
		this.projectManager = projectManager;
	}

	/**
	 * Getter for the Layout with the SYSTEM context
	 * 
	 * @return the SYSTEM Layout
	 */
	@GET
	public Response getSystemLayout() {
		return Response.ok(new Layout(panelLayoutManager.getSystemLayout())).build();
	}

	/**
	 * Getter for the Layout with the context
	 * 
	 * @param context the {@link com.marvelution.jira.plugins.sonar.services.layout.Layout.Context} to get the Layout for
	 * @return the Layout
	 */
	@GET
	@Path("/context/{context}")
	public Response getLayout(@PathParam("context") com.marvelution.jira.plugins.sonar.services.layout.Layout.Context context) {
		return Response.ok(new Layout(panelLayoutManager.getLayout(context))).build();
	}

	/**
	 * Getter for the Context specific Layout
	 * 
	 * @param contextID the Context ID
	 * @return the Context Specific layout
	 */
	@GET
	@Path("{contextID}")
	public Response getLayout(@PathParam("contextID") @DefaultValue("0") Long contextID) {
		if (contextID == 0L) {
			return getSystemLayout();
		}
		return Response.ok(new Layout(panelLayoutManager.getLayout(contextID))).build();
	}

	/**
	 * Change the type of a layout
	 * 
	 * @param layoutId the Id of the layout to change
	 * @param type the new type of the layout
	 * @param authenticationContext the {@link AuthenticationContext}
	 * @return OK {@link Response} if successful
	 */
	@POST
	@Path("change/{layoutId}")
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Response changeLayout(@PathParam("layoutId") Integer layoutId,
					@FormParam("type") com.marvelution.jira.plugins.sonar.services.layout.Layout.Type type,
					@Context AuthenticationContext authenticationContext) {
		com.marvelution.jira.plugins.sonar.services.layout.Layout panelLayout =
			panelLayoutManager.getLayoutById(layoutId);
		if (panelLayout != null && isAuthorized(authenticationContext, panelLayout.getContextID())) {
			panelLayoutManager.changeLayoutType(panelLayout, type);
			return Response.ok().build();
		} else if (panelLayout == null) {
			throw new InvalidLayoutException("No layout with ID: " + layoutId);
		} else {
			logger.error("Deteceted unauthorized access to the change/{layoutId} API by: " + authenticationContext.getPrincipal().getName());
			throw new NotAuthorisedWebException();
		}
	}

	/**
	 * Add a gadget to the given column
	 * 
	 * @param gadgetId the Id of the gadget to add
	 * @param columnId the Id of the column to add the gadget to
	 * @param authenticationContext the {@link AuthenticationContext}
	 * @return OK {@link Response} if successful
	 */
	@POST
	@Path("add/{gadgetId}")
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Response addGadget(@PathParam("gadgetId") String gadgetId, @FormParam("columnId") Integer columnId,
					@Context AuthenticationContext authenticationContext) {
		com.marvelution.jira.plugins.sonar.services.layout.Layout layout = panelLayoutManager.getLayoutByColumnId(columnId);
		if (layout != null && isAuthorized(authenticationContext, layout.getContextID())) {
			Gadget gadget = panelLayoutManager.getGadget(gadgetId);
			if (gadget != null) {
				panelLayoutManager.addGadgetToColumn(gadget, columnId);
				return Response.ok().build();
			} else {
				throw new InvalidGadgetException("No gadget is available with short name " + gadgetId);
			}
		} else if (layout == null) {
			throw new InvalidLayoutException("No layout with a column with id: " + columnId);
		} else {
			logger.error("Deteceted unauthorized access to the add/{gadgetId} API by: " + authenticationContext.getPrincipal().getName());
			throw new NotAuthorisedWebException();
		}
	}

	/**
	 * Remove a gadget from the given column
	 * 
	 * @param gadgetId the Id of the gadget to remove
	 * @param columnId the Id of the column to remove the gadget from
	 * @param authenticationContext the {@link AuthenticationContext}
	 * @return OK {@link Response} if successful
	 */
	@POST
	@Path("remove/{gadgetId}")
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Response removeGadget(@PathParam("gadgetId") String gadgetId, @FormParam("columnId") Integer columnId,
					@Context AuthenticationContext authenticationContext) {
		com.marvelution.jira.plugins.sonar.services.layout.Layout layout = panelLayoutManager.getLayoutByColumnId(columnId);
		if (layout != null && isAuthorized(authenticationContext, layout.getContextID())) {
			Gadget gadget = panelLayoutManager.getGadget(gadgetId);
			if (gadget != null) {
				panelLayoutManager.removeGadgetFromColumn(gadget, columnId);
				return Response.ok().build();
			} else {
				throw new InvalidGadgetException("No gadget is available with short name " + gadgetId);
			}
		} else if (layout == null) {
			throw new InvalidLayoutException("No layout with a column with id: " + columnId);
		} else {
			logger.error("Deteceted unauthorized access to the remove/{gadgetId} API by: " + authenticationContext.getPrincipal().getName());
			throw new NotAuthorisedWebException();
		}
	}

	/**
	 * Move a gadget to the given column
	 * 
	 * @param gadgetId the Id of the gadget to move
	 * @param newColumnId the Id of the column to move the gadget to
	 * @param oldColumnId the Id of the column to move the gadget from
	 * @param position the position to move the gadget to, zero based
	 * @param authenticationContext the {@link AuthenticationContext}
	 * @return OK {@link Response} if successful
	 */
	@POST
	@Path("move/{gadgetId}")
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Response moveGadget(@PathParam("gadgetId") String gadgetId, @FormParam("newColumnId") Integer newColumnId,
					@FormParam("oldColumnId") Integer oldColumnId, @FormParam("position") Integer position,
					@Context AuthenticationContext authenticationContext) {
		com.marvelution.jira.plugins.sonar.services.layout.Layout layout = panelLayoutManager.getLayoutByColumnId(newColumnId);
		if (layout != null && isAuthorized(authenticationContext, layout.getContextID())) {
			Gadget gadget = panelLayoutManager.getGadget(gadgetId);
			if (gadget != null) {
				panelLayoutManager.removeGadgetFromColumn(gadget, oldColumnId);
				panelLayoutManager.addGadgetToColumn(gadget, newColumnId, position);
				return Response.ok().build();
			} else {
				throw new InvalidGadgetException("No gadget is available with short name " + gadgetId);
			}
		} else if (layout == null) {
			throw new InvalidLayoutException("No layout with a column with id: " + newColumnId);
		} else {
			logger.error("Deteceted unauthorized access to the move/{gadgetId} API by: " + authenticationContext.getPrincipal().getName());
			throw new NotAuthorisedWebException();
		}
	}

	/**
	 * Getter for the available layouts
	 * 
	 * @return the layouts
	 */
	@GET
	@Path("types")
	public Response getLayoutTypes() {
		return Response.ok(new Types()).build();
	}

	/**
	 * Getter for the available gadgets
	 * 
	 * @return the gadgets
	 */
	@GET
	@Path("gadgets")
	public Response getGadgets() {
		return Response.ok(new Gadgets(panelLayoutManager.getGadgets())).build();
	}

	/**
	 * API Method to delete a layout by context type (only used for development)
	 * 
	 * @param context the context to delete
	 * @param authenticationContext the {@link AuthenticationContext}
	 * @return {@link Response}
	 */
	@DELETE
	@Path("delete/{context}")
	public Response deleteLayout(@PathParam("context") com.marvelution.jira.plugins.sonar.services.layout.Layout.Context context, @Context AuthenticationContext authenticationContext) {
		com.marvelution.jira.plugins.sonar.services.layout.Layout layout = panelLayoutManager.getLayout(context);
		if (isAuthorized(authenticationContext, layout.getContextID())) {
			panelLayoutManager.removeLayout(layout);
			return Response.ok().build();
		} else {
			logger.error("Deteceted unauthorized access to the delete/{context} API by: " + authenticationContext.getPrincipal().getName());
			throw new NotAuthorisedWebException();
		}
	}

	/**
	 * Internal method to validate the permissions of the user in the {@link AuthenticationContext}
	 * 
	 * @param authenticationContext the {@link AuthenticationContext} of the user to check
	 * @return true if authorized, false otherwise
	 */
	private boolean isAuthorized(AuthenticationContext authenticationContext, Long contextID) {
		Project project = null;
		if (contextID != null && contextID > 0L && projectManager.getProjectObj(contextID) != null) {
			project = projectManager.getProjectObj(contextID);
		}
		final User user = userUtil.getUserObject(authenticationContext.getPrincipal().getName());
		return (user != null && (permissionManager.hasPermission(Permissions.ADMINISTER, user) || (project != null && permissionManager
			.hasPermission(Permissions.PROJECT_ADMIN, project, user))));
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy