outboxget.go (3978B)
1 // GoToSocial 2 // Copyright (C) GoToSocial Authors admin@gotosocial.org 3 // SPDX-License-Identifier: AGPL-3.0-or-later 4 // 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Affero General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Affero General Public License for more details. 14 // 15 // You should have received a copy of the GNU Affero General Public License 16 // along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 package users 19 20 import ( 21 "encoding/json" 22 "errors" 23 "fmt" 24 "net/http" 25 "strconv" 26 "strings" 27 28 "github.com/gin-gonic/gin" 29 apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util" 30 "github.com/superseriousbusiness/gotosocial/internal/gtserror" 31 ) 32 33 // OutboxGETHandler swagger:operation GET /users/{username}/outbox s2sOutboxGet 34 // 35 // Get the public outbox collection for an actor. 36 // 37 // Note that the response will be a Collection with a page as `first`, as shown below, if `page` is `false`. 38 // 39 // If `page` is `true`, then the response will be a single `CollectionPage` without the wrapping `Collection`. 40 // 41 // HTTP signature is required on the request. 42 // 43 // --- 44 // tags: 45 // - s2s/federation 46 // 47 // produces: 48 // - application/activity+json 49 // 50 // parameters: 51 // - 52 // name: username 53 // type: string 54 // description: Username of the account. 55 // in: path 56 // required: true 57 // - 58 // name: page 59 // type: boolean 60 // description: Return response as a CollectionPage. 61 // in: query 62 // default: false 63 // - 64 // name: min_id 65 // type: string 66 // description: Minimum ID of the next status, used for paging. 67 // in: query 68 // - 69 // name: max_id 70 // type: string 71 // description: Maximum ID of the next status, used for paging. 72 // in: query 73 // 74 // responses: 75 // '200': 76 // in: body 77 // schema: 78 // "$ref": "#/definitions/swaggerCollection" 79 // '400': 80 // description: bad request 81 // '401': 82 // description: unauthorized 83 // '403': 84 // description: forbidden 85 // '404': 86 // description: not found 87 func (m *Module) OutboxGETHandler(c *gin.Context) { 88 // usernames on our instance are always lowercase 89 requestedUsername := strings.ToLower(c.Param(UsernameKey)) 90 if requestedUsername == "" { 91 err := errors.New("no username specified in request") 92 apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGetV1) 93 return 94 } 95 96 format, err := apiutil.NegotiateAccept(c, apiutil.HTMLOrActivityPubHeaders...) 97 if err != nil { 98 apiutil.ErrorHandler(c, gtserror.NewErrorNotAcceptable(err, err.Error()), m.processor.InstanceGetV1) 99 return 100 } 101 102 if format == string(apiutil.TextHTML) { 103 // This isn't an ActivityPub request; 104 // redirect to the user's profile. 105 c.Redirect(http.StatusSeeOther, "/@"+requestedUsername) 106 return 107 } 108 109 var page bool 110 if pageString := c.Query(PageKey); pageString != "" { 111 i, err := strconv.ParseBool(pageString) 112 if err != nil { 113 err := fmt.Errorf("error parsing %s: %s", PageKey, err) 114 apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGetV1) 115 return 116 } 117 page = i 118 } 119 120 minID := "" 121 minIDString := c.Query(MinIDKey) 122 if minIDString != "" { 123 minID = minIDString 124 } 125 126 maxID := "" 127 maxIDString := c.Query(MaxIDKey) 128 if maxIDString != "" { 129 maxID = maxIDString 130 } 131 132 resp, errWithCode := m.processor.Fedi().OutboxGet(c.Request.Context(), requestedUsername, page, maxID, minID) 133 if errWithCode != nil { 134 apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1) 135 return 136 } 137 138 b, err := json.Marshal(resp) 139 if err != nil { 140 apiutil.ErrorHandler(c, gtserror.NewErrorInternalError(err), m.processor.InstanceGetV1) 141 return 142 } 143 144 c.Data(http.StatusOK, format, b) 145 }