mirror of https://github.com/h44z/wg-portal.git
				
				
				
			
		
			
				
	
	
		
			231 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			231 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			Go
		
	
	
	
package model
 | 
						|
 | 
						|
import (
 | 
						|
	"time"
 | 
						|
 | 
						|
	"github.com/h44z/wg-portal/internal"
 | 
						|
	"github.com/h44z/wg-portal/internal/domain"
 | 
						|
)
 | 
						|
 | 
						|
const ExpiryDateTimeLayout = "\"2006-01-02\""
 | 
						|
 | 
						|
type ExpiryDate struct {
 | 
						|
	*time.Time
 | 
						|
}
 | 
						|
 | 
						|
// UnmarshalJSON will unmarshal using 2006-01-02 layout
 | 
						|
func (d *ExpiryDate) UnmarshalJSON(b []byte) error {
 | 
						|
	if len(b) == 0 || string(b) == "null" || string(b) == "\"\"" {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
	parsed, err := time.Parse(ExpiryDateTimeLayout, string(b))
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	if !parsed.IsZero() {
 | 
						|
		d.Time = &parsed
 | 
						|
	}
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
// MarshalJSON will marshal using 2006-01-02 layout
 | 
						|
func (d *ExpiryDate) MarshalJSON() ([]byte, error) {
 | 
						|
	if d == nil || d.Time == nil {
 | 
						|
		return []byte("null"), nil
 | 
						|
	}
 | 
						|
 | 
						|
	s := d.Format(ExpiryDateTimeLayout)
 | 
						|
	return []byte(s), nil
 | 
						|
}
 | 
						|
 | 
						|
type Peer struct {
 | 
						|
	Identifier          string     `json:"Identifier" example:"super_nice_peer"` // peer unique identifier
 | 
						|
	DisplayName         string     `json:"DisplayName"`                          // a nice display name/ description for the peer
 | 
						|
	UserIdentifier      string     `json:"UserIdentifier"`                       // the owner
 | 
						|
	InterfaceIdentifier string     `json:"InterfaceIdentifier"`                  // the interface id
 | 
						|
	Disabled            bool       `json:"Disabled"`                             // flag that specifies if the peer is enabled (up) or not (down)
 | 
						|
	DisabledReason      string     `json:"DisabledReason"`                       // the reason why the peer has been disabled
 | 
						|
	ExpiresAt           ExpiryDate `json:"ExpiresAt,omitempty"`                  // expiry dates for peers
 | 
						|
	Notes               string     `json:"Notes"`                                // a note field for peers
 | 
						|
 | 
						|
	Endpoint            ConfigOption[string]   `json:"Endpoint"`            // the endpoint address
 | 
						|
	EndpointPublicKey   ConfigOption[string]   `json:"EndpointPublicKey"`   // the endpoint public key
 | 
						|
	AllowedIPs          ConfigOption[[]string] `json:"AllowedIPs"`          // all allowed ip subnets, comma seperated
 | 
						|
	ExtraAllowedIPs     []string               `json:"ExtraAllowedIPs"`     // all allowed ip subnets on the server side, comma seperated
 | 
						|
	PresharedKey        string                 `json:"PresharedKey"`        // the pre-shared Key of the peer
 | 
						|
	PersistentKeepalive ConfigOption[int]      `json:"PersistentKeepalive"` // the persistent keep-alive interval
 | 
						|
 | 
						|
	PrivateKey string `json:"PrivateKey" example:"abcdef=="` // private Key of the server peer
 | 
						|
	PublicKey  string `json:"PublicKey" example:"abcdef=="`  // public Key of the server peer
 | 
						|
 | 
						|
	Mode string // the peer interface type (server, client, any)
 | 
						|
 | 
						|
	Addresses         []string               `json:"Addresses"`         // the interface ip addresses
 | 
						|
	CheckAliveAddress string                 `json:"CheckAliveAddress"` // optional ip address or DNS name that is used for ping checks
 | 
						|
	Dns               ConfigOption[[]string] `json:"Dns"`               // the dns server that should be set if the interface is up, comma separated
 | 
						|
	DnsSearch         ConfigOption[[]string] `json:"DnsSearch"`         // the dns search option string that should be set if the interface is up, will be appended to DnsStr
 | 
						|
	Mtu               ConfigOption[int]      `json:"Mtu"`               // the device MTU
 | 
						|
	FirewallMark      ConfigOption[uint32]   `json:"FirewallMark"`      // a firewall mark
 | 
						|
	RoutingTable      ConfigOption[string]   `json:"RoutingTable"`      // the routing table
 | 
						|
 | 
						|
	PreUp    ConfigOption[string] `json:"PreUp"`    // action that is executed before the device is up
 | 
						|
	PostUp   ConfigOption[string] `json:"PostUp"`   // action that is executed after the device is up
 | 
						|
	PreDown  ConfigOption[string] `json:"PreDown"`  // action that is executed before the device is down
 | 
						|
	PostDown ConfigOption[string] `json:"PostDown"` // action that is executed after the device is down
 | 
						|
 | 
						|
	// Calculated values
 | 
						|
 | 
						|
	Filename string `json:"Filename"` // the filename of the config file, for example: wg_peer_x.conf
 | 
						|
}
 | 
						|
 | 
						|
func NewPeer(src *domain.Peer) *Peer {
 | 
						|
	return &Peer{
 | 
						|
		Identifier:          string(src.Identifier),
 | 
						|
		DisplayName:         src.DisplayName,
 | 
						|
		UserIdentifier:      string(src.UserIdentifier),
 | 
						|
		InterfaceIdentifier: string(src.InterfaceIdentifier),
 | 
						|
		Disabled:            src.IsDisabled(),
 | 
						|
		DisabledReason:      src.DisabledReason,
 | 
						|
		ExpiresAt:           ExpiryDate{src.ExpiresAt},
 | 
						|
		Notes:               src.Notes,
 | 
						|
		Endpoint:            ConfigOptionFromDomain(src.Endpoint),
 | 
						|
		EndpointPublicKey:   ConfigOptionFromDomain(src.EndpointPublicKey),
 | 
						|
		AllowedIPs:          StringSliceConfigOptionFromDomain(src.AllowedIPsStr),
 | 
						|
		ExtraAllowedIPs:     internal.SliceString(src.ExtraAllowedIPsStr),
 | 
						|
		PresharedKey:        string(src.PresharedKey),
 | 
						|
		PersistentKeepalive: ConfigOptionFromDomain(src.PersistentKeepalive),
 | 
						|
		PrivateKey:          src.Interface.PrivateKey,
 | 
						|
		PublicKey:           src.Interface.PublicKey,
 | 
						|
		Mode:                string(src.Interface.Type),
 | 
						|
		Addresses:           domain.CidrsToStringSlice(src.Interface.Addresses),
 | 
						|
		CheckAliveAddress:   src.Interface.CheckAliveAddress,
 | 
						|
		Dns:                 StringSliceConfigOptionFromDomain(src.Interface.DnsStr),
 | 
						|
		DnsSearch:           StringSliceConfigOptionFromDomain(src.Interface.DnsSearchStr),
 | 
						|
		Mtu:                 ConfigOptionFromDomain(src.Interface.Mtu),
 | 
						|
		FirewallMark:        ConfigOptionFromDomain(src.Interface.FirewallMark),
 | 
						|
		RoutingTable:        ConfigOptionFromDomain(src.Interface.RoutingTable),
 | 
						|
		PreUp:               ConfigOptionFromDomain(src.Interface.PreUp),
 | 
						|
		PostUp:              ConfigOptionFromDomain(src.Interface.PostUp),
 | 
						|
		PreDown:             ConfigOptionFromDomain(src.Interface.PreDown),
 | 
						|
		PostDown:            ConfigOptionFromDomain(src.Interface.PostDown),
 | 
						|
		Filename:            src.GetConfigFileName(),
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func NewPeers(src []domain.Peer) []Peer {
 | 
						|
	results := make([]Peer, len(src))
 | 
						|
	for i := range src {
 | 
						|
		results[i] = *NewPeer(&src[i])
 | 
						|
	}
 | 
						|
 | 
						|
	return results
 | 
						|
}
 | 
						|
 | 
						|
func NewDomainPeer(src *Peer) *domain.Peer {
 | 
						|
	now := time.Now()
 | 
						|
 | 
						|
	cidrs, _ := domain.CidrsFromArray(src.Addresses)
 | 
						|
 | 
						|
	res := &domain.Peer{
 | 
						|
		BaseModel:           domain.BaseModel{},
 | 
						|
		Endpoint:            ConfigOptionToDomain(src.Endpoint),
 | 
						|
		EndpointPublicKey:   ConfigOptionToDomain(src.EndpointPublicKey),
 | 
						|
		AllowedIPsStr:       StringSliceConfigOptionToDomain(src.AllowedIPs),
 | 
						|
		ExtraAllowedIPsStr:  internal.SliceToString(src.ExtraAllowedIPs),
 | 
						|
		PresharedKey:        domain.PreSharedKey(src.PresharedKey),
 | 
						|
		PersistentKeepalive: ConfigOptionToDomain(src.PersistentKeepalive),
 | 
						|
		DisplayName:         src.DisplayName,
 | 
						|
		Identifier:          domain.PeerIdentifier(src.Identifier),
 | 
						|
		UserIdentifier:      domain.UserIdentifier(src.UserIdentifier),
 | 
						|
		InterfaceIdentifier: domain.InterfaceIdentifier(src.InterfaceIdentifier),
 | 
						|
		Disabled:            nil, // set below
 | 
						|
		DisabledReason:      src.DisabledReason,
 | 
						|
		ExpiresAt:           src.ExpiresAt.Time,
 | 
						|
		Notes:               src.Notes,
 | 
						|
		Interface: domain.PeerInterfaceConfig{
 | 
						|
			KeyPair: domain.KeyPair{
 | 
						|
				PrivateKey: src.PrivateKey,
 | 
						|
				PublicKey:  src.PublicKey,
 | 
						|
			},
 | 
						|
			Type:              domain.InterfaceType(src.Mode),
 | 
						|
			Addresses:         cidrs,
 | 
						|
			CheckAliveAddress: src.CheckAliveAddress,
 | 
						|
			DnsStr:            StringSliceConfigOptionToDomain(src.Dns),
 | 
						|
			DnsSearchStr:      StringSliceConfigOptionToDomain(src.DnsSearch),
 | 
						|
			Mtu:               ConfigOptionToDomain(src.Mtu),
 | 
						|
			FirewallMark:      ConfigOptionToDomain(src.FirewallMark),
 | 
						|
			RoutingTable:      ConfigOptionToDomain(src.RoutingTable),
 | 
						|
			PreUp:             ConfigOptionToDomain(src.PreUp),
 | 
						|
			PostUp:            ConfigOptionToDomain(src.PostUp),
 | 
						|
			PreDown:           ConfigOptionToDomain(src.PreDown),
 | 
						|
			PostDown:          ConfigOptionToDomain(src.PostDown),
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	if src.Disabled {
 | 
						|
		res.Disabled = &now
 | 
						|
	}
 | 
						|
 | 
						|
	return res
 | 
						|
}
 | 
						|
 | 
						|
type MultiPeerRequest struct {
 | 
						|
	Identifiers []string `json:"Identifiers"`
 | 
						|
	Suffix      string   `json:"Suffix"`
 | 
						|
}
 | 
						|
 | 
						|
func NewDomainPeerCreationRequest(src *MultiPeerRequest) *domain.PeerCreationRequest {
 | 
						|
	return &domain.PeerCreationRequest{
 | 
						|
		UserIdentifiers: src.Identifiers,
 | 
						|
		Suffix:          src.Suffix,
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
type PeerMailRequest struct {
 | 
						|
	Identifiers []string `json:"Identifiers"`
 | 
						|
	LinkOnly    bool     `json:"LinkOnly"`
 | 
						|
}
 | 
						|
 | 
						|
type PeerStats struct {
 | 
						|
	Enabled bool `json:"Enabled" example:"true"` // peer stats tracking enabled
 | 
						|
 | 
						|
	Stats map[string]PeerStatData `json:"Stats"` // stats, map key = Peer identifier
 | 
						|
}
 | 
						|
 | 
						|
func NewPeerStats(enabled bool, src []domain.PeerStatus) *PeerStats {
 | 
						|
	stats := make(map[string]PeerStatData, len(src))
 | 
						|
 | 
						|
	for _, srcStat := range src {
 | 
						|
		stats[string(srcStat.PeerId)] = PeerStatData{
 | 
						|
			IsConnected:      srcStat.IsConnected,
 | 
						|
			IsPingable:       srcStat.IsPingable,
 | 
						|
			LastPing:         srcStat.LastPing,
 | 
						|
			BytesReceived:    srcStat.BytesReceived,
 | 
						|
			BytesTransmitted: srcStat.BytesTransmitted,
 | 
						|
			LastHandshake:    srcStat.LastHandshake,
 | 
						|
			EndpointAddress:  srcStat.Endpoint,
 | 
						|
			LastSessionStart: srcStat.LastSessionStart,
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return &PeerStats{
 | 
						|
		Enabled: enabled,
 | 
						|
		Stats:   stats,
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
type PeerStatData struct {
 | 
						|
	IsConnected bool `json:"IsConnected"`
 | 
						|
 | 
						|
	IsPingable bool       `json:"IsPingable"`
 | 
						|
	LastPing   *time.Time `json:"LastPing"`
 | 
						|
 | 
						|
	BytesReceived    uint64 `json:"BytesReceived"`
 | 
						|
	BytesTransmitted uint64 `json:"BytesTransmitted"`
 | 
						|
 | 
						|
	LastHandshake    *time.Time `json:"LastHandshake"`
 | 
						|
	EndpointAddress  string     `json:"EndpointAddress"`
 | 
						|
	LastSessionStart *time.Time `json:"LastSessionStart"`
 | 
						|
}
 |