add domain authentication handling, start wm PUT
This commit is contained in:
parent
f74c0c6e5b
commit
9f6450e367
|
@ -3,18 +3,20 @@ package app
|
|||
|
||||
import (
|
||||
"github.com/wgroeneveld/go-jamming/app/index"
|
||||
"github.com/wgroeneveld/go-jamming/app/webmention"
|
||||
"github.com/wgroeneveld/go-jamming/app/pingback"
|
||||
"github.com/wgroeneveld/go-jamming/app/webmention"
|
||||
)
|
||||
|
||||
// stole ideas from https://pace.dev/blog/2018/05/09/how-I-write-http-services-after-eight-years.html
|
||||
// not that contempt with passing conf, but can't create receivers on non-local types, and won't move specifics into package app
|
||||
// https://blog.questionable.services/article/http-handler-error-handling-revisited/ is the better idea, but more work
|
||||
func (s *server) routes() {
|
||||
s.router.HandleFunc("/", index.Handle(s.conf)).Methods("GET")
|
||||
s.router.HandleFunc("/pingback", pingback.HandlePost(s.conf)).Methods("POST")
|
||||
s.router.HandleFunc("/webmention", webmention.HandlePost(s.conf)).Methods("POST")
|
||||
s.router.HandleFunc("/webmention/{domain}/{token}", s.authorizedOnly(webmention.HandleGet(s.conf))).Methods("GET")
|
||||
s.router.HandleFunc("/webmention/{domain}/{token}", s.authorizedOnly(webmention.HandlePut(s.conf))).Methods("PUT")
|
||||
cnf := s.conf
|
||||
|
||||
s.router.HandleFunc("/", index.Handle(cnf)).Methods("GET")
|
||||
s.router.HandleFunc("/pingback", pingback.HandlePost(cnf)).Methods("POST")
|
||||
s.router.HandleFunc("/webmention", webmention.HandlePost(cnf)).Methods("POST")
|
||||
s.router.HandleFunc("/webmention/{domain}/{token}", s.authorizedOnly(webmention.HandleGet(cnf))).Methods("GET")
|
||||
s.router.HandleFunc("/webmention/{domain}/{token}", s.authorizedOnly(webmention.HandlePut(cnf))).Methods("PUT")
|
||||
}
|
||||
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
package app
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/wgroeneveld/go-jamming/common"
|
||||
|
||||
|
@ -22,7 +22,7 @@ func unauthorized(w http.ResponseWriter, r *http.Request) { http.Error(w, "401 u
|
|||
func (s *server) authorizedOnly(h http.HandlerFunc) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
if vars["token"] != s.conf.Token {
|
||||
if vars["token"] != s.conf.Token || !s.conf.IsAnAllowedDomain(vars["domain"]) {
|
||||
unauthorized(w, r)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
package app
|
||||
|
||||
import (
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/wgroeneveld/go-jamming/common"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var conf = &common.Config{
|
||||
Token: "boemsjakkalakka",
|
||||
AllowedWebmentionSources: []string{ "http://ewelja.be" },
|
||||
}
|
||||
|
||||
func TestAuthorizedOnlyUnauthorizedWithWrongToken(t *testing.T) {
|
||||
srv := &server{
|
||||
conf: conf,
|
||||
}
|
||||
|
||||
passed := false
|
||||
handler := srv.authorizedOnly(func(writer http.ResponseWriter, request *http.Request) {
|
||||
passed = true
|
||||
})
|
||||
r, _ := http.NewRequest("PUT", "/whatever", nil)
|
||||
w := httptest.NewRecorder()
|
||||
r = mux.SetURLVars(r, map[string]string{
|
||||
"token": "invalid",
|
||||
"domain": conf.AllowedWebmentionSources[0],
|
||||
})
|
||||
|
||||
handler(w, r)
|
||||
assert.False(t, passed, "should not have called unauthorized func")
|
||||
}
|
||||
|
||||
func TestAuthorizedOnlyUnauthorizedWithWrongDomain(t *testing.T) {
|
||||
srv := &server{
|
||||
conf: conf,
|
||||
}
|
||||
|
||||
passed := false
|
||||
handler := srv.authorizedOnly(func(writer http.ResponseWriter, request *http.Request) {
|
||||
passed = true
|
||||
})
|
||||
r, _ := http.NewRequest("PUT", "/whatever", nil)
|
||||
w := httptest.NewRecorder()
|
||||
r = mux.SetURLVars(r, map[string]string{
|
||||
"token": conf.Token,
|
||||
"domain": "https://sexymoddafokkas.be",
|
||||
})
|
||||
|
||||
handler(w, r)
|
||||
assert.False(t, passed, "should not have called unauthorized func")
|
||||
}
|
||||
|
||||
func TestAuthorizedOnlyOkIfTokenAndDomainMatch(t *testing.T) {
|
||||
srv := &server{
|
||||
conf: conf,
|
||||
}
|
||||
|
||||
passed := false
|
||||
handler := srv.authorizedOnly(func(writer http.ResponseWriter, request *http.Request) {
|
||||
passed = true
|
||||
})
|
||||
r, _ := http.NewRequest("PUT", "/whatever", nil)
|
||||
w := httptest.NewRecorder()
|
||||
r = mux.SetURLVars(r, map[string]string{
|
||||
"token": conf.Token,
|
||||
"domain": conf.AllowedWebmentionSources[0],
|
||||
})
|
||||
|
||||
handler(w, r)
|
||||
assert.True(t, passed, "should have passed authentication!")
|
||||
}
|
|
@ -2,15 +2,19 @@
|
|||
package webmention
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/wgroeneveld/go-jamming/app/mf"
|
||||
"github.com/wgroeneveld/go-jamming/app/webmention/receive"
|
||||
"github.com/wgroeneveld/go-jamming/app/webmention/send"
|
||||
"net/http"
|
||||
"fmt"
|
||||
|
||||
"github.com/wgroeneveld/go-jamming/common"
|
||||
"github.com/wgroeneveld/go-jamming/rest"
|
||||
)
|
||||
|
||||
var httpClient = &rest.HttpClient{}
|
||||
|
||||
func HandleGet(conf *common.Config) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Println("handling get")
|
||||
|
@ -19,13 +23,28 @@ func HandleGet(conf *common.Config) http.HandlerFunc {
|
|||
|
||||
func HandlePut(conf *common.Config) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Println("handling put")
|
||||
since := getSinceQueryParam(r)
|
||||
domain := mux.Vars(r)["domain"]
|
||||
|
||||
snder := send.Sender{
|
||||
RestClient: httpClient,
|
||||
Conf: conf,
|
||||
}
|
||||
go snder.Send(domain, since)
|
||||
rest.Accept(w)
|
||||
}
|
||||
}
|
||||
|
||||
func getSinceQueryParam(r *http.Request) string {
|
||||
sinceParam, _ := r.URL.Query()["since"]
|
||||
since := ""
|
||||
if len(sinceParam) > 0 {
|
||||
since = sinceParam[0]
|
||||
}
|
||||
return since
|
||||
}
|
||||
|
||||
func HandlePost(conf *common.Config) http.HandlerFunc {
|
||||
httpClient := &rest.HttpClient{}
|
||||
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
r.ParseForm()
|
||||
if !validate(r, r.Header, conf) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package send
|
||||
|
||||
import (
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/wgroeneveld/go-jamming/app/mf"
|
||||
"github.com/wgroeneveld/go-jamming/app/pingback/send"
|
||||
"github.com/wgroeneveld/go-jamming/common"
|
||||
|
@ -12,6 +13,10 @@ type Sender struct {
|
|||
Conf *common.Config
|
||||
}
|
||||
|
||||
func (snder *Sender) Send(domain string, since string) {
|
||||
log.Info().Str("domain", domain).Str("since", since).Msg(` OK: someone wants to send mentions`)
|
||||
}
|
||||
|
||||
func mention() {
|
||||
pingbackSender := &send.Sender{
|
||||
RestClient: nil,
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"strconv"
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
|
@ -19,6 +19,15 @@ type Config struct {
|
|||
DisallowedWebmentionDomains []string
|
||||
}
|
||||
|
||||
func (c *Config) IsAnAllowedDomain(url string) bool {
|
||||
for _, domain := range c.AllowedWebmentionSources {
|
||||
if domain == url {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *Config) FetchDomain(url string) (string, error) {
|
||||
for _, domain := range c.AllowedWebmentionSources {
|
||||
if strings.Contains(url, domain) {
|
||||
|
|
|
@ -2,5 +2,6 @@ package common
|
|||
|
||||
import "time"
|
||||
|
||||
// I know it's public. Not sure how to handle this in tests, package-independent
|
||||
// https://labs.yulrizka.com/en/stubbing-time-dot-now-in-golang/
|
||||
// None of the above are very appealing. For now, just use the lazy way.
|
||||
var Now = time.Now
|
||||
|
|
Loading…
Reference in New Issue