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; 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.Solution;
import com.telephoners.krakyournet.ctf.beans.Team; 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.beans.tasks.Task;
import org.mongodb.morphia.Datastore; import org.mongodb.morphia.Datastore;
...@@ -15,10 +17,17 @@ import java.util.stream.Collectors; ...@@ -15,10 +17,17 @@ import java.util.stream.Collectors;
@Singleton @Singleton
public class SolutionsRepository extends Repository<Solution> public class SolutionsRepository extends Repository<Solution>
{ {
private TeamsRepository teamsRepository;
private TasksRepository tasksRepository;
@Inject @Inject
public SolutionsRepository(Datastore datastore) public SolutionsRepository(TeamsRepository teamsRepository,
TasksRepository tasksRepository,
Datastore datastore)
{ {
super(datastore); super(datastore);
this.tasksRepository = tasksRepository;
this.teamsRepository = teamsRepository;
} }
public Map<Integer, List<String>> getTeamSolutions(Team team) public Map<Integer, List<String>> getTeamSolutions(Team team)
...@@ -50,4 +59,27 @@ public class SolutionsRepository extends Repository<Solution> ...@@ -50,4 +59,27 @@ public class SolutionsRepository extends Repository<Solution>
.filter("flag.value", solution.getFlag().getValue()) .filter("flag.value", solution.getFlag().getValue())
.get() != null; .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; ...@@ -2,14 +2,12 @@ package com.telephoners.krakyournet.ctf.repositories;
import com.google.inject.name.Named; import com.google.inject.name.Named;
import com.telephoners.krakyournet.ctf.beans.Flag; 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.User;
import com.telephoners.krakyournet.ctf.beans.tasks.Task; import com.telephoners.krakyournet.ctf.beans.tasks.Task;
import com.telephoners.krakyournet.ctf.core.ApplicationConfiguration; import com.telephoners.krakyournet.ctf.core.ApplicationConfiguration;
import com.telephoners.krakyournet.ctf.core.HashValidator;
import com.telephoners.krakyournet.ctf.helpers.DBObjectUtils; import com.telephoners.krakyournet.ctf.helpers.DBObjectUtils;
import javafx.util.Pair; import javafx.util.Pair;
import org.apache.commons.codec.binary.Hex;
import org.mongodb.morphia.Datastore; import org.mongodb.morphia.Datastore;
import javax.inject.Inject; import javax.inject.Inject;
...@@ -27,12 +25,14 @@ public class TasksRepository extends Repository<Task> ...@@ -27,12 +25,14 @@ public class TasksRepository extends Repository<Task>
private TeamsRepository teamsRepository; private TeamsRepository teamsRepository;
private SolutionsRepository solutionsRepository; private SolutionsRepository solutionsRepository;
private UsersRepository usersRepository; private UsersRepository usersRepository;
private HashValidator hashValidator;
private MessageDigest messageDigest; private MessageDigest messageDigest;
@Inject @Inject
public TasksRepository(ApplicationConfiguration applicationConfiguration, Datastore datastore, public TasksRepository(ApplicationConfiguration applicationConfiguration, Datastore datastore,
TeamsRepository teamsRepository, SolutionsRepository solutionsRepository, TeamsRepository teamsRepository, SolutionsRepository solutionsRepository,
UsersRepository usersRepository, UsersRepository usersRepository,
HashValidator hashValidator,
final @Named("messageDigest") MessageDigest messageDigest) final @Named("messageDigest") MessageDigest messageDigest)
{ {
super(datastore); super(datastore);
...@@ -41,6 +41,7 @@ public class TasksRepository extends Repository<Task> ...@@ -41,6 +41,7 @@ public class TasksRepository extends Repository<Task>
this.teamsRepository = teamsRepository; this.teamsRepository = teamsRepository;
this.solutionsRepository = solutionsRepository; this.solutionsRepository = solutionsRepository;
this.usersRepository = usersRepository; this.usersRepository = usersRepository;
this.hashValidator = hashValidator;
this.messageDigest = messageDigest; this.messageDigest = messageDigest;
} }
...@@ -64,50 +65,18 @@ public class TasksRepository extends Repository<Task> ...@@ -64,50 +65,18 @@ public class TasksRepository extends Repository<Task>
.collect(Collectors.toMap( .collect(Collectors.toMap(
Task::getLevel, Task::getLevel,
task -> task.getFlags().stream() task -> task.getFlags().stream()
.map(flag -> calculateHashValue(usersRepository.getUserByName(username), flag.getValue())) .map(flag -> hashValidator.calculateHashValue(usersRepository.getUserByName(username), flag.getValue()))
.collect(Collectors.toList()) .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(); String username = user.getName();
Flag matchedFlag = getByLevel(taskLevel).getFlags().stream() Flag matchedFlag = getByLevel(taskLevel).getFlags().stream()
.filter(flag -> calculateHashValue(user, flag.getValue()).equals(userHash)) .filter(flag -> hashValidator.calculateHashValue(user, flag.getValue()).equals(userHash))
.findFirst() .findFirst()
.get(); .get();
return new Pair<>(getByLevel(taskLevel), matchedFlag); 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; ...@@ -2,6 +2,7 @@ package com.telephoners.krakyournet.ctf.resources;
import com.telephoners.krakyournet.ctf.beans.Team; import com.telephoners.krakyournet.ctf.beans.Team;
import com.telephoners.krakyournet.ctf.beans.User; 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.SolutionsRepository;
import com.telephoners.krakyournet.ctf.repositories.TasksRepository; import com.telephoners.krakyournet.ctf.repositories.TasksRepository;
import com.telephoners.krakyournet.ctf.repositories.TeamsRepository; import com.telephoners.krakyournet.ctf.repositories.TeamsRepository;
...@@ -25,14 +26,16 @@ public class SolutionsResource ...@@ -25,14 +26,16 @@ public class SolutionsResource
private TeamsRepository teamsRepository; private TeamsRepository teamsRepository;
private SolutionsRepository solutionsRepository; private SolutionsRepository solutionsRepository;
private TasksRepository tasksRepository; private TasksRepository tasksRepository;
private HashValidator hashValidator;
@Inject @Inject
public SolutionsResource(SolutionsRepository solutionsRepository, TasksRepository tasksRepository, public SolutionsResource(SolutionsRepository solutionsRepository, TasksRepository tasksRepository,
TeamsRepository teamsRepository) TeamsRepository teamsRepository, HashValidator hashValidator)
{ {
this.solutionsRepository = solutionsRepository; this.solutionsRepository = solutionsRepository;
this.tasksRepository = tasksRepository; this.tasksRepository = tasksRepository;
this.teamsRepository = teamsRepository; this.teamsRepository = teamsRepository;
this.hashValidator = hashValidator;
} }
@POST @POST
...@@ -41,7 +44,7 @@ public class SolutionsResource ...@@ -41,7 +44,7 @@ public class SolutionsResource
@PathParam("task_level") int taskLevel, @PathParam("task_level") int taskLevel,
String hash) throws Exception String hash) throws Exception
{ {
if (tasksRepository.checkHash(user, hash, taskLevel)) { if (hashValidator.checkHash(user, hash, taskLevel)) {
return Response.ok().build(); return Response.ok().build();
} }
return Response.status(Response.Status.NOT_ACCEPTABLE).build(); return Response.status(Response.Status.NOT_ACCEPTABLE).build();
...@@ -51,7 +54,7 @@ public class SolutionsResource ...@@ -51,7 +54,7 @@ public class SolutionsResource
@Path("/completed") @Path("/completed")
public List<Integer> getTeamCompletedTasks(@Auth User user) public List<Integer> getTeamCompletedTasks(@Auth User user)
{ {
return tasksRepository.getCompletedTasks(teamsRepository.getTeamByUser(user)); return solutionsRepository.getCompletedTasks(teamsRepository.getTeamByUser(user));
} }
@GET @GET
...@@ -62,7 +65,7 @@ public class SolutionsResource ...@@ -62,7 +65,7 @@ public class SolutionsResource
.stream() .stream()
.collect(Collectors.toMap( .collect(Collectors.toMap(
Team::getName, 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