Convert bool string comparisons to strconv.ParseBool for REST parameters (#13650)

* Convert bool string comparisons to strconv.ParseBool for REST parameters

* Log failed bool conversions

* Rename errors, changed log levels

* drop strconv.ParseBool error handling

If the query string parameter is omitted, strconv.ParseBool returns an error for the empty strings, which spams the logs. Instead, just assume the default semantics of a `false` return value if an error occurs.

* allow randomized Client4 booleans

It's hard to test api4's handling of the various boolean input values
accepted. Extend Client4 with support for overriding how it builds those
strings, and pick a random value on test startup.

* gofmt -s

Co-authored-by: mattermod <mattermod@users.noreply.github.com>
Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
Co-authored-by: Jesse Hallam <jesse.hallam@gmail.com>
Этот коммит содержится в:
Arianna Vespri
2020-05-23 23:01:31 +02:00
коммит произвёл GitHub
родитель f7a91c7cf9
Коммит 2135096d88
7 изменённых файлов: 96 добавлений и 73 удалений

Просмотреть файл

@@ -6,6 +6,7 @@ package api4
import (
"fmt"
"io/ioutil"
"math/rand"
"net"
"net/http"
"os"
@@ -153,6 +154,16 @@ func setupTestHelper(dbStore store.Store, searchEngine *searchengine.Broker, ent
th.Client = th.CreateClient()
th.SystemAdminClient = th.CreateClient()
// Verify handling of the supported true/false values by randomizing on each run.
rand.Seed(time.Now().UTC().UnixNano())
trueValues := []string{"1", "t", "T", "TRUE", "true", "True"}
falseValues := []string{"0", "f", "F", "FALSE", "false", "False"}
trueString := trueValues[rand.Intn(len(trueValues))]
falseString := falseValues[rand.Intn(len(falseValues))]
mlog.Debug("Configured Client4 bool string values", mlog.String("true", trueString), mlog.String("false", falseString))
th.Client.SetBoolString(true, trueString)
th.Client.SetBoolString(false, falseString)
th.LocalClient = th.CreateLocalClient(*config.ServiceSettings.LocalModeSocketLocation)
if th.tempWorkspace == "" {

Просмотреть файл

@@ -115,11 +115,11 @@ func getBot(c *Context, w http.ResponseWriter, r *http.Request) {
}
botUserId := c.Params.BotUserId
includeDeleted := r.URL.Query().Get("include_deleted") == "true"
includeDeleted, _ := strconv.ParseBool(r.URL.Query().Get("include_deleted"))
bot, err := c.App.GetBot(botUserId, includeDeleted)
if err != nil {
c.Err = err
bot, appErr := c.App.GetBot(botUserId, includeDeleted)
if appErr != nil {
c.Err = appErr
return
}
@@ -148,8 +148,8 @@ func getBot(c *Context, w http.ResponseWriter, r *http.Request) {
}
func getBots(c *Context, w http.ResponseWriter, r *http.Request) {
includeDeleted := r.URL.Query().Get("include_deleted") == "true"
onlyOrphaned := r.URL.Query().Get("only_orphaned") == "true"
includeDeleted, _ := strconv.ParseBool(r.URL.Query().Get("include_deleted"))
onlyOrphaned, _ := strconv.ParseBool(r.URL.Query().Get("only_orphaned"))
var OwnerId string
if c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_READ_OTHERS_BOTS) {
@@ -163,15 +163,15 @@ func getBots(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
bots, err := c.App.GetBots(&model.BotGetOptions{
bots, appErr := c.App.GetBots(&model.BotGetOptions{
Page: c.Params.Page,
PerPage: c.Params.PerPage,
OwnerId: OwnerId,
IncludeDeleted: includeDeleted,
OnlyOrphaned: onlyOrphaned,
})
if err != nil {
c.Err = err
if appErr != nil {
c.Err = appErr
return
}

Просмотреть файл

@@ -6,6 +6,7 @@ package api4
import (
"encoding/json"
"net/http"
"strconv"
"strings"
"github.com/mattermost/mattermost-server/v5/audit"
@@ -959,18 +960,18 @@ func searchAllChannels(c *Context, w http.ResponseWriter, r *http.Request) {
c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
return
}
includeDeleted, _ := strconv.ParseBool(r.URL.Query().Get("include_deleted"))
opts := model.ChannelSearchOpts{
NotAssociatedToGroup: props.NotAssociatedToGroup,
ExcludeDefaultChannels: props.ExcludeDefaultChannels,
IncludeDeleted: r.URL.Query().Get("include_deleted") == "true",
IncludeDeleted: includeDeleted,
Page: props.Page,
PerPage: props.PerPage,
}
channels, totalCount, err := c.App.SearchAllChannels(props.Term, opts)
if err != nil {
c.Err = err
channels, totalCount, appErr := c.App.SearchAllChannels(props.Term, opts)
if appErr != nil {
c.Err = appErr
return
}
@@ -1037,11 +1038,10 @@ func getChannelByName(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
includeDeleted := r.URL.Query().Get("include_deleted") == "true"
channel, err := c.App.GetChannelByName(c.Params.ChannelName, c.Params.TeamId, includeDeleted)
if err != nil {
c.Err = err
includeDeleted, _ := strconv.ParseBool(r.URL.Query().Get("include_deleted"))
channel, appErr := c.App.GetChannelByName(c.Params.ChannelName, c.Params.TeamId, includeDeleted)
if appErr != nil {
c.Err = appErr
return
}
@@ -1057,9 +1057,9 @@ func getChannelByName(c *Context, w http.ResponseWriter, r *http.Request) {
}
}
err = c.App.FillInChannelProps(channel)
if err != nil {
c.Err = err
appErr = c.App.FillInChannelProps(channel)
if appErr != nil {
c.Err = appErr
return
}
@@ -1072,11 +1072,10 @@ func getChannelByNameForTeamName(c *Context, w http.ResponseWriter, r *http.Requ
return
}
includeDeleted := r.URL.Query().Get("include_deleted") == "true"
channel, err := c.App.GetChannelByNameForTeamName(c.Params.ChannelName, c.Params.TeamName, includeDeleted)
if err != nil {
c.Err = err
includeDeleted, _ := strconv.ParseBool(r.URL.Query().Get("include_deleted"))
channel, appErr := c.App.GetChannelByNameForTeamName(c.Params.ChannelName, c.Params.TeamName, includeDeleted)
if appErr != nil {
c.Err = appErr
return
}
@@ -1085,9 +1084,9 @@ func getChannelByNameForTeamName(c *Context, w http.ResponseWriter, r *http.Requ
return
}
err = c.App.FillInChannelProps(channel)
if err != nil {
c.Err = err
appErr = c.App.FillInChannelProps(channel)
if appErr != nil {
c.Err = appErr
return
}

Просмотреть файл

@@ -213,10 +213,7 @@ func deleteCommand(c *Context, w http.ResponseWriter, r *http.Request) {
}
func listCommands(c *Context, w http.ResponseWriter, r *http.Request) {
customOnly, failConv := strconv.ParseBool(r.URL.Query().Get("custom_only"))
if failConv != nil {
customOnly = false
}
customOnly, _ := strconv.ParseBool(r.URL.Query().Get("custom_only"))
teamId := r.URL.Query().Get("team_id")
if len(teamId) == 0 {

Просмотреть файл

@@ -464,10 +464,7 @@ func getFile(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
forceDownload, convErr := strconv.ParseBool(r.URL.Query().Get("download"))
if convErr != nil {
forceDownload = false
}
forceDownload, _ := strconv.ParseBool(r.URL.Query().Get("download"))
auditRec := c.MakeAuditRecord("getFile", audit.Fail)
defer c.LogAuditRec(auditRec)
@@ -508,11 +505,7 @@ func getFileThumbnail(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
forceDownload, convErr := strconv.ParseBool(r.URL.Query().Get("download"))
if convErr != nil {
forceDownload = false
}
forceDownload, _ := strconv.ParseBool(r.URL.Query().Get("download"))
info, err := c.App.GetFileInfo(c.Params.FileId)
if err != nil {
c.Err = err
@@ -591,11 +584,7 @@ func getFilePreview(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
forceDownload, convErr := strconv.ParseBool(r.URL.Query().Get("download"))
if convErr != nil {
forceDownload = false
}
forceDownload, _ := strconv.ParseBool(r.URL.Query().Get("download"))
info, err := c.App.GetFileInfo(c.Params.FileId)
if err != nil {
c.Err = err

Просмотреть файл

@@ -106,7 +106,7 @@ func installPluginFromUrl(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
force := r.URL.Query().Get("force") == "true"
force, _ := strconv.ParseBool(r.URL.Query().Get("force"))
downloadURL := r.URL.Query().Get("plugin_download_url")
auditRec.AddMeta("url", downloadURL)
@@ -364,11 +364,7 @@ func parseMarketplacePluginFilter(u *url.URL) (*model.MarketplacePluginFilter, e
filter := u.Query().Get("filter")
serverVersion := u.Query().Get("server_version")
localOnly, err := strconv.ParseBool(u.Query().Get("local_only"))
if err != nil {
localOnly = false
}
localOnly, _ := strconv.ParseBool(u.Query().Get("local_only"))
return &model.MarketplacePluginFilter{
Page: page,
PerPage: perPage,