diff --git a/api4/bot.go b/api4/bot.go index 4d254f7f6b..812ab6c89a 100644 --- a/api4/bot.go +++ b/api4/bot.go @@ -4,6 +4,7 @@ package api4 import ( + "encoding/json" "fmt" "io" "io/ioutil" @@ -30,8 +31,9 @@ func (api *API) InitBot() { } func createBot(c *Context, w http.ResponseWriter, r *http.Request) { - botPatch := model.BotPatchFromJson(r.Body) - if botPatch == nil { + var botPatch *model.BotPatch + err := json.NewDecoder(r.Body).Decode(&botPatch) + if err != nil { c.SetInvalidParam("bot") return } @@ -62,9 +64,9 @@ func createBot(c *Context, w http.ResponseWriter, r *http.Request) { return } - createdBot, err := c.App.CreateBot(c.AppContext, bot) - if err != nil { - c.Err = err + createdBot, appErr := c.App.CreateBot(c.AppContext, bot) + if appErr != nil { + c.Err = appErr return } @@ -82,8 +84,9 @@ func patchBot(c *Context, w http.ResponseWriter, r *http.Request) { } botUserId := c.Params.BotUserId - botPatch := model.BotPatchFromJson(r.Body) - if botPatch == nil { + var botPatch *model.BotPatch + err := json.NewDecoder(r.Body).Decode(&botPatch) + if err != nil { c.SetInvalidParam("bot") return } @@ -97,9 +100,9 @@ func patchBot(c *Context, w http.ResponseWriter, r *http.Request) { return } - updatedBot, err := c.App.PatchBot(botUserId, botPatch) - if err != nil { - c.Err = err + updatedBot, appErr := c.App.PatchBot(botUserId, botPatch) + if appErr != nil { + c.Err = appErr return } diff --git a/api4/bot_test.go b/api4/bot_test.go index 25c4ced84d..1d2624a6bb 100644 --- a/api4/bot_test.go +++ b/api4/bot_test.go @@ -4,6 +4,7 @@ package api4 import ( + "encoding/json" "fmt" "io/ioutil" "net/http" @@ -444,13 +445,16 @@ func TestPatchBot(t *testing.T) { CheckCreatedStatus(t, resp) defer th.App.PermanentDeleteBot(createdBot.UserId) - r, err := th.Client.DoApiPut(th.Client.GetBotRoute(createdBot.UserId), `{"creator_id":"`+th.BasicUser2.Id+`"}`) - require.Nil(t, err) + r, appErr := th.Client.DoApiPut(th.Client.GetBotRoute(createdBot.UserId), `{"creator_id":"`+th.BasicUser2.Id+`"}`) + require.Nil(t, appErr) defer func() { _, _ = ioutil.ReadAll(r.Body) _ = r.Body.Close() }() - patchedBot := model.BotFromJson(r.Body) + var patchedBot *model.Bot + err := json.NewDecoder(r.Body).Decode(&patchedBot) + require.NoError(t, err) + resp = model.BuildResponse(r) CheckOKStatus(t, resp) diff --git a/app/oauth.go b/app/oauth.go index 87832ab107..131610d419 100644 --- a/app/oauth.go +++ b/app/oauth.go @@ -7,6 +7,7 @@ import ( "bytes" "context" b64 "encoding/base64" + "encoding/json" "errors" "fmt" "io" @@ -847,9 +848,10 @@ func (a *App) AuthorizeOAuthUser(w http.ResponseWriter, r *http.Request, service var buf bytes.Buffer tee := io.TeeReader(resp.Body, &buf) - ar := model.AccessResponseFromJson(tee) - if ar == nil || resp.StatusCode != http.StatusOK { - return nil, "", stateProps, nil, model.NewAppError("AuthorizeOAuthUser", "api.user.authorize_oauth_user.bad_response.app_error", nil, fmt.Sprintf("response_body=%s, status_code=%d", buf.String(), resp.StatusCode), http.StatusInternalServerError) + var ar *model.AccessResponse + err = json.NewDecoder(tee).Decode(&ar) + if err != nil || resp.StatusCode != http.StatusOK { + return nil, "", stateProps, nil, model.NewAppError("AuthorizeOAuthUser", "api.user.authorize_oauth_user.bad_response.app_error", nil, fmt.Sprintf("response_body=%s, status_code=%d, error=%v", buf.String(), resp.StatusCode, err), http.StatusInternalServerError) } if strings.ToLower(ar.TokenType) != model.AccessTokenType { diff --git a/model/access.go b/model/access.go index 815a874738..6669376216 100644 --- a/model/access.go +++ b/model/access.go @@ -5,7 +5,6 @@ package model import ( "encoding/json" - "io" "net/http" ) @@ -79,19 +78,7 @@ func (ad *AccessData) ToJson() string { return string(b) } -func AccessDataFromJson(data io.Reader) *AccessData { - var ad *AccessData - json.NewDecoder(data).Decode(&ad) - return ad -} - func (ar *AccessResponse) ToJson() string { b, _ := json.Marshal(ar) return string(b) } - -func AccessResponseFromJson(data io.Reader) *AccessResponse { - var ar *AccessResponse - json.NewDecoder(data).Decode(&ar) - return ar -} diff --git a/model/access_test.go b/model/access_test.go index c2b4b37e41..8cf53638d5 100644 --- a/model/access_test.go +++ b/model/access_test.go @@ -4,25 +4,11 @@ package model import ( - "strings" "testing" "github.com/stretchr/testify/require" ) -func TestAccessJson(t *testing.T) { - a1 := AccessData{} - a1.ClientId = NewId() - a1.UserId = NewId() - a1.Token = NewId() - a1.RefreshToken = NewId() - - json := a1.ToJson() - ra1 := AccessDataFromJson(strings.NewReader(json)) - - require.Equal(t, a1.Token, ra1.Token) -} - func TestAccessIsValid(t *testing.T) { ad := AccessData{} diff --git a/model/analytics_row.go b/model/analytics_row.go index d12166642d..4dff8c50bc 100644 --- a/model/analytics_row.go +++ b/model/analytics_row.go @@ -5,7 +5,6 @@ package model import ( "encoding/json" - "io" ) type AnalyticsRow struct { @@ -20,12 +19,6 @@ func (ar *AnalyticsRow) ToJson() string { return string(b) } -func AnalyticsRowFromJson(data io.Reader) *AnalyticsRow { - var ar *AnalyticsRow - json.NewDecoder(data).Decode(&ar) - return ar -} - func (ar AnalyticsRows) ToJson() string { b, err := json.Marshal(ar) if err != nil { @@ -33,9 +26,3 @@ func (ar AnalyticsRows) ToJson() string { } return string(b) } - -func AnalyticsRowsFromJson(data io.Reader) AnalyticsRows { - var ar AnalyticsRows - json.NewDecoder(data).Decode(&ar) - return ar -} diff --git a/model/analytics_row_test.go b/model/analytics_row_test.go deleted file mode 100644 index 2102314df4..0000000000 --- a/model/analytics_row_test.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. - -package model - -import ( - "strings" - "testing" - - "github.com/stretchr/testify/require" -) - -var a1 = AnalyticsRow{ - Name: "2015-10-12", - Value: 12345.0, -} - -func TestAnalyticsRowJson(t *testing.T) { - ra1 := AnalyticsRowFromJson(strings.NewReader(a1.ToJson())) - require.Equal(t, a1.Name, ra1.Name, "days didn't match") -} - -func TestAnalyticsRowsJson(t *testing.T) { - var a1s AnalyticsRows = make([]*AnalyticsRow, 1) - a1s[0] = &a1 - results := AnalyticsRowsFromJson(strings.NewReader(a1s.ToJson())) - require.Equal(t, a1s[0].Name, results[0].Name, "Ids do not match") -} diff --git a/model/audit.go b/model/audit.go index dd1e060260..fcd401af09 100644 --- a/model/audit.go +++ b/model/audit.go @@ -5,7 +5,6 @@ package model import ( "encoding/json" - "io" ) type Audit struct { @@ -22,9 +21,3 @@ func (o *Audit) ToJson() string { b, _ := json.Marshal(o) return string(b) } - -func AuditFromJson(data io.Reader) *Audit { - var o *Audit - json.NewDecoder(data).Decode(&o) - return o -} diff --git a/model/audit_test.go b/model/audit_test.go deleted file mode 100644 index f51abe27a5..0000000000 --- a/model/audit_test.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. - -package model - -import ( - "strings" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestAuditJson(t *testing.T) { - audit := Audit{Id: NewId(), UserId: NewId(), CreateAt: GetMillis()} - json := audit.ToJson() - result := AuditFromJson(strings.NewReader(json)) - require.Equal(t, audit.Id, result.Id, "Ids do not match") -} diff --git a/model/audits.go b/model/audits.go index 54e361f99b..ba20dd25b3 100644 --- a/model/audits.go +++ b/model/audits.go @@ -5,7 +5,6 @@ package model import ( "encoding/json" - "io" ) type Audits []Audit @@ -25,9 +24,3 @@ func (o Audits) ToJson() string { } return string(b) } - -func AuditsFromJson(data io.Reader) Audits { - var o Audits - json.NewDecoder(data).Decode(&o) - return o -} diff --git a/model/audits_test.go b/model/audits_test.go deleted file mode 100644 index fc7fd77ed7..0000000000 --- a/model/audits_test.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. - -package model - -import ( - "strings" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestAuditsJson(t *testing.T) { - audit := Audit{Id: NewId(), UserId: NewId(), CreateAt: GetMillis()} - json := audit.ToJson() - result := AuditFromJson(strings.NewReader(json)) - - require.Equal(t, audit.Id, result.Id, "Ids do not match") - - var audits Audits = make([]Audit, 1) - audits[0] = audit - - ljson := audits.ToJson() - results := AuditsFromJson(strings.NewReader(ljson)) - - require.Equal(t, audits[0].Id, results[0].Id, "Ids do not match") -} diff --git a/model/authorize.go b/model/authorize.go index 8942f2c22c..d7c489ec33 100644 --- a/model/authorize.go +++ b/model/authorize.go @@ -5,7 +5,6 @@ package model import ( "encoding/json" - "io" "net/http" ) @@ -120,23 +119,11 @@ func (ad *AuthData) ToJson() string { return string(b) } -func AuthDataFromJson(data io.Reader) *AuthData { - var ad *AuthData - json.NewDecoder(data).Decode(&ad) - return ad -} - func (ar *AuthorizeRequest) ToJson() string { b, _ := json.Marshal(ar) return string(b) } -func AuthorizeRequestFromJson(data io.Reader) *AuthorizeRequest { - var ar *AuthorizeRequest - json.NewDecoder(data).Decode(&ar) - return ar -} - func (ad *AuthData) IsExpired() bool { return GetMillis() > ad.CreateAt+int64(ad.ExpiresIn*1000) } diff --git a/model/authorize_test.go b/model/authorize_test.go index 26e8978cd6..35c8fc19da 100644 --- a/model/authorize_test.go +++ b/model/authorize_test.go @@ -4,32 +4,11 @@ package model import ( - "strings" "testing" "github.com/stretchr/testify/require" ) -func TestAuthJson(t *testing.T) { - a1 := AuthData{} - a1.ClientId = NewId() - a1.UserId = NewId() - a1.Code = NewId() - - json := a1.ToJson() - ra1 := AuthDataFromJson(strings.NewReader(json)) - require.Equal(t, a1.Code, ra1.Code, "codes didn't match") - - a2 := AuthorizeRequest{} - a2.ClientId = NewId() - a2.Scope = NewId() - - json = a2.ToJson() - ra2 := AuthorizeRequestFromJson(strings.NewReader(json)) - - require.Equal(t, a2.ClientId, ra2.ClientId, "client ids didn't match") -} - func TestAuthPreSave(t *testing.T) { a1 := AuthData{} a1.ClientId = NewId() diff --git a/model/bot.go b/model/bot.go index 239477f8d1..c985fd89ee 100644 --- a/model/bot.go +++ b/model/bot.go @@ -6,7 +6,6 @@ package model import ( "encoding/json" "fmt" - "io" "net/http" "strings" "unicode/utf8" @@ -121,13 +120,6 @@ func (b *Bot) ToJson() []byte { return data } -// BotFromJson deserializes a bot from json. -func BotFromJson(data io.Reader) *Bot { - var bot *Bot - json.NewDecoder(data).Decode(&bot) - return bot -} - // Patch modifies an existing bot with optional fields from the given patch. // TODO 6.0: consider returning a boolean to indicate whether or not the patch // applied any changes. @@ -172,18 +164,6 @@ func (b *BotPatch) ToJson() []byte { return data } -// BotPatchFromJson deserializes a bot patch from json. -func BotPatchFromJson(data io.Reader) *BotPatch { - decoder := json.NewDecoder(data) - var botPatch BotPatch - err := decoder.Decode(&botPatch) - if err != nil { - return nil - } - - return &botPatch -} - // UserFromBot returns a user model describing the bot fields stored in the User store. func UserFromBot(b *Bot) *User { return &User{ @@ -205,13 +185,6 @@ func BotFromUser(u *User) *Bot { } } -// BotListFromJson deserializes a list of bots from json. -func BotListFromJson(data io.Reader) BotList { - var bots BotList - json.NewDecoder(data).Decode(&bots) - return bots -} - // ToJson serializes a list of bots to json. func (l *BotList) ToJson() []byte { b, _ := json.Marshal(l) diff --git a/model/bot_test.go b/model/bot_test.go index 8762b29b1b..be4ed63fff 100644 --- a/model/bot_test.go +++ b/model/bot_test.go @@ -4,7 +4,6 @@ package model import ( - "bytes" "strings" "testing" @@ -352,35 +351,6 @@ func TestBotEtag(t *testing.T) { }) } -func TestBotToAndFromJson(t *testing.T) { - bot1 := &Bot{ - UserId: NewId(), - Username: "username", - DisplayName: "display name", - Description: "description", - OwnerId: NewId(), - LastIconUpdate: 1, - CreateAt: 2, - UpdateAt: 3, - DeleteAt: 4, - } - - bot2 := &Bot{ - UserId: NewId(), - Username: "username", - DisplayName: "display name", - Description: "description 2", - OwnerId: NewId(), - LastIconUpdate: 5, - CreateAt: 6, - UpdateAt: 7, - DeleteAt: 8, - } - - assert.Equal(t, bot1, BotFromJson(bytes.NewReader(bot1.ToJson()))) - assert.Equal(t, bot2, BotFromJson(bytes.NewReader(bot2.ToJson()))) -} - func sToP(s string) *string { return &s } @@ -525,23 +495,6 @@ func TestBotWouldPatch(t *testing.T) { }) } -func TestBotPatchToAndFromJson(t *testing.T) { - botPatch1 := &BotPatch{ - Username: sToP("username"), - DisplayName: sToP("display name"), - Description: sToP("description"), - } - - botPatch2 := &BotPatch{ - Username: sToP("username"), - DisplayName: sToP("display name"), - Description: sToP("description 2"), - } - - assert.Equal(t, botPatch1, BotPatchFromJson(bytes.NewReader(botPatch1.ToJson()))) - assert.Equal(t, botPatch2, BotPatchFromJson(bytes.NewReader(botPatch2.ToJson()))) -} - func TestUserFromBot(t *testing.T) { bot1 := &Bot{ UserId: NewId(), @@ -600,68 +553,6 @@ func TestBotFromUser(t *testing.T) { }, BotFromUser(user)) } -func TestBotListToAndFromJson(t *testing.T) { - testCases := []struct { - Description string - BotList BotList - }{ - { - "empty list", - BotList{}, - }, - { - "single item", - BotList{ - &Bot{ - UserId: NewId(), - Username: "username", - DisplayName: "display name", - Description: "description", - OwnerId: NewId(), - LastIconUpdate: 1, - CreateAt: 2, - UpdateAt: 3, - DeleteAt: 4, - }, - }, - }, - { - "multiple items", - BotList{ - &Bot{ - UserId: NewId(), - Username: "username", - DisplayName: "display name", - Description: "description", - OwnerId: NewId(), - LastIconUpdate: 1, - CreateAt: 2, - UpdateAt: 3, - DeleteAt: 4, - }, - - &Bot{ - UserId: NewId(), - Username: "username", - DisplayName: "display name", - Description: "description 2", - OwnerId: NewId(), - LastIconUpdate: 5, - CreateAt: 6, - UpdateAt: 7, - DeleteAt: 8, - }, - }, - }, - } - - for _, testCase := range testCases { - t.Run(testCase.Description, func(t *testing.T) { - assert.Equal(t, testCase.BotList, BotListFromJson(bytes.NewReader(testCase.BotList.ToJson()))) - }) - } -} - func TestBotListEtag(t *testing.T) { bot1 := &Bot{ UserId: NewId(), diff --git a/model/client4.go b/model/client4.go index 526acd1e6e..c25bdea523 100644 --- a/model/client4.go +++ b/model/client4.go @@ -1331,12 +1331,17 @@ func (c *Client4) PermanentDeleteUser(userId string) (bool, *Response) { // ConvertUserToBot converts a user to a bot user. func (c *Client4) ConvertUserToBot(userId string) (*Bot, *Response) { - r, err := c.DoApiPost(c.GetUserRoute(userId)+"/convert_to_bot", "") - if err != nil { - return nil, BuildErrorResponse(r, err) + r, appErr := c.DoApiPost(c.GetUserRoute(userId)+"/convert_to_bot", "") + if appErr != nil { + return nil, BuildErrorResponse(r, appErr) } defer closeBody(r) - return BotFromJson(r.Body), BuildResponse(r) + var bot *Bot + err := json.NewDecoder(r.Body).Decode(&bot) + if err != nil { + return nil, BuildErrorResponse(r, NewAppError("ConvertUserToBot", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError)) + } + return bot, BuildResponse(r) } // ConvertBotToUser converts a bot user to a user. @@ -1458,12 +1463,18 @@ func (c *Client4) GetTeamsUnreadForUser(userId, teamIdToExclude string) ([]*Team // GetUserAudits returns a list of audit based on the provided user id string. func (c *Client4) GetUserAudits(userId string, page int, perPage int, etag string) (Audits, *Response) { query := fmt.Sprintf("?page=%v&per_page=%v", page, perPage) - r, err := c.DoApiGet(c.GetUserRoute(userId)+"/audits"+query, etag) - if err != nil { - return nil, BuildErrorResponse(r, err) + r, appErr := c.DoApiGet(c.GetUserRoute(userId)+"/audits"+query, etag) + if appErr != nil { + return nil, BuildErrorResponse(r, appErr) } defer closeBody(r) - return AuditsFromJson(r.Body), BuildResponse(r) + + var audits Audits + err := json.NewDecoder(r.Body).Decode(&audits) + if err != nil { + return nil, BuildErrorResponse(r, NewAppError("GetUserAudits", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError)) + } + return audits, BuildResponse(r) } // VerifyUserEmail will verify a user's email using the supplied token. @@ -1657,105 +1668,172 @@ func (c *Client4) EnableUserAccessToken(tokenId string) (bool, *Response) { // CreateBot creates a bot in the system based on the provided bot struct. func (c *Client4) CreateBot(bot *Bot) (*Bot, *Response) { - r, err := c.doApiPostBytes(c.GetBotsRoute(), bot.ToJson()) - if err != nil { - return nil, BuildErrorResponse(r, err) + r, appErr := c.doApiPostBytes(c.GetBotsRoute(), bot.ToJson()) + if appErr != nil { + return nil, BuildErrorResponse(r, appErr) } defer closeBody(r) - return BotFromJson(r.Body), BuildResponse(r) + + var resp *Bot + err := json.NewDecoder(r.Body).Decode(&resp) + if err != nil { + return nil, BuildErrorResponse(r, NewAppError("CreateBot", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError)) + } + + return resp, BuildResponse(r) } // PatchBot partially updates a bot. Any missing fields are not updated. func (c *Client4) PatchBot(userId string, patch *BotPatch) (*Bot, *Response) { - r, err := c.doApiPutBytes(c.GetBotRoute(userId), patch.ToJson()) - if err != nil { - return nil, BuildErrorResponse(r, err) + r, appErr := c.doApiPutBytes(c.GetBotRoute(userId), patch.ToJson()) + if appErr != nil { + return nil, BuildErrorResponse(r, appErr) } defer closeBody(r) - return BotFromJson(r.Body), BuildResponse(r) + + var bot *Bot + err := json.NewDecoder(r.Body).Decode(&bot) + if err != nil { + return nil, BuildErrorResponse(r, NewAppError("PatchBot", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError)) + } + + return bot, BuildResponse(r) } // GetBot fetches the given, undeleted bot. func (c *Client4) GetBot(userId string, etag string) (*Bot, *Response) { - r, err := c.DoApiGet(c.GetBotRoute(userId), etag) - if err != nil { - return nil, BuildErrorResponse(r, err) + r, appErr := c.DoApiGet(c.GetBotRoute(userId), etag) + if appErr != nil { + return nil, BuildErrorResponse(r, appErr) } defer closeBody(r) - return BotFromJson(r.Body), BuildResponse(r) + + var bot *Bot + err := json.NewDecoder(r.Body).Decode(&bot) + if err != nil { + return nil, BuildErrorResponse(r, NewAppError("GetBot", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError)) + } + + return bot, BuildResponse(r) } -// GetBot fetches the given bot, even if it is deleted. +// GetBotIncludeDeleted fetches the given bot, even if it is deleted. func (c *Client4) GetBotIncludeDeleted(userId string, etag string) (*Bot, *Response) { - r, err := c.DoApiGet(c.GetBotRoute(userId)+"?include_deleted="+c.boolString(true), etag) - if err != nil { - return nil, BuildErrorResponse(r, err) + r, appErr := c.DoApiGet(c.GetBotRoute(userId)+"?include_deleted="+c.boolString(true), etag) + if appErr != nil { + return nil, BuildErrorResponse(r, appErr) } defer closeBody(r) - return BotFromJson(r.Body), BuildResponse(r) + + var bot *Bot + err := json.NewDecoder(r.Body).Decode(&bot) + if err != nil { + return nil, BuildErrorResponse(r, NewAppError("GetBotIncludeDeleted", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError)) + } + + return bot, BuildResponse(r) } // GetBots fetches the given page of bots, excluding deleted. func (c *Client4) GetBots(page, perPage int, etag string) ([]*Bot, *Response) { query := fmt.Sprintf("?page=%v&per_page=%v", page, perPage) - r, err := c.DoApiGet(c.GetBotsRoute()+query, etag) - if err != nil { - return nil, BuildErrorResponse(r, err) + r, appErr := c.DoApiGet(c.GetBotsRoute()+query, etag) + if appErr != nil { + return nil, BuildErrorResponse(r, appErr) } defer closeBody(r) - return BotListFromJson(r.Body), BuildResponse(r) + + var bots BotList + err := json.NewDecoder(r.Body).Decode(&bots) + if err != nil { + return nil, BuildErrorResponse(r, NewAppError("GetBots", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError)) + } + return bots, BuildResponse(r) } // GetBotsIncludeDeleted fetches the given page of bots, including deleted. func (c *Client4) GetBotsIncludeDeleted(page, perPage int, etag string) ([]*Bot, *Response) { query := fmt.Sprintf("?page=%v&per_page=%v&include_deleted="+c.boolString(true), page, perPage) - r, err := c.DoApiGet(c.GetBotsRoute()+query, etag) - if err != nil { - return nil, BuildErrorResponse(r, err) + r, appErr := c.DoApiGet(c.GetBotsRoute()+query, etag) + if appErr != nil { + return nil, BuildErrorResponse(r, appErr) } defer closeBody(r) - return BotListFromJson(r.Body), BuildResponse(r) + + var bots BotList + err := json.NewDecoder(r.Body).Decode(&bots) + if err != nil { + return nil, BuildErrorResponse(r, NewAppError("GetBotsIncludeDeleted", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError)) + } + return bots, BuildResponse(r) } // GetBotsOrphaned fetches the given page of bots, only including orphanded bots. func (c *Client4) GetBotsOrphaned(page, perPage int, etag string) ([]*Bot, *Response) { query := fmt.Sprintf("?page=%v&per_page=%v&only_orphaned="+c.boolString(true), page, perPage) - r, err := c.DoApiGet(c.GetBotsRoute()+query, etag) - if err != nil { - return nil, BuildErrorResponse(r, err) + r, appErr := c.DoApiGet(c.GetBotsRoute()+query, etag) + if appErr != nil { + return nil, BuildErrorResponse(r, appErr) } defer closeBody(r) - return BotListFromJson(r.Body), BuildResponse(r) + + var bots BotList + err := json.NewDecoder(r.Body).Decode(&bots) + if err != nil { + return nil, BuildErrorResponse(r, NewAppError("GetBotsOrphaned", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError)) + } + return bots, BuildResponse(r) } // DisableBot disables the given bot in the system. func (c *Client4) DisableBot(botUserId string) (*Bot, *Response) { - r, err := c.doApiPostBytes(c.GetBotRoute(botUserId)+"/disable", nil) - if err != nil { - return nil, BuildErrorResponse(r, err) + r, appErr := c.doApiPostBytes(c.GetBotRoute(botUserId)+"/disable", nil) + if appErr != nil { + return nil, BuildErrorResponse(r, appErr) } defer closeBody(r) - return BotFromJson(r.Body), BuildResponse(r) + + var bot *Bot + err := json.NewDecoder(r.Body).Decode(&bot) + if err != nil { + return nil, BuildErrorResponse(r, NewAppError("DisableBot", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError)) + } + + return bot, BuildResponse(r) } // EnableBot disables the given bot in the system. func (c *Client4) EnableBot(botUserId string) (*Bot, *Response) { - r, err := c.doApiPostBytes(c.GetBotRoute(botUserId)+"/enable", nil) - if err != nil { - return nil, BuildErrorResponse(r, err) + r, appErr := c.doApiPostBytes(c.GetBotRoute(botUserId)+"/enable", nil) + if appErr != nil { + return nil, BuildErrorResponse(r, appErr) } defer closeBody(r) - return BotFromJson(r.Body), BuildResponse(r) + + var bot *Bot + err := json.NewDecoder(r.Body).Decode(&bot) + if err != nil { + return nil, BuildErrorResponse(r, NewAppError("EnableBot", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError)) + } + + return bot, BuildResponse(r) } // AssignBot assigns the given bot to the given user func (c *Client4) AssignBot(botUserId, newOwnerId string) (*Bot, *Response) { - r, err := c.doApiPostBytes(c.GetBotRoute(botUserId)+"/assign/"+newOwnerId, nil) - if err != nil { - return nil, BuildErrorResponse(r, err) + r, appErr := c.doApiPostBytes(c.GetBotRoute(botUserId)+"/assign/"+newOwnerId, nil) + if appErr != nil { + return nil, BuildErrorResponse(r, appErr) } defer closeBody(r) - return BotFromJson(r.Body), BuildResponse(r) + + var bot *Bot + err := json.NewDecoder(r.Body).Decode(&bot) + if err != nil { + return nil, BuildErrorResponse(r, NewAppError("AssignBot", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError)) + } + + return bot, BuildResponse(r) } // SetBotIconImage sets LHS bot icon image. @@ -3602,12 +3680,18 @@ func (c *Client4) RemoveLicenseFile() (bool, *Response) { // to a specific team. func (c *Client4) GetAnalyticsOld(name, teamId string) (AnalyticsRows, *Response) { query := fmt.Sprintf("?name=%v&team_id=%v", name, teamId) - r, err := c.DoApiGet(c.GetAnalyticsRoute()+"/old"+query, "") - if err != nil { - return nil, BuildErrorResponse(r, err) + r, appErr := c.DoApiGet(c.GetAnalyticsRoute()+"/old"+query, "") + if appErr != nil { + return nil, BuildErrorResponse(r, appErr) } defer closeBody(r) - return AnalyticsRowsFromJson(r.Body), BuildResponse(r) + + var rows AnalyticsRows + err := json.NewDecoder(r.Body).Decode(&rows) + if err != nil { + return nil, BuildErrorResponse(r, NewAppError("GetAnalyticsOld", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError)) + } + return rows, BuildResponse(r) } // Webhooks Section @@ -4309,12 +4393,18 @@ func (c *Client4) DeleteLdapPrivateCertificate() (bool, *Response) { // GetAudits returns a list of audits for the whole system. func (c *Client4) GetAudits(page int, perPage int, etag string) (Audits, *Response) { query := fmt.Sprintf("?page=%v&per_page=%v", page, perPage) - r, err := c.DoApiGet("/audits"+query, etag) - if err != nil { - return nil, BuildErrorResponse(r, err) + r, appErr := c.DoApiGet("/audits"+query, etag) + if appErr != nil { + return nil, BuildErrorResponse(r, appErr) } defer closeBody(r) - return AuditsFromJson(r.Body), BuildResponse(r) + + var audits Audits + err := json.NewDecoder(r.Body).Decode(&audits) + if err != nil { + return nil, BuildErrorResponse(r, NewAppError("GetAudits", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError)) + } + return audits, BuildResponse(r) } // Brand Section @@ -4521,9 +4611,10 @@ func (c *Client4) DeauthorizeOAuthApp(appId string) (bool, *Response) { // GetOAuthAccessToken is a test helper function for the OAuth access token endpoint. func (c *Client4) GetOAuthAccessToken(data url.Values) (*AccessResponse, *Response) { - rq, err := http.NewRequest(http.MethodPost, c.Url+"/oauth/access_token", strings.NewReader(data.Encode())) + url := c.Url + "/oauth/access_token" + rq, err := http.NewRequest(http.MethodPost, url, strings.NewReader(data.Encode())) if err != nil { - return nil, &Response{Error: NewAppError(c.Url+"/oauth/access_token", "model.client.connecting.app_error", nil, err.Error(), http.StatusBadRequest)} + return nil, &Response{Error: NewAppError(url, "model.client.connecting.app_error", nil, err.Error(), http.StatusBadRequest)} } rq.Header.Set("Content-Type", "application/x-www-form-urlencoded") @@ -4533,7 +4624,7 @@ func (c *Client4) GetOAuthAccessToken(data url.Values) (*AccessResponse, *Respon rp, err := c.HttpClient.Do(rq) if err != nil || rp == nil { - return nil, &Response{StatusCode: http.StatusForbidden, Error: NewAppError(c.Url+"/oauth/access_token", "model.client.connecting.app_error", nil, err.Error(), 403)} + return nil, &Response{StatusCode: http.StatusForbidden, Error: NewAppError(url, "model.client.connecting.app_error", nil, err.Error(), 403)} } defer closeBody(rp) @@ -4541,7 +4632,13 @@ func (c *Client4) GetOAuthAccessToken(data url.Values) (*AccessResponse, *Respon return nil, BuildErrorResponse(rp, AppErrorFromJson(rp.Body)) } - return AccessResponseFromJson(rp.Body), BuildResponse(rp) + var ar *AccessResponse + err = json.NewDecoder(rp.Body).Decode(&ar) + if err != nil { + return nil, BuildErrorResponse(rp, NewAppError(url, "api.marshal_error", nil, err.Error(), http.StatusInternalServerError)) + } + + return ar, BuildResponse(rp) } // Elasticsearch Section diff --git a/web/oauth.go b/web/oauth.go index c1ebd901db..785279a458 100644 --- a/web/oauth.go +++ b/web/oauth.go @@ -4,6 +4,7 @@ package web import ( + "encoding/json" "html" "net/http" "net/url" @@ -44,8 +45,9 @@ func testHandler(c *Context, w http.ResponseWriter, r *http.Request) { } func authorizeOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) { - authRequest := model.AuthorizeRequestFromJson(r.Body) - if authRequest == nil { + var authRequest *model.AuthorizeRequest + err := json.NewDecoder(r.Body).Decode(&authRequest) + if err != nil || authRequest == nil { c.SetInvalidParam("authorize_request") return } @@ -65,10 +67,9 @@ func authorizeOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) { defer c.LogAuditRec(auditRec) c.LogAudit("attempt") - redirectUrl, err := c.App.AllowOAuthAppAccessToUser(c.AppContext.Session().UserId, authRequest) - - if err != nil { - c.Err = err + redirectUrl, appErr := c.App.AllowOAuthAppAccessToUser(c.AppContext.Session().UserId, authRequest) + if appErr != nil { + c.Err = appErr return }