From a087403e9f25373d5bdea5e10fafb0c5d496a703 Mon Sep 17 00:00:00 2001 From: hmhealey Date: Thu, 1 Oct 2015 15:22:04 -0400 Subject: Added api to get and set preferences --- api/preference.go | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 api/preference.go (limited to 'api/preference.go') diff --git a/api/preference.go b/api/preference.go new file mode 100644 index 000000000..9fadfd2e4 --- /dev/null +++ b/api/preference.go @@ -0,0 +1,63 @@ +// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved. +// See License.txt for license information. + +package api + +import ( + l4g "code.google.com/p/log4go" + "encoding/json" + "github.com/gorilla/mux" + "github.com/mattermost/platform/model" + "net/http" +) + +func InitPreference(r *mux.Router) { + l4g.Debug("Initializing preference api routes") + + sr := r.PathPrefix("/preferences").Subrouter() + sr.Handle("/set", ApiAppHandler(setPreferences)).Methods("POST") + sr.Handle("/{category:[A-Za-z0-9_]+}/{name:[A-Za-z0-9_]+}", ApiAppHandler(getPreferencesByName)).Methods("GET") +} + +func setPreferences(c *Context, w http.ResponseWriter, r *http.Request) { + var preferences []model.Preference + + decoder := json.NewDecoder(r.Body) + if err := decoder.Decode(&preferences); err != nil { + c.Err = model.NewAppError("setPreferences", "Unable to decode preferences from request", err.Error()) + c.Err.StatusCode = http.StatusBadRequest + return + } + + // just attempt to save/update them one by one and abort if one fails + // in the future, this could probably be done in a transaction, but that's unnecessary now + for _, preference := range preferences { + if c.Session.UserId != preference.UserId { + c.Err = model.NewAppError("setPreferences", "Unable to set preferences for other user", "session.user_id="+c.Session.UserId+", preference.user_id="+preference.UserId) + c.Err.StatusCode = http.StatusUnauthorized + return + } + + if result := <-Srv.Store.Preference().Save(&preference); result.Err != nil { + if result = <-Srv.Store.Preference().Update(&preference); result.Err != nil { + c.Err = result.Err + return + } + } + } + + w.Write([]byte("true")) +} + +func getPreferencesByName(c *Context, w http.ResponseWriter, r *http.Request) { + params := mux.Vars(r) + category := params["category"] + name := params["name"] + + if result := <-Srv.Store.Preference().GetByName(c.Session.UserId, category, name); result.Err != nil { + c.Err = result.Err + return + } else { + w.Write([]byte(model.PreferenceListToJson(result.Data.([]*model.Preference)))) + } +} -- cgit v1.2.3-1-g7c22 From a11421c74b338eee6eedb4f4260a75f38aa3fd4c Mon Sep 17 00:00:00 2001 From: hmhealey Date: Mon, 5 Oct 2015 12:45:15 -0400 Subject: Added default direct channels for previously existing users --- api/preference.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'api/preference.go') diff --git a/api/preference.go b/api/preference.go index 9fadfd2e4..84cfc130c 100644 --- a/api/preference.go +++ b/api/preference.go @@ -58,6 +58,15 @@ func getPreferencesByName(c *Context, w http.ResponseWriter, r *http.Request) { c.Err = result.Err return } else { - w.Write([]byte(model.PreferenceListToJson(result.Data.([]*model.Preference)))) + data := result.Data.([]*model.Preference) + + if len(data) == 0 { + if category == model.PREFERENCE_CATEGORY_DIRECT_CHANNELS && name == model.PREFERENCE_NAME_SHOW { + // add direct channels for a user that existed before preferences were added + data = AddDirectChannels(c.Session.UserId, c.Session.TeamId) + } + } + + w.Write([]byte(model.PreferenceListToJson(data))) } } -- cgit v1.2.3-1-g7c22 From a6cd2a79612d6d96e0e929ab769ec5e70cd35f5f Mon Sep 17 00:00:00 2001 From: hmhealey Date: Wed, 7 Oct 2015 10:19:02 -0400 Subject: Moved saving multiple user preferences into a database transaction --- api/preference.go | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'api/preference.go') diff --git a/api/preference.go b/api/preference.go index 84cfc130c..810917a7c 100644 --- a/api/preference.go +++ b/api/preference.go @@ -20,7 +20,7 @@ func InitPreference(r *mux.Router) { } func setPreferences(c *Context, w http.ResponseWriter, r *http.Request) { - var preferences []model.Preference + var preferences []*model.Preference decoder := json.NewDecoder(r.Body) if err := decoder.Decode(&preferences); err != nil { @@ -29,21 +29,17 @@ func setPreferences(c *Context, w http.ResponseWriter, r *http.Request) { return } - // just attempt to save/update them one by one and abort if one fails - // in the future, this could probably be done in a transaction, but that's unnecessary now for _, preference := range preferences { if c.Session.UserId != preference.UserId { c.Err = model.NewAppError("setPreferences", "Unable to set preferences for other user", "session.user_id="+c.Session.UserId+", preference.user_id="+preference.UserId) c.Err.StatusCode = http.StatusUnauthorized return } + } - if result := <-Srv.Store.Preference().Save(&preference); result.Err != nil { - if result = <-Srv.Store.Preference().Update(&preference); result.Err != nil { - c.Err = result.Err - return - } - } + if result := <-Srv.Store.Preference().SaveOrUpdate(preferences...); result.Err != nil { + c.Err = result.Err + return } w.Write([]byte("true")) -- cgit v1.2.3-1-g7c22 From ed6b2cd164b249c67db0e0421cc78964450240c9 Mon Sep 17 00:00:00 2001 From: hmhealey Date: Wed, 7 Oct 2015 10:39:36 -0400 Subject: Removed setting direct channels for a new user at creation time --- api/preference.go | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) (limited to 'api/preference.go') diff --git a/api/preference.go b/api/preference.go index 810917a7c..aa19ee071 100644 --- a/api/preference.go +++ b/api/preference.go @@ -59,10 +59,51 @@ func getPreferencesByName(c *Context, w http.ResponseWriter, r *http.Request) { if len(data) == 0 { if category == model.PREFERENCE_CATEGORY_DIRECT_CHANNELS && name == model.PREFERENCE_NAME_SHOW { // add direct channels for a user that existed before preferences were added - data = AddDirectChannels(c.Session.UserId, c.Session.TeamId) + data = addDirectChannels(c.Session.UserId, c.Session.TeamId) } } w.Write([]byte(model.PreferenceListToJson(data))) } } + +func addDirectChannels(userId, teamId string) []*model.Preference { + var profiles map[string]*model.User + if result := <-Srv.Store.User().GetProfiles(teamId); result.Err != nil { + l4g.Error("Failed to add direct channel preferences for user user_id=%s, team_id=%s, err=%v", userId, teamId, result.Err.Error()) + return []*model.Preference{} + } else { + profiles = result.Data.(map[string]*model.User) + } + + var preferences []*model.Preference + + for id := range profiles { + if id == userId { + continue + } + + profile := profiles[id] + + preference := &model.Preference{ + UserId: userId, + Category: model.PREFERENCE_CATEGORY_DIRECT_CHANNELS, + Name: model.PREFERENCE_NAME_SHOW, + AltId: profile.Id, + Value: "true", + } + + if result := <-Srv.Store.Preference().Save(preference); result.Err != nil { + l4g.Error("Failed to add direct channel preferences for user user_id=%s, alt_id=%s, team_id=%s, err=%v", userId, profile.Id, teamId, result.Err.Error()) + continue + } + + preferences = append(preferences, preference) + + if len(preferences) >= 10 { + break + } + } + + return preferences +} -- cgit v1.2.3-1-g7c22 From 5cecf1afcd1d8e561a5b2d840e5bd1b588a74a27 Mon Sep 17 00:00:00 2001 From: hmhealey Date: Fri, 9 Oct 2015 13:47:11 -0400 Subject: Made structural changes to server-side Preference code based on feedback --- api/preference.go | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) (limited to 'api/preference.go') diff --git a/api/preference.go b/api/preference.go index aa19ee071..855e9ad36 100644 --- a/api/preference.go +++ b/api/preference.go @@ -5,7 +5,6 @@ package api import ( l4g "code.google.com/p/log4go" - "encoding/json" "github.com/gorilla/mux" "github.com/mattermost/platform/model" "net/http" @@ -15,29 +14,27 @@ func InitPreference(r *mux.Router) { l4g.Debug("Initializing preference api routes") sr := r.PathPrefix("/preferences").Subrouter() - sr.Handle("/set", ApiAppHandler(setPreferences)).Methods("POST") + sr.Handle("/save", ApiAppHandler(savePreferences)).Methods("POST") sr.Handle("/{category:[A-Za-z0-9_]+}/{name:[A-Za-z0-9_]+}", ApiAppHandler(getPreferencesByName)).Methods("GET") } -func setPreferences(c *Context, w http.ResponseWriter, r *http.Request) { - var preferences []*model.Preference - - decoder := json.NewDecoder(r.Body) - if err := decoder.Decode(&preferences); err != nil { - c.Err = model.NewAppError("setPreferences", "Unable to decode preferences from request", err.Error()) +func savePreferences(c *Context, w http.ResponseWriter, r *http.Request) { + preferences, err := model.PreferencesFromJson(r.Body) + if err != nil { + c.Err = model.NewAppError("savePreferences", "Unable to decode preferences from request", err.Error()) c.Err.StatusCode = http.StatusBadRequest return } for _, preference := range preferences { if c.Session.UserId != preference.UserId { - c.Err = model.NewAppError("setPreferences", "Unable to set preferences for other user", "session.user_id="+c.Session.UserId+", preference.user_id="+preference.UserId) + c.Err = model.NewAppError("savePreferences", "Unable to set preferences for other user", "session.user_id="+c.Session.UserId+", preference.user_id="+preference.UserId) c.Err.StatusCode = http.StatusUnauthorized return } } - if result := <-Srv.Store.Preference().SaveOrUpdate(preferences...); result.Err != nil { + if result := <-Srv.Store.Preference().Save(&preferences); result.Err != nil { c.Err = result.Err return } @@ -54,7 +51,7 @@ func getPreferencesByName(c *Context, w http.ResponseWriter, r *http.Request) { c.Err = result.Err return } else { - data := result.Data.([]*model.Preference) + data := result.Data.(model.Preferences) if len(data) == 0 { if category == model.PREFERENCE_CATEGORY_DIRECT_CHANNELS && name == model.PREFERENCE_NAME_SHOW { @@ -63,11 +60,11 @@ func getPreferencesByName(c *Context, w http.ResponseWriter, r *http.Request) { } } - w.Write([]byte(model.PreferenceListToJson(data))) + w.Write([]byte(data.ToJson())) } } -func addDirectChannels(userId, teamId string) []*model.Preference { +func addDirectChannels(userId, teamId string) model.Preferences { var profiles map[string]*model.User if result := <-Srv.Store.User().GetProfiles(teamId); result.Err != nil { l4g.Error("Failed to add direct channel preferences for user user_id=%s, team_id=%s, err=%v", userId, teamId, result.Err.Error()) @@ -76,7 +73,7 @@ func addDirectChannels(userId, teamId string) []*model.Preference { profiles = result.Data.(map[string]*model.User) } - var preferences []*model.Preference + var preferences model.Preferences for id := range profiles { if id == userId { @@ -93,11 +90,6 @@ func addDirectChannels(userId, teamId string) []*model.Preference { Value: "true", } - if result := <-Srv.Store.Preference().Save(preference); result.Err != nil { - l4g.Error("Failed to add direct channel preferences for user user_id=%s, alt_id=%s, team_id=%s, err=%v", userId, profile.Id, teamId, result.Err.Error()) - continue - } - preferences = append(preferences, preference) if len(preferences) >= 10 { @@ -105,5 +97,10 @@ func addDirectChannels(userId, teamId string) []*model.Preference { } } - return preferences + if result := <-Srv.Store.Preference().Save(&preferences); result.Err != nil { + l4g.Error("Failed to add direct channel preferences for user user_id=%s, eam_id=%s, err=%v", userId, teamId, result.Err.Error()) + return model.Preferences{} + } else { + return preferences + } } -- cgit v1.2.3-1-g7c22 From 2a39e8dbfab8506b09d0d030f87cac4c079b975a Mon Sep 17 00:00:00 2001 From: hmhealey Date: Tue, 13 Oct 2015 11:52:17 -0400 Subject: Removed Preference.AltId --- api/preference.go | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) (limited to 'api/preference.go') diff --git a/api/preference.go b/api/preference.go index 855e9ad36..2f5ba12dd 100644 --- a/api/preference.go +++ b/api/preference.go @@ -15,7 +15,8 @@ func InitPreference(r *mux.Router) { sr := r.PathPrefix("/preferences").Subrouter() sr.Handle("/save", ApiAppHandler(savePreferences)).Methods("POST") - sr.Handle("/{category:[A-Za-z0-9_]+}/{name:[A-Za-z0-9_]+}", ApiAppHandler(getPreferencesByName)).Methods("GET") + sr.Handle("/{category:[A-Za-z0-9_]+}", ApiAppHandler(getPreferenceCategory)).Methods("GET") + sr.Handle("/{category:[A-Za-z0-9_]+}/{name:[A-Za-z0-9_]+}", ApiAppHandler(getPreference)).Methods("GET") } func savePreferences(c *Context, w http.ResponseWriter, r *http.Request) { @@ -42,19 +43,17 @@ func savePreferences(c *Context, w http.ResponseWriter, r *http.Request) { w.Write([]byte("true")) } -func getPreferencesByName(c *Context, w http.ResponseWriter, r *http.Request) { +func getPreferenceCategory(c *Context, w http.ResponseWriter, r *http.Request) { params := mux.Vars(r) category := params["category"] - name := params["name"] - if result := <-Srv.Store.Preference().GetByName(c.Session.UserId, category, name); result.Err != nil { + if result := <-Srv.Store.Preference().GetCategory(c.Session.UserId, category); result.Err != nil { c.Err = result.Err - return } else { data := result.Data.(model.Preferences) if len(data) == 0 { - if category == model.PREFERENCE_CATEGORY_DIRECT_CHANNELS && name == model.PREFERENCE_NAME_SHOW { + if category == model.PREFERENCE_CATEGORY_DIRECT_CHANNEL_SHOW { // add direct channels for a user that existed before preferences were added data = addDirectChannels(c.Session.UserId, c.Session.TeamId) } @@ -68,7 +67,7 @@ func addDirectChannels(userId, teamId string) model.Preferences { var profiles map[string]*model.User if result := <-Srv.Store.User().GetProfiles(teamId); result.Err != nil { l4g.Error("Failed to add direct channel preferences for user user_id=%s, team_id=%s, err=%v", userId, teamId, result.Err.Error()) - return []*model.Preference{} + return model.Preferences{} } else { profiles = result.Data.(map[string]*model.User) } @@ -82,11 +81,10 @@ func addDirectChannels(userId, teamId string) model.Preferences { profile := profiles[id] - preference := &model.Preference{ + preference := model.Preference{ UserId: userId, - Category: model.PREFERENCE_CATEGORY_DIRECT_CHANNELS, - Name: model.PREFERENCE_NAME_SHOW, - AltId: profile.Id, + Category: model.PREFERENCE_CATEGORY_DIRECT_CHANNEL_SHOW, + Name: profile.Id, Value: "true", } @@ -104,3 +102,16 @@ func addDirectChannels(userId, teamId string) model.Preferences { return preferences } } + +func getPreference(c *Context, w http.ResponseWriter, r *http.Request) { + params := mux.Vars(r) + category := params["category"] + name := params["name"] + + if result := <-Srv.Store.Preference().Get(c.Session.UserId, category, name); result.Err != nil { + c.Err = result.Err + } else { + data := result.Data.(model.Preference) + w.Write([]byte(data.ToJson())) + } +} -- cgit v1.2.3-1-g7c22 From 97b2f6ffe7fa09a2188163740865322582b00b59 Mon Sep 17 00:00:00 2001 From: hmhealey Date: Tue, 13 Oct 2015 15:18:01 -0400 Subject: Made further changes based on feedback --- api/preference.go | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'api/preference.go') diff --git a/api/preference.go b/api/preference.go index 2f5ba12dd..88cb132f8 100644 --- a/api/preference.go +++ b/api/preference.go @@ -14,9 +14,9 @@ func InitPreference(r *mux.Router) { l4g.Debug("Initializing preference api routes") sr := r.PathPrefix("/preferences").Subrouter() - sr.Handle("/save", ApiAppHandler(savePreferences)).Methods("POST") - sr.Handle("/{category:[A-Za-z0-9_]+}", ApiAppHandler(getPreferenceCategory)).Methods("GET") - sr.Handle("/{category:[A-Za-z0-9_]+}/{name:[A-Za-z0-9_]+}", ApiAppHandler(getPreference)).Methods("GET") + sr.Handle("/save", ApiUserRequired(savePreferences)).Methods("POST") + sr.Handle("/{category:[A-Za-z0-9_]+}", ApiUserRequired(getPreferenceCategory)).Methods("GET") + sr.Handle("/{category:[A-Za-z0-9_]+}/{name:[A-Za-z0-9_]+}", ApiUserRequired(getPreference)).Methods("GET") } func savePreferences(c *Context, w http.ResponseWriter, r *http.Request) { @@ -52,17 +52,21 @@ func getPreferenceCategory(c *Context, w http.ResponseWriter, r *http.Request) { } else { data := result.Data.(model.Preferences) - if len(data) == 0 { - if category == model.PREFERENCE_CATEGORY_DIRECT_CHANNEL_SHOW { - // add direct channels for a user that existed before preferences were added - data = addDirectChannels(c.Session.UserId, c.Session.TeamId) - } - } + data = transformPreferences(c, data, category) w.Write([]byte(data.ToJson())) } } +func transformPreferences(c *Context, preferences model.Preferences, category string) model.Preferences { + if len(preferences) == 0 && category == model.PREFERENCE_CATEGORY_DIRECT_CHANNEL_SHOW { + // add direct channels for a user that existed before preferences were added + preferences = addDirectChannels(c.Session.UserId, c.Session.TeamId) + } + + return preferences +} + func addDirectChannels(userId, teamId string) model.Preferences { var profiles map[string]*model.User if result := <-Srv.Store.User().GetProfiles(teamId); result.Err != nil { -- cgit v1.2.3-1-g7c22