Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,12 @@
import uno.cod.platform.server.core.dto.user.UserShortShowDto;
import uno.cod.platform.server.core.exception.CodunoIllegalArgumentException;
import uno.cod.platform.server.core.mapper.ResultMapper;
import uno.cod.platform.server.core.repository.ChallengeRepository;
import uno.cod.platform.server.core.repository.ParticipationRepository;
import uno.cod.platform.server.core.repository.ResultRepository;
import uno.cod.platform.server.core.repository.*;

import javax.servlet.http.HttpSession;
import javax.transaction.Transactional;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.*;

@Service
@Transactional
Expand All @@ -28,14 +24,21 @@ public class ResultService {
private final ChallengeRepository challengeRepository;
private final TaskScheduler taskScheduler;
private final ParticipationRepository participationRepository;
private final HttpSession httpSession;

public static final String CURRENT_CHALLENGE = "CURRENT_CHALLENGE";

@Autowired
public ResultService(ResultRepository repository,
ChallengeRepository challengeRepository, TaskScheduler taskScheduler, ParticipationRepository participationRepository) {
ChallengeRepository challengeRepository,
TaskScheduler taskScheduler,
ParticipationRepository participationRepository,
HttpSession httpSession) {
this.repository = repository;
this.challengeRepository = challengeRepository;
this.taskScheduler = taskScheduler;
this.participationRepository = participationRepository;
this.httpSession = httpSession;
}

public ResultShowDto save(UUID challengeId, User user) {
Expand Down Expand Up @@ -81,6 +84,7 @@ public ResultShowDto save(UUID challengeId, User user) {
repository.save(r);
}, setFinished);

httpSession.setAttribute(CURRENT_CHALLENGE, challenge.getId());
return ResultMapper.map(result);
}

