2019-07-29 07:13:33 +02:00
|
|
|
package serv
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"io/ioutil"
|
|
|
|
"log"
|
|
|
|
"os"
|
|
|
|
"sort"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
type allowItem struct {
|
|
|
|
uri string
|
|
|
|
gql string
|
|
|
|
}
|
|
|
|
|
|
|
|
var _allowList allowList
|
|
|
|
|
|
|
|
type allowList struct {
|
|
|
|
list map[string]*allowItem
|
2019-08-02 16:07:50 +02:00
|
|
|
filepath string
|
2019-07-29 07:13:33 +02:00
|
|
|
saveChan chan *allowItem
|
|
|
|
}
|
|
|
|
|
2019-08-02 16:07:50 +02:00
|
|
|
func initAllowList(path string) {
|
2019-07-29 07:13:33 +02:00
|
|
|
_allowList = allowList{
|
|
|
|
list: make(map[string]*allowItem),
|
|
|
|
saveChan: make(chan *allowItem),
|
|
|
|
}
|
2019-08-02 16:07:50 +02:00
|
|
|
|
|
|
|
if len(path) != 0 {
|
|
|
|
fp := fmt.Sprintf("%s/allow.list", path)
|
|
|
|
|
|
|
|
if _, err := os.Stat(fp); err == nil {
|
|
|
|
_allowList.filepath = fp
|
|
|
|
} else if !os.IsNotExist(err) {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(_allowList.filepath) == 0 {
|
|
|
|
fp := "./allow.list"
|
|
|
|
|
|
|
|
if _, err := os.Stat(fp); err == nil {
|
|
|
|
_allowList.filepath = fp
|
|
|
|
} else if !os.IsNotExist(err) {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(_allowList.filepath) == 0 {
|
|
|
|
fp := "./config/allow.list"
|
|
|
|
|
|
|
|
if _, err := os.Stat(fp); err == nil {
|
|
|
|
_allowList.filepath = fp
|
|
|
|
} else if !os.IsNotExist(err) {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(_allowList.filepath) == 0 {
|
|
|
|
panic("allow.list not found")
|
|
|
|
}
|
|
|
|
|
2019-07-29 07:13:33 +02:00
|
|
|
_allowList.load()
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
for v := range _allowList.saveChan {
|
|
|
|
_allowList.save(v)
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (al *allowList) add(req *gqlReq) {
|
|
|
|
if len(req.ref) == 0 || len(req.Query) == 0 {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
al.saveChan <- &allowItem{
|
|
|
|
uri: req.ref,
|
|
|
|
gql: req.Query,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (al *allowList) load() {
|
2019-08-02 16:07:50 +02:00
|
|
|
b, err := ioutil.ReadFile(al.filepath)
|
2019-07-29 07:13:33 +02:00
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(b) == 0 {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
var uri string
|
|
|
|
|
|
|
|
s, e, c := 0, 0, 0
|
|
|
|
|
|
|
|
for {
|
|
|
|
if c == 0 && b[e] == '#' {
|
|
|
|
s = e
|
2019-07-29 07:49:48 +02:00
|
|
|
for b[e] != '\n' && e < len(b) {
|
|
|
|
e++
|
|
|
|
}
|
|
|
|
if (e - s) > 2 {
|
|
|
|
uri = strings.TrimSpace(string(b[(s + 1):e]))
|
2019-07-29 07:13:33 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if b[e] == '{' {
|
|
|
|
if c == 0 {
|
|
|
|
s = e
|
|
|
|
}
|
|
|
|
c++
|
|
|
|
} else if b[e] == '}' {
|
|
|
|
c--
|
|
|
|
if c == 0 {
|
|
|
|
q := b[s:(e + 1)]
|
2019-07-30 07:38:05 +02:00
|
|
|
al.list[gqlHash(q)] = &allowItem{
|
2019-07-29 07:13:33 +02:00
|
|
|
uri: uri,
|
|
|
|
gql: string(q),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
e++
|
|
|
|
if e >= len(b) {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (al *allowList) save(item *allowItem) {
|
2019-07-30 07:38:05 +02:00
|
|
|
al.list[gqlHash([]byte(item.gql))] = item
|
2019-07-29 07:13:33 +02:00
|
|
|
|
2019-08-02 16:07:50 +02:00
|
|
|
f, err := os.Create(al.filepath)
|
2019-07-29 07:13:33 +02:00
|
|
|
if err != nil {
|
2019-08-03 17:08:16 +02:00
|
|
|
logger.Warn().Err(err).Msg("Failed to write allow list to file")
|
|
|
|
return
|
2019-07-29 07:13:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
defer f.Close()
|
|
|
|
|
|
|
|
keys := []string{}
|
|
|
|
urlMap := make(map[string][]string)
|
|
|
|
|
|
|
|
for _, v := range al.list {
|
|
|
|
urlMap[v.uri] = append(urlMap[v.uri], v.gql)
|
|
|
|
}
|
|
|
|
|
|
|
|
for k := range urlMap {
|
|
|
|
keys = append(keys, k)
|
|
|
|
}
|
|
|
|
sort.Strings(keys)
|
|
|
|
|
|
|
|
for i := range keys {
|
|
|
|
k := keys[i]
|
|
|
|
v := urlMap[k]
|
|
|
|
|
|
|
|
f.WriteString(fmt.Sprintf("# %s\n\n", k))
|
|
|
|
|
|
|
|
for i := range v {
|
|
|
|
f.WriteString(fmt.Sprintf("query %s\n\n", v[i]))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|