mirror of https://gitlab.com/ngerakines/tavern.git
93 lines
2.5 KiB
Go
93 lines
2.5 KiB
Go
package fed
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"net/url"
|
|
"strings"
|
|
|
|
"go.uber.org/zap"
|
|
|
|
"github.com/ngerakines/tavern/storage"
|
|
)
|
|
|
|
type HTTPClient interface {
|
|
Do(req *http.Request) (*http.Response, error)
|
|
}
|
|
|
|
type WebFingerClient struct {
|
|
HTTPClient HTTPClient
|
|
Logger *zap.Logger
|
|
}
|
|
|
|
func (client WebFingerClient) Fetch(location string) (storage.Payload, error) {
|
|
destination, err := BuildWebFingerURL(location)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
client.Logger.Debug("Sending webfinger request", zap.String("url", destination))
|
|
_, payload, err := ldJsonGet(client.HTTPClient, destination)
|
|
return payload, err
|
|
}
|
|
|
|
func BuildWebFingerURL(location string) (string, error) {
|
|
if strings.HasPrefix(location, "@") {
|
|
location = strings.TrimPrefix(location, "@")
|
|
parts := strings.Split(location, "@")
|
|
if len(parts) != 2 {
|
|
return "", fmt.Errorf("invalid actor location: %s", location)
|
|
}
|
|
q := url.QueryEscape(location)
|
|
return fmt.Sprintf("https://%s/.well-known/webfinger?resource=acct:%s", parts[1], q), nil
|
|
}
|
|
|
|
if strings.Index(location, "@") != -1 {
|
|
parts := strings.Split(strings.TrimPrefix(location, "@"), "@")
|
|
if len(parts) != 2 {
|
|
return "", fmt.Errorf("invalid actor location: %s", location)
|
|
}
|
|
q := url.QueryEscape(location)
|
|
return fmt.Sprintf("https://%s/.well-known/webfinger?resource=acct:%s", parts[1], q), nil
|
|
}
|
|
|
|
u, err := url.Parse(location)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
q := url.QueryEscape(location)
|
|
return fmt.Sprintf("https://%s/.well-known/webfinger?resource=acct:%s", u.Host, q), nil
|
|
}
|
|
|
|
func ActorIDFromWebFingerPayload(wfp storage.Payload) (string, error) {
|
|
if wfp == nil {
|
|
return "", fmt.Errorf("unable to get actor href from webfinger content: wfp nil")
|
|
}
|
|
links, ok := wfp["links"]
|
|
if !ok {
|
|
return "", fmt.Errorf("unable to get actor href from webfinger content")
|
|
}
|
|
objLinks, ok := links.([]interface{})
|
|
if !ok {
|
|
return "", fmt.Errorf("unable to get actor href from webfinger content: links not array")
|
|
}
|
|
if len(objLinks) < 1 {
|
|
return "", fmt.Errorf("unable to get actor href from webfinger content: links empty")
|
|
}
|
|
first := objLinks[0]
|
|
firstMap, ok := first.(map[string]interface{})
|
|
if !ok {
|
|
return "", fmt.Errorf("unable to get actor href from webfinger content: first link not map")
|
|
}
|
|
href, ok := firstMap["href"]
|
|
if !ok {
|
|
return "", fmt.Errorf("unable to get actor href from webfinger content: href present")
|
|
}
|
|
hrefStr, ok := href.(string)
|
|
if !ok {
|
|
return "", fmt.Errorf("unable to get actor href from webfinger content: href not string")
|
|
}
|
|
return hrefStr, nil
|
|
}
|