Commit d07c78a5 authored by Grzegorz Pietrusza's avatar Grzegorz Pietrusza

add hashValidator - but circular dependency

parent 86a7adf5
package com.telephoners.krakyournet.ctf.core;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.telephoners.krakyournet.ctf.beans.Flag;
import com.telephoners.krakyournet.ctf.beans.User;
import com.telephoners.krakyournet.ctf.beans.tasks.Task;
import com.telephoners.krakyournet.ctf.repositories.SolutionsRepository;
import com.telephoners.krakyournet.ctf.repositories.TasksRepository;
import javafx.util.Pair;
import org.apache.commons.codec.binary.Hex;
import javax.inject.Named;
import java.security.MessageDigest;
@Singleton
public class HashValidator
{
private ApplicationConfiguration applicationConfiguration;
private MessageDigest messageDigest; //todo: use messageDigestProvider
private SolutionsRepository solutionsRepository;
private TasksRepository tasksRepository;
@Inject
public HashValidator(ApplicationConfiguration applicationConfiguration,
SolutionsRepository solutionsRepository,
TasksRepository tasksRepository,
final @Named("messageDigest") MessageDigest messageDigest)
{
this.applicationConfiguration = applicationConfiguration;
this.solutionsRepository = solutionsRepository;
this.tasksRepository = tasksRepository;
this.messageDigest = messageDigest;
}
public String calculateHashValue(User user, String flagValue)
{
String combinedStrings = applicationConfiguration.getSalt() + user.getName() + flagValue;
return Hex.encodeHexString(messageDigest.digest(combinedStrings.getBytes()));
}
public boolean checkHash(User user, String hashValue, int taskLevel)
{
Pair<Task, Flag> taskFlagPair = tasksRepository.getTaskFlagPairByHashValue(user, hashValue, taskLevel);
//todo: move to solutionsRepository
return solutionsRepository.submitSolution(user, taskFlagPair.getKey(), taskFlagPair.getValue(), hashValue);
}
}
package com.telephoners.krakyournet.ctf.repositories;
import com.telephoners.krakyournet.ctf.beans.Flag;
import com.telephoners.krakyournet.ctf.beans.Solution;
import com.telephoners.krakyournet.ctf.beans.Team;
import com.telephoners.krakyournet.ctf.beans.User;
import com.telephoners.krakyournet.ctf.beans.tasks.Task;
import org.mongodb.morphia.Datastore;
......@@ -15,10 +17,17 @@ import java.util.stream.Collectors;
@Singleton
public class SolutionsRepository extends Repository<Solution>
{
private TeamsRepository teamsRepository;
private TasksRepository tasksRepository;
@Inject
public SolutionsRepository(Datastore datastore)
public SolutionsRepository(TeamsRepository teamsRepository,
TasksRepository tasksRepository,
Datastore datastore)
{
super(datastore);
this.tasksRepository = tasksRepository;
this.teamsRepository = teamsRepository;
}
public Map<Integer, List<String>> getTeamSolutions(Team team)
......@@ -50,4 +59,27 @@ public class SolutionsRepository extends Repository<Solution>
.filter("flag.value", solution.getFlag().getValue())
.get() != null;
}
public List<Integer> getCompletedTasks(Team team)
{
Map<Integer, List<String>> teamSolutions = getTeamSolutions(team);
return tasksRepository.getAll().stream()
.filter(task -> {
List<String> teamTaskSolutions = teamSolutions.get(task.getLevel());
return teamTaskSolutions != null && teamTaskSolutions.size() == task.getFlags().size();
})
.map(Task::getLevel)
.collect(Collectors.toList());
}
public boolean submitSolution(User user, Task task, Flag flag, String hashValue)
{
Team team = teamsRepository.getTeamByUser(user);
Solution solution = new Solution(team, task, flag, hashValue);
if (!isAlreadySubmittedSolution(solution)) {
add(solution);
return true;
}
return false;
}
}
\ No newline at end of file
......@@ -2,14 +2,12 @@ package com.telephoners.krakyournet.ctf.repositories;
import com.google.inject.name.Named;
import com.telephoners.krakyournet.ctf.beans.Flag;
import com.telephoners.krakyournet.ctf.beans.Solution;
import com.telephoners.krakyournet.ctf.beans.Team;
import com.telephoners.krakyournet.ctf.beans.User;
import com.telephoners.krakyournet.ctf.beans.tasks.Task;
import com.telephoners.krakyournet.ctf.core.ApplicationConfiguration;
import com.telephoners.krakyournet.ctf.core.HashValidator;
import com.telephoners.krakyournet.ctf.helpers.DBObjectUtils;
import javafx.util.Pair;
import org.apache.commons.codec.binary.Hex;
import org.mongodb.morphia.Datastore;
import javax.inject.Inject;
......@@ -27,12 +25,14 @@ public class TasksRepository extends Repository<Task>
private TeamsRepository teamsRepository;
private SolutionsRepository solutionsRepository;
private UsersRepository usersRepository;
private HashValidator hashValidator;
private MessageDigest messageDigest;
@Inject
public TasksRepository(ApplicationConfiguration applicationConfiguration, Datastore datastore,
TeamsRepository teamsRepository, SolutionsRepository solutionsRepository,
UsersRepository usersRepository,
HashValidator hashValidator,
final @Named("messageDigest") MessageDigest messageDigest)
{
super(datastore);
......@@ -41,6 +41,7 @@ public class TasksRepository extends Repository<Task>
this.teamsRepository = teamsRepository;
this.solutionsRepository = solutionsRepository;
this.usersRepository = usersRepository;
this.hashValidator = hashValidator;
this.messageDigest = messageDigest;
}
......@@ -64,50 +65,18 @@ public class TasksRepository extends Repository<Task>
.collect(Collectors.toMap(
Task::getLevel,
task -> task.getFlags().stream()
.map(flag -> calculateHashValue(usersRepository.getUserByName(username), flag.getValue()))
.map(flag -> hashValidator.calculateHashValue(usersRepository.getUserByName(username), flag.getValue()))
.collect(Collectors.toList())
));
}
private Pair<Task, Flag> getTaskFlagPairByHashValue(User user, String userHash, int taskLevel)
public Pair<Task, Flag> getTaskFlagPairByHashValue(User user, String userHash, int taskLevel)
{
String username = user.getName();
Flag matchedFlag = getByLevel(taskLevel).getFlags().stream()
.filter(flag -> calculateHashValue(user, flag.getValue()).equals(userHash))
.filter(flag -> hashValidator.calculateHashValue(user, flag.getValue()).equals(userHash))
.findFirst()
.get();
return new Pair<>(getByLevel(taskLevel), matchedFlag);
}
public String calculateHashValue(User user, String flagValue)
{
String combinedStrings = applicationConfiguration.getSalt() + user.getName() + flagValue;
return Hex.encodeHexString(messageDigest.digest(combinedStrings.getBytes()));
}
public boolean checkHash(User user, String hashValue, int taskLevel)
{
Team team = teamsRepository.getTeamByUser(user);
Pair<Task, Flag> taskFlagPair = getTaskFlagPairByHashValue(user, hashValue, taskLevel);
Solution solution = new Solution(team, taskFlagPair.getKey(), taskFlagPair.getValue(), hashValue);
if (!solutionsRepository.isAlreadySubmittedSolution(solution)) {
solutionsRepository.add(solution);
return true;
}
return false;
}
//todo: should it be here?
public List<Integer> getCompletedTasks(Team team)
{
Map<Integer, List<String>> teamSolutions = solutionsRepository.getTeamSolutions(team);
return getAll().stream()
.filter(task -> {
List<String> teamTaskSolutions = teamSolutions.get(task.getLevel());
return teamTaskSolutions != null && teamTaskSolutions.size() == task.getFlags().size();
})
.map(Task::getLevel)
.collect(Collectors.toList());
}
}
\ No newline at end of file
......@@ -2,6 +2,7 @@ package com.telephoners.krakyournet.ctf.resources;
import com.telephoners.krakyournet.ctf.beans.Team;
import com.telephoners.krakyournet.ctf.beans.User;
import com.telephoners.krakyournet.ctf.core.HashValidator;
import com.telephoners.krakyournet.ctf.repositories.SolutionsRepository;
import com.telephoners.krakyournet.ctf.repositories.TasksRepository;
import com.telephoners.krakyournet.ctf.repositories.TeamsRepository;
......@@ -25,14 +26,16 @@ public class SolutionsResource
private TeamsRepository teamsRepository;
private SolutionsRepository solutionsRepository;
private TasksRepository tasksRepository;
private HashValidator hashValidator;
@Inject
public SolutionsResource(SolutionsRepository solutionsRepository, TasksRepository tasksRepository,
TeamsRepository teamsRepository)
TeamsRepository teamsRepository, HashValidator hashValidator)
{
this.solutionsRepository = solutionsRepository;
this.tasksRepository = tasksRepository;
this.teamsRepository = teamsRepository;
this.hashValidator = hashValidator;
}
@POST
......@@ -41,7 +44,7 @@ public class SolutionsResource
@PathParam("task_level") int taskLevel,
String hash) throws Exception
{
if (tasksRepository.checkHash(user, hash, taskLevel)) {
if (hashValidator.checkHash(user, hash, taskLevel)) {
return Response.ok().build();
}
return Response.status(Response.Status.NOT_ACCEPTABLE).build();
......@@ -51,7 +54,7 @@ public class SolutionsResource
@Path("/completed")
public List<Integer> getTeamCompletedTasks(@Auth User user)
{
return tasksRepository.getCompletedTasks(teamsRepository.getTeamByUser(user));
return solutionsRepository.getCompletedTasks(teamsRepository.getTeamByUser(user));
}
@GET
......@@ -62,7 +65,7 @@ public class SolutionsResource
.stream()
.collect(Collectors.toMap(
Team::getName,
team -> tasksRepository.getCompletedTasks(team)
team -> solutionsRepository.getCompletedTasks(team)
));
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment