Add spyware module
continuous-integration/drone/push Build is passing Details

This commit is contained in:
DutchEllie 2022-06-25 11:28:37 +02:00
parent 89f5fd178f
commit eb21ce6d8e
Signed by: DutchEllie
SSH Key Fingerprint: SHA256:dKq6ZSgN5E3Viqrw/+xAdf2VdR6hdRGNyrYqXXwfjTY
8 changed files with 174 additions and 15 deletions

62
api/spyware.go Normal file
View File

@ -0,0 +1,62 @@
package api
import (
"log"
"net/http"
"net/http/cookiejar"
"github.com/google/uuid"
"github.com/gorilla/mux"
"golang.org/x/net/publicsuffix"
)
type ApiApplication interface {
NewRouter() *mux.Router
Visit(w http.ResponseWriter, r *http.Request)
}
func NewApiApp() (ApiApplication, error) {
cookiejar, err := cookiejar.New(&cookiejar.Options{PublicSuffixList: publicsuffix.List})
if err != nil {
return nil, err
}
return &apiapp{
cj: cookiejar,
}, nil
}
type apiapp struct {
router mux.Router
cj *cookiejar.Jar
}
func (a *apiapp) NewRouter() *mux.Router {
router := mux.NewRouter()
router.HandleFunc("/visit", a.Visit)
return router
}
// Called when someone visits any page of the website
// Calls for the spyware cookie and sets it if it doesn't yet exist
func (a *apiapp) Visit(w http.ResponseWriter, r *http.Request) {
log.Printf("Visit called\n")
c, err := r.Cookie("spyware")
if err != nil && err != http.ErrNoCookie {
log.Printf("Error: %s\n", err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
} else if err == http.ErrNoCookie {
// Create cookie and send it
log.Printf("No cookie sent by client, sending cookie to them!\n")
c = &http.Cookie{Name: "spyware", Value: uuid.NewString(), MaxAge: 0}
http.SetCookie(w, c)
}
w.WriteHeader(200)
w.Write([]byte("yeet"))
log.Printf("Someone visited: %s\n", c.Value)
}

View File

@ -9,4 +9,6 @@ type Comment struct {
Email string `json:"email,omitempty" bson:"email,omitempty"` Email string `json:"email,omitempty" bson:"email,omitempty"`
Message string `json:"message" bson:"message"` Message string `json:"message" bson:"message"`
PostDate time.Time `json:"time" bson:"time"` PostDate time.Time `json:"time" bson:"time"`
UUID string `json:"uuid" bson:"uuid"`
} }

4
go.mod
View File

@ -3,12 +3,14 @@ module dutchellie.nl/DutchEllie/proper-website-2
go 1.17 go 1.17
require ( require (
github.com/google/uuid v1.3.0
github.com/gorilla/handlers v1.5.1 github.com/gorilla/handlers v1.5.1
github.com/gorilla/mux v1.8.0
github.com/maxence-charriere/go-app/v9 v9.3.3 github.com/maxence-charriere/go-app/v9 v9.3.3
golang.org/x/net v0.0.0-20220622184535-263ec571b305
) )
require ( require (
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/felixge/httpsnoop v1.0.1 // indirect github.com/felixge/httpsnoop v1.0.1 // indirect
github.com/google/uuid v1.3.0 // indirect
) )

8
go.sum
View File

@ -9,6 +9,8 @@ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4=
github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/maxence-charriere/go-app/v9 v9.3.3 h1:vo+1oohWMfTQ0S3eg9JOjuFEy1n3bVNgeDi4eHNfMzA= github.com/maxence-charriere/go-app/v9 v9.3.3 h1:vo+1oohWMfTQ0S3eg9JOjuFEy1n3bVNgeDi4eHNfMzA=
github.com/maxence-charriere/go-app/v9 v9.3.3/go.mod h1:zo0n1kh4OMKn7P+MrTUUi7QwUMU2HOfHsZ293TITtxI= github.com/maxence-charriere/go-app/v9 v9.3.3/go.mod h1:zo0n1kh4OMKn7P+MrTUUi7QwUMU2HOfHsZ293TITtxI=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@ -18,10 +20,16 @@ github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/dl v0.0.0-20190829154251-82a15e2f2ead/go.mod h1:IUMfjQLJQd4UTqG1Z90tenwKoCX93Gn3MAQJMOSBsDQ= golang.org/dl v0.0.0-20190829154251-82a15e2f2ead/go.mod h1:IUMfjQLJQd4UTqG1Z90tenwKoCX93Gn3MAQJMOSBsDQ=
golang.org/x/net v0.0.0-20210415231046-e915ea6b2b7d/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= golang.org/x/net v0.0.0-20210415231046-e915ea6b2b7d/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=
golang.org/x/net v0.0.0-20220622184535-263ec571b305 h1:dAgbJ2SP4jD6XYfMNLVj0BF21jo2PjChrtGaAvF5M3I=
golang.org/x/net v0.0.0-20220622184535-263ec571b305/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=

