mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2024-05-11 05:55:12 +00:00
DOCS: Removed the SPF flattener (#2146)
Co-authored-by: Tom Limoncelli <tlimoncelli@stackoverflow.com>
This commit is contained in:
committed by
GitHub
parent
fb4426201c
commit
11a8bf994b
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,62 +0,0 @@
|
||||
<html >
|
||||
|
||||
<head>
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
|
||||
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
|
||||
<script src="flattener.js"></script>
|
||||
<style>
|
||||
|
||||
ul {
|
||||
margin: 0px 0px 0px 20px;
|
||||
list-style: none;
|
||||
line-height: 2em;
|
||||
font-family: Arial;
|
||||
}
|
||||
ul li {
|
||||
font-size: 16px;
|
||||
position: relative;
|
||||
}
|
||||
ul li:before {
|
||||
position: absolute;
|
||||
left: -15px;
|
||||
top: 0px;
|
||||
content: '';
|
||||
display: block;
|
||||
border-left: 1px solid #ddd;
|
||||
height: 1em;
|
||||
border-bottom: 1px solid #ddd;
|
||||
width: 10px;
|
||||
}
|
||||
ul li:after {
|
||||
position: absolute;
|
||||
left: -15px;
|
||||
bottom: -7px;
|
||||
content: '';
|
||||
display: block;
|
||||
border-left: 1px solid #ddd;
|
||||
height: 100%;
|
||||
}
|
||||
ul li.root {
|
||||
margin: 0px 0px 0px -20px;
|
||||
}
|
||||
ul li.root:before {
|
||||
display: none;
|
||||
}
|
||||
ul li.root:after {
|
||||
display: none;
|
||||
}
|
||||
ul li:last-child:after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class='container' style='padding-bottom:50px'>
|
||||
<input type="text" id="domain" value="stackoverflow.com"></input>
|
||||
<button id="lookup_btn">Lookup</button>
|
||||
<div id="results"></div>
|
||||
<div id="flattened"></div>
|
||||
</div>
|
||||
</body>
|
@ -1,159 +0,0 @@
|
||||
//go:build js
|
||||
// +build js
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v3/pkg/spflib"
|
||||
"github.com/gopherjs/jquery"
|
||||
)
|
||||
|
||||
type gResolver struct{}
|
||||
|
||||
type gResp struct {
|
||||
Status int
|
||||
Answer []struct {
|
||||
Data string `json:"data"`
|
||||
}
|
||||
}
|
||||
|
||||
func (g gResolver) GetSPF(fqdn string) (string, error) {
|
||||
resp, err := http.Get("https://dns.google.com/resolve?type=txt&name=" + fqdn)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
dec := json.NewDecoder(resp.Body)
|
||||
dat := &gResp{}
|
||||
if err = dec.Decode(dat); err != nil {
|
||||
return "", err
|
||||
}
|
||||
for _, a := range dat.Answer {
|
||||
val := strings.Trim(a.Data, "\"")
|
||||
if strings.HasPrefix(val, "v=spf1 ") {
|
||||
return val, nil
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("No spf records found")
|
||||
}
|
||||
|
||||
var jq = jquery.NewJQuery
|
||||
var parsed *spflib.SPFRecord
|
||||
var domain string
|
||||
|
||||
var resolver = gResolver{}
|
||||
|
||||
func main() {
|
||||
jq(func() {
|
||||
jq("#lookup_btn").On(jquery.CLICK, func(e jquery.Event) {
|
||||
go func() {
|
||||
domain = jq("#domain").Val()
|
||||
text, err := resolver.GetSPF(domain)
|
||||
fmt.Println(text)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
parsed, err = spflib.Parse(text, resolver)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
jq("#results").SetHtml(buildHTML(parsed, domain))
|
||||
jq(".cb").On(jquery.CHANGE, func(e jquery.Event) {
|
||||
updateDisabledChecks()
|
||||
renderResults()
|
||||
})
|
||||
updateDisabledChecks()
|
||||
renderResults()
|
||||
}()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func updateDisabledChecks() {
|
||||
jq("input:checkbox").Each(func(i int, el interface{}) {
|
||||
fmt.Println(jq(el).Prop("disabled"))
|
||||
jq(el).SetProp("disabled", false)
|
||||
})
|
||||
jq("input:checkbox:not(:checked)").Each(func(i int, el interface{}) {
|
||||
fmt.Println(jq(el).Attr("id"))
|
||||
jq(el).Next().Next().Find("input:checkbox").Each(func(i int, el interface{}) {
|
||||
fmt.Println("^^", jq(el).Attr("id"))
|
||||
jq(el).SetProp("disabled", true)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func renderResults() {
|
||||
content := ""
|
||||
addFlattened := func(mode string, filter string) {
|
||||
flat := parsed.Flatten(filter)
|
||||
lookups := 0
|
||||
if filter != "*" {
|
||||
lookups = parsed.Lookups() - len(strings.Split(filter, ","))
|
||||
}
|
||||
content += fmt.Sprintf(`
|
||||
<h3> %s flattened (length %d, %d lookups)</h3><code>%s</code>
|
||||
`, mode, len(flat.TXT()), lookups, flat.TXT())
|
||||
split := flat.TXTSplit("_spf%d."+domain, 0, 255)
|
||||
if len(split) > 1 {
|
||||
lookups += len(split) - 1
|
||||
content += fmt.Sprintf("<h3>%s flattened split (%d lookups)</h3>", mode, lookups)
|
||||
for k, v := range split {
|
||||
content += fmt.Sprintf("<h4>%s</h4><code>%s</code>", k, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
addFlattened("Fully", "*")
|
||||
|
||||
// look for selected divs
|
||||
filters := []string{}
|
||||
jq("input:checked").Each(func(i int, el interface{}) {
|
||||
filters = append(filters, jq(el).Attr("id"))
|
||||
})
|
||||
if len(filters) > 0 {
|
||||
addFlattened("Selectively", strings.Join(filters, ","))
|
||||
}
|
||||
|
||||
jq("#flattened").SetHtml(content)
|
||||
}
|
||||
|
||||
func buildHTML(rec *spflib.SPFRecord, domain string) string {
|
||||
h := "<h1>" + domain + "</h1>"
|
||||
h += fmt.Sprintf("<h2>%d lookups</h2>", rec.Lookups())
|
||||
return h + genRoot(rec)
|
||||
}
|
||||
|
||||
// html based on https://codepen.io/khoama/pen/hpljA
|
||||
func genRoot(rec *spflib.SPFRecord) string {
|
||||
h := fmt.Sprintf(`
|
||||
<ul>
|
||||
<li class='root'>%s</li>
|
||||
`, rec.TXT())
|
||||
for _, p := range rec.Parts {
|
||||
h += genPart(p)
|
||||
}
|
||||
h += "</ul>"
|
||||
return h
|
||||
}
|
||||
|
||||
func genPart(rec *spflib.SPFPart) string {
|
||||
if !rec.IsLookup {
|
||||
return fmt.Sprintf(`<li>%s</li>`, rec.Text)
|
||||
}
|
||||
h := fmt.Sprintf(`<li>
|
||||
<input type="checkbox" class='cb' id="%s" name="%s" />
|
||||
<label for="%s">%s(%d lookups)</label>`, rec.IncludeDomain, rec.IncludeDomain, rec.IncludeDomain, rec.Text, rec.IncludeRecord.Lookups()+1)
|
||||
h += fmt.Sprintf("<ul>")
|
||||
for _, p := range rec.IncludeRecord.Parts {
|
||||
h += genPart(p)
|
||||
}
|
||||
h += "</ul>"
|
||||
h += "</li>"
|
||||
return h
|
||||
}
|
Reference in New Issue
Block a user