package eu.europeana.cloud.service.dps.rest; import javax.ws.rs.Consumes; import javax.ws.rs.FormParam; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import eu.europeana.cloud.service.dps.exception.AccessDeniedOrTopologyDoesNotExistException; import eu.europeana.cloud.service.dps.service.utils.TopologyManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.acls.domain.BasePermission; import org.springframework.security.acls.domain.ObjectIdentityImpl; import org.springframework.security.acls.domain.PrincipalSid; import org.springframework.security.acls.model.MutableAcl; import org.springframework.security.acls.model.MutableAclService; import org.springframework.security.acls.model.ObjectIdentity; import org.springframework.stereotype.Component; import eu.europeana.cloud.service.dps.TaskExecutionReportService; /** * Resource to manage topologies in the DPS service */ @Path("/topologies/{topologyName}") @Component public class TopologiesResource { @Autowired private TaskExecutionReportService dps; @Autowired private MutableAclService mutableAclService; @Autowired private TopologyManager topologyManager; private final static String TOPOLOGY_PREFIX = "Topology"; private static final Logger LOGGER = LoggerFactory.getLogger(TopologiesResource.class); /** * Grants user with given username read/ write permissions for the requested topology. * * <br/><br/> * <div style='border-left: solid 5px #999999; border-radius: 10px; padding: 6px;'> * <strong>Required permissions:</strong> * <ul> * <li>Admin role</li> * </ul> * </div> * * @summary Grant topology permissions * @param topology <strong>REQUIRED</strong> Name of the topology. * @param userName <strong>REQUIRED</strong> Permissions are granted to the account with this unique username * * @return Empty response with status code indicating whether the operation was successful or not. */ @Path("/permit") @POST @PreAuthorize("hasRole('ROLE_ADMIN')") @Consumes({MediaType.APPLICATION_FORM_URLENCODED}) public Response grantPermissionsToTopology(@FormParam("username") String userName, @PathParam("topologyName") String topology) throws AccessDeniedOrTopologyDoesNotExistException{ assertContainTopology(topology); ObjectIdentity topologyIdentity = new ObjectIdentityImpl(TOPOLOGY_PREFIX, topology); MutableAcl topologyAcl = null; try { topologyAcl = (MutableAcl)mutableAclService.readAclById(topologyIdentity); } catch (Exception e) { // not really an exception LOGGER.info("ACL not found for topology {} and user {}. " + "This is ok if it is the first time you are trying to assign permissions for this topology.", topology, userName); topologyAcl = mutableAclService.createAcl(topologyIdentity); } topologyAcl.insertAce(topologyAcl.getEntries().size(), BasePermission.WRITE, new PrincipalSid(userName), true); mutableAclService.updateAcl(topologyAcl); return Response.ok().build(); } private void assertContainTopology(String topology) throws AccessDeniedOrTopologyDoesNotExistException { if(!topologyManager.containsTopology(topology)){ throw new AccessDeniedOrTopologyDoesNotExistException(); } } }