Implemented preferences endpoints for apiv4 (#5531)

* implemented preferences endpoints for apiv4

* added user id in preferences endpoints
Этот коммит содержится в:
Ruzette Tanyag
2017-02-28 04:14:16 -05:00
коммит произвёл George Goldberg
родитель 758402311a
Коммит cef5028cbe
7 изменённых файлов: 594 добавлений и 15 удалений

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

@@ -130,7 +130,7 @@ func InitApi(full bool) {
BaseRoutes.OAuth = BaseRoutes.ApiRoot.PathPrefix("/oauth").Subrouter()
BaseRoutes.Admin = BaseRoutes.ApiRoot.PathPrefix("/admin").Subrouter()
BaseRoutes.System = BaseRoutes.ApiRoot.PathPrefix("/system").Subrouter()
BaseRoutes.Preferences = BaseRoutes.ApiRoot.PathPrefix("/preferences").Subrouter()
BaseRoutes.Preferences = BaseRoutes.User.PathPrefix("/preferences").Subrouter()
BaseRoutes.License = BaseRoutes.ApiRoot.PathPrefix("/license").Subrouter()
BaseRoutes.Public = BaseRoutes.ApiRoot.PathPrefix("/public").Subrouter()
@@ -146,6 +146,7 @@ func InitApi(full bool) {
InitFile()
InitSystem()
InitWebhook()
InitPreference()
app.Srv.Router.Handle("/api/v4/{anything:.*}", http.HandlerFunc(Handle404))

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

@@ -431,3 +431,27 @@ func (c *Context) RequireEmail() *Context {
return c
}
func (c *Context) RequireCategory() *Context {
if c.Err != nil {
return c
}
if !model.IsValidAlphaNum(c.Params.Category, true) {
c.SetInvalidUrlParam("category")
}
return c
}
func (c *Context) RequirePreferenceName() *Context {
if c.Err != nil {
return c
}
if !model.IsValidAlphaNum(c.Params.PreferenceName, true) {
c.SetInvalidUrlParam("preference_name")
}
return c
}

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

@@ -17,20 +17,22 @@ const (
)
type ApiParams struct {
UserId string
TeamId string
ChannelId string
PostId string
FileId string
CommandId string
HookId string
EmojiId string
Email string
Username string
TeamName string
ChannelName string
Page int
PerPage int
UserId string
TeamId string
ChannelId string
PostId string
FileId string
CommandId string
HookId string
EmojiId string
Email string
Username string
TeamName string
ChannelName string
PreferenceName string
Category string
Page int
PerPage int
}
func ApiParamsFromRequest(r *http.Request) *ApiParams {
@@ -86,6 +88,14 @@ func ApiParamsFromRequest(r *http.Request) *ApiParams {
params.ChannelName = val
}
if val, ok := props["category"]; ok {
params.Category = val
}
if val, ok := props["preference_name"]; ok {
params.PreferenceName = val
}
if val, err := strconv.Atoi(r.URL.Query().Get("page")); err != nil {
params.Page = PAGE_DEFAULT
} else {

153
api4/preference.go Обычный файл
Просмотреть файл

@@ -0,0 +1,153 @@
// // Copyright (c) 2017 Mattermost, Inc. All Rights Reserved.
// // See License.txt for license information.
package api4
import (
"net/http"
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
)
func InitPreference() {
l4g.Debug(utils.T("api.preference.init.debug"))
BaseRoutes.Preferences.Handle("", ApiSessionRequired(getPreferences)).Methods("GET")
BaseRoutes.Preferences.Handle("", ApiSessionRequired(updatePreferences)).Methods("PUT")
BaseRoutes.Preferences.Handle("/delete", ApiSessionRequired(deletePreferences)).Methods("POST")
BaseRoutes.Preferences.Handle("/{category:[A-Za-z0-9_]+}", ApiSessionRequired(getPreferencesByCategory)).Methods("GET")
BaseRoutes.Preferences.Handle("/{category:[A-Za-z0-9_]+}/name/{preference_name:[A-Za-z0-9_]+}", ApiSessionRequired(getPreferenceByCategoryAndName)).Methods("GET")
}
func getPreferences(c *Context, w http.ResponseWriter, r *http.Request) {
c.RequireUserId()
if c.Err != nil {
return
}
if !app.SessionHasPermissionToUser(c.Session, c.Params.UserId) {
c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
return
}
if preferences, err := app.GetPreferencesForUser(c.Params.UserId); err != nil {
c.Err = err
return
} else {
w.Write([]byte(preferences.ToJson()))
return
}
}
func getPreferencesByCategory(c *Context, w http.ResponseWriter, r *http.Request) {
c.RequireUserId().RequireCategory()
if c.Err != nil {
return
}
if !app.SessionHasPermissionToUser(c.Session, c.Params.UserId) {
c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
return
}
if preferences, err := app.GetPreferenceByCategoryForUser(c.Params.UserId, c.Params.Category); err != nil {
c.Err = err
return
} else {
w.Write([]byte(preferences.ToJson()))
return
}
}
func getPreferenceByCategoryAndName(c *Context, w http.ResponseWriter, r *http.Request) {
c.RequireUserId().RequireCategory().RequirePreferenceName()
if c.Err != nil {
return
}
if !app.SessionHasPermissionToUser(c.Session, c.Params.UserId) {
c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
return
}
if preferences, err := app.GetPreferenceByCategoryAndNameForUser(c.Params.UserId, c.Params.Category, c.Params.PreferenceName); err != nil {
c.Err = err
return
} else {
w.Write([]byte(preferences.ToJson()))
return
}
}
func updatePreferences(c *Context, w http.ResponseWriter, r *http.Request) {
c.RequireUserId()
if c.Err != nil {
return
}
if !app.SessionHasPermissionToUser(c.Session, c.Params.UserId) {
c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
return
}
preferences, err := model.PreferencesFromJson(r.Body)
if err != nil {
c.SetInvalidParam("preferences")
return
}
for _, preference := range preferences {
if c.Params.UserId != preference.UserId {
c.Err = model.NewAppError("savePreferences", "api.preference.update_preferences.set.app_error", nil,
c.T("api.preference.update_preferences.set_details.app_error",
map[string]interface{}{"SessionUserId": c.Params.UserId, "PreferenceUserId": preference.UserId}),
http.StatusForbidden)
return
}
}
if _, err := app.UpdatePreferences(preferences); err != nil {
c.Err = err
return
}
ReturnStatusOK(w)
}
func deletePreferences(c *Context, w http.ResponseWriter, r *http.Request) {
c.RequireUserId()
if c.Err != nil {
return
}
if !app.SessionHasPermissionToUser(c.Session, c.Params.UserId) {
c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
return
}
preferences, err := model.PreferencesFromJson(r.Body)
if err != nil {
c.SetInvalidParam("preferences")
return
}
for _, preference := range preferences {
if c.Params.UserId != preference.UserId {
c.Err = model.NewAppError("deletePreferences", "api.preference.delete_preferences.delete.app_error", nil,
c.T("api.preference.delete_preferences.delete.app_error",
map[string]interface{}{"SessionUserId": c.Params.UserId, "PreferenceUserId": preference.UserId}),
http.StatusForbidden)
return
}
}
if _, err := app.DeletePreferences(c.Params.UserId, preferences); err != nil {
c.Err = err
return
}
ReturnStatusOK(w)
}

287
api4/preference_test.go Обычный файл
Просмотреть файл

@@ -0,0 +1,287 @@
// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package api4
import (
"github.com/mattermost/platform/model"
"testing"
)
func TestGetPreferences(t *testing.T) {
th := Setup().InitBasic()
defer TearDown()
Client := th.Client
th.LoginBasic()
user1 := th.BasicUser
category := model.NewId()
preferences1 := model.Preferences{
{
UserId: user1.Id,
Category: category,
Name: model.NewId(),
},
{
UserId: user1.Id,
Category: category,
Name: model.NewId(),
},
{
UserId: user1.Id,
Category: model.NewId(),
Name: model.NewId(),
},
}
Client.UpdatePreferences(user1.Id, &preferences1)
prefs, resp := Client.GetPreferences(user1.Id)
CheckNoError(t, resp)
if len(prefs) != 4 {
t.Fatal("received the wrong number of preferences")
}
for _, preference := range prefs {
if preference.UserId != th.BasicUser.Id {
t.Fatal("user id does not match")
}
}
th.LoginBasic2()
prefs, resp = Client.GetPreferences(th.BasicUser2.Id)
CheckNoError(t, resp)
if len(prefs) == 0 {
t.Fatal("received the wrong number of preferences")
}
_, resp = Client.GetPreferences(th.BasicUser.Id)
CheckForbiddenStatus(t, resp)
Client.Logout()
_, resp = Client.GetPreferences(th.BasicUser2.Id)
CheckUnauthorizedStatus(t, resp)
}
func TestGetPreferencesByCategory(t *testing.T) {
th := Setup().InitBasic()
defer TearDown()
Client := th.Client
th.LoginBasic()
user1 := th.BasicUser
category := model.NewId()
preferences1 := model.Preferences{
{
UserId: user1.Id,
Category: category,
Name: model.NewId(),
},
{
UserId: user1.Id,
Category: category,
Name: model.NewId(),
},
{
UserId: user1.Id,
Category: model.NewId(),
Name: model.NewId(),
},
}
Client.UpdatePreferences(user1.Id, &preferences1)
prefs, resp := Client.GetPreferencesByCategory(user1.Id, category)
CheckNoError(t, resp)
if len(prefs) != 2 {
t.Fatalf("received the wrong number of preferences %v:%v", len(prefs), 2)
}
prefs, resp = Client.GetPreferencesByCategory(user1.Id, "junk")
CheckNotFoundStatus(t, resp)
th.LoginBasic2()
prefs, resp = Client.GetPreferencesByCategory(th.BasicUser2.Id, category)
CheckNotFoundStatus(t, resp)
prefs, resp = Client.GetPreferencesByCategory(user1.Id, category)
CheckForbiddenStatus(t, resp)
prefs, resp = Client.GetPreferencesByCategory(th.BasicUser2.Id, "junk")
CheckNotFoundStatus(t, resp)
if len(prefs) != 0 {
t.Fatal("received the wrong number of preferences")
}
Client.Logout()
_, resp = Client.GetPreferencesByCategory(th.BasicUser2.Id, category)
CheckUnauthorizedStatus(t, resp)
}
func TestGetPreferenceByCategoryAndName(t *testing.T) {
th := Setup().InitBasic()
defer TearDown()
Client := th.Client
th.LoginBasic()
user := th.BasicUser
name := model.NewId()
value := model.NewId()
preferences := model.Preferences{
{
UserId: user.Id,
Category: model.PREFERENCE_CATEGORY_DIRECT_CHANNEL_SHOW,
Name: name,
Value: value,
},
{
UserId: user.Id,
Category: model.PREFERENCE_CATEGORY_DIRECT_CHANNEL_SHOW,
Name: model.NewId(),
Value: model.NewId(),
},
}
Client.UpdatePreferences(user.Id, &preferences)
pref, resp := Client.GetPreferenceByCategoryAndName(user.Id, model.PREFERENCE_CATEGORY_DIRECT_CHANNEL_SHOW, name)
CheckNoError(t, resp)
if (pref.UserId != preferences[0].UserId) && (pref.Category != preferences[0].Category) && (pref.Name != preferences[0].Name) {
t.Fatal("preference saved incorrectly")
}
preferences[0].Value = model.NewId()
Client.UpdatePreferences(user.Id, &preferences)
_, resp = Client.GetPreferenceByCategoryAndName(user.Id, "junk", preferences[0].Name)
CheckBadRequestStatus(t, resp)
_, resp = Client.GetPreferenceByCategoryAndName(user.Id, preferences[0].Category, "junk")
CheckBadRequestStatus(t, resp)
_, resp = Client.GetPreferenceByCategoryAndName(th.BasicUser2.Id, preferences[0].Category, "junk")
CheckForbiddenStatus(t, resp)
_, resp = Client.GetPreferenceByCategoryAndName(user.Id, preferences[0].Category, preferences[0].Name)
CheckNoError(t, resp)
Client.Logout()
_, resp = Client.GetPreferenceByCategoryAndName(user.Id, preferences[0].Category, preferences[0].Name)
CheckUnauthorizedStatus(t, resp)
}
func TestUpdatePreferences(t *testing.T) {
th := Setup().InitBasic()
defer TearDown()
Client := th.Client
th.LoginBasic()
user1 := th.BasicUser
category := model.NewId()
preferences1 := model.Preferences{
{
UserId: user1.Id,
Category: category,
Name: model.NewId(),
},
{
UserId: user1.Id,
Category: category,
Name: model.NewId(),
},
{
UserId: user1.Id,
Category: model.NewId(),
Name: model.NewId(),
},
}
_, resp := Client.UpdatePreferences(user1.Id, &preferences1)
CheckNoError(t, resp)
preferences := model.Preferences{
{
UserId: model.NewId(),
Category: category,
Name: model.NewId(),
},
}
_, resp = Client.UpdatePreferences(user1.Id, &preferences)
CheckForbiddenStatus(t, resp)
preferences = model.Preferences{
{
UserId: user1.Id,
Name: model.NewId(),
},
}
_, resp = Client.UpdatePreferences(user1.Id, &preferences)
CheckBadRequestStatus(t, resp)
_, resp = Client.UpdatePreferences(th.BasicUser2.Id, &preferences)
CheckForbiddenStatus(t, resp)
Client.Logout()
_, resp = Client.UpdatePreferences(user1.Id, &preferences1)
CheckUnauthorizedStatus(t, resp)
}
func TestDeletePreferences(t *testing.T) {
th := Setup().InitBasic()
defer TearDown()
Client := th.Client
th.LoginBasic()
prefs, resp := Client.GetPreferences(th.BasicUser.Id)
originalCount := len(prefs)
// save 10 preferences
var preferences model.Preferences
for i := 0; i < 10; i++ {
preference := model.Preference{
UserId: th.BasicUser.Id,
Category: model.PREFERENCE_CATEGORY_DIRECT_CHANNEL_SHOW,
Name: model.NewId(),
}
preferences = append(preferences, preference)
}
Client.UpdatePreferences(th.BasicUser.Id, &preferences)
// delete 10 preferences
th.LoginBasic2()
_, resp = Client.DeletePreferences(th.BasicUser2.Id, &preferences)
CheckForbiddenStatus(t, resp)
th.LoginBasic()
_, resp = Client.DeletePreferences(th.BasicUser.Id, &preferences)
CheckNoError(t, resp)
_, resp = Client.DeletePreferences(th.BasicUser2.Id, &preferences)
CheckForbiddenStatus(t, resp)
prefs, resp = Client.GetPreferences(th.BasicUser.Id)
if len(prefs) != originalCount {
t.Fatal("should've deleted preferences")
}
Client.Logout()
_, resp = Client.DeletePreferences(th.BasicUser.Id, &preferences)
CheckUnauthorizedStatus(t, resp)
}

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

@@ -5,12 +5,56 @@ package app
import (
"github.com/mattermost/platform/model"
"net/http"
)
func GetPreferencesForUser(userId string) (model.Preferences, *model.AppError) {
if result := <-Srv.Store.Preference().GetAll(userId); result.Err != nil {
result.Err.StatusCode = http.StatusBadRequest
return nil, result.Err
} else {
return result.Data.(model.Preferences), nil
}
}
func GetPreferenceByCategoryForUser(userId string, category string) (model.Preferences, *model.AppError) {
if result := <-Srv.Store.Preference().GetCategory(userId, category); result.Err != nil {
result.Err.StatusCode = http.StatusBadRequest
return nil, result.Err
} else if len(result.Data.(model.Preferences)) == 0 {
err := model.NewAppError("getPreferenceCategory", "api.preference.preferences_category.get.app_error", nil, "", http.StatusNotFound)
return nil, err
} else {
return result.Data.(model.Preferences), nil
}
}
func GetPreferenceByCategoryAndNameForUser(userId string, category string, preferenceName string) (*model.Preference, *model.AppError) {
if result := <-Srv.Store.Preference().Get(userId, category, preferenceName); result.Err != nil {
result.Err.StatusCode = http.StatusBadRequest
return nil, result.Err
} else {
data := result.Data.(model.Preference)
return &data, nil
}
}
func UpdatePreferences(preferences model.Preferences) (bool, *model.AppError) {
if result := <-Srv.Store.Preference().Save(&preferences); result.Err != nil {
result.Err.StatusCode = http.StatusBadRequest
return false, result.Err
}
return true, nil
}
func DeletePreferences(userId string, preferences model.Preferences) (bool, *model.AppError) {
for _, preference := range preferences {
if result := <-Srv.Store.Preference().Delete(userId, preference.Category, preference.Name); result.Err != nil {
result.Err.StatusCode = http.StatusBadRequest
return false, result.Err
}
}
return true, nil
}

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

@@ -141,6 +141,10 @@ func (c *Client4) GetIncomingWebhooksRoute() string {
return fmt.Sprintf("/hooks/incoming")
}
func (c *Client4) GetPreferencesRoute(userId string) string {
return fmt.Sprintf(c.GetUserRoute(userId) + "/preferences")
}
func (c *Client4) DoApiGet(url string, etag string) (*http.Response, *AppError) {
return c.DoApiRequest(http.MethodGet, url, "", etag)
}
@@ -871,3 +875,59 @@ func (c *Client4) GetIncomingWebhooksForTeam(teamId string, page int, perPage in
return IncomingWebhookListFromJson(r.Body), BuildResponse(r)
}
}
// Preferences Section
// GetPreferences returns the user's preferences
func (c *Client4) GetPreferences(userId string) (Preferences, *Response) {
if r, err := c.DoApiGet(c.GetPreferencesRoute(userId), ""); err != nil {
return nil, &Response{StatusCode: r.StatusCode, Error: err}
} else {
preferences, _ := PreferencesFromJson(r.Body)
defer closeBody(r)
return preferences, BuildResponse(r)
}
}
// UpdatePreferences saves the user's preferences
func (c *Client4) UpdatePreferences(userId string, preferences *Preferences) (bool, *Response) {
if r, err := c.DoApiPut(c.GetPreferencesRoute(userId), preferences.ToJson()); err != nil {
return false, &Response{StatusCode: r.StatusCode, Error: err}
} else {
defer closeBody(r)
return true, BuildResponse(r)
}
}
// DeletePreferences deletes the user's preferences
func (c *Client4) DeletePreferences(userId string, preferences *Preferences) (bool, *Response) {
if r, err := c.DoApiPost(c.GetPreferencesRoute(userId)+"/delete", preferences.ToJson()); err != nil {
return false, &Response{StatusCode: r.StatusCode, Error: err}
} else {
defer closeBody(r)
return true, BuildResponse(r)
}
}
// GetPreferencesByCategory returns the user's preferences from the provided category string
func (c *Client4) GetPreferencesByCategory(userId string, category string) (Preferences, *Response) {
url := fmt.Sprintf(c.GetPreferencesRoute(userId)+"/%s", category)
if r, err := c.DoApiGet(url, ""); err != nil {
return nil, &Response{StatusCode: r.StatusCode, Error: err}
} else {
preferences, _ := PreferencesFromJson(r.Body)
defer closeBody(r)
return preferences, BuildResponse(r)
}
}
// GetPreferenceByCategoryAndName returns the user's preferences from the provided category and preference name string
func (c *Client4) GetPreferenceByCategoryAndName(userId string, category string, preferenceName string) (*Preference, *Response) {
url := fmt.Sprintf(c.GetPreferencesRoute(userId)+"/%s/name/%v", category, preferenceName)
if r, err := c.DoApiGet(url, ""); err != nil {
return nil, &Response{StatusCode: r.StatusCode, Error: err}
} else {
defer closeBody(r)
return PreferenceFromJson(r.Body), BuildResponse(r)
}
}