more verification according to standard
This commit is contained in:
parent
691158cd0e
commit
76633aaf89
|
@ -85,6 +85,24 @@ func userWebmentionHandler(repo *owl.Repository) func(http.ResponseWriter, *http
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(target[0]) < 7 || (target[0][:7] != "http://" && target[0][:8] != "https://") {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
w.Write([]byte("Not a valid target"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(source[0]) < 7 || (source[0][:7] != "http://" && source[0][:8] != "https://") {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
w.Write([]byte("Not a valid source"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if source[0] == target[0] {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
w.Write([]byte("target and source are equal"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
parts := strings.Split(target[0], "/")
|
parts := strings.Split(target[0], "/")
|
||||||
if len(parts) < 2 {
|
if len(parts) < 2 {
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package main_test
|
package main_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"h4kor/owl-blogs"
|
||||||
main "h4kor/owl-blogs/cmd/owl-web"
|
main "h4kor/owl-blogs/cmd/owl-web"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
|
@ -10,6 +11,36 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func setupWebmentionTest(repo owl.Repository, user owl.User, target string, source string) (*httptest.ResponseRecorder, error) {
|
||||||
|
|
||||||
|
data := url.Values{}
|
||||||
|
data.Set("target", target)
|
||||||
|
data.Set("source", source)
|
||||||
|
|
||||||
|
// Create Request and Response
|
||||||
|
req, err := http.NewRequest("POST", user.UrlPath()+"webmention/", strings.NewReader(data.Encode()))
|
||||||
|
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
req.Header.Add("Content-Length", strconv.Itoa(len(data.Encode())))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
router := main.Router(&repo)
|
||||||
|
router.ServeHTTP(rr, req)
|
||||||
|
|
||||||
|
return rr, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func assertStatus(t *testing.T, rr *httptest.ResponseRecorder, expStatus int) {
|
||||||
|
if status := rr.Code; status != expStatus {
|
||||||
|
t.Errorf("handler returned wrong status code: got %v want %v",
|
||||||
|
status, expStatus)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestWebmentionHandleAccepts(t *testing.T) {
|
func TestWebmentionHandleAccepts(t *testing.T) {
|
||||||
repo := getTestRepo()
|
repo := getTestRepo()
|
||||||
user, _ := repo.CreateUser("test-1")
|
user, _ := repo.CreateUser("test-1")
|
||||||
|
@ -17,62 +48,118 @@ func TestWebmentionHandleAccepts(t *testing.T) {
|
||||||
|
|
||||||
target := post.FullUrl()
|
target := post.FullUrl()
|
||||||
source := "https://example.com"
|
source := "https://example.com"
|
||||||
data := url.Values{}
|
|
||||||
data.Set("target", target)
|
|
||||||
data.Set("source", source)
|
|
||||||
|
|
||||||
// Create Request and Response
|
|
||||||
req, err := http.NewRequest("POST", user.UrlPath()+"webmention/", strings.NewReader(data.Encode()))
|
|
||||||
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
|
||||||
req.Header.Add("Content-Length", strconv.Itoa(len(data.Encode())))
|
|
||||||
|
|
||||||
|
rr, err := setupWebmentionTest(repo, user, target, source)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
rr := httptest.NewRecorder()
|
|
||||||
router := main.Router(&repo)
|
|
||||||
router.ServeHTTP(rr, req)
|
|
||||||
|
|
||||||
// Check the status code is what we expect.
|
assertStatus(t, rr, http.StatusAccepted)
|
||||||
if status := rr.Code; status != http.StatusAccepted {
|
|
||||||
t.Errorf("handler returned wrong status code: got %v want %v",
|
|
||||||
status, http.StatusAccepted)
|
|
||||||
t.Errorf("Body: %v", rr.Body)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestWebmentionWrittenToPost(t *testing.T) {
|
func TestWebmentionWrittenToPost(t *testing.T) {
|
||||||
|
|
||||||
repo := getTestRepo()
|
repo := getTestRepo()
|
||||||
user, _ := repo.CreateUser("test-1")
|
user, _ := repo.CreateUser("test-1")
|
||||||
post, _ := user.CreateNewPost("post-1")
|
post, _ := user.CreateNewPost("post-1")
|
||||||
|
|
||||||
target := post.FullUrl()
|
target := post.FullUrl()
|
||||||
source := "https://example.com"
|
source := "https://example.com"
|
||||||
data := url.Values{}
|
|
||||||
data.Set("target", target)
|
|
||||||
data.Set("source", source)
|
|
||||||
|
|
||||||
// Create Request and Response
|
rr, err := setupWebmentionTest(repo, user, target, source)
|
||||||
req, err := http.NewRequest("POST", user.UrlPath()+"webmention/", strings.NewReader(data.Encode()))
|
|
||||||
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
|
||||||
req.Header.Add("Content-Length", strconv.Itoa(len(data.Encode())))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
rr := httptest.NewRecorder()
|
|
||||||
router := main.Router(&repo)
|
|
||||||
router.ServeHTTP(rr, req)
|
|
||||||
|
|
||||||
// Check the status code is what we expect.
|
// Check the status code is what we expect.
|
||||||
if status := rr.Code; status != http.StatusAccepted {
|
assertStatus(t, rr, http.StatusAccepted)
|
||||||
t.Errorf("handler returned wrong status code: got %v want %v",
|
|
||||||
status, http.StatusAccepted)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(post.Webmentions()) != 1 {
|
if len(post.Webmentions()) != 1 {
|
||||||
t.Errorf("no webmention written to post")
|
t.Errorf("no webmention written to post")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// https://www.w3.org/TR/webmention/#h-request-verification
|
||||||
|
//
|
||||||
|
|
||||||
|
// The receiver MUST check that source and target are valid URLs [URL]
|
||||||
|
// and are of schemes that are supported by the receiver.
|
||||||
|
// (Most commonly this means checking that the source and target schemes are http or https).
|
||||||
|
func TestWebmentionSourceValidation(t *testing.T) {
|
||||||
|
|
||||||
|
repo := getTestRepo()
|
||||||
|
user, _ := repo.CreateUser("test-1")
|
||||||
|
post, _ := user.CreateNewPost("post-1")
|
||||||
|
|
||||||
|
target := post.FullUrl()
|
||||||
|
source := "ftp://example.com"
|
||||||
|
|
||||||
|
rr, err := setupWebmentionTest(repo, user, target, source)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
assertStatus(t, rr, http.StatusBadRequest)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWebmentionTargetValidation(t *testing.T) {
|
||||||
|
|
||||||
|
repo := getTestRepo()
|
||||||
|
user, _ := repo.CreateUser("test-1")
|
||||||
|
post, _ := user.CreateNewPost("post-1")
|
||||||
|
|
||||||
|
target := "ftp://example.com"
|
||||||
|
source := post.FullUrl()
|
||||||
|
|
||||||
|
rr, err := setupWebmentionTest(repo, user, target, source)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
assertStatus(t, rr, http.StatusBadRequest)
|
||||||
|
}
|
||||||
|
|
||||||
|
// The receiver MUST reject the request if the source URL is the same as the target URL.
|
||||||
|
|
||||||
|
func TestWebmentionSameTargetAndSource(t *testing.T) {
|
||||||
|
|
||||||
|
repo := getTestRepo()
|
||||||
|
user, _ := repo.CreateUser("test-1")
|
||||||
|
post, _ := user.CreateNewPost("post-1")
|
||||||
|
|
||||||
|
target := post.FullUrl()
|
||||||
|
source := post.FullUrl()
|
||||||
|
|
||||||
|
rr, err := setupWebmentionTest(repo, user, target, source)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
assertStatus(t, rr, http.StatusBadRequest)
|
||||||
|
}
|
||||||
|
|
||||||
|
// The receiver SHOULD check that target is a valid resource for which it can accept Webmentions.
|
||||||
|
// This check SHOULD happen synchronously to reject invalid Webmentions before more in-depth verification begins.
|
||||||
|
// What a "valid resource" means is up to the receiver.
|
||||||
|
func TestValidationOfTarget(t *testing.T) {
|
||||||
|
repo := getTestRepo()
|
||||||
|
user, _ := repo.CreateUser("test-1")
|
||||||
|
post, _ := user.CreateNewPost("post-1")
|
||||||
|
|
||||||
|
target := post.FullUrl()
|
||||||
|
target = target[:len(target)-1] + "invalid"
|
||||||
|
source := post.FullUrl()
|
||||||
|
|
||||||
|
rr, err := setupWebmentionTest(repo, user, target, source)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
assertStatus(t, rr, http.StatusNotFound)
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// https://www.w3.org/TR/webmention/#h-webmention-verification
|
||||||
|
//
|
||||||
|
|
Loading…
Reference in New Issue