From a54ee4c2e6c460231a72ef422cc7713c92b265ad Mon Sep 17 00:00:00 2001 From: Adphi Date: Fri, 1 Feb 2019 13:13:44 +0100 Subject: [PATCH] Added User's group add and remove to User Update --- gonextcloud_test.go | 39 --------------- update_test.go | 57 +++++++++++++++++++++ users.go | 118 +++++++++++++++++++++++++++++++++++--------- 3 files changed, 151 insertions(+), 63 deletions(-) create mode 100644 update_test.go diff --git a/gonextcloud_test.go b/gonextcloud_test.go index 28388bb..a654019 100644 --- a/gonextcloud_test.go +++ b/gonextcloud_test.go @@ -157,45 +157,6 @@ var ( // }, //}, // - //{ - // "TestUserUpdate", - // func(t *testing.T) { - // if err := initClient(); err != nil { - // return - // } - // username := fmt.Sprintf("%s-2", config.NotExistingUser) - // err := c.Users().Create(username, password, nil) - // assert.NoError(t, err) - // user := &types.UserDetails{ - // ID: username, - // Displayname: strings.ToUpper(username), - // Email: "some@address.com", - // Address: "Main Street, City", - // Twitter: "@me", - // Phone: "42 42 242 424", - // Website: "my.site.com", - // Quota: types.Quota{ - // // Unlimited - // Quota: -3, - // }, - // } - // err = c.Users().Update(user) - // assert.NoError(t, err) - // u, err := c.Users().Get(username) - // assert.NoError(t, err) - // o := structs.Map(user) - // r := structs.Map(u) - // for k := range o { - // if ignoredUserField(k) { - // continue - // } - // assert.Equal(t, o[k], r[k]) - // } - // // Clean up - // err = c.Users().Delete(u.ID) - // assert.NoError(t, err) - // }, - //}, { "TestUserCreateExisting", func(t *testing.T) { diff --git a/update_test.go b/update_test.go new file mode 100644 index 0000000..b6ac6da --- /dev/null +++ b/update_test.go @@ -0,0 +1,57 @@ +package gonextcloud + +import ( + "fmt" + "github.com/fatih/structs" + "github.com/stretchr/testify/assert" + "gitlab.bertha.cloud/partitio/Nextcloud-Partitio/gonextcloud/types" + "strings" + "testing" + "time" +) + +func TestUserUpdate(t *testing.T) { + if err := initClient(); err != nil { + return + } + username := fmt.Sprintf("%s-2", config.NotExistingUser) + err := c.Users().Create(username, password, nil) + if err != nil { + t.FailNow() + } + err = c.Groups().Create(config.NotExistingGroup) + if err != nil { + t.FailNow() + } + user := &types.UserDetails{ + ID: username, + Displayname: strings.ToUpper(username), + Email: "some@mail.com", + Quota: types.Quota{ + // Unlimited + Quota: -3, + }, + Groups: []string{config.NotExistingGroup}, + } + s := time.Now() + err = c.Users().Update(user) + e := time.Now().Sub(s) + fmt.Println(e.String()) + assert.NoError(t, err) + u, err := c.Users().Get(username) + assert.NoError(t, err) + o := structs.Map(user) + r := structs.Map(u) + for k := range o { + if ignoredUserField(k) { + continue + } + assert.Equal(t, o[k], r[k]) + } + // Clean up + err = c.Users().Delete(username) + assert.NoError(t, err) + err = c.Groups().Delete(config.NotExistingGroup) + assert.NoError(t, err) + +} diff --git a/users.go b/users.go index cef1e38..06e718f 100644 --- a/users.go +++ b/users.go @@ -2,7 +2,6 @@ package gonextcloud import ( "encoding/json" - "github.com/fatih/structs" req "github.com/levigross/grequests" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -189,41 +188,103 @@ func (u *Users) SendWelcomeEmail(name string) error { } //Update takes a *types.Users struct to update the user's information +// Updatable fields: Email, Displayname, Phone, Address, Website, Twitter, Quota, Groups func (u *Users) Update(user *types.UserDetails) error { - m := structs.Map(user) + // Get user to update only modified fields + original, err := u.Get(user.ID) + if err != nil { + return err + } + errs := make(chan *types.UpdateError) var wg sync.WaitGroup - for k := range m { - // Filter updatable fields - if ignoredUserField(k) { - continue - } - var value string - // Quota is a special case - if k == "Quota" { - // If empty - if user.Quota == (types.Quota{}) { - value = "default" - } else { - value = user.Quota.String() + update := func(key string, value string) { + defer wg.Done() + if err := u.updateAttribute(user.ID, strings.ToLower(key), value); err != nil { + errs <- &types.UpdateError{ + Field: key, + Error: err, } - } else { - value = m[k].(string) } - if value != "" { + errs <- nil + } + // Email + if user.Email != original.Email { + wg.Add(1) + go update("Email", user.Email) + } + // Displayname + if user.Displayname != original.Displayname { + wg.Add(1) + go update("Displayname", user.Displayname) + } + // Phone + if user.Phone != original.Phone { + wg.Add(1) + go update("Phone", user.Phone) + } + // Address + if user.Address != original.Address { + wg.Add(1) + go update("Address", user.Address) + } + // Website + if user.Website != original.Website { + wg.Add(1) + go update("Website", user.Website) + } + // Twitter + if user.Twitter != original.Twitter { + wg.Add(1) + go update("Twitter", user.Twitter) + } + // Quota + if user.Quota.Quota != original.Quota.Quota { + var value string + // If empty + if user.Quota == (types.Quota{}) { + value = "default" + } else { + value = user.Quota.String() + } + wg.Add(1) + go update("Quota", value) + } + // Groups + // Group removed + for _, g := range original.Groups { + if !contains(user.Groups, g) { wg.Add(1) - // All other non ignored values are strings - go func(key string, value string) { + go func() { defer wg.Done() - if err := u.updateAttribute(user.ID, strings.ToLower(key), value); err != nil { + if err := u.GroupRemove(user.ID, g); err != nil { errs <- &types.UpdateError{ - Field: key, + Field: "Groups/" + g, Error: err, } } - }(k, value) + errs <- nil + }() } } + + // Group Added + for _, g := range user.Groups { + if !contains(original.Groups, g) { + wg.Add(1) + go func() { + defer wg.Done() + if err := u.GroupAdd(user.ID, g); err != nil { + errs <- &types.UpdateError{ + Field: "Groups/" + g, + Error: err, + } + } + errs <- nil + }() + } + } + go func() { wg.Wait() close(errs) @@ -359,7 +420,7 @@ func (u *Users) baseRequest(method string, ro *req.RequestOptions, subRoutes ... } func ignoredUserField(key string) bool { - keys := []string{"Email", "Displayname", "Phone", "Address", "Website", "Twitter", "Quota"} + keys := []string{"Email", "Displayname", "Phone", "Address", "Website", "Twitter", "Quota", "Groups"} for _, k := range keys { if key == k { return false @@ -367,3 +428,12 @@ func ignoredUserField(key string) bool { } return true } + +func contains(slice []string, e string) bool { + for _, s := range slice { + if e == s { + return true + } + } + return false +}