diff --git a/bot/web/web.go b/bot/web/web.go index 9cf2f40..53c8423 100644 --- a/bot/web/web.go +++ b/bot/web/web.go @@ -11,6 +11,8 @@ import ( "net/http" "strings" "time" + + httpin_integration "github.com/ggicci/httpin/integration" ) type Web struct { @@ -77,6 +79,8 @@ func (ws *Web) setupHTTP() { ws.router.Use(middleware.Recoverer) ws.router.Use(middleware.StripSlashes) + httpin_integration.UseGochiURLParam("path", chi.URLParam) + ws.router.HandleFunc("/", ws.serveRoot) ws.router.HandleFunc("/nav", ws.serveNav) ws.router.HandleFunc("/navHTML", ws.serveNavHTML) diff --git a/go.mod b/go.mod index 7da16b4..a149c20 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,8 @@ require ( github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90 github.com/forPelevin/gomoji v1.1.6 github.com/gabriel-vasile/mimetype v1.4.1 - github.com/go-chi/chi/v5 v5.0.7 + github.com/ggicci/httpin v0.16.0 + github.com/go-chi/chi/v5 v5.0.11 github.com/go-chi/httprate v0.7.0 github.com/gocolly/colly v1.2.0 github.com/google/uuid v1.3.0 @@ -32,7 +33,7 @@ require ( github.com/olebedev/when v0.0.0-20190311101825-c3b538a97254 github.com/rs/zerolog v1.28.0 github.com/slack-go/slack v0.11.3 - github.com/stretchr/testify v1.8.2 + github.com/stretchr/testify v1.8.4 github.com/trubitsyn/go-zero-width v1.0.1 github.com/velour/velour v0.0.0-20160303155839-8e090e68d158 golang.org/x/crypto v0.14.0 @@ -57,6 +58,7 @@ require ( github.com/dustin/go-jsonpointer v0.0.0-20160814072949-ba0abeacc3dc // indirect github.com/dustin/gojson v0.0.0-20160307161227-2e71ec9dd5ad // indirect github.com/garyburd/go-oauth v0.0.0-20180319155456-bca2e7f09a17 // indirect + github.com/ggicci/owl v0.7.0 // indirect github.com/go-stack/stack v1.8.0 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/golang-jwt/jwt v3.2.1+incompatible // indirect diff --git a/go.sum b/go.sum index c6f7b50..695ef9e 100644 --- a/go.sum +++ b/go.sum @@ -120,9 +120,13 @@ github.com/gabriel-vasile/mimetype v1.4.1 h1:TRWk7se+TOjCYgRth7+1/OYLNiRNIotknkF github.com/gabriel-vasile/mimetype v1.4.1/go.mod h1:05Vi0w3Y9c/lNvJOdmIwvrrAhX3rYhfQQCaf9VJcv7M= github.com/garyburd/go-oauth v0.0.0-20180319155456-bca2e7f09a17 h1:GOfMz6cRgTJ9jWV0qAezv642OhPnKEG7gtUjJSdStHE= github.com/garyburd/go-oauth v0.0.0-20180319155456-bca2e7f09a17/go.mod h1:HfkOCN6fkKKaPSAeNq/er3xObxTW4VLeY6UUK895gLQ= +github.com/ggicci/httpin v0.16.0 h1:ZR6RXH1xNWg39xqM33V7iz7PP/GuR7vc3aHa2g5mWo4= +github.com/ggicci/httpin v0.16.0/go.mod h1:whE/5nx1jCp//UQ6rgNpq2WNxOr9FV0OpxMnQQC0Xvs= +github.com/ggicci/owl v0.7.0 h1:+AMlCR0AY7j72q7hjtN4pm8VJiikwpROtMgvPnXtuik= +github.com/ggicci/owl v0.7.0/go.mod h1:TRPWshRwYej6uES//YW5aNgLB370URwyta1Ytfs7KXs= github.com/go-chi/chi v1.5.4 h1:QHdzF2szwjqVV4wmByUnTcsbIg7UGaQ0tPF2t5GcAIs= -github.com/go-chi/chi/v5 v5.0.7 h1:rDTPXLDHGATaeHvVlLcR4Qe0zftYethFucbjVQ1PxU8= -github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/go-chi/chi/v5 v5.0.11 h1:BnpYbFZ3T3S1WMpD79r7R5ThWX40TaFB7L31Y8xqSwA= +github.com/go-chi/chi/v5 v5.0.11/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-chi/httprate v0.7.0 h1:8W0dF7Xa2Duz2p8ncGaehIphrxQGNlOtoGY0+NRRfjQ= github.com/go-chi/httprate v0.7.0/go.mod h1:6GOYBSwnpra4CQfAKXu8sQZg+nZ0M1g9QnyFvxrAB8A= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= @@ -215,6 +219,7 @@ 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/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= @@ -252,6 +257,7 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/justinas/alice v1.2.0 h1:+MHSA/vccVCF4Uq37S42jwlkvI2Xzl7zTPCN5BnZNVo= github.com/kennygrant/sanitize v1.2.4 h1:gN25/otpP5vAsO2djbMhF/LQX6R7+O1TB4yv8NzpJ3o= github.com/kennygrant/sanitize v1.2.4/go.mod h1:LGsjYYtgxbetdg5owWB2mpgUL6e2nfw2eObZ0u0qvak= github.com/kevinburke/go-types v0.0.0-20200309064045-f2d4aea18a7a h1:Z7+SSApKiwPjNic+NF9+j7h657Uyvdp/jA3iTKhpj4E= @@ -372,8 +378,8 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/temoto/robotstxt v1.1.1 h1:Gh8RCs8ouX3hRSxxK7B1mO5RFByQ4CmJZDwgom++JaA= github.com/temoto/robotstxt v1.1.1/go.mod h1:+1AmkuG3IYkh1kv0d2qEB9Le88ehNO0zwOr3ujewlOo= github.com/trubitsyn/go-zero-width v1.0.1 h1:AAZhtyGXW79T5BouAF0R9FtDhGcp7IGbLZo2Id3N+m8= diff --git a/plugins/counter/api.go b/plugins/counter/api.go index 2aac9dc..99f86be 100644 --- a/plugins/counter/api.go +++ b/plugins/counter/api.go @@ -3,10 +3,8 @@ package counter import ( "encoding/json" "fmt" - "io" + "github.com/ggicci/httpin" "net/http" - "net/url" - "strconv" "time" "github.com/go-chi/chi/v5" @@ -23,34 +21,48 @@ func (p *CounterPlugin) registerWeb() { dur := time.Duration(seconds) * time.Second subrouter := chi.NewRouter() subrouter.Use(httprate.LimitByIP(requests, dur)) - subrouter.HandleFunc("/api/users/{user}/items/{item}/increment/{delta}", p.mkIncrementByNAPI(1)) - subrouter.HandleFunc("/api/users/{user}/items/{item}/decrement/{delta}", p.mkIncrementByNAPI(-1)) - subrouter.HandleFunc("/api/users/{user}/items/{item}/increment", p.mkIncrementByNAPI(1)) - subrouter.HandleFunc("/api/users/{user}/items/{item}/decrement", p.mkIncrementByNAPI(-1)) + subrouter.With(httpin.NewInput(CounterChangeReq{})). + HandleFunc("/api/users/{user}/items/{item}/increment/{delta}", p.mkIncrementByNAPI(1)) + subrouter.With(httpin.NewInput(CounterChangeReq{})). + HandleFunc("/api/users/{user}/items/{item}/decrement/{delta}", p.mkIncrementByNAPI(-1)) + subrouter.With(httpin.NewInput(CounterChangeReq{})). + HandleFunc("/api/users/{user}/items/{item}/increment", p.mkIncrementByNAPI(1)) + subrouter.With(httpin.NewInput(CounterChangeReq{})). + HandleFunc("/api/users/{user}/items/{item}/decrement", p.mkIncrementByNAPI(-1)) r.Mount("/", subrouter) - r.HandleFunc("/users/{user}/items/{item}/increment", p.incHandler(1)) - r.HandleFunc("/users/{user}/items/{item}/decrement", p.incHandler(-1)) + r.With(httpin.NewInput(CounterChangeReq{})). + HandleFunc("/users/{user}/items/{item}/increment", p.incHandler(1)) + r.With(httpin.NewInput(CounterChangeReq{})). + HandleFunc("/users/{user}/items/{item}/decrement", p.incHandler(-1)) r.HandleFunc("/", p.handleCounter) p.b.GetWeb().RegisterWebName(r, "/counter", "Counter") } +type CounterChangeReq struct { + UserName string `in:"path=user"` + Item string `in:"path=item"` + Password string `in:"form=password"` + Delta int `in:"path=delta"` + Body struct { + Message string `json:"message"` + } `in:"body=json"` +} + func (p *CounterPlugin) incHandler(delta int) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - userName, _ := url.QueryUnescape(chi.URLParam(r, "user")) - itemName, _ := url.QueryUnescape(chi.URLParam(r, "item")) - pass := r.FormValue("password") - if !p.b.CheckPassword("", pass) { + input := r.Context().Value(httpin.Input).(*CounterChangeReq) + if !p.b.CheckPassword("", input.Password) { w.WriteHeader(401) fmt.Fprintf(w, "error") return } - item, err := p.delta(userName, itemName, "", delta) + item, err := p.delta(input.UserName, input.Item, "", delta) if err != nil { w.WriteHeader(500) fmt.Fprintf(w, "error") return } - p.renderItem(userName, item).Render(r.Context(), w) + p.renderItem(input.UserName, item).Render(r.Context(), w) } } @@ -103,13 +115,11 @@ func (p *CounterPlugin) delta(userName, itemName, personalMessage string, delta func (p *CounterPlugin) mkIncrementByNAPI(direction int) func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) { - userName, _ := url.QueryUnescape(chi.URLParam(r, "user")) - itemName, _ := url.QueryUnescape(chi.URLParam(r, "item")) - delta, err := strconv.Atoi(chi.URLParam(r, "delta")) - if err != nil || delta == 0 { - delta = direction + input := r.Context().Value(httpin.Input).(*CounterChangeReq) + if input.Delta == 0 { + input.Delta = direction } else { - delta = delta * direction + input.Delta = input.Delta * direction } secret, pass, ok := r.BasicAuth() @@ -127,15 +137,12 @@ func (p *CounterPlugin) mkIncrementByNAPI(direction int) func(w http.ResponseWri return } - body, _ := io.ReadAll(r.Body) - postData := map[string]string{} - err = json.Unmarshal(body, &postData) personalMsg := "" - if inputMsg, ok := postData["message"]; ok { - personalMsg = fmt.Sprintf("\nMessage: %s", inputMsg) + if input.Body.Message != "" { + personalMsg = fmt.Sprintf("\nMessage: %s", input.Body.Message) } - if _, err := p.delta(userName, itemName, personalMsg, delta*direction); err != nil { + if _, err := p.delta(input.UserName, input.Item, personalMsg, input.Delta*direction); err != nil { log.Error().Err(err).Msg("error finding item") w.WriteHeader(400) j, _ := json.Marshal(struct { diff --git a/plugins/counter/index.html b/plugins/counter/index.html deleted file mode 100644 index 1a5d436..0000000 --- a/plugins/counter/index.html +++ /dev/null @@ -1,104 +0,0 @@ - - - - - - - - - - - - - - Counters - - - -
- - Counters - - {{ item.name }} - - - - {{ err }} - - - - Password: - - - - {{ user }}: - - - - {{ thing }}: - - - {{ count }} - - - - - - - - - -
- - - -