Expand Down Expand Up @@ -111,6 +115,7 @@ public ResultInfoDto getResultInfoForUserAndChallenge(UUID userId, UUID challeng
if (result == null) {
return null;
}
httpSession.setAttribute(CURRENT_CHALLENGE, challengeId);
return new ResultInfoDto(result);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,15 @@

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import uno.cod.platform.server.core.domain.Endpoint;
import uno.cod.platform.server.core.domain.Organization;
import uno.cod.platform.server.core.domain.Runner;
import uno.cod.platform.server.core.domain.Task;
import uno.cod.platform.server.core.domain.*;
import uno.cod.platform.server.core.dto.task.TaskCreateDto;
import uno.cod.platform.server.core.dto.task.TaskShowDto;
import uno.cod.platform.server.core.exception.CodunoAccessDeniedException;
import uno.cod.platform.server.core.exception.CodunoIllegalArgumentException;
import uno.cod.platform.server.core.mapper.TaskMapper;
import uno.cod.platform.server.core.repository.EndpointRepository;
import uno.cod.platform.server.core.repository.OrganizationRepository;
import uno.cod.platform.server.core.repository.RunnerRepository;
import uno.cod.platform.server.core.repository.TaskRepository;
import uno.cod.platform.server.core.repository.*;

import javax.servlet.http.HttpSession;
import javax.transaction.Transactional;
import java.util.List;
import java.util.UUID;
Expand All @@ -26,13 +22,28 @@ public class TaskService {
private final EndpointRepository endpointRepository;
private final OrganizationRepository organizationRepository;
private final RunnerRepository runnerRepository;
private final ChallengeRepository challengeRepository;
private final UserRepository userRepository;
private final ResultRepository resultRepository;
private final HttpSession httpSession;

@Autowired
public TaskService(TaskRepository repository, EndpointRepository endpointRepository, OrganizationRepository organizationRepository, RunnerRepository runnerRepository) {
public TaskService(TaskRepository repository,
EndpointRepository endpointRepository,
OrganizationRepository organizationRepository,
RunnerRepository runnerRepository,
ChallengeRepository challengeRepository,
UserRepository userRepository,
ResultRepository resultRepository,
HttpSession httpSession) {
this.repository = repository;
this.endpointRepository = endpointRepository;
this.organizationRepository = organizationRepository;
this.runnerRepository = runnerRepository;
this.challengeRepository = challengeRepository;
this.userRepository = userRepository;
this.resultRepository = resultRepository;
this.httpSession = httpSession;
}

public UUID save(TaskCreateDto dto) {
Expand Down Expand Up @@ -68,8 +79,28 @@ public UUID save(TaskCreateDto dto) {
return repository.save(task).getId();
}

public TaskShowDto findById(UUID id) {
return TaskMapper.map(repository.findOneWithTemplates(id));
public TaskShowDto findById(UUID taskId, User u) {
Task task = repository.findOneWithTemplates(taskId);
User user = userRepository.findOne(u.getId());
Object attr = httpSession.getAttribute(ResultService.CURRENT_CHALLENGE);
if (attr == null) {
throw new CodunoAccessDeniedException("challenge.invalid");
}

Challenge challenge = challengeRepository.findOne((UUID)attr);

if (canSeeTask(user, challenge, task)) {
return TaskMapper.map(task);
}
throw new CodunoAccessDeniedException("task.denied");
}

private boolean canSeeTask(User user, Challenge challenge, Task task) {
int requestedIndex = challenge.getChallengeTemplate().getTasks().indexOf(task);

// User can see task if it is the first task (requestedIndex == 0) or the previous task was completed
// successfully.
return requestedIndex == 0 || resultRepository.findOneByUserAndChallenge(user.getId(), challenge.getId()).getTaskResults().get(requestedIndex - 1).isSuccessful();
}

public List<TaskShowDto> findAllForOrganization(UUID organizationId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import uno.cod.platform.server.core.domain.Task;
import uno.cod.platform.server.core.domain.*;
import uno.cod.platform.server.core.dto.task.TaskCreateDto;
import uno.cod.platform.server.core.dto.task.TaskShowDto;
import uno.cod.platform.server.core.repository.EndpointRepository;
import uno.cod.platform.server.core.repository.OrganizationRepository;
import uno.cod.platform.server.core.repository.RunnerRepository;
import uno.cod.platform.server.core.repository.TaskRepository;
import uno.cod.platform.server.core.exception.CodunoAccessDeniedException;
import uno.cod.platform.server.core.repository.*;
import uno.cod.platform.server.core.service.util.ChallengeTestUtil;
import uno.cod.platform.server.core.service.util.TaskTestUtil;
import uno.cod.platform.server.core.service.util.UserTestUtil;

import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
Expand All @@ -23,14 +25,22 @@ public class TaskServiceTest {
private EndpointRepository endpointRepository;
private OrganizationRepository organizationRepository;
private RunnerRepository runnerRepository;
private ChallengeRepository challengeRepository;
private UserRepository userRepository;
private ResultRepository resultRepository;
private HttpSession httpSession;

@Before
public void setup() {
this.repository = Mockito.mock(TaskRepository.class);
this.endpointRepository = Mockito.mock(EndpointRepository.class);
this.organizationRepository = Mockito.mock(OrganizationRepository.class);
this.runnerRepository = Mockito.mock(RunnerRepository.class);
this.service = new TaskService(repository, endpointRepository, organizationRepository, runnerRepository);
this.challengeRepository = Mockito.mock(ChallengeRepository.class);
this.userRepository = Mockito.mock(UserRepository.class);
this.resultRepository = Mockito.mock(ResultRepository.class);
this.httpSession = Mockito.mock(HttpSession.class);
this.service = new TaskService(repository, endpointRepository, organizationRepository, runnerRepository, challengeRepository, userRepository, resultRepository, httpSession);
}

@Test
Expand All @@ -48,16 +58,57 @@ public void save() throws Exception {
Assert.assertEquals(id, task.getId());
}

@Test
public void findById() throws Exception {

@Test(expected = CodunoAccessDeniedException.class)
public void findByIdAccessDenied() throws Exception {
// Neither the session attribute is set nor the repository methods are mocked and therefore return null
Task task = TaskTestUtil.getValidTask();
Mockito.when(repository.findOneWithTemplates(task.getId())).thenReturn(task);
User user = UserTestUtil.getUser();

TaskShowDto dto = service.findById(task.getId());
Mockito.when(repository.findOneWithTemplates(task.getId())).thenReturn(task);

TaskShowDto dto = service.findById(task.getId(), user);
assertTaskEquals(task, dto);
}

@Test
public void findByIdAccessGranted() throws Exception {
Task task = TaskTestUtil.getValidTask();
Task newTask = TaskTestUtil.getValidTask();
User user = UserTestUtil.getUser();
Challenge challenge = ChallengeTestUtil.getChallenge();

Result result = new Result();
result.setChallenge(challenge);
result.setUser(user);

TaskResult taskResult = new TaskResult();
taskResult.setSuccessful(true);

TaskResultKey taskResultKey = new TaskResultKey();
taskResultKey.setResult(result);
taskResultKey.setTask(task);

ArrayList<TaskResult> taskResultList = new ArrayList<>();
taskResultList.add(taskResult);
result.setTaskResults(taskResultList);

ArrayList<Task> tasks = new ArrayList<>();
tasks.add(task);
tasks.add(newTask);
challenge.getChallengeTemplate().setTasks(tasks);

Mockito.when(httpSession.getAttribute(ResultService.CURRENT_CHALLENGE)).thenReturn(challenge.getId());
Mockito.when(userRepository.findOne(user.getId())).thenReturn(user);
Mockito.when(repository.findOneWithTemplates(task.getId())).thenReturn(task);
Mockito.when(repository.findOneWithTemplates(newTask.getId())).thenReturn(newTask);
Mockito.when(challengeRepository.findOne(challenge.getId())).thenReturn(challenge);
Mockito.when(resultRepository.findOneByUserAndChallenge(user.getId(), challenge.getId())).thenReturn(result);

TaskShowDto dto = service.findById(newTask.getId(), user);
assertTaskEquals(newTask, dto);
}

@Test
public void findAll() throws Exception {
Task task = TaskTestUtil.getValidTask();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
import uno.cod.platform.server.core.domain.User;
import uno.cod.platform.server.core.dto.task.TaskCreateDto;
import uno.cod.platform.server.core.dto.task.TaskShowDto;
import uno.cod.platform.server.core.security.AllowedForAdmin;
Expand Down Expand Up @@ -32,8 +34,8 @@ public ResponseEntity<UUID> create(@Valid @RequestBody TaskCreateDto dto) {

@RequestMapping(value = RestUrls.TASKS_ID, method = RequestMethod.GET)
@PreAuthorize("isAuthenticated() and @securityService.canAccessTask(principal, #id)")
public ResponseEntity<TaskShowDto> findById(@PathVariable UUID id) {
return new ResponseEntity<>(taskService.findById(id), HttpStatus.OK);
public ResponseEntity<TaskShowDto> findById(@PathVariable UUID id, @AuthenticationPrincipal User user) {
return new ResponseEntity<>(taskService.findById(id, user), HttpStatus.OK);
}

@RequestMapping(value = RestUrls.TASKS, method = RequestMethod.GET, params = {"organization"})
Expand Down