69 lines
1.8 KiB
Go
69 lines
1.8 KiB
Go
package license
|
||
|
||
import (
|
||
"fmt"
|
||
"regexp"
|
||
"strings"
|
||
)
|
||
|
||
// Ein DNS-Label: 1–63 Zeichen, a–z, 0–9 und Bindestrich, nicht am Rand.
|
||
// Internationalisierte Domains werden in Punycode (xn--…) angegeben.
|
||
var labelRe = regexp.MustCompile(`^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$`)
|
||
|
||
// splitHost normalisiert host (klein, ohne Punkt am Ende) und prüft, dass er
|
||
// aus mindestens zwei gültigen Labels besteht.
|
||
func splitHost(host string) (string, bool) {
|
||
h := strings.TrimSuffix(strings.ToLower(strings.TrimSpace(host)), ".")
|
||
if len(h) > 253 {
|
||
return "", false
|
||
}
|
||
labels := strings.Split(h, ".")
|
||
if len(labels) < 2 {
|
||
return "", false
|
||
}
|
||
for _, l := range labels {
|
||
if !labelRe.MatchString(l) {
|
||
return "", false
|
||
}
|
||
}
|
||
return h, true
|
||
}
|
||
|
||
// normalizePattern prüft einen Eintrag aus allowed_domains: entweder eine
|
||
// Domain ("shop.de") oder eine Wildcard ganz vorne ("*.firma.de"). Eine
|
||
// Wildcard direkt auf einer TLD ("*.de") ist nicht erlaubt.
|
||
func normalizePattern(p string) (string, error) {
|
||
p = strings.TrimSpace(p)
|
||
rest, wildcard := strings.CutPrefix(p, "*.")
|
||
h, ok := splitHost(rest)
|
||
if !ok {
|
||
return "", fmt.Errorf("%w: ungültiges Domain-Muster %q", ErrInvalid, p)
|
||
}
|
||
if wildcard {
|
||
return "*." + h, nil
|
||
}
|
||
return h, nil
|
||
}
|
||
|
||
// AllowsDomain meldet, ob host durch allowed_domains gedeckt ist:
|
||
// - "shop.de" deckt genau shop.de (keine Subdomains),
|
||
// - "*.firma.de" deckt jede Subdomain beliebiger Tiefe, nicht firma.de selbst.
|
||
//
|
||
// Groß-/Kleinschreibung und ein Punkt am Ende werden ignoriert.
|
||
func (l License) AllowsDomain(host string) bool {
|
||
h, ok := splitHost(host)
|
||
if !ok {
|
||
return false
|
||
}
|
||
for _, p := range l.AllowedDomains {
|
||
if base, wildcard := strings.CutPrefix(p, "*."); wildcard {
|
||
if strings.HasSuffix(h, "."+base) {
|
||
return true
|
||
}
|
||
} else if h == p {
|
||
return true
|
||
}
|
||
}
|
||
return false
|
||
}
|