search.go (5012B)
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 accounts 19 20 import ( 21 "net/http" 22 23 "github.com/gin-gonic/gin" 24 apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util" 25 "github.com/superseriousbusiness/gotosocial/internal/gtserror" 26 "github.com/superseriousbusiness/gotosocial/internal/oauth" 27 ) 28 29 // AccountSearchGETHandler swagger:operation GET /api/v1/accounts/search accountSearchGet 30 // 31 // Search for accounts by username and/or display name. 32 // 33 // --- 34 // tags: 35 // - accounts 36 // 37 // produces: 38 // - application/json 39 // 40 // parameters: 41 // - 42 // name: limit 43 // type: integer 44 // description: Number of results to try to return. 45 // default: 40 46 // maximum: 80 47 // minimum: 1 48 // in: query 49 // - 50 // name: offset 51 // type: integer 52 // description: >- 53 // Page number of results to return (starts at 0). 54 // This parameter is currently not used, offsets 55 // over 0 will always return 0 results. 56 // default: 0 57 // maximum: 10 58 // minimum: 0 59 // in: query 60 // - 61 // name: q 62 // type: string 63 // description: |- 64 // Query string to search for. This can be in the following forms: 65 // - `@[username]` -- search for an account with the given username on any domain. Can return multiple results. 66 // - `@[username]@[domain]` -- search for a remote account with exact username and domain. Will only ever return 1 result at most. 67 // - any arbitrary string -- search for accounts containing the given string in their username or display name. Can return multiple results. 68 // in: query 69 // required: true 70 // - 71 // name: resolve 72 // type: boolean 73 // description: >- 74 // If query is for `@[username]@[domain]`, or a URL, allow the GoToSocial instance to resolve 75 // the search by making calls to remote instances (webfinger, ActivityPub, etc). 76 // default: false 77 // in: query 78 // - 79 // name: following 80 // type: boolean 81 // description: >- 82 // Show only accounts that the requesting account follows. If this is set to `true`, then the GoToSocial instance 83 // will enhance the search by also searching within account notes, not just in usernames and display names. 84 // default: false 85 // in: query 86 // 87 // security: 88 // - OAuth2 Bearer: 89 // - read:accounts 90 // 91 // responses: 92 // '200': 93 // name: search results 94 // description: Results of the search. 95 // schema: 96 // type: array 97 // items: 98 // "$ref": "#/definitions/account" 99 // '400': 100 // description: bad request 101 // '401': 102 // description: unauthorized 103 // '404': 104 // description: not found 105 // '406': 106 // description: not acceptable 107 // '500': 108 // description: internal server error 109 func (m *Module) AccountSearchGETHandler(c *gin.Context) { 110 authed, err := oauth.Authed(c, true, true, true, true) 111 if err != nil { 112 apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1) 113 return 114 } 115 116 if _, err := apiutil.NegotiateAccept(c, apiutil.JSONAcceptHeaders...); err != nil { 117 apiutil.ErrorHandler(c, gtserror.NewErrorNotAcceptable(err, err.Error()), m.processor.InstanceGetV1) 118 return 119 } 120 121 limit, errWithCode := apiutil.ParseLimit(c.Query(apiutil.LimitKey), 40, 80, 1) 122 if errWithCode != nil { 123 apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1) 124 return 125 } 126 127 offset, errWithCode := apiutil.ParseSearchOffset(c.Query(apiutil.SearchOffsetKey), 0, 10, 0) 128 if errWithCode != nil { 129 apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1) 130 return 131 } 132 133 query, errWithCode := apiutil.ParseSearchQuery(c.Query(apiutil.SearchQueryKey)) 134 if errWithCode != nil { 135 apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1) 136 return 137 } 138 139 resolve, errWithCode := apiutil.ParseSearchResolve(c.Query(apiutil.SearchResolveKey), false) 140 if errWithCode != nil { 141 apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1) 142 return 143 } 144 145 following, errWithCode := apiutil.ParseSearchFollowing(c.Query(apiutil.SearchFollowingKey), false) 146 if errWithCode != nil { 147 apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1) 148 return 149 } 150 151 results, errWithCode := m.processor.Search().Accounts( 152 c.Request.Context(), 153 authed.Account, 154 query, 155 limit, 156 offset, 157 resolve, 158 following, 159 ) 160 if errWithCode != nil { 161 apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1) 162 return 163 } 164 165 c.JSON(http.StatusOK, results) 166 }