diff options
Diffstat (limited to 'webfinger/webfinger.go')
-rw-r--r-- | webfinger/webfinger.go | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/webfinger/webfinger.go b/webfinger/webfinger.go new file mode 100644 index 0000000..ffe7c6d --- /dev/null +++ b/webfinger/webfinger.go @@ -0,0 +1,145 @@ +package webfinger + +import ( + "encoding/json" + "io/ioutil" + "net/http" + "strings" + + "github.com/FChannel0/FChannel-Server/activitypub" + "github.com/FChannel0/FChannel-Server/config" + "github.com/FChannel0/FChannel-Server/util" +) + +type Webfinger struct { + Subject string `json:"subject,omitempty"` + Links []WebfingerLink `json:"links,omitempty"` +} + +type WebfingerLink struct { + Rel string `json:"rel,omitempty"` + Type string `json:"type,omitempty"` + Href string `json:"href,omitempty"` +} + +var ActorCache = make(map[string]activitypub.Actor) + +func GetActor(id string) (activitypub.Actor, error) { + var respActor activitypub.Actor + + if id == "" { + return respActor, nil + } + + actor, instance := util.GetActorInstance(id) + + if ActorCache[actor+"@"+instance].Id != "" { + respActor = ActorCache[actor+"@"+instance] + return respActor, nil + } + + req, err := http.NewRequest("GET", strings.TrimSpace(id), nil) + if err != nil { + return respActor, err + } + req.Header.Set("Accept", config.ActivityStreams) + + resp, err := util.RouteProxy(req) + + if err != nil { + return respActor, err + } + + defer resp.Body.Close() + + body, _ := ioutil.ReadAll(resp.Body) + + if err := json.Unmarshal(body, &respActor); err != nil { + return respActor, err + } + + ActorCache[actor+"@"+instance] = respActor + + return respActor, nil +} + +//looks for actor with pattern of board@instance +func FingerActor(path string) (activitypub.Actor, error) { + var nActor activitypub.Actor + + actor, instance := util.GetActorInstance(path) + + if actor == "" && instance == "" { + return nActor, nil + } + + if ActorCache[actor+"@"+instance].Id != "" { + nActor = ActorCache[actor+"@"+instance] + return nActor, nil + } + + r, err := FingerRequest(actor, instance) + if err != nil { + return nActor, err + } + + if r != nil && r.StatusCode == 200 { + defer r.Body.Close() + + body, _ := ioutil.ReadAll(r.Body) + + if err := json.Unmarshal(body, &nActor); err != nil { + return nActor, err + } + + ActorCache[actor+"@"+instance] = nActor + } + + // TODO: this just falls through and returns a blank Actor object. do something? + return nActor, nil +} + +func FingerRequest(actor string, instance string) (*http.Response, error) { + acct := "acct:" + actor + "@" + instance + + // TODO: respect https + req, err := http.NewRequest("GET", "http://"+instance+"/.well-known/webfinger?resource="+acct, nil) + if err != nil { + return nil, err + } + + resp, err := util.RouteProxy(req) + if err != nil { + return resp, err + } + + var finger Webfinger + + if resp.StatusCode == 200 { + defer resp.Body.Close() + + body, _ := ioutil.ReadAll(resp.Body) + + if err := json.Unmarshal(body, &finger); err != nil { + return resp, err + } + } + + if len(finger.Links) > 0 { + for _, e := range finger.Links { + if e.Type == "application/activity+json" { + req, err := http.NewRequest("GET", e.Href, nil) + if err != nil { + return resp, err + } + + req.Header.Set("Accept", config.ActivityStreams) + + resp, err := util.RouteProxy(req) + return resp, err + } + } + } + + return resp, nil +} |