Work on Maatma interface

This commit is contained in:
nemunaire 2019-03-13 22:06:35 +01:00 committed by Pierre-Olivier Mercier
parent 9cb1ad6e97
commit e965705bfe
6 changed files with 403 additions and 15 deletions

View File

@ -0,0 +1,159 @@
angular.module("AdLinApp", ["ngRoute", "ngResource", "ngSanitize"])
.config(function($routeProvider, $locationProvider) {
$routeProvider
.when("/auth", {
controller: "AuthController",
templateUrl: "views/auth.html"
})
.when("/domains", {
controller: "DomainsController",
templateUrl: "views/domains.html"
})
.when("/tunnels", {
controller: "TunnelsController",
templateUrl: "views/tunnels.html"
})
.when("/", {
templateUrl: "views/home.html"
});
$locationProvider.html5Mode(true);
});
angular.module("AdLinApp")
.factory("Student", function($resource) {
return $resource("/api/students/:studentId", { studentId: '@id' }, {
'update': {method: 'PUT'},
})
})
.factory("Progression", function($resource) {
return $resource("/api/progress")
})
.factory("Challenge", function($resource) {
return $resource("/challenge/:challengeId", { challengeId: '@id' })
});
angular.module("AdLinApp")
.run(function($rootScope, $interval, $http) {
$rootScope.checkLoginState = function() {
if (sessionStorage.token === undefined) {
$rootScope.isLogged = false;
return;
}
var token = sessionStorage.token;
$http({
method: 'GET',
url: "/api/auth",
headers: {
'Authorization': "Bearer " + token
}
}).then(function(response) {
$rootScope.isLogged = response.data;
}, function(response) {
$rootScope.isLogged = false;
});
};
$rootScope.checkLoginState();
$interval($rootScope.checkLoginState, 20000);
$rootScope.disconnectCurrentUser = function() {
sessionStorage.token = undefined;
delete sessionStorage.token;
$rootScope.isLogged = false;
}
})
.controller("AuthController", function($scope, $rootScope, $http, $location) {
$scope.auth = {
"username": "",
"password": "",
};
$scope.logmein = function() {
$scope.pleaseWait = true;
$http({
method: 'POST',
url: "/api/auth",
data: $scope.auth
}).then(function(response) {
sessionStorage.token = response.data.id_session
$scope.pleaseWait = false;
$rootScope.checkLoginState();
$location.url("/");
}, function(response) {
alert(response.data.errmsg);
$scope.pleaseWait = false;
});
}
})
.controller("TunnelsController", function($scope, $http, $interval) {
$scope.updateTunnelInfo = function() {
$http({
method: 'GET',
url: "/api/wginfo",
headers: {
'Authorization': "Bearer " + sessionStorage.token
}
}).then(function(response) {
$scope.wginfo = response.data;
});
};
$scope.updateTunnelInfo();
$scope.updateTunnelsList = function() {
$http({
method: 'GET',
url: "/api/wg/",
headers: {
'Authorization': "Bearer " + sessionStorage.token
}
}).then(function(response) {
$scope.tunnels = response.data;
}, function(response) {
alert(response.data.errmsg);
});
};
$scope.updateTunnelsList();
$interval($scope.updateTunnelsList, 12000);
$scope.newTunnel = function() {
$scope.pleaseWaitNew = true;
$http({
method: 'POST',
url: "/api/wg/",
headers: {
'Authorization': "Bearer " + sessionStorage.token
},
data: {}
}).then(function(response) {
$scope.updateTunnelsList();
$scope.pleaseWaitNew = false;
}, function(response) {
alert(response.data.errmsg);
$scope.pleaseWaitNew = false;
});
}
$scope.dropTunnel = function(tunnel) {
tunnel.pleaseWaitDrop = true;
$http({
method: 'DELETE',
url: "/api/wg/" + tunnel.TokenText,
headers: {
'Authorization': "Bearer " + sessionStorage.token
},
data: {}
}).then(function(response) {
$scope.updateTunnelsList();
tunnel.pleaseWaitDrop = false;
}, function(response) {
alert(response.data.errmsg);
tunnel.pleaseWaitDrop = false;
});
}
})
.controller("DomainsController", function($scope, $http, $interval) {
})

View File

