mirror of
				https://github.com/juanfont/headscale.git
				synced 2025-11-04 01:51:04 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			80 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			80 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package headscale
 | 
						|
 | 
						|
import (
 | 
						|
	"encoding/json"
 | 
						|
	"strings"
 | 
						|
 | 
						|
	"github.com/tailscale/hujson"
 | 
						|
	"inet.af/netaddr"
 | 
						|
)
 | 
						|
 | 
						|
// ACLPolicy represents a Tailscale ACL Policy.
 | 
						|
type ACLPolicy struct {
 | 
						|
	Groups    Groups    `json:"Groups"`
 | 
						|
	Hosts     Hosts     `json:"Hosts"`
 | 
						|
	TagOwners TagOwners `json:"TagOwners"`
 | 
						|
	ACLs      []ACL     `json:"ACLs"`
 | 
						|
	Tests     []ACLTest `json:"Tests"`
 | 
						|
}
 | 
						|
 | 
						|
// ACL is a basic rule for the ACL Policy.
 | 
						|
type ACL struct {
 | 
						|
	Action string   `json:"Action"`
 | 
						|
	Users  []string `json:"Users"`
 | 
						|
	Ports  []string `json:"Ports"`
 | 
						|
}
 | 
						|
 | 
						|
// Groups references a series of alias in the ACL rules.
 | 
						|
type Groups map[string][]string
 | 
						|
 | 
						|
// Hosts are alias for IP addresses or subnets.
 | 
						|
type Hosts map[string]netaddr.IPPrefix
 | 
						|
 | 
						|
// TagOwners specify what users (namespaces?) are allow to use certain tags.
 | 
						|
type TagOwners map[string][]string
 | 
						|
 | 
						|
// ACLTest is not implemented, but should be use to check if a certain rule is allowed.
 | 
						|
type ACLTest struct {
 | 
						|
	User  string   `json:"User"`
 | 
						|
	Allow []string `json:"Allow"`
 | 
						|
	Deny  []string `json:"Deny,omitempty"`
 | 
						|
}
 | 
						|
 | 
						|
// UnmarshalJSON allows to parse the Hosts directly into netaddr objects.
 | 
						|
func (hosts *Hosts) UnmarshalJSON(data []byte) error {
 | 
						|
	newHosts := Hosts{}
 | 
						|
	hostIPPrefixMap := make(map[string]string)
 | 
						|
	ast, err := hujson.Parse(data)
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
	ast.Standardize()
 | 
						|
	data = ast.Pack()
 | 
						|
	err = json.Unmarshal(data, &hostIPPrefixMap)
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
	for host, prefixStr := range hostIPPrefixMap {
 | 
						|
		if !strings.Contains(prefixStr, "/") {
 | 
						|
			prefixStr += "/32"
 | 
						|
		}
 | 
						|
		prefix, err := netaddr.ParseIPPrefix(prefixStr)
 | 
						|
		if err != nil {
 | 
						|
			return err
 | 
						|
		}
 | 
						|
		newHosts[host] = prefix
 | 
						|
	}
 | 
						|
	*hosts = newHosts
 | 
						|
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
// IsZero is perhaps a bit naive here.
 | 
						|
func (policy ACLPolicy) IsZero() bool {
 | 
						|
	if len(policy.Groups) == 0 && len(policy.Hosts) == 0 && len(policy.ACLs) == 0 {
 | 
						|
		return true
 | 
						|
	}
 | 
						|
 | 
						|
	return false
 | 
						|
}
 |