Skip to content

Commit

Permalink
Merge pull request #629 from UnifiedViews/feature/restApiUsers
Browse files Browse the repository at this point in the history
Feature/rest api users improvement - users from User DB
  • Loading branch information
tomas-knap authored Nov 23, 2017
2 parents cf1eb51 + a166e70 commit 83cb58a
Show file tree
Hide file tree
Showing 14 changed files with 263 additions and 82 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import cz.cuni.mff.xrg.odcs.commons.app.user.User;

/**
* Evaluates whether currently authorized user has a given permission on a given
* Evaluates whether currently authenticated user has a given permission on a given
* object.
*
* @author Jan Vojt
Expand Down
4 changes: 0 additions & 4 deletions conf/config.sample.properties
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@ frontend.log.directory = /var/log/unifiedviews/frontend
# directory where backend log should be stored (should not end with / or \ )
backend.log.directory = /var/log/unifiedviews/backend

# credentials for UnifiedViews REST API
master.api.user=master
master.api.password=commander

# Language configuration (e.g.: en, en_US, sk, sk_SK, cz, cz_CZ, ...)
# To use proper localisation
# for more details see:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.File;
Expand Down Expand Up @@ -53,7 +49,7 @@ public class DPUResource {
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
public String importJarDpu(@FormDataParam("file") InputStream inputStream, @FormDataParam("file") FormDataContentDisposition contentDispositionHeader, @QueryParam("name") String dpuName, @QueryParam("description") String dpuDescription, @QueryParam("visibility") String visibility,
@QueryParam("force") boolean force) {
@QueryParam("force") @DefaultValue("false") boolean force) {
LOG.debug("Importing dpu file: {}, name: {}, description: {}, visibility: {}, force?: {}", contentDispositionHeader.getFileName(), dpuName, dpuDescription, visibility, force);
// parse input steam to file, located in temporary directory
File jarFile;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ public class ExecutionResource {
@Autowired
private UserFacade userFacade;

@Autowired
private UserHelper userHelper;

private static final Logger log = LoggerFactory.getLogger(
ExecutionResource.class);

Expand Down Expand Up @@ -180,17 +183,21 @@ public PipelineExecutionDTO createPipelineExecution(@PathParam("pipelineid") Str
log.info("Pipeline exec in the request: {}", newExecution.toString());

// try to get user
User user = userFacade.getUserByExtId(newExecution.getUserExternalId());
String username = userHelper.getUser(newExecution.getUserExternalId());
if (username == null) {
throw new ApiException(Response.Status.NOT_FOUND, Messages.getString("execution.user.id.not.found"), String.format("Username cannot be found in the input - either in the JSON object or in the basic auth"));
}
User user = userFacade.getUserByExtId(username);
if (user == null) {
throw new ApiException(Response.Status.NOT_FOUND, Messages.getString("execution.user.id.not.found"), String.format("User with ID=%s could not be found.", newExecution.getUserExternalId()));
}

log.info("Obtained user ID: {}", user.getId());

UserActor actor = this.userFacade.getUserActorByExternalId(newExecution.getUserActorExternalId());
log.info("Used user ID: {}", user.getId());

final PipelineExecution execution = new PipelineExecution(pipeline);
execution.setOwner(user);

UserActor actor = this.userFacade.getUserActorByExternalId(newExecution.getUserActorExternalId());
if (actor != null) {
log.info("Obtained actor ID: {}, external ID {}", actor.getId(), actor.getExternalId());
execution.setActor(actor);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import cz.cuni.mff.xrg.odcs.commons.app.user.User;
import cz.cuni.mff.xrg.odcs.commons.app.user.UserActor;
import eu.unifiedviews.master.authentication.AuthenticationRequired;
import eu.unifiedviews.master.authentication.BasicAuthenticationFilter;
import eu.unifiedviews.master.converter.ConvertUtils;
import eu.unifiedviews.master.converter.PipelineDTOConverter;
import eu.unifiedviews.master.i18n.Messages;
Expand All @@ -31,6 +32,8 @@
import java.util.ArrayList;
import java.util.List;

import static org.apache.commons.lang3.StringUtils.equalsIgnoreCase;
import static org.apache.commons.lang3.StringUtils.isEmpty;
import static org.apache.commons.lang3.StringUtils.isNotEmpty;

@Component
Expand All @@ -49,6 +52,12 @@ public class PipelineResource {
@Autowired
private UserFacade userFacade;

@Autowired
private UserHelper userHelper;

// @Autowired
// private BasicAuthenticationFilter authFilter;

@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
Expand All @@ -65,15 +74,19 @@ public PipelineDTO createPipeline(PipelineDTO pipelineDTO) {
throw new ApiException(Response.Status.CONFLICT, Messages.getString("pipeline.name.duplicate", pipelineDTO.getName()), String.format("Pipeline with name '%s' already exists. Pipeline cannot be created!", pipelineDTO.getName()));
}

// try to get user
User user = userFacade.getUserByExtId(pipelineDTO.getUserExternalId());
String username = userHelper.getUser(pipelineDTO.getUserExternalId());
if (username == null) {
throw new ApiException(Response.Status.NOT_FOUND, Messages.getString("pipeline.user.id.not.found"), String.format("We cannot fetch username from the request!"));
}
User user = userFacade.getUserByExtId(username);
if (user == null) {
throw new ApiException(Response.Status.NOT_FOUND, Messages.getString("pipeline.user.id.not.found"), String.format("User '%s' could not be found! Pipeline could not be created.", pipelineDTO.getUserExternalId()));
}

pipeline = pipelineFacade.createPipeline();
final UserActor actor = this.userFacade.getUserActorByExternalId(pipelineDTO.getUserActorExternalId());
pipeline.setUser(user);

final UserActor actor = this.userFacade.getUserActorByExternalId(pipelineDTO.getUserActorExternalId());
if (actor != null) {
pipeline.setActor(actor);
}
Expand All @@ -89,19 +102,20 @@ public PipelineDTO createPipeline(PipelineDTO pipelineDTO) {
return PipelineDTOConverter.convert(pipeline);
}

/**
* Returns pipelines for the user specified as a query parameter. If user is not specified, it uses the user from the basic authentication header
* @param userExternalId
* @return Pipelines for the user specified as a query parameter
*/
@GET
@Produces({ MediaType.APPLICATION_JSON })
public List<PipelineDTO> getPipelines(@QueryParam("userExternalId") String userExternalId) {
List<Pipeline> pipelines = null;
try {
if (isNotEmpty(userExternalId)) {
pipelines = this.pipelineFacade.getAllPipelines(userExternalId);
} else {
pipelines = new ArrayList<>();
}

if (pipelines == null) {
pipelines = new ArrayList<>();
try {
String user = userHelper.getUser(userExternalId);
if (user != null) {
pipelines = this.pipelineFacade.getAllPipelines(user);
}
} catch (ApiException e) {
throw e;
Expand All @@ -118,10 +132,9 @@ public List<PipelineDTO> getPipelines(@QueryParam("userExternalId") String userE
public List<PipelineDTO> getVisiblePipelines(@QueryParam("userExternalId") String userExternalId) {
List<Pipeline> pipelines = null;
try {
pipelines = this.pipelineFacade.getAllVisiblePipelines(userExternalId);

if (pipelines == null) {
pipelines = new ArrayList<>();
String user = userHelper.getUser(userExternalId);
if (user != null) {
pipelines = this.pipelineFacade.getAllVisiblePipelines(user);
}
} catch (ApiException e) {
throw e;
Expand All @@ -131,6 +144,7 @@ public List<PipelineDTO> getVisiblePipelines(@QueryParam("userExternalId") Strin
return PipelineDTOConverter.convert(pipelines);
}


@GET
@Path("/{pipelineid}")
@Produces({ MediaType.APPLICATION_JSON })
Expand Down Expand Up @@ -175,8 +189,12 @@ public PipelineDTO clonePipeline(@PathParam("pipelineid") String id, PipelineDTO
if (pipeline == null) {
throw new ApiException(Response.Status.NOT_FOUND, Messages.getString("pipeline.id.not.found", id), String.format("Pipeline with id=%s doesn't exist!", id));
}
// try to get user
User user = userFacade.getUserByExtId(pipelineDTO.getUserExternalId());
// get user
String username = userHelper.getUser(pipelineDTO.getUserExternalId());
if (username == null) {
throw new ApiException(Response.Status.NOT_FOUND, Messages.getString("pipeline.user.id.not.found"), String.format("We cannot fetch username from the request!"));
}
User user = userFacade.getUserByExtId(username);
if (user == null) {
throw new ApiException(Response.Status.NOT_FOUND, Messages.getString("pipeline.user.id.not.found"), String.format("User '%s' could not be found! Pipeline could not be created.", pipelineDTO.getUserExternalId()));
}
Expand All @@ -187,12 +205,14 @@ public PipelineDTO clonePipeline(@PathParam("pipelineid") String id, PipelineDTO
throw new ApiException(Response.Status.CONFLICT, Messages.getString("pipeline.name.duplicate", pipelineDTO.getName()), String.format("Pipeline with name '%s' already exists. Pipeline cannot be created!", pipelineDTO.getName()));
}

final UserActor actor = this.userFacade.getUserActorByExternalId(pipelineDTO.getUserActorExternalId());
pipelineCopy = this.pipelineFacade.copyPipeline(pipeline);
pipelineCopy.setUser(user);

final UserActor actor = this.userFacade.getUserActorByExternalId(pipelineDTO.getUserActorExternalId());
if (actor != null) {
pipelineCopy.setActor(actor);
}

pipelineCopy = PipelineDTOConverter.convertFromDTO(pipelineDTO, pipelineCopy);
this.pipelineFacade.save(pipelineCopy);
} catch (ApiException e) {
Expand All @@ -207,17 +227,18 @@ public PipelineDTO clonePipeline(@PathParam("pipelineid") String id, PipelineDTO
@Path("/import")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
public PipelineDTO importPipeline(@FormDataParam("file") InputStream inputStream, @FormDataParam("file") FormDataContentDisposition contentDispositionHeader, @FormDataParam("userExternalId") String username, @FormDataParam("importUserData") boolean importUserData, @FormDataParam("importSchedule") boolean importSchedule) {
public PipelineDTO importPipeline(@FormDataParam("file") InputStream inputStream, @FormDataParam("file") FormDataContentDisposition contentDispositionHeader, @FormDataParam("userExternalId") String username, @FormDataParam("importUserData") @DefaultValue("false") boolean importUserData, @FormDataParam("importSchedule") @DefaultValue("false") boolean importSchedule) {
// parse input steam to file, located in temporary directory
File pipelineFile;
Pipeline importedPipeline;
try {
pipelineFile = ConvertUtils.inputStreamToFile(inputStream, contentDispositionHeader.getFileName());

if (username == null || username.isEmpty()) {
String usernameCreator = userHelper.getUser(username);
if (usernameCreator == null || usernameCreator.isEmpty()) {
throw new ApiException(Response.Status.INTERNAL_SERVER_ERROR, Messages.getString("pipeline.import.general.error"), "Please specify name of the user who is the pipeline creator");
}
User user = userFacade.getUserByUsername(username);
User user = userFacade.getUserByUsername(usernameCreator);
if (user == null) {
throw new ApiException(Response.Status.INTERNAL_SERVER_ERROR, Messages.getString("pipeline.import.general.error"), "User with the given username does not exist");
}
Expand All @@ -228,4 +249,5 @@ public PipelineDTO importPipeline(@FormDataParam("file") InputStream inputStream
}
return PipelineDTOConverter.convert(importedPipeline);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ public class ScheduleResource {
@Autowired
private UserFacade userFacade;

@Autowired
private UserHelper userHelper;

@GET
@Path("/{pipelineid}/schedules")
@Produces({ MediaType.APPLICATION_JSON })
Expand Down Expand Up @@ -203,7 +206,7 @@ public PipelineScheduleDTO updatePipelineSchedule(@PathParam("pipelineid") Strin
}
}
}
ScheduleDTOConverter.convertFromDTO(scheduleToUpdate, afterPipelines, schedule);
ScheduleDTOConverter.convertFromDTOEdit(scheduleToUpdate, afterPipelines, schedule);
scheduleFacade.save(schedule);
return ScheduleDTOConverter.convertToDTO(schedule);
} else {
Expand All @@ -230,24 +233,29 @@ public PipelineScheduleDTO createPipelineSchedule(@PathParam("pipelineid") Strin
if (pipeline == null) {
throw new ApiException(Response.Status.NOT_FOUND, Messages.getString("pipeline.id.not.found", pipelineId), String.format("Pipeline with id=%s doesn't exist!", pipelineId));
}
// try to get user
User user = userFacade.getUserByExtId(scheduleToUpdate.getUserExternalId());

String username = userHelper.getUser(scheduleToUpdate.getUserExternalId());
if (username == null) {
throw new ApiException(Response.Status.NOT_FOUND, Messages.getString("schedule.user.id.not.found"), String.format("Username cannot be found in the input - either in the JSON object or in the basic auth"));
}
User user = userFacade.getUserByExtId(username);
if (user == null) {
throw new ApiException(Response.Status.NOT_FOUND, Messages.getString("schedule.user.id.not.found"), String.format("User '%s' could not be found! Pipeline could not be created.", scheduleToUpdate.getUserExternalId()));
}

UserActor actor = this.userFacade.getUserActorByExternalId(scheduleToUpdate.getUserActorExternalId());

Schedule schedule = new Schedule();
if (schedule == null) {
throw new ApiException(Response.Status.INTERNAL_SERVER_ERROR, Messages.getString("pipeline.create.schedule.general.error"), "ScheduleFacade returned null, after creation of schedule");
}
schedule.setPipeline(pipeline);
schedule.setType(scheduleToUpdate.getScheduleType());
schedule.setOwner(user);

UserActor actor = this.userFacade.getUserActorByExternalId(scheduleToUpdate.getUserActorExternalId());
if (actor != null) {
schedule.setActor(actor);
}

List<Pipeline> afterPipelines = null;
if (scheduleToUpdate.getAfterPipelines() != null) {
afterPipelines = new ArrayList<Pipeline>();
Expand All @@ -270,4 +278,41 @@ public PipelineScheduleDTO createPipelineSchedule(@PathParam("pipelineid") Strin
throw new ApiException(Response.Status.INTERNAL_SERVER_ERROR, Messages.getString("pipeline.create.schedule.general.error"), e.getMessage());
}
}


@DELETE
@Path("/{pipelineid}/schedules/{scheduleid}/delete")
public Response deletePipelineSchedule(@PathParam("pipelineid") String pipelineId, @PathParam("scheduleid") String scheduleId) {
if (StringUtils.isBlank(pipelineId) || !StringUtils.isNumeric(pipelineId)) {
throw new ApiException(Response.Status.BAD_REQUEST, Messages.getString("pipeline.id.invalid", pipelineId), String.format("ID=%s is not valid pipeline ID", pipelineId));
}
if (StringUtils.isBlank(scheduleId) || !StringUtils.isNumeric(scheduleId)) {
throw new ApiException(Response.Status.BAD_REQUEST, Messages.getString("schedule.id.invalid", scheduleId), String.format("ID=%s is not valid schedule ID", scheduleId));
}
try {
// try to get pipeline
Pipeline pipeline = pipelineFacade.getPipeline(Long.parseLong(pipelineId));
if (pipeline == null) {
throw new ApiException(Response.Status.NOT_FOUND, Messages.getString("pipeline.id.not.found", pipelineId), String.format("Pipeline with id=%s doesn't exist!", pipelineId));
}

Schedule schedule = scheduleFacade.getSchedule(Long.parseLong(scheduleId));
if (schedule == null) {
throw new ApiException(Response.Status.NOT_FOUND, Messages.getString("pipeline.schedule.id.not.found", scheduleId), String.format("Pipeline schedule with id=%s doesn't exist!", scheduleId));
}
if (schedule.getPipeline().getId().equals(pipeline.getId())) {
scheduleFacade.delete(schedule);
return Response.status(204).entity("Employee deleted successfully !!").build();
} else {
throw new ApiException(Response.Status.BAD_REQUEST, Messages.getString("pipeline.schedule.mismatch", scheduleId, pipelineId),String.format("Schedule with id=%s is not schedule of pipeline with id=%s!", scheduleId, pipelineId));
}

} catch (ApiException e) {
throw e;
} catch (RuntimeException e) {
throw new ApiException(Response.Status.INTERNAL_SERVER_ERROR, Messages.getString("pipeline.create.schedule.general.error"), e.getMessage());
}
}


}
38 changes: 38 additions & 0 deletions master/src/main/java/eu/unifiedviews/master/api/UserHelper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package eu.unifiedviews.master.api;

import eu.unifiedviews.master.authentication.BasicAuthenticationFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import static org.apache.commons.lang3.StringUtils.isEmpty;

@Component
public class UserHelper {

@Autowired
private BasicAuthenticationFilter authFilter;

private static final Logger LOG = LoggerFactory.getLogger(UserHelper.class);

public String getUser(String userExternalId) {

if (isEmpty(userExternalId)) {
String username = this.authFilter.getUserName();
if (isEmpty(username)) {
LOG.error("No user defined in the parameter and no user was retrieved from the authentication header");
return null;
}
else {
return username;
}
}
else {
//no change, return what was provided in the param
return userExternalId;
}

}

}
Loading

0 comments on commit 83cb58a

Please sign in to comment.