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: ...@@ -17,6 +17,10 @@ admins:
password: "41b450e73c974fca46911eba84e114f2" #gpietrus md5 password: "41b450e73c974fca46911eba84e114f2" #gpietrus md5
email: "gpietrusza@gmail.com" email: "gpietrusza@gmail.com"
admin: true admin: true
- name: "anteq_admin"
password: "1a7fcdd5a9fd433523268883cfded9d0" #gpietrus md5
email: "antonigrzanka@gmail.com"
admin: true
teams: teams:
- name: "misiaczki" - name: "misiaczki"
......
...@@ -55,15 +55,15 @@ public class SolutionsResource ...@@ -55,15 +55,15 @@ public class SolutionsResource
} }
@GET @GET
@Path("/completed") @Path("/my/completed")
public List<Integer> getTeamCompletedTasks(@Auth User user) public List<Integer> getTeamCompletedTasks(@Auth User user)
{ {
return solutionsRepository.getCompletedTasks(teamsRepository.getTeamByUser(user)); return solutionsRepository.getCompletedTasks(teamsRepository.getTeamByUser(user));
} }
@GET @GET
@Path("/completed/all") @Path("/all/completed")
public Map<String, List<Integer>> getAllTeamsCompletetdTasks(@Auth User user) public Map<String, List<Integer>> getAllTeamsCompletedTasks(@Auth User user)
{ {
return teamsRepository.getAll() return teamsRepository.getAll()
.stream() .stream()
......
...@@ -89,4 +89,70 @@ p { ...@@ -89,4 +89,70 @@ p {
background-color: red; background-color: red;
color: black; color: black;
font-weight: bold; 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(){ (function(){
angular.module('ctfApp').controller('ScoreboardController', ['$scope', '$http', 'AppSettings', function($scope, $http, AppSettings) { angular.module('ctfApp').controller('ScoreboardController', ['$scope', '$http', 'AppSettings', 'APIProvider', function($scope, $http, AppSettings, APIProvider) {
var mock = { "nazwa zadania": ["lista","druzyn","ktora","rozwiazala"], "drugie zadanie": ["inna","druzyn","ktora","go"] };
var calculatePerTeam = function(data) { var calculatePerTeam = function(data) {
var teams = {}; var teams = {};
for (var key in data) { for (var team in data) {
if (data.hasOwnProperty(key)) { if (data.hasOwnProperty(team)) {
var task = data[key]; var task = data[team];
for(var i = 0; i < task.length; i++){ for(var i = 0; i < task.length; i++){
if (!teams[task[i]]){ if (!teams[task[i]]){
teams[task[i]] = 1; teams[task[i]] = 1;
...@@ -31,16 +31,14 @@ ...@@ -31,16 +31,14 @@
} }
$http.get('http://' + AppSettings.apiAddress + '/solutions/all'). APIProvider.getScores(function(data){
success(function(data) { console.log('Data from server', data);
console.log(data); $scope.teamsScores = calculatePerTeam(data);
if ($.isEmptyObject(data)){ console.log('Teams scores', $scope.teamsScores);
data = mock; // Delete! viewGraph();
} });
$scope.teamsScores = calculatePerTeam(data);
console.log($scope.teamsScores);
viewGraph();
});
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
$scope.submitFlag = function(){ $scope.submitFlag = function(){
var flag = $('input#flag-to-submit').val(); var flag = $('input#flag-to-submit').val();
$scope.submitUnknown = true; $scope.submitUnknown = true;
APIProvider.submitFlag(flag).success(function(){ APIProvider.submitFlag($stateParams.taskLevel, flag).success(function(){
Materialize.toast('Poprawna flaga! :)', 5000, 'toast-success'); Materialize.toast('Poprawna flaga! :)', 5000, 'toast-success');
$scope.submitUnknown = false; $scope.submitUnknown = false;
}).error(function(){ }).error(function(){
......
...@@ -3,6 +3,16 @@ ...@@ -3,6 +3,16 @@
$scope.apiAddress = AppSettings.apiAddress; $scope.apiAddress = AppSettings.apiAddress;
APIProvider.getTasks(function(data){ APIProvider.getTasks(function(data){
console.log(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; $scope.tasks = data;
}); });
}]); }]);
......
...@@ -2,14 +2,38 @@ ...@@ -2,14 +2,38 @@
angular.module('ctfApp').factory('APIProvider', ['$http', 'AppSettings', function($http, AppSettings){ angular.module('ctfApp').factory('APIProvider', ['$http', 'AppSettings', function($http, AppSettings){
var tasks, teams, scores; var tasks, teams, scores;
return { 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){ getTasks: function(callback){
$http.get('http://' + AppSettings.apiAddress + '/tasks'). $http.get('http://' + AppSettings.apiAddress + '/tasks').
success(function(data) { 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); if (callback) callback(data);
}); });
}, },
getTaskById: function(id, callback){ getTaskById: function(id, callback){
var result; var result;
if (!tasks) { if (!tasks) {
...@@ -24,8 +48,31 @@ ...@@ -24,8 +48,31 @@
} }
callback(result); 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 @@ ...@@ -3,7 +3,7 @@
<div class="row"> <div class="row">
<div class="col s12"> <div class="col s12">
<a href="#/tasks" class="breadcrumb"><i class="fa fa-angle-left" style="margin-right:20px"></i> Powrót</a> <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> </div>
<div class="row"> <div class="row">
...@@ -36,11 +36,18 @@ ...@@ -36,11 +36,18 @@
<div class="col s11">Flagi</div> <div class="col s11">Flagi</div>
</div> </div>
</span> </span>
<p>
<p ng-if="!task.completedFlags || task.completedFlags.length === 0">
Nie dodano żadnych flag. Nie dodano żadnych flag.
</p> </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 style="float:right" ng-if="!submitUnknown">Submit
<i class="material-icons right">send</i> <i class="material-icons right">send</i>
</button> </button>
...@@ -59,7 +66,7 @@ ...@@ -59,7 +66,7 @@
</div> </div>
</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"> <input placeholder="Wpisz flagę" id="flag-to-submit" type="text" class="validate">
</div> </div>
......
<div ng-controller="TasksController"> <div ng-controller="TasksController">
<div class="row"> <div class="row">
<div class="col s12 m6" ng-repeat="task in tasks"> <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="card-content white-text">
<div class="ribbon" ng-if="task.completed"><span>UKOŃCZONE</span></div>
<span class="card-title"> <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 === 'CRYPTO'" class="fa fa-key" alt="Zadanie kryptograficzne"></i>
<i ng-if="task.taskType === 'WEB'" class="fa fa-globe" alt="Zadanie webowe"></i> <i ng-if="task.taskType === 'WEB'" class="fa fa-globe" alt="Zadanie webowe"></i>
{{task.name}} {{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