code.gitea.io/gitea@v1.21.7/routers/api/v1/activitypub/person.go (about) 1 // Copyright 2022 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package activitypub 5 6 import ( 7 "fmt" 8 "net/http" 9 "strings" 10 11 "code.gitea.io/gitea/modules/activitypub" 12 "code.gitea.io/gitea/modules/context" 13 "code.gitea.io/gitea/modules/log" 14 "code.gitea.io/gitea/modules/setting" 15 16 ap "github.com/go-ap/activitypub" 17 "github.com/go-ap/jsonld" 18 ) 19 20 // Person function returns the Person actor for a user 21 func Person(ctx *context.APIContext) { 22 // swagger:operation GET /activitypub/user-id/{user-id} activitypub activitypubPerson 23 // --- 24 // summary: Returns the Person actor for a user 25 // produces: 26 // - application/json 27 // parameters: 28 // - name: user-id 29 // in: path 30 // description: user ID of the user 31 // type: integer 32 // required: true 33 // responses: 34 // "200": 35 // "$ref": "#/responses/ActivityPub" 36 37 // TODO: the setting.AppURL during the test doesn't follow the definition: "It always has a '/' suffix" 38 link := fmt.Sprintf("%s/api/v1/activitypub/user-id/%d", strings.TrimSuffix(setting.AppURL, "/"), ctx.ContextUser.ID) 39 person := ap.PersonNew(ap.IRI(link)) 40 41 person.Name = ap.NaturalLanguageValuesNew() 42 err := person.Name.Set("en", ap.Content(ctx.ContextUser.FullName)) 43 if err != nil { 44 ctx.ServerError("Set Name", err) 45 return 46 } 47 48 person.PreferredUsername = ap.NaturalLanguageValuesNew() 49 err = person.PreferredUsername.Set("en", ap.Content(ctx.ContextUser.Name)) 50 if err != nil { 51 ctx.ServerError("Set PreferredUsername", err) 52 return 53 } 54 55 person.URL = ap.IRI(ctx.ContextUser.HTMLURL()) 56 57 person.Icon = ap.Image{ 58 Type: ap.ImageType, 59 MediaType: "image/png", 60 URL: ap.IRI(ctx.ContextUser.AvatarLink(ctx)), 61 } 62 63 person.Inbox = ap.IRI(link + "/inbox") 64 person.Outbox = ap.IRI(link + "/outbox") 65 66 person.PublicKey.ID = ap.IRI(link + "#main-key") 67 person.PublicKey.Owner = ap.IRI(link) 68 69 publicKeyPem, err := activitypub.GetPublicKey(ctx, ctx.ContextUser) 70 if err != nil { 71 ctx.ServerError("GetPublicKey", err) 72 return 73 } 74 person.PublicKey.PublicKeyPem = publicKeyPem 75 76 binary, err := jsonld.WithContext(jsonld.IRI(ap.ActivityBaseURI), jsonld.IRI(ap.SecurityContextURI)).Marshal(person) 77 if err != nil { 78 ctx.ServerError("MarshalJSON", err) 79 return 80 } 81 ctx.Resp.Header().Add("Content-Type", activitypub.ActivityStreamsContentType) 82 ctx.Resp.WriteHeader(http.StatusOK) 83 if _, err = ctx.Resp.Write(binary); err != nil { 84 log.Error("write to resp err: %v", err) 85 } 86 } 87 88 // PersonInbox function handles the incoming data for a user inbox 89 func PersonInbox(ctx *context.APIContext) { 90 // swagger:operation POST /activitypub/user-id/{user-id}/inbox activitypub activitypubPersonInbox 91 // --- 92 // summary: Send to the inbox 93 // produces: 94 // - application/json 95 // parameters: 96 // - name: user-id 97 // in: path 98 // description: user ID of the user 99 // type: integer 100 // required: true 101 // responses: 102 // "204": 103 // "$ref": "#/responses/empty" 104 105 ctx.Status(http.StatusNoContent) 106 }