@ -0,0 +1,45 @@
<!DOCTYPE html>
<html ng-app="AdLinApp">
<head>
<meta charset="utf-8">
<title>Maatma: Domains Names, Web Hosting. SSL Certificates, the DIY way</title>
<link href="css/bootstrap.min.css" type="text/css" rel="stylesheet">
<base href="/maatma/">
</head>
<body>
<nav class="navbar sticky-top navbar-expand-lg navbar-dark bg-dark">
<a class="navbar-brand" href=".">
Maatma
</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#adminMenu" aria-controls="adminMenu" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="loggedMenu" ng-if="isLogged">
<ul class="navbar-nav mr-auto">
<li class="nav-item"><a class="nav-link" href="tunnels">Tunnels</a></li>
<li class="nav-item"><a class="nav-link" href="domains">Noms de domaine</a></li>
</ul>
<button class="navbar-text btn btn-link" ng-click="disconnectCurrentUser()">
Se déconnecter
</button>
</div>
<div class="collapse navbar-collapse" id="loggedMenu" ng-if="!isLogged">
<ul class="navbar-nav mr-auto">
<li class="nav-item"><a class="nav-link" href="auth">Se connecter</a></li>
</ul>
</div>
</nav>
<div class="container mt-1" ng-view></div>
<script src="js/angular.min.js"></script>
<script src="js/i18n/angular-locale_fr-fr.js"></script>
<script src="js/angular-resource.min.js"></script>
<script src="js/angular-route.min.js"></script>
<script src="js/angular-sanitize.min.js"></script>
<script src="js/adlin-main.js"></script>
</body>
</html>

View File

@ -0,0 +1,16 @@
<h2>Accès à votre compte</h2>
<form ng-submit="logmein()">
<div class="form-group">
<label for="login">CRI login</label>
<input class="form-control" id="login" ng-model="auth.username" placeholder="Entrer votre login" autofocus>
</div>
<div class="form-group">
<label for="password">Mot de passe</label>
<input type="password" class="form-control" id="password" ng-model="auth.password" placeholder="Mot de passe">
</div>
<button type="submit" class="btn btn-primary">
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true" ng-show="pleaseWait"></span>
Me connecter
</button>
</form>

View File

@ -0,0 +1,43 @@
<div class="jumbotron">
<h1>
Bienvenue {{ isLogged.login }} chez Maatma&nbsp;!
</h1>
<p class="lead text-muted">L'hébergement vraiment pas cher (mais DIY)&nbsp;!</p>
<hr class="my-4">
<h2 ng-if="!isLogged">
Connectez-vous&nbsp;!
</h2>
<h2 ng-if="isLogged">
Qu'allons-nous faire aujourd'hui&nbsp;?
</h2>
</div>
<div class="card-deck">
<div class="card">
<img src="..." class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<p class="card-text">This is a longer card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.</p>
<p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
</div>
</div>
<div class="card">
<img src="..." class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<p class="card-text">This card has supporting text below as a natural lead-in to additional content.</p>
<p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
</div>
</div>
<div class="card">
<img src="..." class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<p class="card-text">This is a wider card with supporting text below as a natural lead-in to additional content. This card has even longer content than the first to show that equal height action.</p>
<p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
</div>
</div>
</div>

View File

@ -0,0 +1,48 @@
<h2>
Tunnels
</h2>
<table class="table table-striped table-hover">
<thead>
<tr>
<th>Token</th>
<th>Dernière utilisation</th>
<th>Clef publique</th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="tunnel in tunnels">
<td><code>{{ tunnel.TokenText }}</code></td>
<td>{{ tunnel.Time | date:"medium" }}</td>
<td><code ng-show="tunnel.PubKey">{{ tunnel.PubKey }}</code><span ng-show="!tunnel.PubKey">(none)</span></td>
<td>
<button class="btn btn-danger" ng-click="dropTunnel(tunnel)" disabled>
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true" ng-show="tunnel.pleaseWaitDrop"></span>
Supprimer
</button>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="4">
<button class="btn btn-primary" ng-click="newTunnel()">
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true" ng-show="pleaseWaitNew"></span>
Nouveau tunnel
</button>
</td>
</tr>
</tfoot>
</table>
<div class="card mb-4" style="margin: auto; width: 50%;">
<h4 class="card-header">Paramètres du tunnel</h4>
<ul class="list-group list-group-flush">
<li class="list-group-item"><strong>Statut&nbsp;:</strong> {{ wginfo.status }}</li>
<li class="list-group-item"><strong>Clef publique du serveur&nbsp;:</strong> <code>{{ wginfo.srv_pubkey }}</code></li>
<li class="list-group-item"><strong>Port d'écoute du serveur&nbsp;:</strong> {{ wginfo.srv_port }}</li>
<li class="list-group-item"><strong>Adresse IPv6 du tunnel&nbsp;:</strong> {{ wginfo.clt_ipv6 }}/{{ wginfo.clt_range }}</li>
<li class="list-group-item"><strong>Gateway/passerelle IPv6&nbsp;:</strong> {{ wginfo.srv_gw6 }}</li>
</ul>
</div>

