Commit 648f7301 authored by Grzegorz Pietrusza's avatar Grzegorz Pietrusza

Merge remote-tracking branch 'remotes/origin/flags-ui'

parents 02febf41 9d157e38
...@@ -26,7 +26,7 @@ module.exports = function (grunt) { ...@@ -26,7 +26,7 @@ module.exports = function (grunt) {
htmlmin: { htmlmin: {
target: { target: {
options: { options: {
removeComments: true, removeComments: false,
collapseWhitespace: true collapseWhitespace: true
}, },
files: { files: {
......
...@@ -16,6 +16,10 @@ admins: ...@@ -16,6 +16,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"
......
...@@ -56,15 +56,15 @@ public class SolutionsResource ...@@ -56,15 +56,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()
......
body { body {
background: url('/statics/img/bkg.jpg'); background: url('/statics/img/bkg.jpg');
color: white; color: white;
background-position: bottom right;
height: 100vh;
}
#background {
position: absolute;
/*top: 69%;*/
bottom: 0;
/*left: 81%;*/
right: 252px;
height: 286px;
width: 134px;
z-index:10;
background-repeat: no-repeat;
} }
nav { nav {
...@@ -10,6 +24,15 @@ nav { ...@@ -10,6 +24,15 @@ nav {
box-shadow: none; box-shadow: none;
} }
@media only screen and (max-width: 992px) {
.title .username {
display: none;
}
.title {
font-size: 80%;
}
}
p { p {
color:white; color:white;
} }
...@@ -89,4 +112,70 @@ p { ...@@ -89,4 +112,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('LoginController', angular.module('ctfApp').controller('LoginController',
['$scope', '$rootScope', '$location', 'AuthenticationService', '$window', ['$scope', '$rootScope', '$location', 'AuthenticationService', '$window', 'NavbarService',
function ($scope, $rootScope, $location, AuthenticationService, $window) { function ($scope, $rootScope, $location, AuthenticationService, $window, NavbarService) {
// reset login status // reset login status
AuthenticationService.clearCredentials(); AuthenticationService.clearCredentials();
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
$scope.dataLoading = true; $scope.dataLoading = true;
AuthenticationService.login($scope.username, $scope.password, function(response) { AuthenticationService.login($scope.username, $scope.password, function(response) {
if(response.status == 200) { if(response.status == 200) {
$('.title').html($scope.username+'@<b>capture-the-flAGH-2016</b>:~$'); NavbarService.setUsername($scope.username);
$location.path('/'); $location.path('/');
AuthenticationService.setCredentials($scope.username, $scope.password, response.team); AuthenticationService.setCredentials($scope.username, $scope.password, response.team);
// redirect to additional external auth point // redirect to additional external auth point
......
(function(){ (function(){
angular.module('ctfApp').controller('NavigationController', ['$scope', '$rootScope', '$location', 'AuthenticationService', angular.module('ctfApp').controller('NavigationController', ['$scope', '$rootScope', '$location', 'AuthenticationService', 'NavbarService',
function($scope, $rootScope, $location, AuthenticationService){ function($scope, $rootScope, $location, AuthenticationService, NavbarService){
$scope.logged = $rootScope.globals ? !!$rootScope.globals.currentUser : false; $scope.logged = $rootScope.globals ? !!$rootScope.globals.currentUser : false;
$scope.user = $rootScope.globals && $rootScope.globals.currentUser ? $rootScope.globals.currentUser.username : undefined; $scope.user = $rootScope.globals && $rootScope.globals.currentUser ? $rootScope.globals.currentUser.username : undefined;
$scope.logout = function(){ $scope.logout = function(){
$('.title').html('guest@<b>capture-the-flAGH-2016</b>:~$'); NavbarService.setGuest();
AuthenticationService.logout(function(data){ AuthenticationService.logout(function(data){
$location.path('/'); $location.path('/login');
}); }.bind(this));
}; };
$scope.$watch(function(){ $scope.$watch(function(){
......
(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;
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
function viewGraph(){ function viewGraph(){
$('.column').css('height','0'); $('.column').css('height','0');
console.log($scope.teamsScores); // console.log($scope.teamsScores);
setTimeout(function(){ setTimeout(function(){
$('.column').each(function(){ $('.column').each(function(){
$(this).animate({width: 150*$(this).attr('data-score')}, 1500); $(this).animate({width: 150*$(this).attr('data-score')}, 1500);
...@@ -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();
});
......
...@@ -3,19 +3,19 @@ ...@@ -3,19 +3,19 @@
$scope.submitUnknown = false; $scope.submitUnknown = false;
$scope.apiAddress = 'http://' + AppSettings.apiAddress; $scope.apiAddress = 'http://' + AppSettings.apiAddress;
$scope.selectedTaskId = $stateParams.taskLevel; $scope.selectedTaskId = $stateParams.taskLevel;
console.log('SELECTED TASK ID', $scope.selectedTaskId); // console.log('SELECTED TASK ID', $scope.selectedTaskId);
APIProvider.getTaskById($scope.selectedTaskId, function(data){ APIProvider.getTaskById($scope.selectedTaskId, function(data){
console.log(data); // console.log(data);
$scope.task = data; $scope.task = data;
}); });
$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(){
console.log("Flaga zla!"); // console.log("Flaga zla!");
Materialize.toast('Błędna flaga! :(', 5000 ,'toast-error'); Materialize.toast('Błędna flaga! :(', 5000 ,'toast-error');
$scope.submitUnknown = false; $scope.submitUnknown = false;
}); });
......
...@@ -2,7 +2,17 @@ ...@@ -2,7 +2,17 @@
angular.module('ctfApp').controller('TasksController', ['$scope', '$http', 'APIProvider', 'AppSettings', function($scope, $http, APIProvider, AppSettings) { angular.module('ctfApp').controller('TasksController', ['$scope', '$http', 'APIProvider', 'AppSettings', function($scope, $http, APIProvider, AppSettings) {
$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;
}); });
}]); }]);
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -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);
} }
}; };
}]); }]);
......
(function () {
angular.module('ctfApp').factory('NavbarService', [
function () {
var selector = '.title';
var firstDomain = 'capture-the-flag';
var secondDomain = 'capture-the-flAGH-2016';
return {
createNavbarString: function(username, domain){
return '<span class="username">'+username+'@</span><b>'+ (domain ? domain : secondDomain) +'</b>' + (domain ? ':~$' : '');
},
setUsername: function(username){
$(selector).html(this.createNavbarString(username));
},
setGuest: function(){
return this.setUsername('guest');
},
getTypedStrings: function(username){
return [this.createNavbarString(username, firstDomain), this.createNavbarString(username, secondDomain)];
},
getGuestTypedStrings: function(){
return this.getTypedStrings('guest');
}
};
}]);
})();
\ No newline at end of file
...@@ -86,7 +86,7 @@ ...@@ -86,7 +86,7 @@
this.stop = false; this.stop = false;
// custom cursor // custom cursor
this.cursorChar = '<a href="http://bit.do/aCoToChybaNieKolejnaFlaga">' + this.options.cursorChar + '</a>'; this.cursorChar = '<a href="http://bit.ly/1TnySYC">' + this.options.cursorChar + '</a>';
// shuffle the strings // shuffle the strings
this.shuffle = this.options.shuffle; this.shuffle = this.options.shuffle;
......
...@@ -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>
...@@ -55,11 +62,11 @@ ...@@ -55,11 +62,11 @@
</div> </div>
<div class="circle-clipper right"> <div class="circle-clipper right">
<div class="circle"></div> <div class="circle"></div>
</div> </div>c
</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>
...@@ -67,7 +74,7 @@ ...@@ -67,7 +74,7 @@
</div> </div>
</div> </div>
<div class="col s12 m4" style="text-align:center"> <div class="col s12 m4" style="text-align:center">
<img src="http://lorempixel.com/400/300/"/> <img class="responsive-img" src="http://lorempixel.com/400/300/"/>
<a class="waves-effect waves-light btn" target="_blank" href="{{apiAddress}}/task/{{task.level}}" <a class="waves-effect waves-light btn" target="_blank" href="{{apiAddress}}/task/{{task.level}}"
style="width:100%;margin-top:15px">Otwórz stronę z zadaniem</a> style="width:100%;margin-top:15px">Otwórz stronę z zadaniem</a>
</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 m6 s12" 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