many small improvements
This commit is contained in:
parent
e09ef939c0
commit
eb51c2dd74
|
@ -0,0 +1,3 @@
|
||||||
|
# WireGuard Portal
|
||||||
|
|
||||||
|
[![Build Status](https://travis-ci.com/h44z/wg-portal.svg?token=q4pSqaqT58Jzpxdx62xk&branch=master)](https://travis-ci.com/h44z/wg-portal)
|
|
@ -13,6 +13,18 @@
|
||||||
$(function () {
|
$(function () {
|
||||||
$('[data-toggle="tooltip"]').tooltip()
|
$('[data-toggle="tooltip"]').tooltip()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$(".online-status").each(function(){
|
||||||
|
const onlineStatusID = "#" + $(this).attr('id');
|
||||||
|
$.get( "/user/status?pkey=" + encodeURIComponent($(this).attr('data-pkey')), function( data ) {
|
||||||
|
console.log(onlineStatusID + " " + data)
|
||||||
|
if(data === true) {
|
||||||
|
$(onlineStatusID).html('<i class="fas fa-link text-success"></i>');
|
||||||
|
} else {
|
||||||
|
$(onlineStatusID).html('<i class="fas fa-unlink"></i>');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
})(jQuery); // End of use strict
|
})(jQuery); // End of use strict
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -18,12 +18,7 @@
|
||||||
<div class="container mt-5">
|
<div class="container mt-5">
|
||||||
<h1>Create new clients</h1>
|
<h1>Create new clients</h1>
|
||||||
<h2>Enter valid LDAP user email addresses to quickly create new accounts.</h2>
|
<h2>Enter valid LDAP user email addresses to quickly create new accounts.</h2>
|
||||||
{{if $.Alerts.HasAlert}}
|
{{template "prt_flashes.html" .}}
|
||||||
<div class="alert alert-{{$.Alerts.Type}}" role="alert">
|
|
||||||
{{$.Alerts.Message}}
|
|
||||||
</div>
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
<form method="post" enctype="multipart/form-data">
|
<form method="post" enctype="multipart/form-data">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<div class="form-group col-md-12">
|
<div class="form-group col-md-12">
|
||||||
|
|
|
@ -19,22 +19,39 @@
|
||||||
<h1>Edit client <strong>{{.Peer.Identifier}}</strong></h1>
|
<h1>Edit client <strong>{{.Peer.Identifier}}</strong></h1>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{if $.Alerts.HasAlert}}
|
{{template "prt_flashes.html" .}}
|
||||||
<div class="alert alert-{{$.Alerts.Type}}" role="alert">
|
|
||||||
{{$.Alerts.Message}}
|
|
||||||
</div>
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
<form method="post" enctype="multipart/form-data">
|
<form method="post" enctype="multipart/form-data">
|
||||||
<input type="hidden" name="uid" value="{{.Peer.UID}}">
|
<input type="hidden" name="uid" value="{{.Peer.UID}}">
|
||||||
<input type="hidden" name="privkey" value="{{.Peer.PrivateKey}}">
|
{{if .EditableKeys}}
|
||||||
<input type="hidden" name="presharedkey" value="{{.Peer.PresharedKey}}">
|
<div class="form-row">
|
||||||
<div class="form-row">
|
<div class="form-group col-md-12">
|
||||||
<div class="form-group col-md-12">
|
<label for="inputServerPrivateKey">Private Key</label>
|
||||||
<label for="inputServerPublicKey">Public Key</label>
|
<input type="text" name="privkey" class="form-control" id="inputServerPrivateKey" value="{{.Peer.PrivateKey}}">
|
||||||
<input type="text" name="pubkey" readonly class="form-control" id="inputServerPublicKey" value="{{.Peer.PublicKey}}">
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="form-row">
|
||||||
|
<div class="form-group col-md-12">
|
||||||
|
<label for="inputServerPublicKey">Public Key</label>
|
||||||
|
<input type="text" name="pubkey" class="form-control" id="inputServerPublicKey" value="{{.Peer.PublicKey}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="form-group col-md-12">
|
||||||
|
<label for="inputServerPresharedKey">Preshared Key</label>
|
||||||
|
<input type="text" name="presharedkey" class="form-control" id="inputServerPresharedKey" value="{{.Peer.PresharedKey}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{else}}
|
||||||
|
<input type="hidden" name="privkey" value="{{.Peer.PrivateKey}}">
|
||||||
|
<input type="hidden" name="presharedkey" value="{{.Peer.PresharedKey}}">
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="form-group col-md-12">
|
||||||
|
<label for="inputServerPublicKey">Public Key</label>
|
||||||
|
<input type="text" name="pubkey" readonly class="form-control" id="inputServerPublicKey" value="{{.Peer.PublicKey}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<div class="form-group col-md-12">
|
<div class="form-group col-md-12">
|
||||||
<label for="inputIdentifier">Client Friendly Name</label>
|
<label for="inputIdentifier">Client Friendly Name</label>
|
||||||
|
|
|
@ -14,12 +14,7 @@
|
||||||
{{template "prt_nav.html" .}}
|
{{template "prt_nav.html" .}}
|
||||||
<div class="container mt-5 main-app">
|
<div class="container mt-5 main-app">
|
||||||
<h1>Edit interface <strong>{{.Device.DeviceName}}</strong></h1>
|
<h1>Edit interface <strong>{{.Device.DeviceName}}</strong></h1>
|
||||||
|
{{template "prt_flashes.html" .}}
|
||||||
{{if $.Alerts.HasAlert}}
|
|
||||||
<div class="alert alert-{{$.Alerts.Type}}" role="alert">
|
|
||||||
{{$.Alerts.Message}}
|
|
||||||
</div>
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
<form method="post" enctype="multipart/form-data">
|
<form method="post" enctype="multipart/form-data">
|
||||||
<input type="hidden" name="device" value="{{.Device.DeviceName}}">
|
<input type="hidden" name="device" value="{{.Device.DeviceName}}">
|
||||||
|
@ -96,6 +91,7 @@
|
||||||
|
|
||||||
<button type="submit" class="btn btn-primary">Save</button>
|
<button type="submit" class="btn btn-primary">Save</button>
|
||||||
<a href="/admin" class="btn btn-secondary">Cancel</a>
|
<a href="/admin" class="btn btn-secondary">Cancel</a>
|
||||||
|
<a href="/admin/applyglobals" class="btn btn-dark float-right">Apply Allowed IP's to clients</a>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
{{template "prt_footer.html" .}}
|
{{template "prt_footer.html" .}}
|
||||||
|
|
|
@ -14,11 +14,7 @@
|
||||||
{{template "prt_nav.html" .}}
|
{{template "prt_nav.html" .}}
|
||||||
<div class="container mt-5">
|
<div class="container mt-5">
|
||||||
<h1>WireGuard VPN Administration</h1>
|
<h1>WireGuard VPN Administration</h1>
|
||||||
{{if $.Alerts.HasAlert}}
|
{{template "prt_flashes.html" .}}
|
||||||
<div class="alert alert-{{$.Alerts.Type}}" role="alert">
|
|
||||||
{{$.Alerts.Message}}
|
|
||||||
</div>
|
|
||||||
{{end}}
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
|
@ -116,6 +112,7 @@
|
||||||
<th scope="row" class="list-image-cell">
|
<th scope="row" class="list-image-cell">
|
||||||
<a href="#{{$p.UID}}" data-toggle="collapse" class="collapse-indicator collapsed"></a>
|
<a href="#{{$p.UID}}" data-toggle="collapse" class="collapse-indicator collapsed"></a>
|
||||||
<!-- online check -->
|
<!-- online check -->
|
||||||
|
<span class="online-status" id="online-{{$p.UID}}" data-pkey="{{$p.PublicKey}}"><i class="fas fa-unlink"></i></span>
|
||||||
</th>
|
</th>
|
||||||
<td>{{$p.Identifier}}</td>
|
<td>{{$p.Identifier}}</td>
|
||||||
<td>{{$p.PublicKey}}</td>
|
<td>{{$p.PublicKey}}</td>
|
||||||
|
@ -162,7 +159,7 @@
|
||||||
{{if not $p.Peer}}
|
{{if not $p.Peer}}
|
||||||
<p>No Traffic data available...</p>
|
<p>No Traffic data available...</p>
|
||||||
{{else}}
|
{{else}}
|
||||||
<p>{{if $p.DeactivatedAt}}-{{else}}{{$p.Peer.ReceiveBytes}} / {{$p.Peer.TransmitBytes}}{{end}}</p>
|
<p>{{if $p.DeactivatedAt}}-{{else}}<i class="fas fa-long-arrow-alt-down"></i></i> {{formatBytes $p.Peer.ReceiveBytes}} / <i class="fas fa-long-arrow-alt-up"></i> {{formatBytes $p.Peer.TransmitBytes}}{{end}}</p>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
<div id="t2{{$p.UID}}" class="tab-pane fade">
|
<div id="t2{{$p.UID}}" class="tab-pane fade">
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
<h1>WireGuard VPN Portal</h1>
|
<h1>WireGuard VPN Portal</h1>
|
||||||
</div>
|
</div>
|
||||||
|
{{template "prt_flashes.html" .}}
|
||||||
<p class="lead">WireGuard® is an extremely simple yet fast and modern VPN that utilizes state-of-the-art cryptography. It aims to be faster, simpler, leaner, and more useful than IPsec, while avoiding the massive headache. It intends to be considerably more performant than OpenVPN. </p>
|
<p class="lead">WireGuard® is an extremely simple yet fast and modern VPN that utilizes state-of-the-art cryptography. It aims to be faster, simpler, leaner, and more useful than IPsec, while avoiding the massive headache. It intends to be considerably more performant than OpenVPN. </p>
|
||||||
|
|
||||||
<h3>VPN Profiles and configuration</h3>
|
<h3>VPN Profiles and configuration</h3>
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{{template "prt_flashes.html" .}}
|
||||||
</div>
|
</div>
|
||||||
<script src="/js/jquery.min.js"></script>
|
<script src="/js/jquery.min.js"></script>
|
||||||
<script src="/js/bootstrap.bundle.min.js"></script>
|
<script src="/js/bootstrap.bundle.min.js"></script>
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
{{range $flash := $.Alerts}}
|
||||||
|
<div class="alert alert-{{$flash.Type}}" role="alert">
|
||||||
|
{{$flash.Message}}
|
||||||
|
</div>
|
||||||
|
{{end}}
|
|
@ -7,12 +7,12 @@
|
||||||
<div id="topNavbar" class="navbar-collapse collapse">
|
<div id="topNavbar" class="navbar-collapse collapse">
|
||||||
<ul class="navbar-nav mr-auto mt-2 mt-lg-0">
|
<ul class="navbar-nav mr-auto mt-2 mt-lg-0">
|
||||||
<li class="nav-spacer"></li>
|
<li class="nav-spacer"></li>
|
||||||
{{with eq $.Session.LoggedIn true}}{{with eq $.Session.IsAdmin true}}
|
{{with eq $.Session.LoggedIn true}}{{with eq $.Session.IsAdmin true}}{{with eq $.Route "/admin/"}}
|
||||||
<form class="form-inline my-2 my-lg-0" method="get">
|
<form class="form-inline my-2 my-lg-0" method="get">
|
||||||
<input class="form-control mr-sm-2" name="search" type="search" placeholder="Search" aria-label="Search" value="{{$.Session.Search}}">
|
<input class="form-control mr-sm-2" name="search" type="search" placeholder="Search" aria-label="Search" value="{{$.Session.Search}}">
|
||||||
<button class="btn btn-outline-success my-2 my-sm-0" type="submit"><i class="fa fa-search"></i></button>
|
<button class="btn btn-outline-success my-2 my-sm-0" type="submit"><i class="fa fa-search"></i></button>
|
||||||
</form>
|
</form>
|
||||||
{{end}}{{end}}
|
{{end}}{{end}}{{end}}
|
||||||
</ul>
|
</ul>
|
||||||
{{if eq $.Session.LoggedIn true}}
|
{{if eq $.Session.LoggedIn true}}
|
||||||
<div class="nav-item dropdown">
|
<div class="nav-item dropdown">
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
<th scope="row" class="list-image-cell">
|
<th scope="row" class="list-image-cell">
|
||||||
<a href="#{{$p.UID}}" data-toggle="collapse" class="collapse-indicator collapsed"></a>
|
<a href="#{{$p.UID}}" data-toggle="collapse" class="collapse-indicator collapsed"></a>
|
||||||
<!-- online check -->
|
<!-- online check -->
|
||||||
|
<span class="online-status" id="online-{{$p.UID}}" data-pkey="{{$p.PublicKey}}"><i class="fas fa-unlink"></i></span>
|
||||||
</th>
|
</th>
|
||||||
<td>{{$p.Identifier}}</td>
|
<td>{{$p.Identifier}}</td>
|
||||||
<td>{{$p.PublicKey}}</td>
|
<td>{{$p.PublicKey}}</td>
|
||||||
|
@ -72,7 +73,7 @@
|
||||||
{{if not $p.Peer}}
|
{{if not $p.Peer}}
|
||||||
<p>No Traffic data available...</p>
|
<p>No Traffic data available...</p>
|
||||||
{{else}}
|
{{else}}
|
||||||
<p>{{if $p.DeactivatedAt}}-{{else}}{{$p.Peer.ReceiveBytes}} / {{$p.Peer.TransmitBytes}}{{end}}</p>
|
<p>{{if $p.DeactivatedAt}}-{{else}}<i class="fas fa-long-arrow-alt-down"></i></i> {{formatBytes $p.Peer.ReceiveBytes}} / <i class="fas fa-long-arrow-alt-up"></i> {{formatBytes $p.Peer.TransmitBytes}}{{end}}</p>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
<div id="t2{{$p.UID}}" class="tab-pane fade">
|
<div id="t2{{$p.UID}}" class="tab-pane fade">
|
||||||
|
|
1
go.mod
1
go.mod
|
@ -12,6 +12,7 @@ require (
|
||||||
github.com/kelseyhightower/envconfig v1.4.0
|
github.com/kelseyhightower/envconfig v1.4.0
|
||||||
github.com/sirupsen/logrus v1.7.0
|
github.com/sirupsen/logrus v1.7.0
|
||||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
||||||
|
github.com/tatsushid/go-fastping v0.0.0-20160109021039-d7bb493dee3e
|
||||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20200609130330-bd2cb7843e1b
|
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20200609130330-bd2cb7843e1b
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c
|
||||||
gorm.io/driver/sqlite v1.1.3
|
gorm.io/driver/sqlite v1.1.3
|
||||||
|
|
|
@ -62,6 +62,7 @@ type Config struct {
|
||||||
AdminUser string `yaml:"adminUser" envconfig:"ADMIN_USER"` // optional, non LDAP admin user
|
AdminUser string `yaml:"adminUser" envconfig:"ADMIN_USER"` // optional, non LDAP admin user
|
||||||
AdminPassword string `yaml:"adminPass" envconfig:"ADMIN_PASS"`
|
AdminPassword string `yaml:"adminPass" envconfig:"ADMIN_PASS"`
|
||||||
DatabasePath string `yaml:"database" envconfig:"DATABASE_PATH"`
|
DatabasePath string `yaml:"database" envconfig:"DATABASE_PATH"`
|
||||||
|
EditableKeys bool `yaml:"editableKeys" envconfig:"EDITABLE_KEYS"`
|
||||||
} `yaml:"core"`
|
} `yaml:"core"`
|
||||||
Email MailConfig `yaml:"email"`
|
Email MailConfig `yaml:"email"`
|
||||||
LDAP ldap.Config `yaml:"ldap"`
|
LDAP ldap.Config `yaml:"ldap"`
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
@ -55,3 +56,18 @@ func ParseStringList(lst string) []string {
|
||||||
func ListToString(lst []string) string {
|
func ListToString(lst []string) string {
|
||||||
return strings.Join(lst, ", ")
|
return strings.Join(lst, ", ")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://yourbasic.org/golang/formatting-byte-size-to-human-readable-format/
|
||||||
|
func ByteCountSI(b int64) string {
|
||||||
|
const unit = 1000
|
||||||
|
if b < unit {
|
||||||
|
return fmt.Sprintf("%d B", b)
|
||||||
|
}
|
||||||
|
div, exp := int64(unit), 0
|
||||||
|
for n := b / unit; n >= unit; n /= unit {
|
||||||
|
div *= unit
|
||||||
|
exp++
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%.1f %cB",
|
||||||
|
float64(b)/float64(div), "kMGTPE"[exp])
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"html/template"
|
"html/template"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
|
@ -26,6 +27,7 @@ const CacheRefreshDuration = 5 * time.Minute
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
gob.Register(SessionData{})
|
gob.Register(SessionData{})
|
||||||
|
gob.Register(FlashData{})
|
||||||
gob.Register(User{})
|
gob.Register(User{})
|
||||||
gob.Register(Device{})
|
gob.Register(Device{})
|
||||||
gob.Register(LdapCreateForm{})
|
gob.Register(LdapCreateForm{})
|
||||||
|
@ -47,7 +49,7 @@ type SessionData struct {
|
||||||
FormData interface{}
|
FormData interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
type AlertData struct {
|
type FlashData struct {
|
||||||
HasAlert bool
|
HasAlert bool
|
||||||
Message string
|
Message string
|
||||||
Type string
|
Type string
|
||||||
|
@ -126,6 +128,10 @@ func (s *Server) Setup() error {
|
||||||
|
|
||||||
// Setup http server
|
// Setup http server
|
||||||
s.server = gin.Default()
|
s.server = gin.Default()
|
||||||
|
s.server.SetFuncMap(template.FuncMap{
|
||||||
|
"formatBytes": common.ByteCountSI,
|
||||||
|
"urlEncode": url.QueryEscape,
|
||||||
|
})
|
||||||
|
|
||||||
// Setup templates
|
// Setup templates
|
||||||
log.Infof("Loading templates from: %s", filepath.Join(dir, "/assets/tpl/*.html"))
|
log.Infof("Loading templates from: %s", filepath.Join(dir, "/assets/tpl/*.html"))
|
||||||
|
@ -205,17 +211,19 @@ func (s *Server) getSessionData(c *gin.Context) SessionData {
|
||||||
return sessionData
|
return sessionData
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) getAlertData(c *gin.Context) AlertData {
|
func (s *Server) getFlashes(c *gin.Context) []FlashData {
|
||||||
currentSession := s.getSessionData(c)
|
session := sessions.Default(c)
|
||||||
alertData := AlertData{
|
flashes := session.Flashes()
|
||||||
HasAlert: currentSession.AlertData != "",
|
if err := session.Save(); err != nil {
|
||||||
Message: currentSession.AlertData,
|
log.Errorf("Failed to store session after setting flash: %v", err)
|
||||||
Type: currentSession.AlertType,
|
|
||||||
}
|
}
|
||||||
// Reset alerts
|
|
||||||
_ = s.setAlert(c, "", "")
|
|
||||||
|
|
||||||
return alertData
|
flashData := make([]FlashData, len(flashes))
|
||||||
|
for i := range flashes {
|
||||||
|
flashData[i] = flashes[i].(FlashData)
|
||||||
|
}
|
||||||
|
|
||||||
|
return flashData
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) updateSessionData(c *gin.Context, data SessionData) error {
|
func (s *Server) updateSessionData(c *gin.Context, data SessionData) error {
|
||||||
|
@ -248,13 +256,15 @@ func (s *Server) getStaticData() StaticData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) setAlert(c *gin.Context, message, typ string) SessionData {
|
func (s *Server) setFlashMessage(c *gin.Context, message, typ string) {
|
||||||
currentSession := s.getSessionData(c)
|
session := sessions.Default(c)
|
||||||
currentSession.AlertData = message
|
session.AddFlash(FlashData{
|
||||||
currentSession.AlertType = typ
|
Message: message,
|
||||||
_ = s.updateSessionData(c, currentSession)
|
Type: typ,
|
||||||
|
})
|
||||||
return currentSession
|
if err := session.Save(); err != nil {
|
||||||
|
log.Errorf("Failed to store session after setting flash: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s SessionData) GetSortIcon(field string) string {
|
func (s SessionData) GetSortIcon(field string) string {
|
||||||
|
|
|
@ -23,13 +23,13 @@ func (s *Server) GetHandleError(c *gin.Context, code int, message, details strin
|
||||||
func (s *Server) GetIndex(c *gin.Context) {
|
func (s *Server) GetIndex(c *gin.Context) {
|
||||||
c.HTML(http.StatusOK, "index.html", struct {
|
c.HTML(http.StatusOK, "index.html", struct {
|
||||||
Route string
|
Route string
|
||||||
Alerts AlertData
|
Alerts []FlashData
|
||||||
Session SessionData
|
Session SessionData
|
||||||
Static StaticData
|
Static StaticData
|
||||||
Device Device
|
Device Device
|
||||||
}{
|
}{
|
||||||
Route: c.Request.URL.Path,
|
Route: c.Request.URL.Path,
|
||||||
Alerts: s.getAlertData(c),
|
Alerts: s.getFlashes(c),
|
||||||
Session: s.getSessionData(c),
|
Session: s.getSessionData(c),
|
||||||
Static: s.getStaticData(),
|
Static: s.getStaticData(),
|
||||||
Device: s.users.GetDevice(),
|
Device: s.users.GetDevice(),
|
||||||
|
@ -77,7 +77,7 @@ func (s *Server) GetAdminIndex(c *gin.Context) {
|
||||||
|
|
||||||
c.HTML(http.StatusOK, "admin_index.html", struct {
|
c.HTML(http.StatusOK, "admin_index.html", struct {
|
||||||
Route string
|
Route string
|
||||||
Alerts AlertData
|
Alerts []FlashData
|
||||||
Session SessionData
|
Session SessionData
|
||||||
Static StaticData
|
Static StaticData
|
||||||
Peers []User
|
Peers []User
|
||||||
|
@ -86,7 +86,7 @@ func (s *Server) GetAdminIndex(c *gin.Context) {
|
||||||
LdapDisabled bool
|
LdapDisabled bool
|
||||||
}{
|
}{
|
||||||
Route: c.Request.URL.Path,
|
Route: c.Request.URL.Path,
|
||||||
Alerts: s.getAlertData(c),
|
Alerts: s.getFlashes(c),
|
||||||
Session: currentSession,
|
Session: currentSession,
|
||||||
Static: s.getStaticData(),
|
Static: s.getStaticData(),
|
||||||
Peers: users,
|
Peers: users,
|
||||||
|
@ -125,7 +125,7 @@ func (s *Server) GetUserIndex(c *gin.Context) {
|
||||||
|
|
||||||
c.HTML(http.StatusOK, "user_index.html", struct {
|
c.HTML(http.StatusOK, "user_index.html", struct {
|
||||||
Route string
|
Route string
|
||||||
Alerts AlertData
|
Alerts []FlashData
|
||||||
Session SessionData
|
Session SessionData
|
||||||
Static StaticData
|
Static StaticData
|
||||||
Peers []User
|
Peers []User
|
||||||
|
@ -133,7 +133,7 @@ func (s *Server) GetUserIndex(c *gin.Context) {
|
||||||
Device Device
|
Device Device
|
||||||
}{
|
}{
|
||||||
Route: c.Request.URL.Path,
|
Route: c.Request.URL.Path,
|
||||||
Alerts: s.getAlertData(c),
|
Alerts: s.getFlashes(c),
|
||||||
Session: currentSession,
|
Session: currentSession,
|
||||||
Static: s.getStaticData(),
|
Static: s.getStaticData(),
|
||||||
Peers: users,
|
Peers: users,
|
||||||
|
|
|
@ -20,14 +20,14 @@ func (s *Server) GetAdminEditInterface(c *gin.Context) {
|
||||||
|
|
||||||
c.HTML(http.StatusOK, "admin_edit_interface.html", struct {
|
c.HTML(http.StatusOK, "admin_edit_interface.html", struct {
|
||||||
Route string
|
Route string
|
||||||
Alerts AlertData
|
Alerts []FlashData
|
||||||
Session SessionData
|
Session SessionData
|
||||||
Static StaticData
|
Static StaticData
|
||||||
Peers []User
|
Peers []User
|
||||||
Device Device
|
Device Device
|
||||||
}{
|
}{
|
||||||
Route: c.Request.URL.Path,
|
Route: c.Request.URL.Path,
|
||||||
Alerts: s.getAlertData(c),
|
Alerts: s.getFlashes(c),
|
||||||
Session: currentSession,
|
Session: currentSession,
|
||||||
Static: s.getStaticData(),
|
Static: s.getStaticData(),
|
||||||
Peers: users,
|
Peers: users,
|
||||||
|
@ -43,7 +43,7 @@ func (s *Server) PostAdminEditInterface(c *gin.Context) {
|
||||||
}
|
}
|
||||||
if err := c.ShouldBind(&formDevice); err != nil {
|
if err := c.ShouldBind(&formDevice); err != nil {
|
||||||
_ = s.updateFormInSession(c, formDevice)
|
_ = s.updateFormInSession(c, formDevice)
|
||||||
s.setAlert(c, "failed to bind form data: "+err.Error(), "danger")
|
s.setFlashMessage(c, err.Error(), "danger")
|
||||||
c.Redirect(http.StatusSeeOther, "/admin/device/edit?formerr=bind")
|
c.Redirect(http.StatusSeeOther, "/admin/device/edit?formerr=bind")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ func (s *Server) PostAdminEditInterface(c *gin.Context) {
|
||||||
err := s.wg.UpdateDevice(formDevice.DeviceName, formDevice.GetDeviceConfig())
|
err := s.wg.UpdateDevice(formDevice.DeviceName, formDevice.GetDeviceConfig())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = s.updateFormInSession(c, formDevice)
|
_ = s.updateFormInSession(c, formDevice)
|
||||||
s.setAlert(c, "failed to update device in WireGuard: "+err.Error(), "danger")
|
s.setFlashMessage(c, "Failed to update device in WireGuard: "+err.Error(), "danger")
|
||||||
c.Redirect(http.StatusSeeOther, "/admin/device/edit?formerr=wg")
|
c.Redirect(http.StatusSeeOther, "/admin/device/edit?formerr=wg")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -68,12 +68,13 @@ func (s *Server) PostAdminEditInterface(c *gin.Context) {
|
||||||
err = s.users.UpdateDevice(formDevice)
|
err = s.users.UpdateDevice(formDevice)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = s.updateFormInSession(c, formDevice)
|
_ = s.updateFormInSession(c, formDevice)
|
||||||
s.setAlert(c, "failed to update device in database: "+err.Error(), "danger")
|
s.setFlashMessage(c, "Failed to update device in database: "+err.Error(), "danger")
|
||||||
c.Redirect(http.StatusSeeOther, "/admin/device/edit?formerr=update")
|
c.Redirect(http.StatusSeeOther, "/admin/device/edit?formerr=update")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
s.setAlert(c, "changes applied successfully", "success")
|
s.setFlashMessage(c, "Changes applied successfully!", "success")
|
||||||
|
s.setFlashMessage(c, "WireGuard must be restarted to apply ip changes.", "warning")
|
||||||
c.Redirect(http.StatusSeeOther, "/admin/device/edit")
|
c.Redirect(http.StatusSeeOther, "/admin/device/edit")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,3 +93,21 @@ func (s *Server) GetInterfaceConfig(c *gin.Context) {
|
||||||
c.Data(http.StatusOK, "application/config", cfg)
|
c.Data(http.StatusOK, "application/config", cfg)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) GetApplyGlobalConfig(c *gin.Context) {
|
||||||
|
device := s.users.GetDevice()
|
||||||
|
users := s.users.GetAllUsers()
|
||||||
|
|
||||||
|
for _, user := range users {
|
||||||
|
user.AllowedIPs = device.AllowedIPs
|
||||||
|
user.AllowedIPsStr = device.AllowedIPsStr
|
||||||
|
if err := s.users.UpdateUser(user); err != nil {
|
||||||
|
s.setFlashMessage(c, err.Error(), "danger")
|
||||||
|
c.Redirect(http.StatusSeeOther, "/admin/device/edit")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s.setFlashMessage(c, "Allowed ip's updated for all clients.", "success")
|
||||||
|
c.Redirect(http.StatusSeeOther, "/admin/device/edit")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -11,6 +12,7 @@ import (
|
||||||
"github.com/h44z/wg-portal/internal/common"
|
"github.com/h44z/wg-portal/internal/common"
|
||||||
"github.com/h44z/wg-portal/internal/ldap"
|
"github.com/h44z/wg-portal/internal/ldap"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
"github.com/tatsushid/go-fastping"
|
||||||
)
|
)
|
||||||
|
|
||||||
type LdapCreateForm struct {
|
type LdapCreateForm struct {
|
||||||
|
@ -29,19 +31,21 @@ func (s *Server) GetAdminEditPeer(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
c.HTML(http.StatusOK, "admin_edit_client.html", struct {
|
c.HTML(http.StatusOK, "admin_edit_client.html", struct {
|
||||||
Route string
|
Route string
|
||||||
Alerts AlertData
|
Alerts []FlashData
|
||||||
Session SessionData
|
Session SessionData
|
||||||
Static StaticData
|
Static StaticData
|
||||||
Peer User
|
Peer User
|
||||||
Device Device
|
Device Device
|
||||||
|
EditableKeys bool
|
||||||
}{
|
}{
|
||||||
Route: c.Request.URL.Path,
|
Route: c.Request.URL.Path,
|
||||||
Alerts: s.getAlertData(c),
|
Alerts: s.getFlashes(c),
|
||||||
Session: currentSession,
|
Session: currentSession,
|
||||||
Static: s.getStaticData(),
|
Static: s.getStaticData(),
|
||||||
Peer: currentSession.FormData.(User),
|
Peer: currentSession.FormData.(User),
|
||||||
Device: device,
|
Device: device,
|
||||||
|
EditableKeys: s.config.Core.EditableKeys,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +60,7 @@ func (s *Server) PostAdminEditPeer(c *gin.Context) {
|
||||||
}
|
}
|
||||||
if err := c.ShouldBind(&formUser); err != nil {
|
if err := c.ShouldBind(&formUser); err != nil {
|
||||||
_ = s.updateFormInSession(c, formUser)
|
_ = s.updateFormInSession(c, formUser)
|
||||||
s.setAlert(c, "failed to bind form data: "+err.Error(), "danger")
|
s.setFlashMessage(c, "failed to bind form data: "+err.Error(), "danger")
|
||||||
c.Redirect(http.StatusSeeOther, "/admin/peer/edit?pkey="+urlEncodedKey+"&formerr=bind")
|
c.Redirect(http.StatusSeeOther, "/admin/peer/edit?pkey="+urlEncodedKey+"&formerr=bind")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -78,12 +82,12 @@ func (s *Server) PostAdminEditPeer(c *gin.Context) {
|
||||||
// Update in database
|
// Update in database
|
||||||
if err := s.UpdateUser(formUser, now); err != nil {
|
if err := s.UpdateUser(formUser, now); err != nil {
|
||||||
_ = s.updateFormInSession(c, formUser)
|
_ = s.updateFormInSession(c, formUser)
|
||||||
s.setAlert(c, "failed to update user: "+err.Error(), "danger")
|
s.setFlashMessage(c, "failed to update user: "+err.Error(), "danger")
|
||||||
c.Redirect(http.StatusSeeOther, "/admin/peer/edit?pkey="+urlEncodedKey+"&formerr=update")
|
c.Redirect(http.StatusSeeOther, "/admin/peer/edit?pkey="+urlEncodedKey+"&formerr=update")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
s.setAlert(c, "changes applied successfully", "success")
|
s.setFlashMessage(c, "changes applied successfully", "success")
|
||||||
c.Redirect(http.StatusSeeOther, "/admin/peer/edit?pkey="+urlEncodedKey)
|
c.Redirect(http.StatusSeeOther, "/admin/peer/edit?pkey="+urlEncodedKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,19 +100,21 @@ func (s *Server) GetAdminCreatePeer(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.HTML(http.StatusOK, "admin_edit_client.html", struct {
|
c.HTML(http.StatusOK, "admin_edit_client.html", struct {
|
||||||
Route string
|
Route string
|
||||||
Alerts AlertData
|
Alerts []FlashData
|
||||||
Session SessionData
|
Session SessionData
|
||||||
Static StaticData
|
Static StaticData
|
||||||
Peer User
|
Peer User
|
||||||
Device Device
|
Device Device
|
||||||
|
EditableKeys bool
|
||||||
}{
|
}{
|
||||||
Route: c.Request.URL.Path,
|
Route: c.Request.URL.Path,
|
||||||
Alerts: s.getAlertData(c),
|
Alerts: s.getFlashes(c),
|
||||||
Session: currentSession,
|
Session: currentSession,
|
||||||
Static: s.getStaticData(),
|
Static: s.getStaticData(),
|
||||||
Peer: currentSession.FormData.(User),
|
Peer: currentSession.FormData.(User),
|
||||||
Device: device,
|
Device: device,
|
||||||
|
EditableKeys: s.config.Core.EditableKeys,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +126,7 @@ func (s *Server) PostAdminCreatePeer(c *gin.Context) {
|
||||||
}
|
}
|
||||||
if err := c.ShouldBind(&formUser); err != nil {
|
if err := c.ShouldBind(&formUser); err != nil {
|
||||||
_ = s.updateFormInSession(c, formUser)
|
_ = s.updateFormInSession(c, formUser)
|
||||||
s.setAlert(c, "failed to bind form data: "+err.Error(), "danger")
|
s.setFlashMessage(c, "failed to bind form data: "+err.Error(), "danger")
|
||||||
c.Redirect(http.StatusSeeOther, "/admin/peer/create?formerr=bind")
|
c.Redirect(http.StatusSeeOther, "/admin/peer/create?formerr=bind")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -139,12 +145,12 @@ func (s *Server) PostAdminCreatePeer(c *gin.Context) {
|
||||||
|
|
||||||
if err := s.CreateUser(formUser); err != nil {
|
if err := s.CreateUser(formUser); err != nil {
|
||||||
_ = s.updateFormInSession(c, formUser)
|
_ = s.updateFormInSession(c, formUser)
|
||||||
s.setAlert(c, "failed to add user: "+err.Error(), "danger")
|
s.setFlashMessage(c, "failed to add user: "+err.Error(), "danger")
|
||||||
c.Redirect(http.StatusSeeOther, "/admin/peer/create?formerr=create")
|
c.Redirect(http.StatusSeeOther, "/admin/peer/create?formerr=create")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
s.setAlert(c, "client created successfully", "success")
|
s.setFlashMessage(c, "client created successfully", "success")
|
||||||
c.Redirect(http.StatusSeeOther, "/admin")
|
c.Redirect(http.StatusSeeOther, "/admin")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +163,7 @@ func (s *Server) GetAdminCreateLdapPeers(c *gin.Context) {
|
||||||
|
|
||||||
c.HTML(http.StatusOK, "admin_create_clients.html", struct {
|
c.HTML(http.StatusOK, "admin_create_clients.html", struct {
|
||||||
Route string
|
Route string
|
||||||
Alerts AlertData
|
Alerts []FlashData
|
||||||
Session SessionData
|
Session SessionData
|
||||||
Static StaticData
|
Static StaticData
|
||||||
Users []*ldap.UserCacheHolderEntry
|
Users []*ldap.UserCacheHolderEntry
|
||||||
|
@ -165,7 +171,7 @@ func (s *Server) GetAdminCreateLdapPeers(c *gin.Context) {
|
||||||
Device Device
|
Device Device
|
||||||
}{
|
}{
|
||||||
Route: c.Request.URL.Path,
|
Route: c.Request.URL.Path,
|
||||||
Alerts: s.getAlertData(c),
|
Alerts: s.getFlashes(c),
|
||||||
Session: currentSession,
|
Session: currentSession,
|
||||||
Static: s.getStaticData(),
|
Static: s.getStaticData(),
|
||||||
Users: s.ldapUsers.GetSortedUsers("sn", "asc"),
|
Users: s.ldapUsers.GetSortedUsers("sn", "asc"),
|
||||||
|
@ -182,7 +188,7 @@ func (s *Server) PostAdminCreateLdapPeers(c *gin.Context) {
|
||||||
}
|
}
|
||||||
if err := c.ShouldBind(&formData); err != nil {
|
if err := c.ShouldBind(&formData); err != nil {
|
||||||
_ = s.updateFormInSession(c, formData)
|
_ = s.updateFormInSession(c, formData)
|
||||||
s.setAlert(c, "failed to bind form data: "+err.Error(), "danger")
|
s.setFlashMessage(c, "failed to bind form data: "+err.Error(), "danger")
|
||||||
c.Redirect(http.StatusSeeOther, "/admin/peer/createldap?formerr=bind")
|
c.Redirect(http.StatusSeeOther, "/admin/peer/createldap?formerr=bind")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -192,7 +198,7 @@ func (s *Server) PostAdminCreateLdapPeers(c *gin.Context) {
|
||||||
// TODO: also check email addr for validity?
|
// TODO: also check email addr for validity?
|
||||||
if !strings.ContainsRune(emails[i], '@') || s.ldapUsers.GetUserDNByMail(emails[i]) == "" {
|
if !strings.ContainsRune(emails[i], '@') || s.ldapUsers.GetUserDNByMail(emails[i]) == "" {
|
||||||
_ = s.updateFormInSession(c, formData)
|
_ = s.updateFormInSession(c, formData)
|
||||||
s.setAlert(c, "invalid email address: "+emails[i], "danger")
|
s.setFlashMessage(c, "invalid email address: "+emails[i], "danger")
|
||||||
c.Redirect(http.StatusSeeOther, "/admin/peer/createldap?formerr=mail")
|
c.Redirect(http.StatusSeeOther, "/admin/peer/createldap?formerr=mail")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -203,13 +209,13 @@ func (s *Server) PostAdminCreateLdapPeers(c *gin.Context) {
|
||||||
for i := range emails {
|
for i := range emails {
|
||||||
if err := s.CreateUserByEmail(emails[i], formData.Identifier, false); err != nil {
|
if err := s.CreateUserByEmail(emails[i], formData.Identifier, false); err != nil {
|
||||||
_ = s.updateFormInSession(c, formData)
|
_ = s.updateFormInSession(c, formData)
|
||||||
s.setAlert(c, "failed to add user: "+err.Error(), "danger")
|
s.setFlashMessage(c, "failed to add user: "+err.Error(), "danger")
|
||||||
c.Redirect(http.StatusSeeOther, "/admin/peer/createldap?formerr=create")
|
c.Redirect(http.StatusSeeOther, "/admin/peer/createldap?formerr=create")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s.setAlert(c, "client(s) created successfully", "success")
|
s.setFlashMessage(c, "client(s) created successfully", "success")
|
||||||
c.Redirect(http.StatusSeeOther, "/admin/peer/createldap")
|
c.Redirect(http.StatusSeeOther, "/admin/peer/createldap")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,7 +225,7 @@ func (s *Server) GetAdminDeletePeer(c *gin.Context) {
|
||||||
s.GetHandleError(c, http.StatusInternalServerError, "Deletion error", err.Error())
|
s.GetHandleError(c, http.StatusInternalServerError, "Deletion error", err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.setAlert(c, "user deleted successfully", "success")
|
s.setFlashMessage(c, "user deleted successfully", "success")
|
||||||
c.Redirect(http.StatusSeeOther, "/admin")
|
c.Redirect(http.StatusSeeOther, "/admin")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,6 +319,55 @@ func (s *Server) GetPeerConfigMail(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
s.setAlert(c, "mail sent successfully", "success")
|
s.setFlashMessage(c, "mail sent successfully", "success")
|
||||||
c.Redirect(http.StatusSeeOther, "/admin")
|
c.Redirect(http.StatusSeeOther, "/admin")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) GetPeerStatus(c *gin.Context) {
|
||||||
|
user := s.users.GetUserByKey(c.Query("pkey"))
|
||||||
|
currentSession := s.getSessionData(c)
|
||||||
|
if !currentSession.IsAdmin && user.Email != currentSession.Email {
|
||||||
|
s.GetHandleError(c, http.StatusUnauthorized, "No permissions", "You don't have permissions to view this resource!")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if user.Peer == nil { // no peer means disabled
|
||||||
|
c.JSON(http.StatusOK, false)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
isOnline := false
|
||||||
|
ping := make(chan bool)
|
||||||
|
defer close(ping)
|
||||||
|
for _, cidr := range user.IPs {
|
||||||
|
ip, _, _ := net.ParseCIDR(cidr)
|
||||||
|
var ra *net.IPAddr
|
||||||
|
if common.IsIPv6(ip.String()) {
|
||||||
|
ra, _ = net.ResolveIPAddr("ip6:ipv6-icmp", ip.String())
|
||||||
|
} else {
|
||||||
|
|
||||||
|
ra, _ = net.ResolveIPAddr("ip4:icmp", ip.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
p := fastping.NewPinger()
|
||||||
|
p.AddIPAddr(ra)
|
||||||
|
p.OnRecv = func(addr *net.IPAddr, rtt time.Duration) {
|
||||||
|
ping <- true
|
||||||
|
p.Stop()
|
||||||
|
}
|
||||||
|
p.OnIdle = func() {
|
||||||
|
ping <- false
|
||||||
|
p.Stop()
|
||||||
|
}
|
||||||
|
p.MaxRTT = 500 * time.Millisecond
|
||||||
|
p.RunLoop()
|
||||||
|
|
||||||
|
if <-ping {
|
||||||
|
isOnline = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, isOnline)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ func SetupRoutes(s *Server) {
|
||||||
admin.GET("/device/edit", s.GetAdminEditInterface)
|
admin.GET("/device/edit", s.GetAdminEditInterface)
|
||||||
admin.POST("/device/edit", s.PostAdminEditInterface)
|
admin.POST("/device/edit", s.PostAdminEditInterface)
|
||||||
admin.GET("/device/download", s.GetInterfaceConfig)
|
admin.GET("/device/download", s.GetInterfaceConfig)
|
||||||
|
admin.GET("/device/applyglobals", s.GetApplyGlobalConfig)
|
||||||
admin.GET("/peer/edit", s.GetAdminEditPeer)
|
admin.GET("/peer/edit", s.GetAdminEditPeer)
|
||||||
admin.POST("/peer/edit", s.PostAdminEditPeer)
|
admin.POST("/peer/edit", s.PostAdminEditPeer)
|
||||||
admin.GET("/peer/create", s.GetAdminCreatePeer)
|
admin.GET("/peer/create", s.GetAdminCreatePeer)
|
||||||
|
@ -40,6 +41,7 @@ func SetupRoutes(s *Server) {
|
||||||
user.GET("/profile", s.GetUserIndex)
|
user.GET("/profile", s.GetUserIndex)
|
||||||
user.GET("/download", s.GetPeerConfig)
|
user.GET("/download", s.GetPeerConfig)
|
||||||
user.GET("/email", s.GetPeerConfigMail)
|
user.GET("/email", s.GetPeerConfigMail)
|
||||||
|
user.GET("/status", s.GetPeerStatus)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) RequireAuthentication(scope string) gin.HandlerFunc {
|
func (s *Server) RequireAuthentication(scope string) gin.HandlerFunc {
|
||||||
|
|
|
@ -1,47 +1,52 @@
|
||||||
package wireguard
|
package wireguard
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ClientCfgTpl = `[Interface]
|
ClientCfgTpl = `#{{ .Client.Identifier }}
|
||||||
#{{ .Client.Identifier }}
|
[Interface]
|
||||||
Address = {{ .Client.IPsStr }}
|
Address = {{ .Client.IPsStr }}
|
||||||
PrivateKey = {{ .Client.PrivateKey }}
|
PrivateKey = {{ .Client.PrivateKey }}
|
||||||
{{ if ne (len .Server.DNS) 0 -}}
|
{{if .Server.DNSStr -}}
|
||||||
DNS = {{ .Server.DNSStr }}
|
DNS = {{ .Server.DNSStr }}
|
||||||
{{- end }}
|
|
||||||
{{ if ne .Server.Mtu 0 -}}
|
|
||||||
MTU = {{.Server.Mtu}}
|
|
||||||
{{- end}}
|
{{- end}}
|
||||||
|
{{- if ne .Server.Mtu 0 -}}
|
||||||
|
MTU = {{.Server.Mtu}}
|
||||||
|
{{- end -}}
|
||||||
[Peer]
|
[Peer]
|
||||||
PublicKey = {{ .Server.PublicKey }}
|
PublicKey = {{ .Server.PublicKey }}
|
||||||
|
{{- if .Client.PresharedKey -}}
|
||||||
PresharedKey = {{ .Client.PresharedKey }}
|
PresharedKey = {{ .Client.PresharedKey }}
|
||||||
|
{{- end -}}
|
||||||
AllowedIPs = {{ .Client.AllowedIPsStr }}
|
AllowedIPs = {{ .Client.AllowedIPsStr }}
|
||||||
Endpoint = {{ .Server.Endpoint }}
|
Endpoint = {{ .Server.Endpoint }}
|
||||||
{{ if and (ne .Server.PersistentKeepalive 0) (not .Client.IgnorePersistentKeepalive) -}}
|
{{if and (ne .Server.PersistentKeepalive 0) (not .Client.IgnorePersistentKeepalive) -}}
|
||||||
PersistentKeepalive = {{.Server.PersistentKeepalive}}
|
PersistentKeepalive = {{.Server.PersistentKeepalive}}
|
||||||
{{- end}}
|
{{- end}}
|
||||||
`
|
`
|
||||||
DeviceCfgTpl = `# Updated: {{ .Server.UpdatedAt }} / Created: {{ .Server.CreatedAt }}
|
DeviceCfgTpl = `# AUTOGENERATED FILE - DO NOT EDIT
|
||||||
|
# Updated: {{ .Server.UpdatedAt }} / Created: {{ .Server.CreatedAt }}
|
||||||
[Interface]
|
[Interface]
|
||||||
{{- range .Server.IPs }}
|
{{- range .Server.IPs }}
|
||||||
Address = {{ . }}
|
Address = {{ . }}
|
||||||
{{- end }}
|
{{- end}}
|
||||||
ListenPort = {{ .Server.ListenPort }}
|
ListenPort = {{ .Server.ListenPort }}
|
||||||
PrivateKey = {{ .Server.PrivateKey }}
|
PrivateKey = {{ .Server.PrivateKey }}
|
||||||
{{ if ne .Server.Mtu 0 -}}
|
{{- if ne .Server.Mtu 0 -}}
|
||||||
MTU = {{.Server.Mtu}}
|
MTU = {{.Server.Mtu}}
|
||||||
{{- end}}
|
{{- end -}}
|
||||||
PreUp = {{ .Server.PreUp }}
|
PreUp = {{ .Server.PreUp }}
|
||||||
PostUp = {{ .Server.PostUp }}
|
PostUp = {{ .Server.PostUp }}
|
||||||
PreDown = {{ .Server.PreDown }}
|
PreDown = {{ .Server.PreDown }}
|
||||||
PostDown = {{ .Server.PostDown }}
|
PostDown = {{ .Server.PostDown }}
|
||||||
|
|
||||||
{{ range .Clients }}
|
{{range .Clients}}
|
||||||
{{ if not .DeactivatedAt -}}
|
{{if not .DeactivatedAt -}}
|
||||||
# {{.Identifier}} / {{.Email}} / Updated: {{.UpdatedAt}} / Created: {{.CreatedAt}}
|
# {{.Identifier}} / {{.Email}} / Updated: {{.UpdatedAt}} / Created: {{.CreatedAt}}
|
||||||
[Peer]
|
[Peer]
|
||||||
PublicKey = {{ .PublicKey }}
|
PublicKey = {{ .PublicKey }}
|
||||||
|
{{- if .PresharedKey -}}
|
||||||
PresharedKey = {{ .PresharedKey }}
|
PresharedKey = {{ .PresharedKey }}
|
||||||
|
{{- end -}}
|
||||||
AllowedIPs = {{ StringsJoin .IPs ", " }}
|
AllowedIPs = {{ StringsJoin .IPs ", " }}
|
||||||
{{- end }}
|
{{- end}}
|
||||||
{{ end }}`
|
{{end}}`
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue