aboutsummaryrefslogtreecommitdiff
path: root/routers/api/v1/activitypub/repo.go
diff options
context:
space:
mode:
Diffstat (limited to 'routers/api/v1/activitypub/repo.go')
-rw-r--r--routers/api/v1/activitypub/repo.go198
1 files changed, 198 insertions, 0 deletions
diff --git a/routers/api/v1/activitypub/repo.go b/routers/api/v1/activitypub/repo.go
new file mode 100644
index 000000000..f2abb3977
--- /dev/null
+++ b/routers/api/v1/activitypub/repo.go
@@ -0,0 +1,198 @@
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package activitypub
+
+import (
+ "io"
+ "net/http"
+ "strings"
+
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/models/forgefed"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/context"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/routers/api/v1/utils"
+
+ ap "github.com/go-ap/activitypub"
+)
+
+// Repo function
+func Repo(ctx *context.APIContext) {
+ // swagger:operation GET /activitypub/user/{username}/{reponame} activitypub activitypubRepo
+ // ---
+ // summary: Returns the repository
+ // produces:
+ // - application/activity+json
+ // parameters:
+ // - name: username
+ // in: path
+ // description: username of the user
+ // type: string
+ // required: true
+ // - name: reponame
+ // in: path
+ // description: name of the repository
+ // type: string
+ // required: true
+ // responses:
+ // "200":
+ // "$ref": "#/responses/ActivityPub"
+
+ link := strings.TrimSuffix(setting.AppURL, "/") + strings.TrimSuffix(ctx.Req.URL.EscapedPath(), "/")
+ repo := forgefed.RepositoryNew(ap.IRI(link))
+
+ repo.Name = ap.NaturalLanguageValuesNew()
+ err := repo.Name.Set("en", ap.Content(ctx.Repo.Repository.Name))
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "Set Name", err)
+ return
+ }
+
+ repo.AttributedTo = ap.IRI(strings.TrimSuffix(link, "/"+ctx.Repo.Repository.Name))
+
+ repo.Summary = ap.NaturalLanguageValuesNew()
+ err = repo.Summary.Set("en", ap.Content(ctx.Repo.Repository.Description))
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "Set Description", err)
+ return
+ }
+
+ repo.Inbox = ap.IRI(link + "/inbox")
+ repo.Outbox = ap.IRI(link + "/outbox")
+ repo.Followers = ap.IRI(link + "/followers")
+ repo.Team = ap.IRI(link + "/team")
+
+ response(ctx, repo)
+}
+
+// RepoInbox function
+func RepoInbox(ctx *context.APIContext) {
+ // swagger:operation POST /activitypub/user/{username}/{reponame}/inbox activitypub activitypubRepoInbox
+ // ---
+ // summary: Send to the inbox
+ // produces:
+ // - application/activity+json
+ // parameters:
+ // - name: username
+ // in: path
+ // description: username of the user
+ // type: string
+ // required: true
+ // - name: reponame
+ // in: path
+ // description: name of the repository
+ // type: string
+ // required: true
+ // responses:
+ // "204":
+ // "$ref": "#/responses/empty"
+
+ body, err := io.ReadAll(ctx.Req.Body)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "Error reading request body", err)
+ }
+
+ var activity ap.Activity
+ activity.UnmarshalJSON(body)
+ if activity.Type == ap.FollowType {
+ // activitypub.Follow(ctx, activity)
+ } else {
+ log.Warn("ActivityStreams type not supported", activity)
+ }
+
+ ctx.Status(http.StatusNoContent)
+}
+
+// RepoOutbox function
+func RepoOutbox(ctx *context.APIContext) {
+ // swagger:operation GET /activitypub/user/{username}/outbox activitypub activitypubPersonOutbox
+ // ---
+ // summary: Returns the outbox
+ // produces:
+ // - application/activity+json
+ // parameters:
+ // - name: username
+ // in: path
+ // description: username of the user
+ // type: string
+ // required: true
+ // - name: reponame
+ // in: path
+ // description: name of the repository
+ // type: string
+ // required: true
+ // responses:
+ // "200":
+ // "$ref": "#/responses/ActivityPub"
+
+ link := strings.TrimSuffix(setting.AppURL, "/") + strings.TrimSuffix(ctx.Req.URL.EscapedPath(), "/")
+
+ feed, err := models.GetFeeds(ctx, models.GetFeedsOptions{
+ RequestedUser: ctx.ContextUser,
+ Actor: ctx.ContextUser,
+ IncludePrivate: false,
+ OnlyPerformedBy: true,
+ IncludeDeleted: false,
+ Date: ctx.FormString("date"),
+ })
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "Couldn't fetch outbox", err)
+ }
+
+ outbox := ap.OrderedCollectionNew(ap.IRI(link))
+ for _, action := range feed {
+ /*if action.OpType == ExampleType {
+ activity := ap.ExampleNew()
+ outbox.OrderedItems.Append(activity)
+ }*/
+ log.Debug(action.Content)
+ }
+ outbox.TotalItems = uint(len(outbox.OrderedItems))
+
+ response(ctx, outbox)
+}
+
+// RepoFollowers function
+func RepoFollowers(ctx *context.APIContext) {
+ // swagger:operation GET /activitypub/user/{username}/{reponame}/followers activitypub activitypubRepoFollowers
+ // ---
+ // summary: Returns the followers collection
+ // produces:
+ // - application/activity+json
+ // parameters:
+ // - name: username
+ // in: path
+ // description: username of the user
+ // type: string
+ // required: true
+ // - name: reponame
+ // in: path
+ // description: name of the repository
+ // type: string
+ // required: true
+ // responses:
+ // "200":
+ // "$ref": "#/responses/ActivityPub"
+
+ link := strings.TrimSuffix(setting.AppURL, "/") + strings.TrimSuffix(ctx.Req.URL.EscapedPath(), "/")
+
+ users, err := user_model.GetUserFollowers(ctx.ContextUser, utils.GetListOptions(ctx))
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "GetUserFollowers", err)
+ return
+ }
+
+ followers := ap.OrderedCollectionNew(ap.IRI(link))
+ followers.TotalItems = uint(len(users))
+
+ for _, user := range users {
+ person := ap.PersonNew(ap.IRI(user.Website))
+ followers.OrderedItems.Append(person)
+ }
+
+ response(ctx, followers)
+}