Commit 9fc81b4a authored by Antek Grzanka's avatar Antek Grzanka

Small reorganization of API. Displaying added flags and completed tasks.

parent d74fbd2d
......@@ -17,6 +17,10 @@ admins:
password: "41b450e73c974fca46911eba84e114f2" #gpietrus md5
email: "gpietrusza@gmail.com"
admin: true
- name: "anteq_admin"
password: "1a7fcdd5a9fd433523268883cfded9d0" #gpietrus md5
email: "antonigrzanka@gmail.com"
admin: true
teams:
- name: "misiaczki"
......
......@@ -55,15 +55,15 @@ public class SolutionsResource
}
@GET
@Path("/completed")
@Path("/my/completed")
public List<Integer> getTeamCompletedTasks(@Auth User user)
{
return solutionsRepository.getCompletedTasks(teamsRepository.getTeamByUser(user));
}
@GET
@Path("/completed/all")
public Map<String, List<Integer>> getAllTeamsCompletetdTasks(@Auth User user)
@Path("/all/completed")
public Map<String, List<Integer>> getAllTeamsCompletedTasks(@Auth User user)
{
return teamsRepository.getAll()
.stream()
......
......@@ -89,4 +89,70 @@ p {
background-color: red;
color: black;
font-weight: bold;
}
.task-completed {
opacity: 0.9;
}
.level-number {
color:lightgreen;
font-weight:bold;
}
.level-number::after {
content: " - ";
}
.task-finished-banner {
color: lightgreen;
font-weight: bold;
}
.task-finished-banner::before {
content: " - ";
}
.ribbon {
position: absolute;
right: -5px; top: -5px;
z-index: 1;
overflow: hidden;
width: 75px; height: 75px;
text-align: right;
}
.ribbon span {
font-size: 10px;
font-weight: bold;
color: #FFF;
text-transform: uppercase;
text-align: center;
line-height: 20px;
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
width: 100px;
display: block;
background: #79A70A;
background: linear-gradient(#F70505 0%, #8F0808 100%);
box-shadow: 0 3px 10px -5px rgba(0, 0, 0, 1);
position: absolute;
top: 19px; right: -21px;
}
.ribbon span::before {
content: "";
position: absolute; left: 0px; top: 100%;
z-index: -1;
border-left: 3px solid #8F0808;
border-right: 3px solid transparent;
border-bottom: 3px solid transparent;
border-top: 3px solid #8F0808;
}
.ribbon span::after {
content: "";
position: absolute; right: 0px; top: 100%;
z-index: -1;
border-left: 3px solid transparent;
border-right: 3px solid #8F0808;
border-bottom: 3px solid transparent;
border-top: 3px solid #8F0808;
}
\ No newline at end of file
(function(){
angular.module('ctfApp').controller('ScoreboardController', ['$scope', '$http', 'AppSettings', function($scope, $http, AppSettings) {
var mock = { "nazwa zadania": ["lista","druzyn","ktora","rozwiazala"], "drugie zadanie": ["inna","druzyn","ktora","go"] };
angular.module('ctfApp').controller('ScoreboardController', ['$scope', '$http', 'AppSettings', 'APIProvider', function($scope, $http, AppSettings, APIProvider) {
var calculatePerTeam = function(data) {
var teams = {};
for (var key in data) {
if (data.hasOwnProperty(key)) {
var task = data[key];
for (var team in data) {
if (data.hasOwnProperty(team)) {
var task = data[team];
for(var i = 0; i < task.length; i++){
if (!teams[task[i]]){
teams[task[i]] = 1;
......@@ -31,16 +31,14 @@
}
$http.get('http://' + AppSettings.apiAddress + '/solutions/all').
success(function(data) {
console.log(data);
if ($.isEmptyObject(data)){
data = mock; // Delete!
}
$scope.teamsScores = calculatePerTeam(data);
console.log($scope.teamsScores);
viewGraph();
});
APIProvider.getScores(function(data){
console.log('Data from server', data);
$scope.teamsScores = calculatePerTeam(data);
console.log('Teams scores', $scope.teamsScores);
viewGraph();
});
......
......@@ -11,7 +11,7 @@
$scope.submitFlag = function(){
var flag = $('input#flag-to-submit').val();
$scope.submitUnknown = true;
APIProvider.submitFlag(flag).success(function(){
APIProvider.submitFlag($stateParams.taskLevel, flag).success(function(){
Materialize.toast('Poprawna flaga! :)', 5000, 'toast-success');
$scope.submitUnknown = false;
}).error(function(){
......
......@@ -3,6 +3,16 @@
$scope.apiAddress = AppSettings.apiAddress;
APIProvider.getTasks(function(data){
console.log(data);
APIProvider.getMyCompletedLevelsList(function(completed){
$.each(data, function(key, task){
if (completed.indexOf(task.level) !== -1){
data[key].completed = true;
}
else {
data[key].completed = false;
}
});
});
$scope.tasks = data;
});
}]);
......
......@@ -2,14 +2,38 @@
angular.module('ctfApp').factory('APIProvider', ['$http', 'AppSettings', function($http, AppSettings){
var tasks, teams, scores;
return {
getScores: function(){},
getScores: function(callback){
$http.get('http://' + AppSettings.apiAddress + '/solutions/all').
success(function(data) {
scores = data;
if (callback) callback(data);
});
},
getTasks: function(callback){
$http.get('http://' + AppSettings.apiAddress + '/tasks').
success(function(data) {
tasks = data;
this.getMySolutions(function(solutions){
data.filter(function(task){
return Object.keys(solutions).map(function(a){return parseInt(a);}).indexOf(task.level) !== -1;
}).map(function(task){
task.completedFlags = solutions[task.level];
return task;
});
tasks = data;
if (callback) callback(data);
});
}.bind(this));
},
getMySolutions: function(callback){
$http.get('http://' + AppSettings.apiAddress + '/solutions/my').
success(function(data) {
if (callback) callback(data);
});
},
getTaskById: function(id, callback){
var result;
if (!tasks) {
......@@ -24,8 +48,31 @@
}
callback(result);
},
submitFlag: function(flag){
return $http.post('http://' + AppSettings.apiAddress + '/solutions', flag);
getMySubmittedFlagsForTask: function(id){
},
/**
* Returns an array of completed levels' ids.
* @param callback
*/
getMyCompletedLevelsList: function(callback){
$http.get('http://' + AppSettings.apiAddress + '/solutions/my/completed').
success(function(data) {
if (callback) callback(data);
});
},
/**
*
* @param level
* @param flag
* @returns {HttpPromise}
*/
submitFlag: function(level, flag){
return $http.post('http://' + AppSettings.apiAddress + '/solutions/' + level, flag);
}
};
}]);
......
......@@ -3,7 +3,7 @@
<div class="row">
<div class="col s12">
<a href="#/tasks" class="breadcrumb"><i class="fa fa-angle-left" style="margin-right:20px"></i> Powrót</a>
<h1 class="left-align">{{task.name}}</h1>
<h1 class="left-align">{{task.name}} <span ng-if="task.completed" class="task-finished-banner">ukończono!</span></h1>
</div>
</div>
<div class="row">
......@@ -36,11 +36,18 @@
<div class="col s11">Flagi</div>
</div>
</span>
<p>
<p ng-if="!task.completedFlags || task.completedFlags.length === 0">
Nie dodano żadnych flag.
</p>
<button ng-click="submitFlag()" class="btn waves-effect waves-light" type="submit" name="action"
<p ng-if="task.completedFlags && task.completedFlags.length !== 0">
<div ng-repeat="flag in task.completedFlags">
{{ flag }}
</div>
</p>
<button ng-if="!task.completed" ng-click="submitFlag()" class="btn waves-effect waves-light" type="submit" name="action"
style="float:right" ng-if="!submitUnknown">Submit
<i class="material-icons right">send</i>
</button>
......@@ -59,7 +66,7 @@
</div>
</div>
<div class="input-field" style="overflow:hidden">
<div class="input-field" style="overflow:hidden" ng-if="!task.completed">
<input placeholder="Wpisz flagę" id="flag-to-submit" type="text" class="validate">
</div>
......
<div ng-controller="TasksController">
<div class="row">
<div class="col s12 m6" ng-repeat="task in tasks">
<div class="card blue-grey darken-1">
<div class="card blue-grey darken-1" ng-class="task.completed ? 'task-completed' : 'task-not-completed'">
<div class="card-content white-text">
<div class="ribbon" ng-if="task.completed"><span>UKOŃCZONE</span></div>
<span class="card-title">
<span class="level-number">{{task.level}}</span>
<i ng-if="task.taskType === 'CRYPTO'" class="fa fa-key" alt="Zadanie kryptograficzne"></i>
<i ng-if="task.taskType === 'WEB'" class="fa fa-globe" alt="Zadanie webowe"></i>
{{task.name}}
......
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