mirror of
https://github.com/h44z/wg-portal.git
synced 2025-04-19 08:55:12 +00:00
177 lines
8.3 KiB
Go
177 lines
8.3 KiB
Go
package models
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/h44z/wg-portal/internal"
|
|
"github.com/h44z/wg-portal/internal/domain"
|
|
)
|
|
|
|
const ExpiryDateTimeLayout = "2006-01-02"
|
|
|
|
// Peer represents a WireGuard peer entry.
|
|
type Peer struct {
|
|
// Identifier is the unique identifier of the peer. It is always equal to the public key of the peer.
|
|
Identifier string `json:"Identifier" example:"xTIBA5rboUvnH4htodjb6e697QjLERt1NAB4mZqp8Dg=" binding:"required,len=44"`
|
|
// DisplayName is a nice display name / description for the peer.
|
|
DisplayName string `json:"DisplayName" example:"My Peer" binding:"omitempty,max=64"`
|
|
// UserIdentifier is the identifier of the user that owns the peer.
|
|
UserIdentifier string `json:"UserIdentifier" example:"uid-1234567"`
|
|
// InterfaceIdentifier is the identifier of the interface the peer is linked to.
|
|
InterfaceIdentifier string `json:"InterfaceIdentifier" binding:"required" example:"wg0"`
|
|
// Disabled is a flag that specifies if the peer is enabled or not. Disabled peers are not able to connect.
|
|
Disabled bool `json:"Disabled" example:"false"`
|
|
// DisabledReason is the reason why the peer has been disabled.
|
|
DisabledReason string `json:"DisabledReason" binding:"required_if=Disabled true" example:"This is a reason why the peer has been disabled."`
|
|
// ExpiresAt is the expiry date of the peer in YYYY-MM-DD format. An expired peer is not able to connect.
|
|
ExpiresAt string `json:"ExpiresAt,omitempty" binding:"omitempty,datetime=2006-01-02"`
|
|
// Notes is a note field for peers.
|
|
Notes string `json:"Notes" example:"This is a note for the peer."`
|
|
|
|
// Endpoint is the endpoint address of the peer.
|
|
Endpoint ConfigOption[string] `json:"Endpoint"`
|
|
// EndpointPublicKey is the endpoint public key.
|
|
EndpointPublicKey ConfigOption[string] `json:"EndpointPublicKey"`
|
|
// AllowedIPs is a list of allowed IP subnets for the peer.
|
|
AllowedIPs ConfigOption[[]string] `json:"AllowedIPs"`
|
|
// ExtraAllowedIPs is a list of additional allowed IP subnets for the peer. These allowed IP subnets are added on the server side.
|
|
ExtraAllowedIPs []string `json:"ExtraAllowedIPs"`
|
|
// PresharedKey is the optional pre-shared Key of the peer.
|
|
PresharedKey string `json:"PresharedKey" example:"yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk=" binding:"omitempty,len=44"`
|
|
// PersistentKeepalive is the optional persistent keep-alive interval in seconds.
|
|
PersistentKeepalive ConfigOption[int] `json:"PersistentKeepalive"`
|
|
|
|
// PrivateKey is the private Key of the peer.
|
|
PrivateKey string `json:"PrivateKey" example:"yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk=" binding:"required,len=44"`
|
|
// PublicKey is the public Key of the server peer.
|
|
PublicKey string `json:"PublicKey" example:"TrMvSoP4jYQlY6RIzBgbssQqY3vxI2Pi+y71lOWWXX0=" binding:"omitempty,len=44"`
|
|
|
|
// Mode is the peer interface type (server, client, any).
|
|
Mode string `json:"Mode" example:"client" binding:"omitempty,oneof=server client any"`
|
|
|
|
// Addresses is a list of IP addresses in CIDR format (both IPv4 and IPv6) for the peer.
|
|
Addresses []string `json:"Addresses" example:"10.11.12.2/24" binding:"omitempty,dive,cidr"`
|
|
// CheckAliveAddress is an optional ip address or DNS name that is used for ping checks.
|
|
CheckAliveAddress string `json:"CheckAliveAddress" binding:"omitempty,ip|fqdn" example:"1.1.1.1"`
|
|
// Dns is a list of DNS servers that should be set if the peer interface is up.
|
|
Dns ConfigOption[[]string] `json:"Dns"`
|
|
// DnsSearch is the dns search option string that should be set if the peer interface is up, will be appended to Dns servers.
|
|
DnsSearch ConfigOption[[]string] `json:"DnsSearch"`
|
|
// Mtu is the device MTU of the peer.
|
|
Mtu ConfigOption[int] `json:"Mtu"`
|
|
// FirewallMark is an optional firewall mark which is used to handle peer traffic.
|
|
FirewallMark ConfigOption[uint32] `json:"FirewallMark"`
|
|
// RoutingTable is an optional routing table which is used to route peer traffic.
|
|
RoutingTable ConfigOption[string] `json:"RoutingTable"`
|
|
|
|
// PreUp is an optional action that is executed before the device is up.
|
|
PreUp ConfigOption[string] `json:"PreUp"`
|
|
// PostUp is an optional action that is executed after the device is up.
|
|
PostUp ConfigOption[string] `json:"PostUp"`
|
|
// PreDown is an optional action that is executed before the device is down.
|
|
PreDown ConfigOption[string] `json:"PreDown"`
|
|
// PostDown is an optional action that is executed after the device is down.
|
|
PostDown ConfigOption[string] `json:"PostDown"`
|
|
}
|
|
|
|
func NewPeer(src *domain.Peer) *Peer {
|
|
expiresAt := ""
|
|
if src.ExpiresAt != nil && !src.ExpiresAt.IsZero() {
|
|
expiresAt = src.ExpiresAt.Format(ExpiryDateTimeLayout)
|
|
}
|
|
|
|
return &Peer{
|
|
Identifier: string(src.Identifier),
|
|
DisplayName: src.DisplayName,
|
|
UserIdentifier: string(src.UserIdentifier),
|
|
InterfaceIdentifier: string(src.InterfaceIdentifier),
|
|
Disabled: src.IsDisabled(),
|
|
DisabledReason: src.DisabledReason,
|
|
ExpiresAt: 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),
|
|
}
|
|
}
|
|
|
|
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)
|
|
var expiresAt *time.Time
|
|
if src.ExpiresAt != "" {
|
|
if t, err := time.Parse(ExpiryDateTimeLayout, src.ExpiresAt); err == nil {
|
|
expiresAt = &t
|
|
}
|
|
}
|
|
|
|
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: expiresAt,
|
|
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
|
|
}
|