peer expiry feature: database model, frontend updates

This commit is contained in:
Christoph Haas
2022-10-28 23:21:37 +02:00
parent e4b927bc45
commit fe3247bdc1
13 changed files with 90 additions and 18 deletions

View File

@@ -36,6 +36,14 @@ func init() {
return nil
},
})
migrations = append(migrations, Migration{
version: "1.0.9",
migrateFn: func(db *gorm.DB) error {
logrus.Infof("upgraded database format to version 1.0.9")
return nil
},
})
}
type SupportedDatabase string

View File

@@ -4,6 +4,7 @@ import (
"fmt"
"net"
"strings"
"time"
)
// BroadcastAddr returns the last address in the given network, or the broadcast address.
@@ -21,7 +22,7 @@ func BroadcastAddr(n *net.IPNet) net.IP {
return broadcast
}
// http://play.golang.org/p/m8TNTtygK0
// http://play.golang.org/p/m8TNTtygK0
func IncreaseIP(ip net.IP) {
for j := len(ip) - 1; j >= 0; j-- {
ip[j]++
@@ -84,3 +85,11 @@ func ByteCountSI(b int64) string {
return fmt.Sprintf("%.1f %cB",
float64(b)/float64(div), "kMGTPE"[exp])
}
func FormatDateHTML(t *time.Time) string {
if t == nil {
return ""
}
return t.Format("2006-01-02")
}

View File

@@ -439,6 +439,7 @@ func (s *ApiServer) PutPeer(c *gin.Context) {
now := time.Now()
if updatePeer.DeactivatedAt != nil {
updatePeer.DeactivatedAt = &now
updatePeer.DeactivatedReason = "api update"
}
if err := s.s.UpdatePeer(updatePeer, now); err != nil {
c.JSON(http.StatusInternalServerError, ApiError{Message: err.Error()})
@@ -516,6 +517,7 @@ func (s *ApiServer) PatchPeer(c *gin.Context) {
now := time.Now()
if mergedPeer.DeactivatedAt != nil {
mergedPeer.DeactivatedAt = &now
mergedPeer.DeactivatedReason = "api update"
}
if err := s.s.UpdatePeer(mergedPeer, now); err != nil {
c.JSON(http.StatusInternalServerError, ApiError{Message: err.Error()})

View File

@@ -71,8 +71,13 @@ func (s *Server) PostAdminEditPeer(c *gin.Context) {
now := time.Now()
if disabled && currentPeer.DeactivatedAt == nil {
formPeer.DeactivatedAt = &now
formPeer.DeactivatedReason = "admin update"
} else if !disabled {
formPeer.DeactivatedAt = nil
formPeer.DeactivatedReason = ""
}
if formPeer.ExpiresAt != nil && formPeer.ExpiresAt.IsZero() {
formPeer.ExpiresAt = nil
}
// Update in database
@@ -129,6 +134,7 @@ func (s *Server) PostAdminCreatePeer(c *gin.Context) {
now := time.Now()
if disabled {
formPeer.DeactivatedAt = &now
formPeer.DeactivatedReason = "admin create"
}
if err := s.CreatePeer(currentSession.DeviceName, formPeer); err != nil {
@@ -189,7 +195,7 @@ func (s *Server) PostAdminCreateLdapPeers(c *gin.Context) {
logrus.Infof("creating %d ldap peers", len(emails))
for i := range emails {
if err := s.CreatePeerByEmail(currentSession.DeviceName, emails[i], formData.Identifier, false); err != nil {
if err := s.CreatePeerByEmail(currentSession.DeviceName, emails[i], formData.Identifier); err != nil {
_ = s.updateFormInSession(c, formData)
SetFlashMessage(c, "failed to add user: "+err.Error(), "danger")
c.Redirect(http.StatusSeeOther, "/admin/peer/createldap?formerr=create")
@@ -440,6 +446,7 @@ func (s *Server) PostUserCreatePeer(c *gin.Context) {
now := time.Now()
if disabled {
formPeer.DeactivatedAt = &now
formPeer.DeactivatedReason = "user create"
}
if err := s.CreatePeer(currentSession.DeviceName, formPeer); err != nil {
@@ -496,6 +503,7 @@ func (s *Server) PostUserEditPeer(c *gin.Context) {
now := time.Now()
if disabled && currentPeer.DeactivatedAt == nil {
currentPeer.DeactivatedAt = &now
currentPeer.DeactivatedReason = "user update"
}
// Update in database

View File

@@ -112,6 +112,7 @@ func (s *Server) disableMissingLdapUsers(ldapUsers []ldap.RawLdapData) {
for _, peer := range s.peers.GetPeersByMail(activeUsers[i].Email) {
now := time.Now()
peer.DeactivatedAt = &now
peer.DeactivatedReason = "missing ldap user"
if err := s.UpdatePeer(peer, now); err != nil {
logrus.Errorf("failed to update deactivated peer %s: %v", peer.PublicKey, err)
}
@@ -141,6 +142,7 @@ func (s *Server) updateLdapUsers(ldapUsers []ldap.RawLdapData) {
for _, peer := range s.peers.GetPeersByMail(user.Email) {
now := time.Now()
peer.DeactivatedAt = nil
peer.DeactivatedReason = ""
if err = s.UpdatePeer(peer, now); err != nil {
logrus.Errorf("failed to update activated peer %s: %v", peer.PublicKey, err)
}

View File

@@ -127,6 +127,7 @@ func (s *Server) Setup(ctx context.Context) error {
})
s.server.Use(sessions.Sessions("authsession", cookieStore))
s.server.SetFuncMap(template.FuncMap{
"formatDate": common.FormatDateHTML,
"formatBytes": common.ByteCountSI,
"urlEncode": url.QueryEscape,
"startsWith": strings.HasPrefix,

View File

@@ -62,7 +62,7 @@ func (s *Server) PrepareNewPeer(device string) (wireguard.Peer, error) {
}
// CreatePeerByEmail creates a new peer for the given email.
func (s *Server) CreatePeerByEmail(device, email, identifierSuffix string, disabled bool) error {
func (s *Server) CreatePeerByEmail(device, email, identifierSuffix string) error {
user := s.users.GetUser(email)
peer, err := s.PrepareNewPeer(device)
@@ -75,10 +75,6 @@ func (s *Server) CreatePeerByEmail(device, email, identifierSuffix string, disab
} else {
peer.Identifier = fmt.Sprintf("%s (%s)", email, identifierSuffix)
}
now := time.Now()
if disabled {
peer.DeactivatedAt = &now
}
return s.CreatePeer(device, peer)
}
@@ -281,6 +277,7 @@ func (s *Server) UpdateUser(user users.User) error {
for _, peer := range s.peers.GetPeersByMail(user.Email) {
now := time.Now()
peer.DeactivatedAt = nil
peer.DeactivatedReason = ""
if err := s.UpdatePeer(peer, now); err != nil {
logrus.Errorf("failed to update (re)activated peer %s for %s: %v", peer.PublicKey, user.Email, err)
}
@@ -302,6 +299,7 @@ func (s *Server) DeleteUser(user users.User) error {
for _, peer := range s.peers.GetPeersByMail(user.Email) {
now := time.Now()
peer.DeactivatedAt = &now
peer.DeactivatedReason = "user deleted"
if err := s.UpdatePeer(peer, now); err != nil {
logrus.Errorf("failed to update deactivated peer %s for %s: %v", peer.PublicKey, user.Email, err)
}

View File

@@ -1,4 +1,4 @@
package server
var Version = "testbuild"
var DatabaseVersion = "1.0.8"
var DatabaseVersion = "1.0.9"

View File

@@ -108,11 +108,15 @@ type Peer struct {
// Global Device Settings (can be ignored, only make sense if device is in server mode)
Mtu int `form:"mtu" binding:"gte=0,lte=1500"`
DeactivatedAt *time.Time `json:",omitempty"`
CreatedBy string
UpdatedBy string
CreatedAt time.Time
UpdatedAt time.Time
DeactivatedAt *time.Time `json:",omitempty"`
DeactivatedReason string `json:",omitempty"`
ExpiresAt *time.Time `json:",omitempty" form:"expires_at" binding:"omitempty" time_format:"2006-01-02"`
CreatedBy string
UpdatedBy string
CreatedAt time.Time
UpdatedAt time.Time
}
func (p *Peer) SetIPAddresses(addresses ...string) {
@@ -238,6 +242,19 @@ func (p Peer) IsValid() bool {
return true
}
func (p Peer) WillExpire() bool {
if p.ExpiresAt == nil {
return false
}
if p.DeactivatedAt != nil {
return false // already deactivated...
}
if p.ExpiresAt.After(time.Now()) {
return true
}
return false
}
func (p Peer) GetConfigFileName() string {
reg := regexp.MustCompile("[^a-zA-Z0-9_-]+")
return reg.ReplaceAllString(strings.ReplaceAll(p.Identifier, " ", "-"), "") + ".conf"