From c82a84ed765bd9c4d601b93201d93af92f6ee742 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Espino?= Date: Tue, 2 Oct 2018 08:04:38 +0200 Subject: MM-12067: Add SetDefaultProfileImage to reset the user profile image to a generated one (#9449) * MM-12067: Add SetDefaultProfileImage to reset the user profile image to a generated one * Allow to get the default profile image for my user * Allowing to reset the last update image date to 0 * PR reviews --- api4/user.go | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ api4/user_test.go | 44 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) (limited to 'api4') diff --git a/api4/user.go b/api4/user.go index 2570a6f25..5a8474b8d 100644 --- a/api4/user.go +++ b/api4/user.go @@ -27,8 +27,10 @@ func (api *API) InitUser() { api.BaseRoutes.Users.Handle("/stats", api.ApiSessionRequired(getTotalUsersStats)).Methods("GET") api.BaseRoutes.User.Handle("", api.ApiSessionRequired(getUser)).Methods("GET") + api.BaseRoutes.User.Handle("/image/default", api.ApiSessionRequiredTrustRequester(getDefaultProfileImage)).Methods("GET") api.BaseRoutes.User.Handle("/image", api.ApiSessionRequiredTrustRequester(getProfileImage)).Methods("GET") api.BaseRoutes.User.Handle("/image", api.ApiSessionRequired(setProfileImage)).Methods("POST") + api.BaseRoutes.User.Handle("/image", api.ApiSessionRequired(setDefaultProfileImage)).Methods("DELETE") api.BaseRoutes.User.Handle("", api.ApiSessionRequired(updateUser)).Methods("PUT") api.BaseRoutes.User.Handle("/patch", api.ApiSessionRequired(patchUser)).Methods("PUT") api.BaseRoutes.User.Handle("", api.ApiSessionRequired(deleteUser)).Methods("DELETE") @@ -193,6 +195,35 @@ func getUserByEmail(c *Context, w http.ResponseWriter, r *http.Request) { w.Write([]byte(user.ToJson())) } +func getDefaultProfileImage(c *Context, w http.ResponseWriter, r *http.Request) { + c.RequireUserId() + if c.Err != nil { + return + } + + users, err := c.App.GetUsersByIds([]string{c.Params.UserId}, c.IsSystemAdmin()) + if err != nil { + c.Err = err + return + } + + if len(users) == 0 { + c.Err = model.NewAppError("getProfileImage", "api.user.get_profile_image.not_found.app_error", nil, "", http.StatusNotFound) + return + } + + user := users[0] + img, err := c.App.GetDefaultProfileImage(user) + if err != nil { + c.Err = err + return + } + + w.Header().Set("Cache-Control", fmt.Sprintf("max-age=%v, public", 24*60*60)) // 24 hrs + w.Header().Set("Content-Type", "image/png") + w.Write(img) +} + func getProfileImage(c *Context, w http.ResponseWriter, r *http.Request) { c.RequireUserId() if c.Err != nil { @@ -286,6 +317,37 @@ func setProfileImage(c *Context, w http.ResponseWriter, r *http.Request) { ReturnStatusOK(w) } +func setDefaultProfileImage(c *Context, w http.ResponseWriter, r *http.Request) { + c.RequireUserId() + if c.Err != nil { + return + } + + if !c.App.SessionHasPermissionToUser(c.Session, c.Params.UserId) { + c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS) + return + } + + if len(*c.App.Config().FileSettings.DriverName) == 0 { + c.Err = model.NewAppError("setDefaultProfileImage", "api.user.upload_profile_user.storage.app_error", nil, "", http.StatusNotImplemented) + return + } + + user, err := c.App.GetUser(c.Params.UserId) + if err != nil { + c.Err = err + return + } + + if err := c.App.SetDefaultProfileImage(user); err != nil { + c.Err = err + return + } + + c.LogAudit("") + ReturnStatusOK(w) +} + func getTotalUsersStats(c *Context, w http.ResponseWriter, r *http.Request) { if c.Err != nil { return diff --git a/api4/user_test.go b/api4/user_test.go index a9aa967be..d50dfa3b6 100644 --- a/api4/user_test.go +++ b/api4/user_test.go @@ -2309,6 +2309,50 @@ func TestSetProfileImage(t *testing.T) { t.Fatal(err) } } + +func TestSetDefaultProfileImage(t *testing.T) { + th := Setup().InitBasic().InitSystemAdmin() + defer th.TearDown() + Client := th.Client + user := th.BasicUser + + ok, resp := Client.SetDefaultProfileImage(user.Id) + if !ok { + t.Fatal(resp.Error) + } + CheckNoError(t, resp) + + ok, resp = Client.SetDefaultProfileImage(model.NewId()) + if ok { + t.Fatal("Should return false, set profile image not allowed") + } + CheckForbiddenStatus(t, resp) + + // status code returns either forbidden or unauthorized + // note: forbidden is set as default at Client4.SetDefaultProfileImage when request is terminated early by server + Client.Logout() + _, resp = Client.SetDefaultProfileImage(user.Id) + if resp.StatusCode == http.StatusForbidden { + CheckForbiddenStatus(t, resp) + } else if resp.StatusCode == http.StatusUnauthorized { + CheckUnauthorizedStatus(t, resp) + } else { + t.Fatal("Should have failed either forbidden or unauthorized") + } + + _, resp = th.SystemAdminClient.SetDefaultProfileImage(user.Id) + CheckNoError(t, resp) + + ruser, err := th.App.GetUser(user.Id) + require.Nil(t, err) + assert.Equal(t, int64(0), ruser.LastPictureUpdate, "Picture should have resetted to default") + + info := &model.FileInfo{Path: "users/" + user.Id + "/profile.png"} + if err := th.cleanupTestFile(info); err != nil { + t.Fatal(err) + } +} + func TestCBALogin(t *testing.T) { th := Setup().InitBasic() defer th.TearDown() -- cgit v1.2.3-1-g7c22