Commit c5404482 authored by Lukas Matt's avatar Lukas Matt Committed by GitHub

Merge pull request #4 from ganggo/webfinger

Implement new webfinger discovery method
parents 2b8153b7 ef10bfbf
......@@ -2,13 +2,9 @@ language: go
sudo: false
go:
- 1.8.x
before_install:
install:
- go get -t -v ./...
script: |
go test -v -race -coverprofile=p.out -covermode=atomic
[ -f p.out ] && cat p.out >> coverage.txt || echo "" > coverage.txt
script:
- go test -v -race -coverprofile=coverage.txt -covermode=atomic
after_success:
- bash <(curl -s https://codecov.io/bash)
......@@ -69,7 +69,11 @@ func push(host, endpoint, proto, contentType string, body io.Reader) error {
}
func FetchJson(method, url string, body io.Reader, result interface{}) error {
req, err := http.NewRequest(method, url, body)
var proto string
if !strings.HasPrefix(url, "http") {
proto = "https://"
}
req, err := http.NewRequest(method, proto + url, body)
if err != nil {
return err
}
......@@ -80,6 +84,9 @@ func FetchJson(method, url string, body io.Reader, result interface{}) error {
}
resp, err := client.Do(req)
if err != nil {
if !strings.HasPrefix(url, "http") {
return FetchJson(method, "http://" + url, body, result)
}
return err
}
......
......@@ -23,6 +23,7 @@ import (
"net/http/httptest"
"testing"
"encoding/xml"
"io/ioutil"
)
type Test struct {
......@@ -86,6 +87,22 @@ func TestFetchJson(t *testing.T) {
t.Errorf("Some error occured while sending: %v", err)
}
err = FetchJson("GET", ts.URL, nil, nil)
if err == nil {
t.Errorf("Web request without result struct should throw an error")
}
// run without protocol
err = FetchJson("GET", ts.URL[7:], nil, &res)
if err != nil {
t.Errorf("Some error occured while sending: %v", err)
}
err = FetchJson("GET", "https://" + ts.URL[7:], nil, &res)
if err == nil {
t.Errorf("HTTPS should fail since we do not have ssl enabled")
}
if res.A != "a" || res.B != "b" {
t.Errorf("Expected to be a and b, got %s and %s", res.A, res.B)
}
......@@ -99,12 +116,64 @@ func TestFetchXml(t *testing.T) {
defer ts.Close()
var res Test
err := FetchXml("GET", ts.URL, nil, &res)
err := FetchXml("GET", ts.URL, nil, nil)
if err == nil {
t.Errorf("Web request without result struct should throw an error")
}
err = FetchXml("GET", ts.URL, nil, &res)
if err != nil {
t.Errorf("Some error occured while sending: %v", err)
}
// run without protocol
err = FetchXml("GET", ts.URL[7:], nil, &res)
if err != nil {
t.Errorf("Some error occured while sending: %v", err)
}
err = FetchXml("GET", "https://" + ts.URL[7:], nil, &res)
if err == nil {
t.Errorf("HTTPS should fail since we do not have ssl enabled")
}
if res.A != "a" || res.B != "b" {
t.Errorf("Expected to be a and b, got %s and %s", res.A, res.B)
}
}
func TestFetchHtml(t *testing.T) {
expectedData := `<AB><A>a</A><B>b</B></AB>`
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
fmt.Fprintln(w, expectedData)
}))
defer ts.Close()
resp, err := FetchHtml("GET", ts.URL, nil)
if err != nil {
t.Errorf("Some error occured while sending: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
t.Errorf("Status code is %d, expected %d", resp.StatusCode, http.StatusOK)
}
dataArr, err := ioutil.ReadAll(resp.Body)
if err != nil {
t.Errorf("Some error occured while sending: %v", err)
}
data := string(dataArr)
data = data[:len(data)-1] // trim newline
if data != expectedData {
t.Errorf("Body is '%s', expected '%s'", data, expectedData)
}
// run without protocol
_, err = FetchHtml("GET", ts.URL[7:], nil)
if err != nil {
t.Errorf("Some error occured while sending: %v", err)
}
}
......@@ -19,17 +19,19 @@ package federation
import (
"encoding/xml"
"strings"
"fmt"
"errors"
)
type WebFinger struct {
Host string
Handle string
Xrd WebfingerXml
Json WebfingerJson
}
// TODO XML webfinger is deprecated
// TODO XML webfinger is deprecated but
// still used in host-meta which is required
// for a successful pod-active check
type WebfingerXml struct {
XMLName xml.Name `xml:"XRD"`
Xmlns string `xml:"xmlns,attr"`
......@@ -60,24 +62,14 @@ type WebfingerJsonLink struct {
}
func (w *WebFinger) Discovery() error {
err := FetchXml("GET", w.Host + "/.well-known/host-meta", nil, &w.Xrd)
url := fmt.Sprintf("%s/.well-known/webfinger?resource=acct:%s", w.Host, w.Handle)
err := FetchJson("GET", url, nil, &w.Json)
if err != nil {
return err
}
if len(w.Xrd.Links) < 1 {
return errors.New("XRD Link missing")
if len(w.Json.Links) < 1 {
return errors.New("Webfinger Links missing")
}
for _, link := range w.Xrd.Links {
if link.Rel == "lrdd" && link.Template != "" {
err = FetchXml("GET", strings.Replace(
link.Template, "{uri}", "acct:" + w.Handle, 1), nil, &w.Xrd)
if err != nil {
return err
}
return nil
}
}
return errors.New("No lrdd rel found in webfinger document!")
return nil
}
......@@ -17,11 +17,26 @@ package federation
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
import "testing"
import (
"testing"
"net/http"
"net/http/httptest"
"fmt"
)
func TestWebFinger(t *testing.T) {
tmplBody := `{"subject": "acct:podmin@joindiaspora.com","aliases":[],"links":[`
body := tmplBody + `{"rel":"http://microformats.org/profile/hcard"}]}`
failBody := tmplBody + `]}`
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
fmt.Fprintln(w, body)
}))
defer ts.Close()
finger := WebFinger{
Host: "joindiaspora.com",
Host: ts.URL[7:], // without protocol
Handle: "podmin@joindiaspora.com",
}
err := finger.Discovery()
......@@ -29,13 +44,21 @@ func TestWebFinger(t *testing.T) {
t.Errorf("Some error occured while discovering: %v", err)
}
for _, link := range finger.Xrd.Links {
if link.Rel == WebFingerHcard {
if link.Href != TEST_HCARD_LINK {
t.Errorf("Expected to be %s, got %s", TEST_HCARD_LINK, link.Href)
}
return
}
ts = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
fmt.Fprintln(w, failBody)
}))
defer ts.Close()
finger.Host = ts.URL[7:]
err = finger.Discovery()
if err == nil {
t.Errorf("Webfinger discovery should throw an error on invalid links")
}
finger.Host = ""
err = finger.Discovery()
if err == nil {
t.Errorf("Webfinger discovery should throw an error on empty host")
}
t.Errorf("Expected hcard link, got nothing")
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment