mirror of
				https://github.com/h44z/wg-portal.git
				synced 2025-11-03 23:56:18 +00:00 
			
		
		
		
	peer expiry feature: expiration check
This commit is contained in:
		@@ -67,10 +67,11 @@ type Config struct {
 | 
			
		||||
		EditableKeys            bool   `yaml:"editableKeys" envconfig:"EDITABLE_KEYS"`
 | 
			
		||||
		CreateDefaultPeer       bool   `yaml:"createDefaultPeer" envconfig:"CREATE_DEFAULT_PEER"`
 | 
			
		||||
		SelfProvisioningAllowed bool   `yaml:"selfProvisioning" envconfig:"SELF_PROVISIONING"`
 | 
			
		||||
		WGExoprterFriendlyNames bool   `yaml:"wgExporterFriendlyNames" envconfig:"WG_EXPORTER_FRIENDLY_NAMES"`
 | 
			
		||||
		WGExporterFriendlyNames bool   `yaml:"wgExporterFriendlyNames" envconfig:"WG_EXPORTER_FRIENDLY_NAMES"`
 | 
			
		||||
		LdapEnabled             bool   `yaml:"ldapEnabled" envconfig:"LDAP_ENABLED"`
 | 
			
		||||
		SessionSecret           string `yaml:"sessionSecret" envconfig:"SESSION_SECRET"`
 | 
			
		||||
		LogoUrl                 string `yaml:"logoUrl" envconfig:"LOGO_URL"`
 | 
			
		||||
		BackgroundTaskInterval  int    `yaml:"backgroundTaskInterval" envconfig:"BACKGROUND_TASK_INTERVAL"` // in seconds
 | 
			
		||||
	} `yaml:"core"`
 | 
			
		||||
	Database common.DatabaseConfig `yaml:"database"`
 | 
			
		||||
	Email    common.MailConfig     `yaml:"email"`
 | 
			
		||||
@@ -92,8 +93,9 @@ func NewConfig() *Config {
 | 
			
		||||
	cfg.Core.AdminPassword = "wgportal"
 | 
			
		||||
	cfg.Core.LdapEnabled = false
 | 
			
		||||
	cfg.Core.EditableKeys = true
 | 
			
		||||
	cfg.Core.WGExoprterFriendlyNames = false
 | 
			
		||||
	cfg.Core.WGExporterFriendlyNames = false
 | 
			
		||||
	cfg.Core.SessionSecret = "secret"
 | 
			
		||||
	cfg.Core.BackgroundTaskInterval = 15 * 60 // 15 minutes
 | 
			
		||||
 | 
			
		||||
	cfg.Database.Typ = "sqlite"
 | 
			
		||||
	cfg.Database.Database = "data/wg_portal.db"
 | 
			
		||||
 
 | 
			
		||||
@@ -112,7 +112,7 @@ func (s *Server) GetInterfaceConfig(c *gin.Context) {
 | 
			
		||||
	currentSession := GetSessionData(c)
 | 
			
		||||
	device := s.peers.GetDevice(currentSession.DeviceName)
 | 
			
		||||
	peers := s.peers.GetActivePeers(device.DeviceName)
 | 
			
		||||
	cfg, err := device.GetConfigFile(peers, s.config.Core.WGExoprterFriendlyNames)
 | 
			
		||||
	cfg, err := device.GetConfigFile(peers, s.config.Core.WGExporterFriendlyNames)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		s.GetHandleError(c, http.StatusInternalServerError, "ConfigFile error", err.Error())
 | 
			
		||||
		return
 | 
			
		||||
 
 | 
			
		||||
@@ -216,6 +216,8 @@ func (s *Server) Run() {
 | 
			
		||||
		go s.SyncLdapWithUserDatabase()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	go s.RunBackgroundTasks(s.ctx)
 | 
			
		||||
 | 
			
		||||
	// Run web service
 | 
			
		||||
	srv := &http.Server{
 | 
			
		||||
		Addr:    s.config.Core.ListeningAddress,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
package server
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"crypto/md5"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
@@ -205,7 +206,7 @@ func (s *Server) WriteWireGuardConfigFile(device string) error {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dev := s.peers.GetDevice(device)
 | 
			
		||||
	cfg, err := dev.GetConfigFile(s.peers.GetActivePeers(device), s.config.Core.WGExoprterFriendlyNames)
 | 
			
		||||
	cfg, err := dev.GetConfigFile(s.peers.GetActivePeers(device), s.config.Core.WGExporterFriendlyNames)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return errors.WithMessage(err, "failed to get config file")
 | 
			
		||||
	}
 | 
			
		||||
@@ -374,3 +375,60 @@ func (s *Server) GetDeviceNames() map[string]string {
 | 
			
		||||
 | 
			
		||||
	return devNames
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *Server) RunBackgroundTasks(ctx context.Context) {
 | 
			
		||||
	running := true
 | 
			
		||||
	for running {
 | 
			
		||||
		select {
 | 
			
		||||
		case <-ctx.Done():
 | 
			
		||||
			running = false
 | 
			
		||||
			continue
 | 
			
		||||
		case <-time.After(time.Duration(s.config.Core.BackgroundTaskInterval) * time.Second):
 | 
			
		||||
			// sleep completed, select will stop blocking
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		logrus.Debug("running periodic background tasks...")
 | 
			
		||||
 | 
			
		||||
		err := s.checkExpiredPeers()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			logrus.Errorf("failed to check expired peers: %v", err)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *Server) checkExpiredPeers() error {
 | 
			
		||||
	now := time.Now()
 | 
			
		||||
 | 
			
		||||
	for _, devName := range s.wg.Cfg.DeviceNames {
 | 
			
		||||
		changed := false
 | 
			
		||||
		peers := s.peers.GetAllPeers(devName)
 | 
			
		||||
		for _, peer := range peers {
 | 
			
		||||
			if peer.IsExpired() && !peer.IsDeactivated() {
 | 
			
		||||
				changed = true
 | 
			
		||||
 | 
			
		||||
				peer.UpdatedAt = now
 | 
			
		||||
				peer.DeactivatedAt = &now
 | 
			
		||||
				peer.DeactivatedReason = "expired"
 | 
			
		||||
 | 
			
		||||
				res := s.db.Save(&peer)
 | 
			
		||||
				if res.Error != nil {
 | 
			
		||||
					return fmt.Errorf("failed save expired peer %s: %w", peer.PublicKey, res.Error)
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				err := s.wg.RemovePeer(peer.DeviceName, peer.PublicKey)
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					return fmt.Errorf("failed to expire peer %s: %w", peer.PublicKey, err)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if changed {
 | 
			
		||||
			err := s.WriteWireGuardConfigFile(devName)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return fmt.Errorf("failed to persist config for interface %s: %w", devName, err)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -255,6 +255,20 @@ func (p Peer) WillExpire() bool {
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p Peer) IsExpired() bool {
 | 
			
		||||
	if p.ExpiresAt == nil {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	if p.ExpiresAt.Before(time.Now()) {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p Peer) IsDeactivated() bool {
 | 
			
		||||
	return p.DeactivatedAt != nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p Peer) GetConfigFileName() string {
 | 
			
		||||
	reg := regexp.MustCompile("[^a-zA-Z0-9_-]+")
 | 
			
		||||
	return reg.ReplaceAllString(strings.ReplaceAll(p.Identifier, " ", "-"), "") + ".conf"
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user