fix mail template (#3) and rename some variables, also change default ordering (latest handshake first)

This commit is contained in:
Christoph Haas 2021-03-22 12:39:50 +01:00
parent 6ab00ef567
commit f4edc55851
3 changed files with 35 additions and 32 deletions

View File

@ -92,7 +92,7 @@
<th class="column-top" width="210" style="font-size:0pt; line-height:0pt; padding:0; margin:0; font-weight:normal; vertical-align:top;"> <th class="column-top" width="210" style="font-size:0pt; line-height:0pt; padding:0; margin:0; font-weight:normal; vertical-align:top;">
<table width="100%" border="0" cellspacing="0" cellpadding="0"> <table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr> <tr>
<td class="fluid-img" style="font-size:0pt; line-height:0pt; text-align:left;"><img src="cid:{{.QrcodePngName}}" width="210" height="210" border="0" alt="" /></td> <td class="fluid-img" style="font-size:0pt; line-height:0pt; text-align:left;"><img src="cid:{{$.QrcodePngName}}" width="210" height="210" border="0" alt="" /></td>
</tr> </tr>
</table> </table>
</th> </th>
@ -100,14 +100,14 @@
<th class="column-top" width="280" style="font-size:0pt; line-height:0pt; padding:0; margin:0; font-weight:normal; vertical-align:top;"> <th class="column-top" width="280" style="font-size:0pt; line-height:0pt; padding:0; margin:0; font-weight:normal; vertical-align:top;">
<table width="100%" border="0" cellspacing="0" cellpadding="0"> <table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr> <tr>
{{if .Client.LdapUser}} {{if $.User}}
<td class="h4 pb20" style="color:#000000; font-family:'Muli', Arial,sans-serif; font-size:20px; line-height:28px; text-align:left; padding-bottom:20px;">Hello {{.Client.LdapUser.Firstname}} {{.Client.LdapUser.Lastname}}</td> <td class="h4 pb20" style="color:#000000; font-family:'Muli', Arial,sans-serif; font-size:20px; line-height:28px; text-align:left; padding-bottom:20px;">Hello {{$.User.Firstname}} {{$.User.Lastname}}</td>
{{else}} {{else}}
<td class="h4 pb20" style="color:#000000; font-family:'Muli', Arial,sans-serif; font-size:20px; line-height:28px; text-align:left; padding-bottom:20px;">Hello</td> <td class="h4 pb20" style="color:#000000; font-family:'Muli', Arial,sans-serif; font-size:20px; line-height:28px; text-align:left; padding-bottom:20px;">Hello</td>
{{end}} {{end}}
</tr> </tr>
<tr> <tr>
<td class="text pb20" style="color:#000000; font-family:Arial,sans-serif; font-size:14px; line-height:26px; text-align:left; padding-bottom:20px;">You or your administrator probably requested this VPN configuration. Scan the Qrcode or open the attached configuration file ({{.Client.GetConfigFileName}}) in the WireGuard VPN client to establish a secure VPN connection.</td> <td class="text pb20" style="color:#000000; font-family:Arial,sans-serif; font-size:14px; line-height:26px; text-align:left; padding-bottom:20px;">You or your administrator probably requested this VPN configuration. Scan the Qrcode or open the attached configuration file ({{$.Peer.GetConfigFileName}}) in the WireGuard VPN client to establish a secure VPN connection.</td>
</tr> </tr>
</table> </table>
</th> </th>
@ -170,7 +170,7 @@
<td class="text-footer1 pb10" style="color:#000000; font-family:'Muli', Arial,sans-serif; font-size:16px; line-height:20px; text-align:center; padding-bottom:10px;">This mail was generated using WireGuard Portal.</td> <td class="text-footer1 pb10" style="color:#000000; font-family:'Muli', Arial,sans-serif; font-size:16px; line-height:20px; text-align:center; padding-bottom:10px;">This mail was generated using WireGuard Portal.</td>
</tr> </tr>
<tr> <tr>
<td class="text-footer2" style="color:#000000; font-family:'Muli', Arial,sans-serif; font-size:12px; line-height:26px; text-align:center;"><a href="{{.PortalUrl}}" target="_blank" rel="noopener noreferrer" class="link" style="color:#000000; text-decoration:none;"><span class="link" style="color:#000000; text-decoration:none;">Visit WireGuard Portal</span></a></td> <td class="text-footer2" style="color:#000000; font-family:'Muli', Arial,sans-serif; font-size:12px; line-height:26px; text-align:center;"><a href="{{$.PortalUrl}}" target="_blank" rel="noopener noreferrer" class="link" style="color:#000000; text-decoration:none;"><span class="link" style="color:#000000; text-decoration:none;">Visit WireGuard Portal</span></a></td>
</tr> </tr>
</table> </table>
</td> </td>

View File

@ -8,10 +8,10 @@ import (
"strings" "strings"
"time" "time"
"github.com/h44z/wg-portal/internal/wireguard"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/h44z/wg-portal/internal/common" "github.com/h44z/wg-portal/internal/common"
"github.com/h44z/wg-portal/internal/users"
"github.com/h44z/wg-portal/internal/wireguard"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/tatsushid/go-fastping" "github.com/tatsushid/go-fastping"
) )
@ -197,8 +197,8 @@ func (s *Server) PostAdminCreateLdapPeers(c *gin.Context) {
} }
func (s *Server) GetAdminDeletePeer(c *gin.Context) { func (s *Server) GetAdminDeletePeer(c *gin.Context) {
currentUser := s.peers.GetPeerByKey(c.Query("pkey")) currentPeer := s.peers.GetPeerByKey(c.Query("pkey"))
if err := s.DeletePeer(currentUser); err != nil { if err := s.DeletePeer(currentPeer); err != nil {
s.GetHandleError(c, http.StatusInternalServerError, "Deletion error", err.Error()) s.GetHandleError(c, http.StatusInternalServerError, "Deletion error", err.Error())
return return
} }
@ -207,14 +207,14 @@ func (s *Server) GetAdminDeletePeer(c *gin.Context) {
} }
func (s *Server) GetPeerQRCode(c *gin.Context) { func (s *Server) GetPeerQRCode(c *gin.Context) {
user := s.peers.GetPeerByKey(c.Query("pkey")) peer := s.peers.GetPeerByKey(c.Query("pkey"))
currentSession := GetSessionData(c) currentSession := GetSessionData(c)
if !currentSession.IsAdmin && user.Email != currentSession.Email { if !currentSession.IsAdmin && peer.Email != currentSession.Email {
s.GetHandleError(c, http.StatusUnauthorized, "No permissions", "You don't have permissions to view this resource!") s.GetHandleError(c, http.StatusUnauthorized, "No permissions", "You don't have permissions to view this resource!")
return return
} }
png, err := user.GetQRCode() png, err := peer.GetQRCode()
if err != nil { if err != nil {
s.GetHandleError(c, http.StatusInternalServerError, "QRCode error", err.Error()) s.GetHandleError(c, http.StatusInternalServerError, "QRCode error", err.Error())
return return
@ -224,38 +224,40 @@ func (s *Server) GetPeerQRCode(c *gin.Context) {
} }
func (s *Server) GetPeerConfig(c *gin.Context) { func (s *Server) GetPeerConfig(c *gin.Context) {
user := s.peers.GetPeerByKey(c.Query("pkey")) peer := s.peers.GetPeerByKey(c.Query("pkey"))
currentSession := GetSessionData(c) currentSession := GetSessionData(c)
if !currentSession.IsAdmin && user.Email != currentSession.Email { if !currentSession.IsAdmin && peer.Email != currentSession.Email {
s.GetHandleError(c, http.StatusUnauthorized, "No permissions", "You don't have permissions to view this resource!") s.GetHandleError(c, http.StatusUnauthorized, "No permissions", "You don't have permissions to view this resource!")
return return
} }
cfg, err := user.GetConfigFile(s.peers.GetDevice(currentSession.DeviceName)) cfg, err := peer.GetConfigFile(s.peers.GetDevice(currentSession.DeviceName))
if err != nil { if err != nil {
s.GetHandleError(c, http.StatusInternalServerError, "ConfigFile error", err.Error()) s.GetHandleError(c, http.StatusInternalServerError, "ConfigFile error", err.Error())
return return
} }
c.Header("Content-Disposition", "attachment; filename="+user.GetConfigFileName()) c.Header("Content-Disposition", "attachment; filename="+peer.GetConfigFileName())
c.Data(http.StatusOK, "application/config", cfg) c.Data(http.StatusOK, "application/config", cfg)
return return
} }
func (s *Server) GetPeerConfigMail(c *gin.Context) { func (s *Server) GetPeerConfigMail(c *gin.Context) {
user := s.peers.GetPeerByKey(c.Query("pkey")) peer := s.peers.GetPeerByKey(c.Query("pkey"))
currentSession := GetSessionData(c) currentSession := GetSessionData(c)
if !currentSession.IsAdmin && user.Email != currentSession.Email { if !currentSession.IsAdmin && peer.Email != currentSession.Email {
s.GetHandleError(c, http.StatusUnauthorized, "No permissions", "You don't have permissions to view this resource!") s.GetHandleError(c, http.StatusUnauthorized, "No permissions", "You don't have permissions to view this resource!")
return return
} }
cfg, err := user.GetConfigFile(s.peers.GetDevice(currentSession.DeviceName)) user := s.users.GetUser(peer.Email)
cfg, err := peer.GetConfigFile(s.peers.GetDevice(currentSession.DeviceName))
if err != nil { if err != nil {
s.GetHandleError(c, http.StatusInternalServerError, "ConfigFile error", err.Error()) s.GetHandleError(c, http.StatusInternalServerError, "ConfigFile error", err.Error())
return return
} }
png, err := user.GetQRCode() png, err := peer.GetQRCode()
if err != nil { if err != nil {
s.GetHandleError(c, http.StatusInternalServerError, "QRCode error", err.Error()) s.GetHandleError(c, http.StatusInternalServerError, "QRCode error", err.Error())
return return
@ -263,11 +265,13 @@ func (s *Server) GetPeerConfigMail(c *gin.Context) {
// Apply mail template // Apply mail template
var tplBuff bytes.Buffer var tplBuff bytes.Buffer
if err := s.mailTpl.Execute(&tplBuff, struct { if err := s.mailTpl.Execute(&tplBuff, struct {
Client wireguard.Peer Peer wireguard.Peer
User *users.User
QrcodePngName string QrcodePngName string
PortalUrl string PortalUrl string
}{ }{
Client: user, Peer: peer,
User: user,
QrcodePngName: "wireguard-config.png", QrcodePngName: "wireguard-config.png",
PortalUrl: s.config.Core.ExternalUrl, PortalUrl: s.config.Core.ExternalUrl,
}); err != nil { }); err != nil {
@ -278,7 +282,7 @@ func (s *Server) GetPeerConfigMail(c *gin.Context) {
// Send mail // Send mail
attachments := []common.MailAttachment{ attachments := []common.MailAttachment{
{ {
Name: user.GetConfigFileName(), Name: peer.GetConfigFileName(),
ContentType: "application/config", ContentType: "application/config",
Data: bytes.NewReader(cfg), Data: bytes.NewReader(cfg),
}, },
@ -291,7 +295,7 @@ func (s *Server) GetPeerConfigMail(c *gin.Context) {
if err := common.SendEmailWithAttachments(s.config.Email, s.config.Core.MailFrom, "", "WireGuard VPN Configuration", if err := common.SendEmailWithAttachments(s.config.Email, s.config.Core.MailFrom, "", "WireGuard VPN Configuration",
"Your mail client does not support HTML. Please find the configuration attached to this mail.", tplBuff.String(), "Your mail client does not support HTML. Please find the configuration attached to this mail.", tplBuff.String(),
[]string{user.Email}, attachments); err != nil { []string{peer.Email}, attachments); err != nil {
s.GetHandleError(c, http.StatusInternalServerError, "Email error", err.Error()) s.GetHandleError(c, http.StatusInternalServerError, "Email error", err.Error())
return return
} }
@ -301,14 +305,14 @@ func (s *Server) GetPeerConfigMail(c *gin.Context) {
} }
func (s *Server) GetPeerStatus(c *gin.Context) { func (s *Server) GetPeerStatus(c *gin.Context) {
user := s.peers.GetPeerByKey(c.Query("pkey")) peer := s.peers.GetPeerByKey(c.Query("pkey"))
currentSession := GetSessionData(c) currentSession := GetSessionData(c)
if !currentSession.IsAdmin && user.Email != currentSession.Email { if !currentSession.IsAdmin && peer.Email != currentSession.Email {
s.GetHandleError(c, http.StatusUnauthorized, "No permissions", "You don't have permissions to view this resource!") s.GetHandleError(c, http.StatusUnauthorized, "No permissions", "You don't have permissions to view this resource!")
return return
} }
if user.Peer == nil { // no peer means disabled if peer.Peer == nil { // no peer means disabled
c.JSON(http.StatusOK, false) c.JSON(http.StatusOK, false)
return return
} }
@ -316,7 +320,7 @@ func (s *Server) GetPeerStatus(c *gin.Context) {
isOnline := false isOnline := false
ping := make(chan bool) ping := make(chan bool)
defer close(ping) defer close(ping)
for _, cidr := range user.IPs { for _, cidr := range peer.IPs {
ip, _, _ := net.ParseCIDR(cidr) ip, _, _ := net.ParseCIDR(cidr)
var ra *net.IPAddr var ra *net.IPAddr
if common.IsIPv6(ip.String()) { if common.IsIPv6(ip.String()) {

View File

@ -14,8 +14,6 @@ import (
"strings" "strings"
"time" "time"
"gorm.io/gorm"
"github.com/gin-contrib/sessions" "github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/memstore" "github.com/gin-contrib/sessions/memstore"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@ -28,6 +26,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
ginlogrus "github.com/toorop/gin-logrus" ginlogrus "github.com/toorop/gin-logrus"
"gorm.io/gorm"
) )
const SessionIdentifier = "wgPortalSession" const SessionIdentifier = "wgPortalSession"
@ -258,8 +257,8 @@ func GetSessionData(c *gin.Context) SessionData {
} else { } else {
sessionData = SessionData{ sessionData = SessionData{
Search: map[string]string{"peers": "", "userpeers": "", "users": ""}, Search: map[string]string{"peers": "", "userpeers": "", "users": ""},
SortedBy: map[string]string{"peers": "mail", "userpeers": "mail", "users": "email"}, SortedBy: map[string]string{"peers": "handshake", "userpeers": "id", "users": "email"},
SortDirection: map[string]string{"peers": "asc", "userpeers": "asc", "users": "asc"}, SortDirection: map[string]string{"peers": "desc", "userpeers": "asc", "users": "asc"},
Email: "", Email: "",
Firstname: "", Firstname: "",
Lastname: "", Lastname: "",