diff --git a/greataped/activitypub/collection.go b/greataped/activitypub/collection.go index 4bf501e..8439283 100644 --- a/greataped/activitypub/collection.go +++ b/greataped/activitypub/collection.go @@ -8,6 +8,7 @@ type OrderedCollection struct { Type string `json:"type,omitempty"` TotalItems int `json:"totalItems"` OrderedItems interface{} `json:"orderedItems,omitempty"` + First string `json:"first,omitempty"` } func NewOrderedCollection(id string, items interface{}, length int) *OrderedCollection { diff --git a/greataped/app/routes/all.go b/greataped/app/routes/all.go index b8bb1ea..5231c0f 100644 --- a/greataped/app/routes/all.go +++ b/greataped/app/routes/all.go @@ -20,6 +20,7 @@ var All = []contracts.IRoute{ OutboxPost, OutboxGet, Followers, + Following, Follow, Authorize, } diff --git a/greataped/app/routes/followers.go b/greataped/app/routes/followers.go index 1a23f62..620d875 100644 --- a/greataped/app/routes/followers.go +++ b/greataped/app/routes/followers.go @@ -2,6 +2,7 @@ package routes import ( "activitypub" + "app/models/domain" "app/models/repos" "app/models/types" "config" @@ -15,30 +16,53 @@ import ( ) var Followers = route.New(HttpGet, "/u/:username/followers", func(x IContext) error { - username := x.Request().Params("username") - actor := x.StringUtil().Format("%s://%s/u/%s", config.PROTOCOL, config.DOMAIN, username) - id := x.StringUtil().Format("%s://%s/u/%s/followers", config.PROTOCOL, config.DOMAIN, username) - - followers := &[]types.FollowerResponse{} - err := repos.FindFollowers(followers, actor).Error - if err != nil { - x.InternalServerError(err) + username := domain.Username(x.Request().Params("username")) + if username.IsEmpty() { + return x.BadRequest("username required.") } - items := []string{} - for _, follower := range *followers { - items = append(items, follower.Handle) - } + if username.IsFederated() { + webfinger := activitypub.Webfinger{} + if err := x.GetActivityStream(username.Webfinger(), nil, &webfinger); err != nil { + return x.InternalServerError(err) + } - result := &activitypub.Followers{ - Context: activitypub.ActivityStreams, - ID: id, - Type: activitypub.TypeOrderedCollection, - TotalItems: len(items), - OrderedItems: items, - } + actor := activitypub.Actor{} + if err := x.GetActivityStream(webfinger.Self(), nil, &actor); err != nil { + return x.InternalServerError(err) + } - return x.Activity(result) + followers := activitypub.OrderedCollection{} + if err := x.GetActivityStream(actor.Followers, nil, &followers); err != nil { + return x.InternalServerError(err) + } + + return x.Activity(followers) + } else { + actor := x.StringUtil().Format("%s://%s/u/%s", config.PROTOCOL, config.DOMAIN, username) + id := x.StringUtil().Format("%s://%s/u/%s/followers", config.PROTOCOL, config.DOMAIN, username) + + followers := &[]types.FollowerResponse{} + err := repos.FindFollowers(followers, actor).Error + if err != nil { + x.InternalServerError(err) + } + + items := []string{} + for _, follower := range *followers { + items = append(items, follower.Handle) + } + + result := &activitypub.Followers{ + Context: activitypub.ActivityStreams, + ID: id, + Type: activitypub.TypeOrderedCollection, + TotalItems: len(items), + OrderedItems: items, + } + + return x.Activity(result) + } }) var AcceptFollowRequest = route.New(HttpPut, "/u/:username/followers/:id/accept", func(x IContext) error { diff --git a/greataped/app/routes/following.go b/greataped/app/routes/following.go index 5409753..1956f49 100644 --- a/greataped/app/routes/following.go +++ b/greataped/app/routes/following.go @@ -2,6 +2,7 @@ package routes import ( "activitypub" + "app/models/domain" "app/models/repos" "app/models/types" "config" @@ -10,21 +11,44 @@ import ( ) var Following = route.New(HttpGet, "/u/:username/following", func(x IContext) error { - username := x.Request().Params("username") - actor := x.StringUtil().Format("%s://%s/u/%s", config.PROTOCOL, config.DOMAIN, username) - id := x.StringUtil().Format("%s://%s/u/%s/following", config.PROTOCOL, config.DOMAIN, username) - - followings := &[]types.FollowerResponse{} - err := repos.FindFollowing(followings, actor).Error - if err != nil { - x.InternalServerError(err) + username := domain.Username(x.Request().Params("username")) + if username.IsEmpty() { + return x.BadRequest("username required.") } - items := []string{} - for _, following := range *followings { - items = append(items, following.Target) - } + if username.IsFederated() { + webfinger := activitypub.Webfinger{} + if err := x.GetActivityStream(username.Webfinger(), nil, &webfinger); err != nil { + return x.InternalServerError(err) + } - result := activitypub.NewOrderedCollection(id, items, len(items)) - return x.Activity(result) + actor := activitypub.Actor{} + if err := x.GetActivityStream(webfinger.Self(), nil, &actor); err != nil { + return x.InternalServerError(err) + } + + following := activitypub.OrderedCollection{} + if err := x.GetActivityStream(actor.Following, nil, &following); err != nil { + return x.InternalServerError(err) + } + + return x.Activity(following) + } else { + actor := x.StringUtil().Format("%s://%s/u/%s", config.PROTOCOL, config.DOMAIN, username) + id := x.StringUtil().Format("%s://%s/u/%s/following", config.PROTOCOL, config.DOMAIN, username) + + followings := &[]types.FollowerResponse{} + err := repos.FindFollowing(followings, actor).Error + if err != nil { + x.InternalServerError(err) + } + + items := []string{} + for _, following := range *followings { + items = append(items, following.Target) + } + + result := activitypub.NewOrderedCollection(id, items, len(items)) + return x.Activity(result) + } })