admin: Able to import Cyberrange teams from interface

This commit is contained in:
nemunaire 2025-03-26 14:44:02 +01:00
parent f1ada8ce99
commit 485e6b0173
4 changed files with 64 additions and 8 deletions

View file

@ -1,6 +1,7 @@
package api
import (
"encoding/json"
"fmt"
"log"
"net/http"
@ -320,8 +321,21 @@ func allAssociations(c *gin.Context) {
}
func importTeamsFromCyberrange(c *gin.Context) {
file, err := c.FormFile("file")
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"errmsg": "Failed to get file: " + err.Error()})
return
}
src, err := file.Open()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"errmsg": "Failed to open file: " + err.Error()})
return
}
defer src.Close()
var ut []fic.CyberrangeTeam
err := c.ShouldBindJSON(&fic.CyberrangeAPIResponse{Data: &ut})
err = json.NewDecoder(src).Decode(&fic.CyberrangeAPIResponse{Data: &ut})
if err != nil {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": err.Error()})
return

View file

@ -2504,6 +2504,24 @@ angular.module("FICApp")
$scope.show = function (id) {
$location.url("/teams/" + id);
};
$scope.triggerTeamsImport = function() {
document.getElementById('crTeamsInput').click();
};
$scope.uploadFile = function() {
var formData = new FormData();
formData.append('file', $scope.selectedFile);
$http.post('api/cyberrange-teams.json', formData, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined},
}).then(function(response) {
$scope.teams = response.data;
$scope.addToast('success', 'Import des équipes', "L'import a été réalisé avec succès !");
}, function(error) {
console.log(error);
$scope.addToast('danger', 'Import des équipes', error.data.errmsg);
});
};
})
.controller("TeamMembersController", function ($scope, TeamMember) {
$scope.fields = ["firstname", "lastname", "nickname", "company"];

View file

@ -81,6 +81,22 @@ angular.module("FICApp")
});
}
}
}])
.directive('fileModel', ['$parse', function ($parse) {
return {
restrict: 'A',
link: function($scope, element, attrs) {
var model = $parse(attrs.fileModel);
var modelSetter = model.assign;
element.bind('change', function(){
$scope.$apply(function(){
modelSetter($scope, element[0].files[0]);
$scope.uploadFile();
});
});
}
};
}]);
angular.module("FICApp")

View file

@ -1,10 +1,18 @@
<h2>
&Eacute;quipes
<button type="button" ng-click="show('new')" class="float-right btn btn-sm btn-primary"><span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Ajouter une équipe</button>
<button type="button" ng-click="show('print')" class="float-right btn btn-sm btn-secondary mr-2" title="Imprimer les équipes et leurs membres"><span class="glyphicon glyphicon-print" aria-hidden="true"></span></button>
<button type="button" ng-click="show('export')" class="float-right btn btn-sm btn-secondary mr-2"><span class="glyphicon glyphicon-export" aria-hidden="true"></span> Statistiques générales</button>
<button type="button" ng-click="desactiveTeams()" class="float-right btn btn-sm btn-danger mr-2" title="Cliquer pour marquer les équipes sans certificat comme inactives (et ainsi éviter que ses fichiers ne soient générés)"><span class="glyphicon glyphicon-leaf" aria-hidden="true"></span> Désactiver les équipes inactives</button>
</h2>
<div class="d-flex justify-content-between align-items-center">
<h2>
&Eacute;quipes
</h2>
<div>
<button type="button" ng-click="show('new')" class="btn btn-sm btn-primary ml-1"><span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Ajouter une équipe</button>
<form class="d-inline">
<input id="crTeamsInput" type="file" file-model="selectedFile" class="d-none" />
<button type="button" ng-click="triggerTeamsImport()" class="btn btn-sm btn-secondary ml-1"><span class="glyphicon glyphicon-import" aria-hidden="true"></span> Import Cyberrange</button>
</form>
<button type="button" ng-click="show('print')" class="btn btn-sm btn-secondary ml-1" title="Imprimer les équipes et leurs membres"><span class="glyphicon glyphicon-print" aria-hidden="true"></span></button>
<button type="button" ng-click="show('export')" class="btn btn-sm btn-secondary ml-1"><span class="glyphicon glyphicon-export" aria-hidden="true"></span> Statistiques générales</button>
<button type="button" ng-click="desactiveTeams()" class="btn btn-sm btn-danger ml-1" title="Cliquer pour marquer les équipes sans certificat comme inactives (et ainsi éviter que ses fichiers ne soient générés)"><span class="glyphicon glyphicon-leaf" aria-hidden="true"></span> Désactiver les équipes inactives</button>
</div>
</div>
<p><input type="search" class="form-control" placeholder="Search" ng-model="query" ng-keypress="validateSearch($event)" autofocus></p>
<table class="table table-hover table-bordered table-striped table-sm">