View File

@ -25,12 +25,15 @@ type guestbook struct {
lastHash [32]byte lastHash [32]byte
gbModalOpen bool gbModalOpen bool
gbErrorModalOpen bool
errorText string
OnSubmit func( OnSubmit func(
ctx app.Context, ctx app.Context,
name string, name string,
email string, email string,
website string, website string,
message string, message string,
uuid string,
) // Handler to implement which calls the api ) // Handler to implement which calls the api
} }
@ -138,19 +141,42 @@ func (g guestbook) Render() app.UI {
g.gbModalOpen = true g.gbModalOpen = true
return return
} }
g.OnSubmit(ctx, g.name, g.email, g.website, g.message) var uuid string = ""
c := client.Jar.Cookies(app.Window().URL())
for _, c2 := range c {
if c2.Name == "spyware" {
uuid = c2.Value
}
}
// Check if uuid is set, if it's not, then clearly the cookie does not exist
if uuid == "" {
uuid = "undetermined"
g.gbErrorModalOpen = true
return
}
g.OnSubmit(ctx, g.name, g.email, g.website, g.message, uuid)
g.clear() g.clear()
ctx.NewAction("guestbook-loadcomments") ctx.NewAction("guestbook-loadcomments")
//g.LoadComments(ctx) //g.LoadComments(ctx)
}), }),
app.If( app.If(
g.gbModalOpen, g.gbModalOpen,
&guestbookAlertModal{ NewGuestbookAlertModal().
OnClose: func() { OnClose(func() {
g.gbModalOpen = false g.gbModalOpen = false
g.Update() g.Update()
}, }).
}, Text("Your name must be <= 40 and your message must be <= 360 characters"),
),
app.If(
g.gbErrorModalOpen,
NewGuestbookAlertModal().
OnClose(func() {
g.gbModalOpen = false
g.Update()
}).
Text(fmt.Sprintf("Error placing comment: %s", g.errorText)),
), ),
app.Div().Body( app.Div().Body(
app.Range(g.comments).Slice(func(i int) app.UI { app.Range(g.comments).Slice(func(i int) app.UI {
@ -292,7 +318,22 @@ type guestbookAlertModal struct {
app.Compo app.Compo
PreviousAttempts int PreviousAttempts int
OnClose func() // For when we close the modal IOnClose func() // For when we close the modal
IText string
}
func NewGuestbookAlertModal() *guestbookAlertModal {
return &guestbookAlertModal{}
}
func (g *guestbookAlertModal) OnClose(v func()) *guestbookAlertModal {
g.IOnClose = v
return g
}
func (g *guestbookAlertModal) Text(v string) *guestbookAlertModal {
g.IText = v
return g
} }
func (g *guestbookAlertModal) Render() app.UI { func (g *guestbookAlertModal) Render() app.UI {
@ -300,7 +341,7 @@ func (g *guestbookAlertModal) Render() app.UI {
Class("gb-modal"). Class("gb-modal").
ID("gbModal"). ID("gbModal").
OnClick(func(ctx app.Context, e app.Event) { OnClick(func(ctx app.Context, e app.Event) {
g.OnClose() g.IOnClose()
}). }).
Body( Body(
app.Div(). app.Div().
@ -310,9 +351,9 @@ func (g *guestbookAlertModal) Render() app.UI {
OnClick(func(ctx app.Context, e app.Event) { OnClick(func(ctx app.Context, e app.Event) {
//modal := app.Window().GetElementByID("gbModal") //modal := app.Window().GetElementByID("gbModal")
//modal.Set("style", "none") //modal.Set("style", "none")
g.OnClose() g.IOnClose()
}), }),
app.P().Text("Your name must be <= 40 and your message must be <= 360 characters"), app.P().Text(g.IText),
), ),
) )
} }

View File

@ -41,12 +41,13 @@ func (p *Homepage) Render() app.UI {
Class("contentblock"). Class("contentblock").
UI( UI(
&guestbook{ &guestbook{
OnSubmit: func(ctx app.Context, name, email, website, message string) { OnSubmit: func(ctx app.Context, name, email, website, message, uuid string) {
var comment entity.Comment var comment entity.Comment
comment.Name = name comment.Name = name
comment.Email = email comment.Email = email
comment.Website = website comment.Website = website
comment.Message = message comment.Message = message
comment.UUID = uuid
jsondata, err := json.Marshal(comment) jsondata, err := json.Marshal(comment)
if err != nil { if err != nil {

View File

@ -4,8 +4,10 @@ import (
"compress/gzip" "compress/gzip"
"log" "log"
"net/http" "net/http"
"net/http/cookiejar"
"os" "os"
"dutchellie.nl/DutchEllie/proper-website-2/api"
"github.com/gorilla/handlers" "github.com/gorilla/handlers"
"github.com/maxence-charriere/go-app/v9/pkg/app" "github.com/maxence-charriere/go-app/v9/pkg/app"
) )
@ -16,7 +18,21 @@ import (
// collection *mongo.Collection // collection *mongo.Collection
//} //}
var jar http.CookieJar
var client http.Client
func main() { func main() {
// Create cookiejar
var err error
jar, err = cookiejar.New(nil)
if err != nil {
log.Fatalf("Error creating cookiejar: %s\n", err.Error())
}
client = http.Client{
Jar: jar,
}
homepage := NewHomepage() homepage := NewHomepage()
aboutpage := NewAboutPage() aboutpage := NewAboutPage()
galaxiespage := NewGalaxiesPage() galaxiespage := NewGalaxiesPage()
@ -92,7 +108,17 @@ func main() {
app.GenerateStaticWebsite("./staticsite", handler) app.GenerateStaticWebsite("./staticsite", handler)
compressed := handlers.CompressHandlerLevel(handler, gzip.BestSpeed) compressed := handlers.CompressHandlerLevel(handler, gzip.BestSpeed)
// Create spyware module
spywareapi, err := api.NewApiApp()
if err != nil {
log.Fatal(err)
}
http.Handle("/", compressed) http.Handle("/", compressed)
http.HandleFunc("/api/visit", spywareapi.Visit)
// router.HandleFunc("/api/visit", spywareapi.Visit)
if os.Getenv("GEN_STATIC_SITE") == "true" { if os.Getenv("GEN_STATIC_SITE") == "true" {
return return
} }

View File

@ -1,6 +1,10 @@
package main package main
import "github.com/maxence-charriere/go-app/v9/pkg/app" import (
"fmt"
"github.com/maxence-charriere/go-app/v9/pkg/app"
)
// Page is a generic page. By default it has a header, navbar and a default leftbar // Page is a generic page. By default it has a header, navbar and a default leftbar
type page struct { type page struct {
@ -54,6 +58,19 @@ func (p *page) Main(v ...app.UI) *page {
func (p *page) OnMount(ctx app.Context) { func (p *page) OnMount(ctx app.Context) {
ctx.Handle("right-hide", p.hideRight) ctx.Handle("right-hide", p.hideRight)
ctx.Handle("right-show", p.showRight) ctx.Handle("right-show", p.showRight)
// Send a visit request to the spyware API to track people
ctx.Async(func() {
resp, err := client.Get("/api/visit")
if err != nil {
app.Logf("Error while creating vist request %s\n", err.Error())
}
defer resp.Body.Close()
c := resp.Cookies()
fmt.Printf("c: %v\n", c)
})
} }
func (p *page) Render() app.UI { func (p *page) Render() app.UI {