diff options
-rw-r--r-- | routers/api/v1/activitypub/person.go | 111 | ||||
-rw-r--r-- | routers/api/v1/api.go | 14 | ||||
-rw-r--r-- | templates/swagger/v1_json.tmpl | 56 |
3 files changed, 172 insertions, 9 deletions
diff --git a/routers/api/v1/activitypub/person.go b/routers/api/v1/activitypub/person.go index e72353858..b46c2db25 100644 --- a/routers/api/v1/activitypub/person.go +++ b/routers/api/v1/activitypub/person.go @@ -11,11 +11,13 @@ import ( "net/url" "strings" + user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/activitypub" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/routers/api/v1/user" + "code.gitea.io/gitea/routers/api/v1/utils" "github.com/go-fed/activity/streams" "github.com/go-fed/activity/streams/vocab" @@ -66,6 +68,16 @@ func Person(ctx *context.APIContext) { obox.SetIRI(urlObject) person.SetActivityStreamsOutbox(obox) + following := streams.NewActivityStreamsFollowingProperty() + urlObject, _ = url.Parse(link + "/following") + following.SetIRI(urlObject) + person.SetActivityStreamsFollowing(following) + + followers := streams.NewActivityStreamsFollowersProperty() + urlObject, _ = url.Parse(link + "/followers") + followers.SetIRI(urlObject) + person.SetActivityStreamsFollowers(followers) + publicKeyProp := streams.NewW3IDSecurityV1PublicKeyProperty() publicKeyType := streams.NewW3IDSecurityV1PublicKey() @@ -104,7 +116,7 @@ func PersonInboxGet(ctx *context.APIContext) { // --- // summary: Returns the inbox // produces: - // - application/json + // - application/activity+json // parameters: // - name: username // in: path @@ -167,7 +179,7 @@ func PersonOutboxGet(ctx *context.APIContext) { // --- // summary: Returns the outbox // produces: - // - application/json + // - application/activity+json // parameters: // - name: username // in: path @@ -251,3 +263,98 @@ func PersonOutboxPost(ctx *context.APIContext) { */ ctx.Status(http.StatusNoContent) } + +// PersonFollowing function +func PersonFollowing(ctx *context.APIContext) { + // swagger:operation GET /activitypub/user/{username}/following activitypub activitypubPersonFollowing + // --- + // summary: Returns the following collection + // produces: + // - application/activity+json + // parameters: + // - name: username + // in: path + // description: username of the user + // type: string + // required: true + // responses: + // "200": + // "$ref": "#/responses/ActivityPub" + + user := user.GetUserByParamsName(ctx, "username") + if user == nil { + return + } + users, err := user_model.GetUserFollowing(user, utils.GetListOptions(ctx)) + if err != nil { + ctx.Error(http.StatusInternalServerError, "GetUserFollowing", err) + return + } + + following := streams.NewActivityStreamsOrderedCollection() + + totalItems := streams.NewActivityStreamsTotalItemsProperty() + totalItems.Set(len(users)) + following.SetActivityStreamsTotalItems(totalItems) + + items := streams.NewActivityStreamsOrderedItemsProperty() + for i := 0; i < len(users); i++ { + user, _ := url.Parse(setting.AppURL+"api/v1/activitypub/user/"+users[i].Name) + items.AppendIRI(user) + } + following.SetActivityStreamsOrderedItems(items) + + jsonmap, err := streams.Serialize(following) + if err != nil { + ctx.Error(http.StatusInternalServerError, "Serialize", err) + } + ctx.JSON(http.StatusOK, jsonmap) +} + +// PersonFollowers function +func PersonFollowers(ctx *context.APIContext) { + // swagger:operation GET /activitypub/user/{username}/followers activitypub activitypubPersonFollowers + // --- + // summary: Returns the followers collection + // produces: + // - application/activity+json + // parameters: + // - name: username + // in: path + // description: username of the user + // type: string + // required: true + // responses: + // "200": + // "$ref": "#/responses/ActivityPub" + + user := user.GetUserByParamsName(ctx, "username") + if user == nil { + return + } + users, err := user_model.GetUserFollowers(user, utils.GetListOptions(ctx)) + if err != nil { + ctx.Error(http.StatusInternalServerError, "GetUserFollowers", err) + return + } + + followers := streams.NewActivityStreamsOrderedCollection() + + totalItems := streams.NewActivityStreamsTotalItemsProperty() + totalItems.Set(len(users)) + followers.SetActivityStreamsTotalItems(totalItems) + + items := streams.NewActivityStreamsOrderedItemsProperty() + for i := 0; i < len(users); i++ { + user, _ := url.Parse(setting.AppURL+"api/v1/activitypub/user/"+users[i].Name) + items.AppendIRI(user) + } + followers.SetActivityStreamsOrderedItems(items) + + jsonmap, err := streams.Serialize(followers) + fmt.Println(jsonmap) + if err != nil { + ctx.Error(http.StatusInternalServerError, "Serialize", err) + } + ctx.JSON(http.StatusOK, jsonmap) +} diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 19b0d80ca..20d63fc2f 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -599,11 +599,15 @@ func Routes(sessioner func(http.Handler) http.Handler) *web.Route { if setting.Federation.Enabled { m.Get("/nodeinfo", misc.NodeInfo) m.Group("/activitypub", func() { - m.Get("/user/{username}", activitypub.Person) - m.Get("/user/{username}/inbox", activitypub.PersonInboxGet) - m.Post("/user/{username}/inbox", activitypub.ReqSignature(), activitypub.PersonInboxPost) - m.Get("/user/{username}/outbox", activitypub.PersonOutboxGet) - m.Post("/user/{username}/outbox", activitypub.ReqSignature(), activitypub.PersonOutboxPost) + m.Group("/user/{username}", func() { + m.Get("", activitypub.Person) + m.Get("/inbox", activitypub.PersonInboxGet) + m.Post("/inbox", activitypub.ReqSignature(), activitypub.PersonInboxPost) + m.Get("/outbox", activitypub.PersonOutboxGet) + m.Post("/outbox", activitypub.ReqSignature(), activitypub.PersonOutboxPost) + m.Get("/following", activitypub.PersonFollowing) + m.Get("/followers", activitypub.PersonFollowers) + }) }) } m.Get("/signing-key.gpg", misc.SigningKey) diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 646479379..3dd36e081 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -52,7 +52,7 @@ "/activitypub/user/{username}/inbox": { "get": { "produces": [ - "application/json" + "application/activity+json" ], "tags": [ "activitypub" @@ -102,7 +102,7 @@ "/activitypub/user/{username}/outbox": { "get": { "produces": [ - "application/json" + "application/activity+json" ], "tags": [ "activitypub" @@ -149,6 +149,58 @@ } } }, + "/activitypub/user/{username}/following": { + "get": { + "produces": [ + "application/activity+json" + ], + "tags": [ + "activitypub" + ], + "summary": "Returns the following collection", + "operationId": "activitypubPersonFollowing", + "parameters": [ + { + "type": "string", + "description": "username of the user", + "name": "username", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/ActivityPub" + } + } + } + }, + "/activitypub/user/{username}/followers": { + "get": { + "produces": [ + "application/activity+json" + ], + "tags": [ + "activitypub" + ], + "summary": "Returns the followers collection", + "operationId": "activitypubPersonFollowers", + "parameters": [ + { + "type": "string", + "description": "username of the user", + "name": "username", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/ActivityPub" + } + } + } + }, "/admin/cron": { "get": { "produces": [ |