From d2cd80b476201c480351759c2c0c29d774ce11ee Mon Sep 17 00:00:00 2001 From: Tomas Knap Date: Wed, 18 Oct 2017 14:51:15 +0200 Subject: [PATCH 1/4] UV users and passwords may be used for UV REST API calls --- .../app/auth/DefaultPermissionEvaluator.java | 2 +- .../master/api/PipelineResource.java | 20 ++++- .../BasicAuthenticationFilter.java | 74 ++++++++++++++++++- .../MasterAuthenticationContext.java | 24 ------ .../resources/master-context-security.xml | 11 +++ master/src/main/webapp/WEB-INF/web.xml | 5 +- 6 files changed, 108 insertions(+), 28 deletions(-) delete mode 100644 master/src/main/java/eu/unifiedviews/master/converter/MasterAuthenticationContext.java create mode 100644 master/src/main/resources/master-context-security.xml diff --git a/commons-app/src/main/java/cz/cuni/mff/xrg/odcs/commons/app/auth/DefaultPermissionEvaluator.java b/commons-app/src/main/java/cz/cuni/mff/xrg/odcs/commons/app/auth/DefaultPermissionEvaluator.java index 5e30151c2a..9d024d259f 100644 --- a/commons-app/src/main/java/cz/cuni/mff/xrg/odcs/commons/app/auth/DefaultPermissionEvaluator.java +++ b/commons-app/src/main/java/cz/cuni/mff/xrg/odcs/commons/app/auth/DefaultPermissionEvaluator.java @@ -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 diff --git a/master/src/main/java/eu/unifiedviews/master/api/PipelineResource.java b/master/src/main/java/eu/unifiedviews/master/api/PipelineResource.java index 68f91adbdf..53b8af88f8 100644 --- a/master/src/main/java/eu/unifiedviews/master/api/PipelineResource.java +++ b/master/src/main/java/eu/unifiedviews/master/api/PipelineResource.java @@ -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; @@ -49,6 +50,9 @@ public class PipelineResource { @Autowired private UserFacade userFacade; + @Autowired + private BasicAuthenticationFilter authFilter; + @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @@ -89,15 +93,29 @@ 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 getPipelines(@QueryParam("userExternalId") String userExternalId) { List pipelines = null; + try { if (isNotEmpty(userExternalId)) { pipelines = this.pipelineFacade.getAllPipelines(userExternalId); } else { - pipelines = new ArrayList<>(); + //user is empty, use the one from the basic auth header + userExternalId = this.authFilter.getUserName(); + if (isNotEmpty(userExternalId)) { + pipelines = this.pipelineFacade.getAllPipelines(userExternalId); + } + else { + LOG.error("No user defined in the parameter and no user was retrieved from the authentication header"); + pipelines = new ArrayList<>(); + } } if (pipelines == null) { diff --git a/master/src/main/java/eu/unifiedviews/master/authentication/BasicAuthenticationFilter.java b/master/src/main/java/eu/unifiedviews/master/authentication/BasicAuthenticationFilter.java index e9b34412fe..b7c78134a4 100644 --- a/master/src/main/java/eu/unifiedviews/master/authentication/BasicAuthenticationFilter.java +++ b/master/src/main/java/eu/unifiedviews/master/authentication/BasicAuthenticationFilter.java @@ -2,19 +2,32 @@ import static org.apache.commons.lang3.StringUtils.isEmpty; +import cz.cuni.mff.xrg.odcs.commons.app.auth.AuthenticationContext; +import cz.cuni.mff.xrg.odcs.commons.app.auth.PasswordHash; import cz.cuni.mff.xrg.odcs.commons.app.conf.AppConfig; import cz.cuni.mff.xrg.odcs.commons.app.conf.ConfigProperty; +import cz.cuni.mff.xrg.odcs.commons.app.facade.UserFacade; +import cz.cuni.mff.xrg.odcs.commons.app.user.User; import eu.unifiedviews.master.i18n.Messages; import eu.unifiedviews.master.model.ApiException; import org.glassfish.jersey.internal.util.Base64; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; import org.springframework.stereotype.Component; +import org.springframework.security.authentication.AuthenticationManager; import javax.annotation.PostConstruct; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerRequestFilter; import javax.ws.rs.core.Response; import java.io.IOException; +import java.security.NoSuchAlgorithmException; +import java.security.spec.InvalidKeySpecException; /** * Authentication filter, that filters incoming request to resource. @@ -28,7 +41,17 @@ public class BasicAuthenticationFilter implements ContainerRequestFilter { @Autowired private AppConfig configuration; + @Autowired + @Qualifier("authenticationManager") + private AuthenticationManager authManager; + + @Autowired + private AuthenticationContext authCtx; + private String credentials; + private String username = ""; + + private static final Logger log = LoggerFactory.getLogger(BasicAuthenticationFilter.class); @PostConstruct private void init() { @@ -64,12 +87,61 @@ public void filter(ContainerRequestContext requestContext) throws IOException { } } + public String getUserName() { + return this.username; + } + private boolean isAuthorizationValid(String authorization) { if(isEmpty(authorization)) { return false; } // remove "Basic " part from header authorization = authorization.replaceAll("[Bb]asic ", ""); - return authorization.equals(credentials); + + // return authorization.equals(credentials); + + + + //get the user, correctPass, check + String decodedToken = Base64.decodeAsString(authorization); + + //parse username and password + int delim = decodedToken.indexOf(":"); + + if (delim == -1) { + log.error("Invalid basic authentication token {}", decodedToken); + return false; + } + + this.username = decodedToken.substring(0, delim); + String pass = decodedToken.substring(delim + 1); + + //authentication + try { + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, pass); + Authentication authentication = authManager.authenticate(token); + authCtx.setAuthentication(authentication); + } catch (AuthenticationException ex) { + //authentication failed + log.error("Basic authentication failed: {}", ex.getLocalizedMessage()); + return false; + } + + return true; + +// //authentication manual, not needed +// User u = users.getUserByUsername(username); +// u.getPassword(); +// +// +// String correctPassHashed = u.getPassword(); +// try { +// return PasswordHash.validatePassword(pass,correctPassHashed); +// } catch (NoSuchAlgorithmException e) { +// e.printStackTrace(); +// } catch (InvalidKeySpecException e) { +// e.printStackTrace(); +// } +// return false; } } diff --git a/master/src/main/java/eu/unifiedviews/master/converter/MasterAuthenticationContext.java b/master/src/main/java/eu/unifiedviews/master/converter/MasterAuthenticationContext.java deleted file mode 100644 index 0f313a77c2..0000000000 --- a/master/src/main/java/eu/unifiedviews/master/converter/MasterAuthenticationContext.java +++ /dev/null @@ -1,24 +0,0 @@ -package eu.unifiedviews.master.converter; - -import cz.cuni.mff.xrg.odcs.commons.app.auth.AuthenticationContext; -import cz.cuni.mff.xrg.odcs.commons.app.facade.UserFacade; -import cz.cuni.mff.xrg.odcs.commons.app.user.User; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -/** - * Authentication context for Master API. - * - * Authentication is hard-wired to admin user(user with id 1). - */ -@Component -public class MasterAuthenticationContext extends AuthenticationContext { - - @Autowired - private UserFacade userFacade; - - @Override - public User getUser() { - return userFacade.getUser(1); - } -} diff --git a/master/src/main/resources/master-context-security.xml b/master/src/main/resources/master-context-security.xml new file mode 100644 index 0000000000..1bbdc75c12 --- /dev/null +++ b/master/src/main/resources/master-context-security.xml @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/master/src/main/webapp/WEB-INF/web.xml b/master/src/main/webapp/WEB-INF/web.xml index ad011b035e..275e1872ba 100644 --- a/master/src/main/webapp/WEB-INF/web.xml +++ b/master/src/main/webapp/WEB-INF/web.xml @@ -5,7 +5,10 @@ id="WebApp_ID" version="3.0"> contextConfigLocation - classpath:master-context.xml + + classpath:master-context.xml + classpath:master-context-security.xml + org.springframework.web.context.ContextLoaderListener From 56e5352933ba7d38cae76bf8930ec0c72a48aed0 Mon Sep 17 00:00:00 2001 From: Tomas Knap Date: Thu, 23 Nov 2017 10:52:07 +0100 Subject: [PATCH 2/4] Adjusted pipeline and scheduler rest api services --- .../master/api/PipelineResource.java | 64 ++++++++++--------- .../master/api/ScheduleResource.java | 55 ++++++++++++++-- .../unifiedviews/master/api/UserHelper.java | 38 +++++++++++ .../converter/PipelineDTOConverter.java | 18 +++--- .../converter/ScheduleDTOConverter.java | 30 +++++++++ .../resources/master-messages_en.properties | 7 +- 6 files changed, 166 insertions(+), 46 deletions(-) create mode 100644 master/src/main/java/eu/unifiedviews/master/api/UserHelper.java diff --git a/master/src/main/java/eu/unifiedviews/master/api/PipelineResource.java b/master/src/main/java/eu/unifiedviews/master/api/PipelineResource.java index 53b8af88f8..a714777104 100644 --- a/master/src/main/java/eu/unifiedviews/master/api/PipelineResource.java +++ b/master/src/main/java/eu/unifiedviews/master/api/PipelineResource.java @@ -32,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 @@ -51,7 +53,10 @@ public class PipelineResource { private UserFacade userFacade; @Autowired - private BasicAuthenticationFilter authFilter; + private UserHelper userHelper; + +// @Autowired +// private BasicAuthenticationFilter authFilter; @POST @Consumes(MediaType.APPLICATION_JSON) @@ -69,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); } @@ -104,22 +113,9 @@ public List getPipelines(@QueryParam("userExternalId") String userE List pipelines = null; try { - if (isNotEmpty(userExternalId)) { - pipelines = this.pipelineFacade.getAllPipelines(userExternalId); - } else { - //user is empty, use the one from the basic auth header - userExternalId = this.authFilter.getUserName(); - if (isNotEmpty(userExternalId)) { - pipelines = this.pipelineFacade.getAllPipelines(userExternalId); - } - else { - LOG.error("No user defined in the parameter and no user was retrieved from the authentication header"); - pipelines = new ArrayList<>(); - } - } - - if (pipelines == null) { - pipelines = new ArrayList<>(); + String user = userHelper.getUser(userExternalId); + if (user != null) { + pipelines = this.pipelineFacade.getAllPipelines(user); } } catch (ApiException e) { throw e; @@ -136,10 +132,9 @@ public List getPipelines(@QueryParam("userExternalId") String userE public List getVisiblePipelines(@QueryParam("userExternalId") String userExternalId) { List 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; @@ -149,6 +144,7 @@ public List getVisiblePipelines(@QueryParam("userExternalId") Strin return PipelineDTOConverter.convert(pipelines); } + @GET @Path("/{pipelineid}") @Produces({ MediaType.APPLICATION_JSON }) @@ -193,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())); } @@ -205,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) { @@ -225,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"); } @@ -246,4 +249,5 @@ public PipelineDTO importPipeline(@FormDataParam("file") InputStream inputStream } return PipelineDTOConverter.convert(importedPipeline); } + } diff --git a/master/src/main/java/eu/unifiedviews/master/api/ScheduleResource.java b/master/src/main/java/eu/unifiedviews/master/api/ScheduleResource.java index 7defab2fc7..47ccbb8ba0 100644 --- a/master/src/main/java/eu/unifiedviews/master/api/ScheduleResource.java +++ b/master/src/main/java/eu/unifiedviews/master/api/ScheduleResource.java @@ -37,6 +37,9 @@ public class ScheduleResource { @Autowired private UserFacade userFacade; + @Autowired + private UserHelper userHelper; + @GET @Path("/{pipelineid}/schedules") @Produces({ MediaType.APPLICATION_JSON }) @@ -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 { @@ -230,14 +233,16 @@ 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"); @@ -245,9 +250,12 @@ public PipelineScheduleDTO createPipelineSchedule(@PathParam("pipelineid") Strin schedule.setPipeline(pipeline); schedule.setType(scheduleToUpdate.getScheduleType()); schedule.setOwner(user); + + UserActor actor = this.userFacade.getUserActorByExternalId(scheduleToUpdate.getUserActorExternalId()); if (actor != null) { schedule.setActor(actor); } + List afterPipelines = null; if (scheduleToUpdate.getAfterPipelines() != null) { afterPipelines = new ArrayList(); @@ -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()); + } + } + + } diff --git a/master/src/main/java/eu/unifiedviews/master/api/UserHelper.java b/master/src/main/java/eu/unifiedviews/master/api/UserHelper.java new file mode 100644 index 0000000000..da223ee7ae --- /dev/null +++ b/master/src/main/java/eu/unifiedviews/master/api/UserHelper.java @@ -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; + } + + } + +} diff --git a/master/src/main/java/eu/unifiedviews/master/converter/PipelineDTOConverter.java b/master/src/main/java/eu/unifiedviews/master/converter/PipelineDTOConverter.java index eefb22b436..94ceee6bdd 100644 --- a/master/src/main/java/eu/unifiedviews/master/converter/PipelineDTOConverter.java +++ b/master/src/main/java/eu/unifiedviews/master/converter/PipelineDTOConverter.java @@ -28,17 +28,19 @@ public static PipelineDTO convert(Pipeline pipeline) { } public static List convert(List pipelines) { - List dtos = null; - if (pipelines != null) { - dtos = new ArrayList(); - for (Pipeline pipeline : pipelines) { - PipelineDTO dto = convert(pipeline); - if (dto != null) { - dtos.add(dto); - } + if (pipelines == null) { + pipelines = new ArrayList<>(); + } + + List dtos = new ArrayList(); + for (Pipeline pipeline : pipelines) { + PipelineDTO dto = convert(pipeline); + if (dto != null) { + dtos.add(dto); } } + return dtos; } diff --git a/master/src/main/java/eu/unifiedviews/master/converter/ScheduleDTOConverter.java b/master/src/main/java/eu/unifiedviews/master/converter/ScheduleDTOConverter.java index 47d8c9b1f2..347eb07ce4 100644 --- a/master/src/main/java/eu/unifiedviews/master/converter/ScheduleDTOConverter.java +++ b/master/src/main/java/eu/unifiedviews/master/converter/ScheduleDTOConverter.java @@ -91,4 +91,34 @@ public static Schedule convertFromDTO(PipelineScheduleDTO dto, List pi } return schedule; } + + public static Schedule convertFromDTOEdit(PipelineScheduleDTO dto, List pipelines, Schedule schedule) { + if (dto.getDescription() != null) { + schedule.setDescription(dto.getDescription()); + } + schedule.setJustOnce(dto.isJustOnce()); + schedule.setEnabled(dto.isEnabled()); + if (dto.getFirstExecution() != null) { + schedule.setFirstExecution(ConvertUtils.stringToDate(dto.getFirstExecution())); + } + if (dto.getLastExecution() != null) { + schedule.setLastExecution(ConvertUtils.stringToDate(dto.getLastExecution())); + } + + //TODO after pipelines are always cleared! + Set originalSet = schedule.getAfterPipelines(); + originalSet.clear(); + if (pipelines != null) { + originalSet.addAll(pipelines); + schedule.setAfterPipelines(originalSet); + } else { + schedule.setAfterPipelines(null); + } + + if (dto.getPeriod() != null && dto.getPeriodUnit() != null) { + schedule.setPeriod(dto.getPeriod()); + schedule.setPeriodUnit(PeriodUnit.valueOf(dto.getPeriodUnit())); + } + return schedule; + } } diff --git a/master/src/main/resources/master-messages_en.properties b/master/src/main/resources/master-messages_en.properties index 6b574a99ab..252c7562b7 100644 --- a/master/src/main/resources/master-messages_en.properties +++ b/master/src/main/resources/master-messages_en.properties @@ -2,6 +2,7 @@ general.exception = Error occurred during processing of a request. visibility.input.error = Chosen visibility type does not exist. pipeline.id.invalid = Pipeline ID=''{0}'' is not valid! +schedule.id.invalid = Schedule ID=''{0}'' is not valid! pipeline.execution.id.invalid = Pipeline execution ID=''{0}'' is not valid! pipeline.schedule.id.invalid = Pipeline schedule ID=''{0}'' is not valid! pipeline.id.not.found = Pipeline with ID=''{0}'' not found! @@ -15,10 +16,10 @@ pipeline.import.general.error = Pipeline cannot be imported. pipeline.create.general.error = Pipeline cannot be created. pipeline.get.executions.general.error = Pipeline execution cannot be retrieved. pipeline.get.executions.events.general.error = Pipeline execution events cannot be retrieved. -pipeline.get.schedule.general.error = Pipeline execution cannot be retrieved. +pipeline.get.schedule.general.error = Scheduled event cannot be retrieved. pipeline.create.execution.general.error = Pipeline execution cannot be created. -pipeline.update.schedule.general.error = Pipeline schedule cannot be updated. -pipeline.create.schedule.general.error = Pipeline schedule cannot be created. +pipeline.update.schedule.general.error = Scheduled event cannot be updated. +pipeline.create.schedule.general.error = Scheduled event cannot be created. pipeline.name.duplicate = Pipeline with name ''{0}'' already exists. Pipeline cannot be created! pipeline.name.length.exceeded = Pipeline name length exceeds maximum number of 1024 characters! pipeline.user.id.not.found = User not found! Pipeline could not be created. From 5955e37e9cde940db88ac5c26fb701af5d24fcf9 Mon Sep 17 00:00:00 2001 From: Tomas Knap Date: Thu, 23 Nov 2017 11:46:40 +0100 Subject: [PATCH 3/4] Adjusted execution resource + dpu import + pruned basic auth filter --- .../unifiedviews/master/api/DPUResource.java | 8 ++---- .../master/api/ExecutionResource.java | 15 ++++++++--- .../BasicAuthenticationFilter.java | 26 +++---------------- 3 files changed, 17 insertions(+), 32 deletions(-) diff --git a/master/src/main/java/eu/unifiedviews/master/api/DPUResource.java b/master/src/main/java/eu/unifiedviews/master/api/DPUResource.java index 5cbfe1258f..1cb150a7f8 100644 --- a/master/src/main/java/eu/unifiedviews/master/api/DPUResource.java +++ b/master/src/main/java/eu/unifiedviews/master/api/DPUResource.java @@ -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; @@ -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; diff --git a/master/src/main/java/eu/unifiedviews/master/api/ExecutionResource.java b/master/src/main/java/eu/unifiedviews/master/api/ExecutionResource.java index 4a971f524c..0942dfdd25 100644 --- a/master/src/main/java/eu/unifiedviews/master/api/ExecutionResource.java +++ b/master/src/main/java/eu/unifiedviews/master/api/ExecutionResource.java @@ -42,6 +42,9 @@ public class ExecutionResource { @Autowired private UserFacade userFacade; + @Autowired + private UserHelper userHelper; + private static final Logger log = LoggerFactory.getLogger( ExecutionResource.class); @@ -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); diff --git a/master/src/main/java/eu/unifiedviews/master/authentication/BasicAuthenticationFilter.java b/master/src/main/java/eu/unifiedviews/master/authentication/BasicAuthenticationFilter.java index b7c78134a4..ee87de1947 100644 --- a/master/src/main/java/eu/unifiedviews/master/authentication/BasicAuthenticationFilter.java +++ b/master/src/main/java/eu/unifiedviews/master/authentication/BasicAuthenticationFilter.java @@ -55,10 +55,10 @@ public class BasicAuthenticationFilter implements ContainerRequestFilter { @PostConstruct private void init() { - String username = configuration.getString(ConfigProperty.MASTER_API_USER); - String password = configuration.getString(ConfigProperty.MASTER_API_PASSWORD); - - this.credentials = Base64.encodeAsString(username + ":" + password); +// String username = configuration.getString(ConfigProperty.MASTER_API_USER); +// String password = configuration.getString(ConfigProperty.MASTER_API_PASSWORD); +// +// this.credentials = Base64.encodeAsString(username + ":" + password); } /** @@ -98,10 +98,6 @@ private boolean isAuthorizationValid(String authorization) { // remove "Basic " part from header authorization = authorization.replaceAll("[Bb]asic ", ""); - // return authorization.equals(credentials); - - - //get the user, correctPass, check String decodedToken = Base64.decodeAsString(authorization); @@ -129,19 +125,5 @@ private boolean isAuthorizationValid(String authorization) { return true; -// //authentication manual, not needed -// User u = users.getUserByUsername(username); -// u.getPassword(); -// -// -// String correctPassHashed = u.getPassword(); -// try { -// return PasswordHash.validatePassword(pass,correctPassHashed); -// } catch (NoSuchAlgorithmException e) { -// e.printStackTrace(); -// } catch (InvalidKeySpecException e) { -// e.printStackTrace(); -// } -// return false; } } From a166e707ee1bf0876a971312ae33598e382e6fd2 Mon Sep 17 00:00:00 2001 From: Tomas Knap Date: Thu, 23 Nov 2017 11:47:35 +0100 Subject: [PATCH 4/4] Credentials for rest api removed from config - not needed anymore --- conf/config.sample.properties | 4 ---- 1 file changed, 4 deletions(-) diff --git a/conf/config.sample.properties b/conf/config.sample.properties index ec8426587f..259dba0219 100644 --- a/conf/config.sample.properties +++ b/conf/config.sample.properties @@ -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: