aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Hanley <felix@userspace.com.au>2020-03-16 01:44:27 +0000
committerFelix Hanley <felix@userspace.com.au>2020-03-16 01:44:27 +0000
commit9edc3228ad3728cda598e028cd2277aa3686d7c0 (patch)
tree5940047ebbab1e0ae41b41336ac014998da5ae2f
parentf519c4195f4b0a7d9a6098ee4e3aeaee4f29939c (diff)
downloadsws-9edc3228ad3728cda598e028cd2277aa3686d7c0.tar.gz
sws-9edc3228ad3728cda598e028cd2277aa3686d7c0.tar.bz2
Add hit restrictions
-rw-r--r--cmd/server/hits.go70
-rw-r--r--go.mod6
-rw-r--r--go.sum37
-rw-r--r--sql/sqlite3/05_site_restrictions.sql2
-rw-r--r--store.go17
-rw-r--r--store/sqlite3.go43
6 files changed, 125 insertions, 50 deletions
diff --git a/cmd/server/hits.go b/cmd/server/hits.go
index 0c4ac3f..27bb11d 100644
--- a/cmd/server/hits.go
+++ b/cmd/server/hits.go
@@ -11,7 +11,6 @@ import (
"text/template"
"github.com/hashicorp/golang-lru"
- maxminddb "github.com/oschwald/maxminddb-golang"
"src.userspace.com.au/sws"
)
@@ -31,6 +30,9 @@ func handleHitCounter(db sws.CounterStore, mmdbPath string) http.HandlerFunc {
}
return func(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("Access-Control-Allow-Origin", "*")
+ w.Header().Set("Cache-Control", "no-store")
+
hit, err := sws.HitFromRequest(r)
if err != nil {
log("failed to extract hit", err)
@@ -38,23 +40,37 @@ func handleHitCounter(db sws.CounterStore, mmdbPath string) http.HandlerFunc {
return
}
- site, err := db.GetSiteByName(hit.Host)
+ site, err := verifyHit(db, hit)
if err != nil {
- log("failed to get site", err)
- http.Error(w, "invalid site", http.StatusNotFound)
+ log("failed to verify site", err)
+ http.Error(w, "invalid site", http.StatusBadRequest)
return
}
- hit.SiteID = site.ID
+
hit.Addr = r.RemoteAddr
if strings.Contains(r.RemoteAddr, ":") {
hit.Addr, _, err = net.SplitHostPort(r.RemoteAddr)
}
+
+ if r.Header.Get("X-Moz") == "prefetch" || r.Header.Get("X-Purpose") == "preview" {
+ w.Header().Set("Content-Type", "image/gif")
+ w.Write(gifBytes)
+ return
+ }
+
+ // Ignore IPs
+ if site.IgnoreIPs != "" && strings.Contains(site.IgnoreIPs, hit.Addr) {
+ w.Header().Set("Content-Type", "image/gif")
+ w.Write(gifBytes)
+ return
+ }
+
if err == nil && hit.Addr != "" {
var cc *string
if v, ok := cache.Get(hit.Addr); ok {
cc = v.(*string)
} else if mmdbPath != "" {
- if cc, err = fetchCountryCode(mmdbPath, hit.Addr); err != nil {
+ if cc, err = sws.FetchCountryCode(mmdbPath, hit.Addr); err != nil {
log("geoip lookup failed:", err)
}
cache.Add(hit.Addr, cc)
@@ -68,15 +84,32 @@ func handleHitCounter(db sws.CounterStore, mmdbPath string) http.HandlerFunc {
//http.Error(w, err.Error(), http.StatusInternalServerError)
//return
}
- // TODO restrict to site sites
- w.Header().Set("Access-Control-Allow-Origin", "*")
- w.Header().Set("Cache-Control", "no-store")
w.Header().Set("Content-Type", "image/gif")
w.Write(gifBytes)
return
}
}
+func verifyHit(db sws.SiteGetter, h *sws.Hit) (*sws.Site, error) {
+ if h.SiteID == nil {
+ return nil, fmt.Errorf("invalid site ID")
+ }
+ site, err := db.GetSiteByID(*h.SiteID)
+ if err != nil {
+ return nil, err
+ }
+ if site.Name == h.Host {
+ return site, nil
+ }
+ if strings.Contains(site.Aliases, h.Host) {
+ return site, nil
+ }
+ if site.AcceptSubdomains && strings.HasSuffix(h.Host, site.Name) {
+ return site, nil
+ }
+ return nil, fmt.Errorf("invalid host")
+}
+
func handleCounter(addr string) http.HandlerFunc {
counter := getCounter()
tmpl, err := template.New("counter").Parse(counter)
@@ -108,22 +141,3 @@ func handleCounter(addr string) http.HandlerFunc {
}
}
}
-
-func fetchCountryCode(path, host string) (*string, error) {
- db, err := maxminddb.Open(path)
- if err != nil {
- return nil, err
- }
- defer db.Close()
-
- ip := net.ParseIP(host)
- var r struct {
- Country struct {
- ISOCode string `maxminddb:"iso_code"`
- } `maxminddb:"country"`
- }
- if err := db.Lookup(ip, &r); err != nil {
- return nil, err
- }
- return &r.Country.ISOCode, nil
-}
diff --git a/go.mod b/go.mod
index 82da0b1..59bf815 100644
--- a/go.mod
+++ b/go.mod
@@ -25,8 +25,12 @@ require (
google.golang.org/appengine v1.6.5 // indirect
src.userspace.com.au/go-migrate v0.0.0-20200208102934-cf11cf76db3f
src.userspace.com.au/templates v0.0.0-20200308073907-e96b7a1f2a49
+ zgo.at/goatcounter v1.0.0 // indirect
+ zgo.at/tz v0.0.0-20200314040300-b1cfaf56ef7e // indirect
+ zgo.at/zdb v0.0.0-20200221072833-2c234b210cf1 // indirect
+ zgo.at/zhttp v0.0.0-20200301180126-a9b7c887528b // indirect
)
//replace src.userspace.com.au/templates => ../templates
-go 1.13
+go 1.14
diff --git a/go.sum b/go.sum
index 7227555..af351eb 100644
--- a/go.sum
+++ b/go.sum
@@ -1,3 +1,5 @@
+github.com/arp242/geoip2-golang v1.4.0/go.mod h1:AZYwUhu7pAKqHkiZTQhSCWaexFJDwzR3K9jIrhkNDko=
+github.com/arp242/maxminddb-golang v1.6.0/go.mod h1:zZGWhFkxTFX80NKfpEHn6vqd50ksDYTBP8Zi+Xk10OI=
github.com/blend/go-sdk v2.0.0+incompatible h1:FL9X/of4ZYO5D2JJNI4vHrbXPfuSDbUa7h8JP9+E92w=
github.com/blend/go-sdk v2.0.0+incompatible/go.mod h1:3GUb0YsHFNTJ6hsJTpzdmCUl05o8HisKjx5OAlzYKdw=
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
@@ -6,6 +8,8 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/go-chi/chi v4.0.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
github.com/go-chi/chi v4.0.3+incompatible h1:gakN3pDJnzZN5jqFV2TEdF66rTfKeITyR8qu6ekICEY=
github.com/go-chi/chi v4.0.3+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
github.com/go-chi/jwtauth v4.0.4+incompatible h1:LGIxg6YfvSBzxU2BljXbrzVc1fMlgqSKBQgKOGAVtPY=
@@ -17,6 +21,8 @@ github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRx
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 h1:vr3AYkKovP8uR8AvSGGUK1IDqRa5lAAvEkZG1LKaCRc=
@@ -27,14 +33,19 @@ github.com/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA=
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
+github.com/mattn/go-sqlite3 v2.0.2+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
+github.com/monoculum/formam v0.0.0-20191229172733-952f0766a724/go.mod h1:JKa2av1XVkGjhxdLS59nDoXa2JpmIHpnURWNbzCtXtc=
+github.com/mssola/user_agent v0.5.0/go.mod h1:UFiKPVaShrJGW93n4uo8dpPdg1BSVpw2P9bneo0Mtp8=
github.com/mssola/user_agent v0.5.1 h1:sJUCUozh+j7c0dR2zMIUX5aJjoY/TNo/gXiNujoH5oY=
github.com/mssola/user_agent v0.5.1/go.mod h1:TTPno8LPY3wAIEKRpAtkdMT0f8SE24pLRGPahjCH4uw=
github.com/oschwald/maxminddb-golang v1.6.0 h1:KAJSjdHQ8Kv45nFIbtoLGrGWqHFajOIm7skTyz/+Dls=
github.com/oschwald/maxminddb-golang v1.6.0/go.mod h1:DUJFucBg2cvqx42YmDa/+xHvb0elJtOm3o4aFQ/nb/w=
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -46,6 +57,8 @@ github.com/speps/go-hashids v2.0.0+incompatible/go.mod h1:P7hqPzMdnZOfyIk+xrlG1Q
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/teamwork/guru v1.0.0/go.mod h1:1DW23kFX0aXn1kRSuQAY+Byk74h1kZHvhJL72qBUrfU=
+github.com/teamwork/reload v1.3.0/go.mod h1:kHdVPdfdmA+ygkBbigWUeerpy6EK4Kcukx1TNyePXHA=
github.com/wcharczuk/go-chart v2.0.1+incompatible h1:0pz39ZAycJFF7ju/1mepnk26RLVLBCWz1STcD3doU0A=
github.com/wcharczuk/go-chart v2.0.1+incompatible/go.mod h1:PF5tmL4EIx/7Wf+hEkpCqYi5He4u90sw+0+6FhrryuE=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@@ -56,9 +69,13 @@ golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+o
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65 h1:+rhAzEzT3f4JtomfC371qB+0Ola2caSKcY69NUBZrRQ=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
+golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191110163157-d32e6e3b99c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191224085550-c709ea063b76/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -76,3 +93,23 @@ src.userspace.com.au/go-migrate v0.0.0-20200208102934-cf11cf76db3f h1:Vdn/5kMeLX
src.userspace.com.au/go-migrate v0.0.0-20200208102934-cf11cf76db3f/go.mod h1:QaSWOcvGubR8TBPs8XgLN67muYgAKnmIgHAaQk5ZR1c=
src.userspace.com.au/templates v0.0.0-20200308073907-e96b7a1f2a49 h1:xKLfGVLhd+jTT5Z1jCIEGcr5LzzuRnpaYvU5pA/iD7I=
src.userspace.com.au/templates v0.0.0-20200308073907-e96b7a1f2a49/go.mod h1:lB6Vdw9R/8jR8CzvPxfQ8ryBwpNDni1fCdeRjj90gxA=
+zgo.at/goatcounter v1.0.0/go.mod h1:Y76wF7BC58KvDzjsd57kdAHxqzsdgbdOVhToYqvefnE=
+zgo.at/tz v0.0.0-20200314040300-b1cfaf56ef7e h1:AkOzghahAFiffIAXjd0KBlxGZsR0wERvCNs67kAAcSc=
+zgo.at/tz v0.0.0-20200314040300-b1cfaf56ef7e/go.mod h1:A/XeaYjeMGoXptRB3EcR80tgir37tJnzCb6itDaHPxo=
+zgo.at/utils v1.2.0/go.mod h1:7acz1AfMZAOOC1wTi6QbYFie+eA0LRSHE38TwLZsFcA=
+zgo.at/utils v1.3.1/go.mod h1:7acz1AfMZAOOC1wTi6QbYFie+eA0LRSHE38TwLZsFcA=
+zgo.at/zdb v0.0.0-20200104065131-90c5bb37d973/go.mod h1:GT5Nyrxb9H6JszZtd7o0m5CPEd3C7DFqAeJt98nyNQI=
+zgo.at/zdb v0.0.0-20200221072833-2c234b210cf1 h1:g7p4cSjq/eL/A/Lojxw410mSLGLDJrB6+xZfplTKzjc=
+zgo.at/zdb v0.0.0-20200221072833-2c234b210cf1/go.mod h1:GT5Nyrxb9H6JszZtd7o0m5CPEd3C7DFqAeJt98nyNQI=
+zgo.at/zhttp v0.0.0-20200108041919-3990cfa2823e/go.mod h1:7PO/E4nqxbstyxX95cqKJOpZAVKNKoohk5utWZIdKz0=
+zgo.at/zhttp v0.0.0-20200301180126-a9b7c887528b h1:L1WcdQu/XDN1cfBPEXcM+8xKMtWKUJ1HudfWgV5Icmc=
+zgo.at/zhttp v0.0.0-20200301180126-a9b7c887528b/go.mod h1:qpNbBXqMQVTnjYbUlaBT1+SHctAfsRUGmWL/Sdwsrwo=
+zgo.at/zlog v1.0.7/go.mod h1:0RldP/sQzWwOCPsJogZcxnJneFt56T1zfDtIN/LcYec=
+zgo.at/zlog v1.0.8/go.mod h1:0RldP/sQzWwOCPsJogZcxnJneFt56T1zfDtIN/LcYec=
+zgo.at/zlog v1.0.9/go.mod h1:0RldP/sQzWwOCPsJogZcxnJneFt56T1zfDtIN/LcYec=
+zgo.at/zpack v1.0.0/go.mod h1:2laAAHqImmeiTlMAQ2PlMRBVhS6YKPkUoosMfdv7GXY=
+zgo.at/zstripe v1.0.0/go.mod h1:EqblFpMvXAhzZAUUt0EVom06EnN5+D5ESBTSOkwSwTY=
+zgo.at/ztest v1.0.0/go.mod h1:iTxcAVkHLq73Qnd+a8rlwc6Ayrk8sbnJPsGeapG/y0Q=
+zgo.at/ztest v1.0.1/go.mod h1:iTxcAVkHLq73Qnd+a8rlwc6Ayrk8sbnJPsGeapG/y0Q=
+zgo.at/zvalidate v1.0.0 h1:glc7tbq3X2EyPEQf00N6HgsWCVDlJkNLvdRbBBOrhs4=
+zgo.at/zvalidate v1.0.0/go.mod h1:3w++OX5k3nkvwwf7OkdYnjpzF+U4OGJ5xmP7SphmUuk=
diff --git a/sql/sqlite3/05_site_restrictions.sql b/sql/sqlite3/05_site_restrictions.sql
new file mode 100644
index 0000000..d383df1
--- /dev/null
+++ b/sql/sqlite3/05_site_restrictions.sql
@@ -0,0 +1,2 @@
+alter table sites add column subdomains integer not null default 0;
+alter table sites add column ignore_ips varchar null;
diff --git a/store.go b/store.go
index 06ec219..d09460e 100644
--- a/store.go
+++ b/store.go
@@ -3,27 +3,28 @@ package sws
type Store interface {
SiteStore
UserStore
- GetSiteByName(string) (*Site, error)
HitSaver
+ HitCursor(func(*Hit) error) error
}
type HitSaver interface {
SaveHit(*Hit) error
}
-type SimpleSiteStore interface {
- GetSiteByName(string) (*Site, error)
-}
type SiteStore interface {
- GetSites() ([]*Site, error)
- GetSiteByID(int) (*Site, error)
+ SiteGetter
GetHits(Site, map[string]interface{}) ([]*Hit, error)
+ GetSites() ([]*Site, error)
SaveSite(*Site) error
}
+type SiteGetter interface {
+ GetSiteByID(int) (*Site, error)
+}
type HitStore interface {
- SimpleSiteStore
+ HitSaver
GetHits(Site, map[string]interface{}) ([]*Hit, error)
+ HitCursor(func(*Hit) error) error
}
type CounterStore interface {
- SimpleSiteStore
+ SiteGetter
HitSaver
}
type UserStore interface {
diff --git a/store/sqlite3.go b/store/sqlite3.go
index a74d7dc..a889547 100644
--- a/store/sqlite3.go
+++ b/store/sqlite3.go
@@ -88,6 +88,30 @@ func (s *Sqlite3) GetHits(d sws.Site, filter map[string]interface{}) ([]*sws.Hit
return hits, nil
}
+func (s *Sqlite3) HitCursor(f func(h *sws.Hit) error) error {
+ sql := `select h.*,
+ua.hash as "ua.hash", ua.name as "ua.name", ua.last_seen_at as "ua.last_seen_at"
+from hits h
+join user_agents ua on h.user_agent_hash = ua.hash`
+
+ rows, err := s.db.Queryx(sql)
+ if err != nil {
+ return err
+ }
+ defer rows.Close()
+
+ for rows.Next() {
+ h := &sws.Hit{}
+ if err := rows.StructScan(h); err != nil {
+ return err
+ }
+ if err := f(h); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
func (s *Sqlite3) SaveHit(h *sws.Hit) error {
if h.UserAgent != nil {
if _, err := s.db.NamedExec(stmts["saveUserAgent"], *h.UserAgent); err != nil {
@@ -141,27 +165,20 @@ func processFilter(sql *string, filter map[string]interface{}) {
}
var stmts = map[string]string{
- "sites": `select id, name, description, aliases, enabled,
-created_at, updated_at
-from sites`,
+ "sites": `select * from sites`,
- "siteByName": `select id, name, description, aliases, enabled,
-created_at, updated_at
-from sites
-where name = $1 limit 1`,
+ "siteByName": `select * from sites where name = $1 limit 1`,
- "siteByID": `select id, name, description, aliases, enabled,
-created_at, updated_at
-from sites
-where id = $1 limit 1`,
+ "siteByID": `select * from sites where id = $1 limit 1`,
"saveSite": `insert into sites (
-name, description, aliases, enabled, created_at, updated_at)
-values (:name, :description, :aliases, :enabled, date('now'), date('now'))
+name, description, aliases, enabled, subdomains, ignore_ips, created_at, updated_at)
+values (:name, :description, :aliases, :enabled, :subdomains, :ignore_ips, date('now'), date('now'))
on conflict(id) do update set
name = :name,
description = :description,
aliases = :aliases,
+subdomains = :subdomains,
updated_at = date('now')`,
"userAgentByHash": `select id, hash, name, last_seen_at from sites