mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-12-23 14:53:34 +01:00
204 lines
4.1 KiB
Go
204 lines
4.1 KiB
Go
|
// Copyright 2024 James Hatfield
|
||
|
// SPDX-License-Identifier: MIT
|
||
|
|
||
|
//go:build ignore
|
||
|
|
||
|
package main
|
||
|
|
||
|
import (
|
||
|
"bufio"
|
||
|
"bytes"
|
||
|
"crypto"
|
||
|
"flag"
|
||
|
"fmt"
|
||
|
"go/format"
|
||
|
"io"
|
||
|
"log"
|
||
|
"net/http"
|
||
|
"os"
|
||
|
"regexp"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
const disposableEmailListURL string = "https://raw.githubusercontent.com/disposable-email-domains/disposable-email-domains/%s/disposable_email_blocklist.conf"
|
||
|
|
||
|
var (
|
||
|
gitRef *string = flag.String("r", "master", "Git reference of the domain list version")
|
||
|
outPat *string = flag.String("o", "modules/setting/disposable_email_domain_data.go", "Output path")
|
||
|
check *bool = flag.Bool("check", false, "Check if the current output file matches the current upstream list")
|
||
|
)
|
||
|
|
||
|
func main() {
|
||
|
flag.Parse()
|
||
|
|
||
|
if *check {
|
||
|
// read in the local copy of the domain list
|
||
|
local, err := get_local_file()
|
||
|
if err != nil {
|
||
|
log.Fatalf("File Read Error: %v", err)
|
||
|
}
|
||
|
|
||
|
// generate the remote copy of the domain list
|
||
|
remote, err := generate()
|
||
|
if err != nil {
|
||
|
log.Fatalf("Generation Error: %v", err)
|
||
|
}
|
||
|
|
||
|
// strip the comments from both (so we dont fail simply due to git ref difference)
|
||
|
local = strip_comments(local)
|
||
|
remote = strip_comments(remote)
|
||
|
|
||
|
// generate the hash of the local copy
|
||
|
local_sha, err := hash(local)
|
||
|
if err != nil {
|
||
|
log.Fatalf("Local Hash Generation Error: %v", err)
|
||
|
}
|
||
|
|
||
|
// generate the hash of the remote copy
|
||
|
remote_sha, err := hash(remote)
|
||
|
if err != nil {
|
||
|
log.Fatalf("Remote Hash Generation Error: %v", err)
|
||
|
}
|
||
|
|
||
|
// if the hashes dont match then the local copy needs to be updated
|
||
|
if local_sha != remote_sha {
|
||
|
log.Fatalf("Disposable email domain list needs to be updated!! \"make lint-disposable-emails-fix\"")
|
||
|
}
|
||
|
} else {
|
||
|
// generate the source code (array of domains)
|
||
|
res, err := generate()
|
||
|
if err != nil {
|
||
|
log.Fatalf("Generation Error: %v", err)
|
||
|
}
|
||
|
|
||
|
// write result to a file
|
||
|
err = os.WriteFile(*outPat, res, 0o644)
|
||
|
if err != nil {
|
||
|
log.Fatalf("File Write Error: %v", err)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func strip_comments(data []byte) []byte {
|
||
|
result := make([]byte, 0, len(data))
|
||
|
|
||
|
re := regexp.MustCompile(`^\W*//.*$`)
|
||
|
|
||
|
for _, line := range bytes.Split(data, []byte("\n")) {
|
||
|
if !re.Match(line) {
|
||
|
result = append(result, line...)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return result
|
||
|
}
|
||
|
|
||
|
func hash(data []byte) (string, error) {
|
||
|
var err error
|
||
|
|
||
|
hash := crypto.SHA3_256.New()
|
||
|
|
||
|
_, err = hash.Write(data)
|
||
|
if err != nil {
|
||
|
return "", err
|
||
|
}
|
||
|
|
||
|
return fmt.Sprintf("%x", hash.Sum(nil)), err
|
||
|
}
|
||
|
|
||
|
func get_local_file() ([]byte, error) {
|
||
|
var err error
|
||
|
|
||
|
f, err := os.Open(*outPat)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
defer f.Close()
|
||
|
|
||
|
data, err := io.ReadAll(f)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
return data, err
|
||
|
}
|
||
|
|
||
|
func get_remote() ([]string, error) {
|
||
|
var err error
|
||
|
var url string = fmt.Sprintf(disposableEmailListURL, *gitRef)
|
||
|
|
||
|
// download the domain list
|
||
|
res, err := http.Get(url)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
defer res.Body.Close()
|
||
|
|
||
|
body, err := io.ReadAll(res.Body)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
// go through all entries (1 domain per line)
|
||
|
scanner := bufio.NewScanner(bytes.NewReader(body))
|
||
|
|
||
|
var arrDomains []string
|
||
|
for scanner.Scan() {
|
||
|
line := scanner.Text()
|
||
|
arrDomains = append(arrDomains, line)
|
||
|
}
|
||
|
|
||
|
return arrDomains, err
|
||
|
}
|
||
|
|
||
|
func generate() ([]byte, error) {
|
||
|
var err error
|
||
|
var url string = fmt.Sprintf(disposableEmailListURL, *gitRef)
|
||
|
|
||
|
// download the domains list
|
||
|
arrDomains, err := get_remote()
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
// build the string in a readable way
|
||
|
var sb strings.Builder
|
||
|
|
||
|
_, err = sb.WriteString("[]string{\n")
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
for _, item := range arrDomains {
|
||
|
_, err = sb.WriteString(fmt.Sprintf("\t%q,\n", item))
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
}
|
||
|
|
||
|
_, err = sb.WriteString("}")
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
// insert the values into file
|
||
|
final := fmt.Sprintf(hdr, url, sb.String())
|
||
|
|
||
|
return format.Source([]byte(final))
|
||
|
}
|
||
|
|
||
|
const hdr = `
|
||
|
// Copyright 2024 James Hatfield
|
||
|
// SPDX-License-Identifier: MIT
|
||
|
//
|
||
|
// Code generated by build/generate-disposable-email.go. DO NOT EDIT
|
||
|
// Sourced from %s
|
||
|
package setting
|
||
|
|
||
|
import "sync"
|
||
|
|
||
|
var DisposableEmailDomains = sync.OnceValue(func() []string {
|
||
|
return %s
|
||
|
})
|
||
|
`
|