View File

@ -4,6 +4,7 @@ import (
"fmt"
"net/http"
"path"
"strings"
"github.com/julienschmidt/httprouter"
)
@ -12,21 +13,6 @@ import (
//go:generate go fmt bindata.go
func init() {
Router().GET("/", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
if data, err := Asset("htdocs/index.html"); err != nil {
fmt.Fprintf(w, "{\"errmsg\":%q}", err)
} else {
w.Write(data)
}
})
Router().GET("/dashboard/", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
if data, err := Asset("htdocs/dashboard.html"); err != nil {
fmt.Fprintf(w, "{\"errmsg\":%q}", err)
} else {
w.Write(data)
}
})
Router().GET("/css/*_", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
w.Header().Set("Content-Type", "text/css")
if data, err := Asset(path.Join("htdocs", r.URL.Path)); err != nil {
@ -65,4 +51,95 @@ func init() {
w.Write(data)
}
})
Router().GET("/dashboard/", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
if data, err := Asset("htdocs/dashboard.html"); err != nil {
fmt.Fprintf(w, "{\"errmsg\":%q}", err)
} else {
w.Write(data)
}
})
Router().GET("/dashboard/css/*_", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
w.Header().Set("Content-Type", "text/css")
if data, err := Asset(path.Join("htdocs", strings.TrimPrefix(r.URL.Path, "/dashboard"))); err != nil {
http.NotFound(w, r)
} else {
w.Write(data)
}
})
Router().GET("/dashboard/js/*_", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
w.Header().Set("Content-Type", "text/javascript")
if data, err := Asset(path.Join("htdocs", strings.TrimPrefix(r.URL.Path, "/dashboard"))); err != nil {
http.NotFound(w, r)
} else {
w.Write(data)
}
})
Router().GET("/maatma/", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
if data, err := Asset("htdocs/maatma.html"); err != nil {
fmt.Fprintf(w, "{\"errmsg\":%q}", err)
} else {
w.Write(data)
}
})
Router().GET("/maatma/auth", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
if data, err := Asset("htdocs/maatma.html"); err != nil {
fmt.Fprintf(w, "{\"errmsg\":%q}", err)
} else {
w.Write(data)
}
})
Router().GET("/maatma/domains", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
if data, err := Asset("htdocs/maatma.html"); err != nil {
fmt.Fprintf(w, "{\"errmsg\":%q}", err)
} else {
w.Write(data)
}
})
Router().GET("/maatma/tunnels", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
if data, err := Asset("htdocs/maatma.html"); err != nil {
fmt.Fprintf(w, "{\"errmsg\":%q}", err)
} else {
w.Write(data)
}
})
Router().GET("/maatma/css/*_", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
w.Header().Set("Content-Type", "text/css")
if data, err := Asset(path.Join("htdocs", strings.TrimPrefix(r.URL.Path, "/maatma"))); err != nil {
http.NotFound(w, r)
} else {
w.Write(data)
}
})
Router().GET("/maatma/fonts/*_", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
if data, err := Asset(path.Join("htdocs", strings.TrimPrefix(r.URL.Path, "/maatma"))); err != nil {
http.NotFound(w, r)
} else {
w.Write(data)
}
})
Router().GET("/maatma/img/*_", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
if data, err := Asset(path.Join("htdocs", strings.TrimPrefix(r.URL.Path, "/maatma"))); err != nil {
http.NotFound(w, r)
} else {
w.Write(data)
}
})
Router().GET("/maatma/js/*_", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
w.Header().Set("Content-Type", "text/javascript")
if data, err := Asset(path.Join("htdocs", strings.TrimPrefix(r.URL.Path, "/maatma"))); err != nil {
http.NotFound(w, r)
} else {
w.Write(data)
}
})
Router().GET("/maatma/views/*_", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
w.Header().Set("Content-Type", "text/html")
if data, err := Asset(path.Join("htdocs", strings.TrimPrefix(r.URL.Path, "/maatma"))); err != nil {
http.NotFound(w, r)
} else {
w.Write(data)
}
})
}