emojisget.go (7578B)
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 admin 19 20 import ( 21 "fmt" 22 "net/http" 23 "strconv" 24 "strings" 25 26 "github.com/gin-gonic/gin" 27 apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util" 28 "github.com/superseriousbusiness/gotosocial/internal/config" 29 "github.com/superseriousbusiness/gotosocial/internal/db" 30 "github.com/superseriousbusiness/gotosocial/internal/gtserror" 31 "github.com/superseriousbusiness/gotosocial/internal/oauth" 32 ) 33 34 // EmojisGETHandler swagger:operation GET /api/v1/admin/custom_emojis emojisGet 35 // 36 // View local and remote emojis available to / known by this instance. 37 // 38 // The next and previous queries can be parsed from the returned Link header. 39 // Example: 40 // 41 // `<http://localhost:8080/api/v1/admin/custom_emojis?limit=30&max_shortcode_domain=yell@fossbros-anonymous.io&filter=domain:all>; rel="next", <http://localhost:8080/api/v1/admin/custom_emojis?limit=30&min_shortcode_domain=rainbow@&filter=domain:all>; rel="prev"` 42 // 43 // --- 44 // tags: 45 // - admin 46 // 47 // produces: 48 // - application/json 49 // 50 // parameters: 51 // - 52 // name: filter 53 // type: string 54 // description: |- 55 // Comma-separated list of filters to apply to results. Recognized filters are: 56 // 57 // `domain:[domain]` -- show emojis from the given domain, eg `?filter=domain:example.org` will show emojis from `example.org` only. 58 // Instead of giving a specific domain, you can also give either one of the key words `local` or `all` to show either local emojis only (`domain:local`) or show all emojis from all domains (`domain:all`). 59 // Note: `domain:*` is equivalent to `domain:all` (including local). 60 // If no domain filter is provided, `domain:all` will be assumed. 61 // 62 // `disabled` -- include emojis that have been disabled. 63 // 64 // `enabled` -- include emojis that are enabled. 65 // 66 // `shortcode:[shortcode]` -- show only emojis with the given shortcode, eg `?filter=shortcode:blob_cat_uwu` will show only emojis with the shortcode `blob_cat_uwu` (case sensitive). 67 // 68 // If neither `disabled` or `enabled` are provided, both disabled and enabled emojis will be shown. 69 // 70 // If no filter query string is provided, the default `domain:all` will be used, which will show all emojis from all domains. 71 // in: query 72 // required: false 73 // default: "domain:all" 74 // - 75 // name: limit 76 // type: integer 77 // description: Number of emojis to return. Less than 1, or not set, means unlimited (all emojis). 78 // default: 50 79 // in: query 80 // - 81 // name: max_shortcode_domain 82 // type: string 83 // description: >- 84 // Return only emojis with `[shortcode]@[domain]` *LOWER* (alphabetically) than given `[shortcode]@[domain]`. 85 // For example, if `max_shortcode_domain=beep@example.org`, then returned values might include emojis with 86 // `[shortcode]@[domain]`s like `car@example.org`, `debian@aaa.com`, `test@` (local emoji), etc. 87 // 88 // Emoji with the given `[shortcode]@[domain]` will not be included in the result set. 89 // in: query 90 // - 91 // name: min_shortcode_domain 92 // type: string 93 // description: >- 94 // Return only emojis with `[shortcode]@[domain]` *HIGHER* (alphabetically) than given `[shortcode]@[domain]`. 95 // For example, if `max_shortcode_domain=beep@example.org`, then returned values might include emojis with 96 // `[shortcode]@[domain]`s like `arse@test.com`, `0101_binary@hackers.net`, `bee@` (local emoji), etc. 97 // 98 // Emoji with the given `[shortcode]@[domain]` will not be included in the result set. 99 // in: query 100 // 101 // responses: 102 // '200': 103 // headers: 104 // Link: 105 // type: string 106 // description: Links to the next and previous queries. 107 // description: An array of emojis, arranged alphabetically by shortcode and domain. 108 // schema: 109 // type: array 110 // items: 111 // "$ref": "#/definitions/adminEmoji" 112 // '400': 113 // description: bad request 114 // '401': 115 // description: unauthorized 116 // '403': 117 // description: forbidden 118 // '404': 119 // description: not found 120 // '406': 121 // description: not acceptable 122 // '500': 123 // description: internal server error 124 func (m *Module) EmojisGETHandler(c *gin.Context) { 125 authed, err := oauth.Authed(c, true, true, true, true) 126 if err != nil { 127 apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1) 128 return 129 } 130 131 if !*authed.User.Admin { 132 err := fmt.Errorf("user %s not an admin", authed.User.ID) 133 apiutil.ErrorHandler(c, gtserror.NewErrorForbidden(err, err.Error()), m.processor.InstanceGetV1) 134 return 135 } 136 137 if _, err := apiutil.NegotiateAccept(c, apiutil.JSONAcceptHeaders...); err != nil { 138 apiutil.ErrorHandler(c, gtserror.NewErrorNotAcceptable(err, err.Error()), m.processor.InstanceGetV1) 139 return 140 } 141 142 maxShortcodeDomain := c.Query(MaxShortcodeDomainKey) 143 minShortcodeDomain := c.Query(MinShortcodeDomainKey) 144 145 limit := 50 146 limitString := c.Query(LimitKey) 147 if limitString != "" { 148 i, err := strconv.ParseInt(limitString, 10, 32) 149 if err != nil { 150 err := fmt.Errorf("error parsing %s: %s", LimitKey, err) 151 apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGetV1) 152 return 153 } 154 limit = int(i) 155 } 156 if limit < 0 { 157 limit = 0 158 } 159 160 var domain string 161 var includeDisabled bool 162 var includeEnabled bool 163 var shortcode string 164 if filterParam := c.Query(FilterQueryKey); filterParam != "" { 165 filters := strings.Split(filterParam, ",") 166 for _, filter := range filters { 167 lower := strings.ToLower(filter) 168 switch { 169 case strings.HasPrefix(lower, "domain:"): 170 domain = strings.TrimPrefix(lower, "domain:") 171 case lower == "disabled": 172 includeDisabled = true 173 case lower == "enabled": 174 includeEnabled = true 175 case strings.HasPrefix(lower, "shortcode:"): 176 shortcode = strings.Trim(filter[10:], ":") // remove any errant ":" 177 default: 178 err := fmt.Errorf("filter %s not recognized; accepted values are 'domain:[domain]', 'disabled', 'enabled', 'shortcode:[shortcode]'", filter) 179 apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGetV1) 180 return 181 } 182 } 183 } 184 185 if domain == "" { 186 // default is to show all domains 187 domain = db.EmojiAllDomains 188 } else if domain == "local" || domain == config.GetHost() || domain == config.GetAccountDomain() { 189 // pass empty string for local domain 190 domain = "" 191 } 192 193 // normalize filters 194 if !includeDisabled && !includeEnabled { 195 // include both if neither specified 196 includeDisabled = true 197 includeEnabled = true 198 } 199 200 resp, errWithCode := m.processor.Admin().EmojisGet(c.Request.Context(), authed.Account, authed.User, domain, includeDisabled, includeEnabled, shortcode, maxShortcodeDomain, minShortcodeDomain, limit) 201 if errWithCode != nil { 202 apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1) 203 return 204 } 205 206 if resp.LinkHeader != "" { 207 c.Header("Link", resp.LinkHeader) 208 } 209 c.JSON(http.StatusOK, resp.Items) 210 }