diff --git a/apps.go b/apps.go index fdac44e..dd1c873 100644 --- a/apps.go +++ b/apps.go @@ -6,9 +6,24 @@ import ( "net/http" ) -//AppList return the list of the Nextcloud Apps -func (c *Client) AppList() ([]string, error) { - res, err := c.baseRequest(http.MethodGet, routes.apps, nil) +//AppsI available methods +type AppsI interface { + List() ([]string, error) + ListEnabled() ([]string, error) + ListDisabled() ([]string, error) + Infos(name string) (types.App, error) + Enable(name string) error + Disable(name string) error +} + +//Apps contains all Apps available actions +type Apps struct { + c *Client +} + +//List return the list of the Nextcloud Apps +func (a *Apps) List() ([]string, error) { + res, err := a.c.baseRequest(http.MethodGet, routes.apps, nil) if err != nil { return nil, err } @@ -17,12 +32,12 @@ func (c *Client) AppList() ([]string, error) { return r.Ocs.Data.Apps, nil } -//AppListEnabled lists the enabled apps -func (c *Client) AppListEnabled() ([]string, error) { +//ListEnabled lists the enabled apps +func (a *Apps) ListEnabled() ([]string, error) { ro := &req.RequestOptions{ Params: map[string]string{"filter": "enabled"}, } - res, err := c.baseRequest(http.MethodGet, routes.apps, ro) + res, err := a.c.baseRequest(http.MethodGet, routes.apps, ro) if err != nil { return nil, err } @@ -31,12 +46,12 @@ func (c *Client) AppListEnabled() ([]string, error) { return r.Ocs.Data.Apps, nil } -//AppListDisabled lists the disabled apps -func (c *Client) AppListDisabled() ([]string, error) { +//ListDisabled lists the disabled apps +func (a *Apps) ListDisabled() ([]string, error) { ro := &req.RequestOptions{ Params: map[string]string{"filter": "disabled"}, } - res, err := c.baseRequest(http.MethodGet, routes.apps, ro) + res, err := a.c.baseRequest(http.MethodGet, routes.apps, ro) if err != nil { return nil, err } @@ -45,9 +60,9 @@ func (c *Client) AppListDisabled() ([]string, error) { return r.Ocs.Data.Apps, nil } -//AppInfos return the app's details -func (c *Client) AppInfos(name string) (types.App, error) { - res, err := c.baseRequest(http.MethodGet, routes.apps, nil, name) +//Infos return the app's details +func (a *Apps) Infos(name string) (types.App, error) { + res, err := a.c.baseRequest(http.MethodGet, routes.apps, nil, name) if err != nil { return types.App{}, err } @@ -56,14 +71,14 @@ func (c *Client) AppInfos(name string) (types.App, error) { return r.Ocs.Data, nil } -//AppEnable enables an app -func (c *Client) AppEnable(name string) error { - _, err := c.baseRequest(http.MethodPost, routes.apps, nil, name) +//Enable enables an app +func (a *Apps) Enable(name string) error { + _, err := a.c.baseRequest(http.MethodPost, routes.apps, nil, name) return err } -//AppDisable disables an app -func (c *Client) AppDisable(name string) error { - _, err := c.baseRequest(http.MethodDelete, routes.apps, nil, name) +//Disable disables an app +func (a *Apps) Disable(name string) error { + _, err := a.c.baseRequest(http.MethodDelete, routes.apps, nil, name) return err } diff --git a/apps_test.go b/apps_test.go new file mode 100644 index 0000000..faec5ba --- /dev/null +++ b/apps_test.go @@ -0,0 +1,15 @@ +package gonextcloud + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestClientAppsList(t *testing.T) { + if err := initClient(); err != nil { + t.FailNow() + } + l, err := c.Apps.List() + assert.NoError(t, err) + assert.NotEmpty(t, l) +} diff --git a/appsconfig.go b/appsconfig.go index 37f8b02..421d3db 100644 --- a/appsconfig.go +++ b/appsconfig.go @@ -7,9 +7,25 @@ import ( "sync" ) -//AppsConfigList lists all the available apps -func (c *Client) AppsConfigList() (apps []string, err error) { - res, err := c.baseRequest(http.MethodGet, routes.appsConfig, nil) +//AppsConfigI available methods +type AppsConfigI interface { + List() (apps []string, err error) + Keys(id string) (keys []string, err error) + Value(id, key string) (string, error) + SetValue(id, key, value string) error + DeleteValue(id, key, value string) error + Get() (map[string]map[string]string, error) + Details(appID string) (map[string]string, error) +} + +//AppsConfig contains all Apps Configuration available actions +type AppsConfig struct { + c *Client +} + +//List lists all the available apps +func (a *AppsConfig) List() (apps []string, err error) { + res, err := a.c.baseRequest(http.MethodGet, routes.appsConfig, nil) if err != nil { return nil, err } @@ -18,9 +34,9 @@ func (c *Client) AppsConfigList() (apps []string, err error) { return r.Ocs.Data.Data, nil } -//AppsConfigKeys returns the app's config keys -func (c *Client) AppsConfigKeys(id string) (keys []string, err error) { - res, err := c.baseRequest(http.MethodGet, routes.appsConfig, nil, id) +//Keys returns the app's config keys +func (a *AppsConfig) Keys(id string) (keys []string, err error) { + res, err := a.c.baseRequest(http.MethodGet, routes.appsConfig, nil, id) if err != nil { return nil, err } @@ -29,9 +45,9 @@ func (c *Client) AppsConfigKeys(id string) (keys []string, err error) { return r.Ocs.Data.Data, nil } -//AppsConfigValue get the config value for the given app's key -func (c *Client) AppsConfigValue(id, key string) (string, error) { - res, err := c.baseRequest(http.MethodGet, routes.appsConfig, nil, id, key) +//Value get the config value for the given app's key +func (a *AppsConfig) Value(id, key string) (string, error) { + res, err := a.c.baseRequest(http.MethodGet, routes.appsConfig, nil, id, key) if err != nil { return "", err } @@ -40,28 +56,28 @@ func (c *Client) AppsConfigValue(id, key string) (string, error) { return r.Ocs.Data.Data, nil } -//AppsConfigSetValue set the config value for the given app's key -func (c *Client) AppsConfigSetValue(id, key, value string) error { +//SetValue set the config value for the given app's key +func (a *AppsConfig) SetValue(id, key, value string) error { ro := &req.RequestOptions{ Data: map[string]string{ "value": value, }, } - _, err := c.baseRequest(http.MethodPost, routes.appsConfig, ro, id, key) + _, err := a.c.baseRequest(http.MethodPost, routes.appsConfig, ro, id, key) return err } -//AppsConfigDeleteValue delete the config value and (!! be careful !!) the key -func (c *Client) AppsConfigDeleteValue(id, key, value string) error { - _, err := c.baseRequest(http.MethodDelete, routes.appsConfig, nil, id, key) +//DeleteValue delete the config value and (!! be careful !!) the key +func (a *AppsConfig) DeleteValue(id, key, value string) error { + _, err := a.c.baseRequest(http.MethodDelete, routes.appsConfig, nil, id, key) return err } -//AppsConfig returns all apps AppConfigDetails -func (c *Client) AppsConfig() (map[string]map[string]string, error) { +//Get returns all apps AppConfigDetails +func (a *AppsConfig) Get() (map[string]map[string]string, error) { config := map[string]map[string]string{} m := sync.Mutex{} - appsIDs, err := c.AppsConfigList() + appsIDs, err := a.List() if err != nil { return nil, err } @@ -70,7 +86,7 @@ func (c *Client) AppsConfig() (map[string]map[string]string, error) { for i := range appsIDs { go func(id string) { defer wg.Done() - d, err := c.AppsConfigDetails(id) + d, err := a.Details(id) if err == nil { m.Lock() config[id] = d @@ -82,13 +98,13 @@ func (c *Client) AppsConfig() (map[string]map[string]string, error) { return config, err } -//AppsConfigDetails returns all the config's key, values pair of the app -func (c *Client) AppsConfigDetails(appID string) (map[string]string, error) { +//Details returns all the config's key, values pair of the app +func (a *AppsConfig) Details(appID string) (map[string]string, error) { config := map[string]string{} m := sync.Mutex{} var err error var ks []string - ks, err = c.AppsConfigKeys(appID) + ks, err = a.Keys(appID) if err != nil { return config, err } @@ -97,7 +113,7 @@ func (c *Client) AppsConfigDetails(appID string) (map[string]string, error) { for i := range ks { go func(key string) { defer wg.Done() - v, err := c.AppsConfigValue(appID, key) + v, err := a.Value(appID, key) if err == nil { m.Lock() config[key] = v diff --git a/appsconfig_test.go b/appsconfig_test.go index 31ee998..e992015 100644 --- a/appsconfig_test.go +++ b/appsconfig_test.go @@ -10,7 +10,7 @@ func TestAppsConfig(t *testing.T) { if err := initClient(); err != nil { t.Fatal(err) } - ac, err := c.AppsConfig() + ac, err := c.AppsConfig.Get() assert.NoError(t, err) assert.NotEmpty(t, ac) } @@ -20,7 +20,7 @@ func TestAppsConfigList(t *testing.T) { if err := initClient(); err != nil { t.Fatal(err) } - a, err := c.AppsConfigList() + a, err := c.AppsConfig.List() assert.NoError(t, err) assert.Contains(t, a, "files") } @@ -30,7 +30,7 @@ func TestAppsConfigKeys(t *testing.T) { if err := initClient(); err != nil { t.Fatal(err) } - ks, err := c.AppsConfigKeys("activity") + ks, err := c.AppsConfig.Keys("activity") assert.NoError(t, err) assert.Contains(t, ks, "enabled") } @@ -40,7 +40,7 @@ func TestAppsConfigValue(t *testing.T) { if err := initClient(); err != nil { t.Fatal(err) } - k, err := c.AppsConfigValue("files", "enabled") + k, err := c.AppsConfig.Value("files", "enabled") assert.NoError(t, err) assert.Equal(t, "yes", k) } @@ -50,7 +50,7 @@ func TestAppConfigDetails(t *testing.T) { if err := initClient(); err != nil { t.Fatal(err) } - d, err := c.AppsConfigDetails("activity") + d, err := c.AppsConfig.Details("activity") assert.NoError(t, err) assert.NotEmpty(t, d) } diff --git a/client.go b/client.go index 563bfd1..b79f4b9 100644 --- a/client.go +++ b/client.go @@ -15,6 +15,14 @@ type Client struct { headers map[string]string capabilities *types.Capabilities version *types.Version + + Apps *Apps + AppsConfig *AppsConfig + GroupFolders *GroupFolders + Notifications *Notifications + Shares *Shares + Users *Users + Groups *Groups } // NewClient create a new Client from the Nextcloud Instance URL @@ -27,12 +35,19 @@ func NewClient(hostname string) (*Client, error) { } } - c := Client{ + c := &Client{ baseURL: baseURL, headers: map[string]string{ "OCS-APIREQUEST": "true", "Accept": "application/json", }, } - return &c, nil + c.Apps = &Apps{c} + c.AppsConfig = &AppsConfig{c} + c.GroupFolders = &GroupFolders{c} + c.Notifications = &Notifications{c} + c.Shares = &Shares{c} + c.Users = &Users{c} + c.Groups = &Groups{c} + return c, nil } diff --git a/doc.go b/doc.go index adf9cd0..4c423e5 100644 --- a/doc.go +++ b/doc.go @@ -30,7 +30,7 @@ For example, to list all the Nextcloud's instance users: } defer c.Logout() - users, err := c.UserList() + users, err := c.List() if err != nil { panic(err) } diff --git a/gonextcloud_test.go b/gonextcloud_test.go index 8c00f8d..2f89d0f 100644 --- a/gonextcloud_test.go +++ b/gonextcloud_test.go @@ -74,7 +74,7 @@ var ( { "user list", func(t *testing.T) { - us, err := c.UserList() + us, err := c.Users.List() assert.NoError(t, err) assert.Contains(t, us, config.Login) }, @@ -83,7 +83,7 @@ var ( { "existing user", func(t *testing.T) { - u, err := c.User(config.Login) + u, err := c.Users.Get(config.Login) assert.NoError(t, err) assert.NotNil(t, u) }, @@ -92,7 +92,7 @@ var ( { "empty user", func(t *testing.T) { - u, err := c.User("") + u, err := c.Users.Get("") assert.Error(t, err) assert.Empty(t, u) }, @@ -101,7 +101,7 @@ var ( { "TestNonExistingUser", func(t *testing.T) { - _, err := c.User(config.NotExistingUser) + _, err := c.Users.Get(config.NotExistingUser) assert.Error(t, err) }, }, @@ -109,7 +109,7 @@ var ( { "TestUserSearch", func(t *testing.T) { - us, err := c.UserSearch(config.Login) + us, err := c.Users.Search(config.Login) assert.NoError(t, err) assert.Contains(t, us, config.Login) }, @@ -118,7 +118,7 @@ var ( { "TestUserCreate", func(t *testing.T) { - err := c.UserCreate(config.NotExistingUser, password, nil) + err := c.Users.Create(config.NotExistingUser, password, nil) assert.NoError(t, err) }, }, @@ -129,7 +129,7 @@ var ( // return // } // username := fmt.Sprintf("%s-2", config.NotExistingUser) - // user := &types.User{ + // user := &types.Users{ // ID: username, // Displayname: strings.ToUpper(username), // Email: "some@address.com", @@ -138,9 +138,9 @@ var ( // Phone: "42 42 242 424", // Website: "my.site.com", // } - // err := c.UserCreate(username, password, user) + // err := c.Users.Create(username, password, user) // assert.NoError(t, err) - // u, err := c.User(username) + // u, err := c.Users.Get(username) // assert.NoError(t, err) // o := structs.Map(user) // r := structs.Map(u) @@ -151,7 +151,7 @@ var ( // assert.Equal(t, o[k], r[k]) // } // // Clean up - // err = c.UserDelete(u.ID) + // err = c.Users.Delete(u.ID) // assert.NoError(t, err) // }, //}, @@ -163,9 +163,9 @@ var ( // return // } // username := fmt.Sprintf("%s-2", config.NotExistingUser) - // err := c.UserCreate(username, password, nil) + // err := c.Users.Create(username, password, nil) // assert.NoError(t, err) - // user := &types.User{ + // user := &types.Users{ // ID: username, // Displayname: strings.ToUpper(username), // Email: "some@address.com", @@ -174,9 +174,9 @@ var ( // Phone: "42 42 242 424", // Website: "my.site.com", // } - // err = c.UserUpdate(user) + // err = c.Users.Update(user) // assert.NoError(t, err) - // u, err := c.User(username) + // u, err := c.Users.Get(username) // assert.NoError(t, err) // o := structs.Map(user) // r := structs.Map(u) @@ -187,14 +187,14 @@ var ( // assert.Equal(t, o[k], r[k]) // } // // Clean up - // err = c.UserDelete(u.ID) + // err = c.Users.Delete(u.ID) // assert.NoError(t, err) // }, //}, { "TestUserCreateExisting", func(t *testing.T) { - err := c.UserCreate(config.Login, password, nil) + err := c.Users.Create(config.Login, password, nil) assert.Error(t, err) }, }, @@ -202,7 +202,7 @@ var ( { "TestGroupList", func(t *testing.T) { - gs, err := c.GroupList() + gs, err := c.Groups.List() assert.NoError(t, err) assert.Contains(t, gs, "admin") }, @@ -211,7 +211,7 @@ var ( { "TestGroupCreate", func(t *testing.T) { - err := c.GroupCreate(config.NotExistingGroup) + err := c.Groups.Create(config.NotExistingGroup) assert.NoError(t, err) }, }, @@ -220,9 +220,9 @@ var ( "TestUserUpdateEmail", func(t *testing.T) { email := "my@mail.com" - err := c.UserUpdateEmail(config.NotExistingUser, email) + err := c.Users.UpdateEmail(config.NotExistingUser, email) assert.NoError(t, err) - u, err := c.User(config.NotExistingUser) + u, err := c.Users.Get(config.NotExistingUser) assert.NoError(t, err) if err != nil { t.Fail() @@ -236,9 +236,9 @@ var ( "TestUserUpdateDisplayName", func(t *testing.T) { displayName := "Display Name" - err := c.UserUpdateDisplayName(config.NotExistingUser, displayName) + err := c.Users.UpdateDisplayName(config.NotExistingUser, displayName) assert.NoError(t, err) - u, err := c.User(config.NotExistingUser) + u, err := c.Users.Get(config.NotExistingUser) assert.NoError(t, err) if err != nil { t.Fail() @@ -252,9 +252,9 @@ var ( "TestUserUpdatePhone", func(t *testing.T) { phone := "+33 42 42 42 42" - err := c.UserUpdatePhone(config.NotExistingUser, phone) + err := c.Users.UpdatePhone(config.NotExistingUser, phone) assert.NoError(t, err) - u, err := c.User(config.NotExistingUser) + u, err := c.Users.Get(config.NotExistingUser) assert.NoError(t, err) if err != nil { t.Fail() @@ -268,9 +268,9 @@ var ( "TestUserUpdateAddress", func(t *testing.T) { address := "Main Street, Galifrey" - err := c.UserUpdateAddress(config.NotExistingUser, address) + err := c.Users.UpdateAddress(config.NotExistingUser, address) assert.NoError(t, err) - u, err := c.User(config.NotExistingUser) + u, err := c.Users.Get(config.NotExistingUser) assert.NoError(t, err) if err != nil { t.Fail() @@ -284,9 +284,9 @@ var ( "TestUserUpdateWebSite", func(t *testing.T) { website := "www.doctor.who" - err := c.UserUpdateWebSite(config.NotExistingUser, website) + err := c.Users.UpdateWebSite(config.NotExistingUser, website) assert.NoError(t, err) - u, err := c.User(config.NotExistingUser) + u, err := c.Users.Get(config.NotExistingUser) assert.NoError(t, err) if err != nil { t.Fail() @@ -299,9 +299,9 @@ var ( "TestUserUpdateTwitter", func(t *testing.T) { twitter := "@doctorwho" - err := c.UserUpdateTwitter(config.NotExistingUser, twitter) + err := c.Users.UpdateTwitter(config.NotExistingUser, twitter) assert.NoError(t, err) - u, err := c.User(config.NotExistingUser) + u, err := c.Users.Get(config.NotExistingUser) assert.NoError(t, err) if err != nil { t.Fail() @@ -314,10 +314,10 @@ var ( "TestUserUpdateQuota", func(t *testing.T) { quota := 1024 * 1024 * 1024 - err := c.UserUpdateQuota(config.NotExistingUser, quota) + err := c.Users.UpdateQuota(config.NotExistingUser, quota) assert.NoError(t, err) - // TODO : Find better verification : A never connected User does not have quota available - //u, err := c.User(config.NotExistingUser) + // TODO : Find better verification : A never connected Users does not have quota available + //u, err := c.Users(config.NotExistingUser) //assert.NoError(t, err) //assert.Equal(t, quota, u.Quota.Quota) }, @@ -326,15 +326,15 @@ var ( "TestUserUpdatePassword", func(t *testing.T) { password := "newcomplexpassword" - err := c.UserUpdatePassword(config.NotExistingUser, password) + err := c.Users.UpdatePassword(config.NotExistingUser, password) assert.NoError(t, err) }}, { "TestUserGroupAdd", func(t *testing.T) { - err := c.UserGroupAdd(config.NotExistingUser, config.NotExistingGroup) + err := c.Users.GroupAdd(config.NotExistingUser, config.NotExistingGroup) assert.NoError(t, err) - gs, err := c.UserGroupList(config.NotExistingUser) + gs, err := c.Users.GroupList(config.NotExistingUser) assert.NoError(t, err) assert.Contains(t, gs, config.NotExistingGroup) }, @@ -342,7 +342,7 @@ var ( { "TestUserGroupSubAdminList", func(t *testing.T) { - gs, err := c.UserGroupSubAdminList(config.NotExistingUser) + gs, err := c.Users.GroupSubAdminList(config.NotExistingUser) assert.NoError(t, err) assert.Empty(t, gs) }, @@ -350,9 +350,9 @@ var ( { "TestUserGroupPromote", func(t *testing.T) { - err := c.UserGroupPromote(config.NotExistingUser, config.NotExistingGroup) + err := c.Users.GroupPromote(config.NotExistingUser, config.NotExistingGroup) assert.NoError(t, err) - gs, err := c.UserGroupSubAdminList(config.NotExistingUser) + gs, err := c.Users.GroupSubAdminList(config.NotExistingUser) assert.NoError(t, err) assert.Contains(t, gs, config.NotExistingGroup) }, @@ -360,7 +360,7 @@ var ( { "TestUserGroupDemote", func(t *testing.T) { - err := c.UserGroupDemote(config.NotExistingUser, config.NotExistingGroup) + err := c.Users.GroupDemote(config.NotExistingUser, config.NotExistingGroup) assert.NoError(t, err) //gs, err := c.UserGroupSubAdminList(config.NotExistingUser) //assert.NoError(t, err) @@ -370,9 +370,9 @@ var ( { "TestUserDisable", func(t *testing.T) { - err := c.UserDisable(config.NotExistingUser) + err := c.Users.Disable(config.NotExistingUser) assert.NoError(t, err) - u, err := c.User(config.NotExistingUser) + u, err := c.Users.Get(config.NotExistingUser) assert.NoError(t, err) if err != nil { t.Fail() @@ -384,9 +384,9 @@ var ( { "TestUserEnable", func(t *testing.T) { - err := c.UserEnable(config.NotExistingUser) + err := c.Users.Enable(config.NotExistingUser) assert.NoError(t, err) - u, err := c.User(config.NotExistingUser) + u, err := c.Users.Get(config.NotExistingUser) assert.NoError(t, err) if err != nil { t.Fail() @@ -398,14 +398,14 @@ var ( { "TestGroupDelete", func(t *testing.T) { - err := c.GroupDelete(config.NotExistingGroup) + err := c.Groups.Delete(config.NotExistingGroup) assert.NoError(t, err) }, }, { "TestUserDelete", func(t *testing.T) { - err := c.UserDelete(config.NotExistingUser) + err := c.Users.Delete(config.NotExistingUser) assert.NoError(t, err) }, }, @@ -424,7 +424,7 @@ var ( if err := initClient(); err != nil { return } - s, err := c.SharesList() + s, err := c.Shares.List() assert.NoError(t, err) assert.NotNil(t, s) }, @@ -482,9 +482,9 @@ func TestUserCreateWithoutPassword(t *testing.T) { t.SkipNow() } // Nextcloud does not seems to like recreating a deleted user - err := c.UserCreateWithoutPassword(config.NotExistingUser, config.Email, strings.Title(config.NotExistingUser)) + err := c.Users.CreateWithoutPassword(config.NotExistingUser, config.Email, strings.Title(config.NotExistingUser)) assert.NoError(t, err) - err = c.UserDelete(config.NotExistingUser) + err = c.Users.Delete(config.NotExistingUser) assert.NoError(t, err) } @@ -493,7 +493,7 @@ func TestUserListDetails(t *testing.T) { if err := initClient(); err != nil { t.Fatal(err) } - us, err := c.UserListDetails() + us, err := c.Users.ListDetails() assert.NoError(t, err) assert.Contains(t, us, config.Login) } @@ -503,7 +503,7 @@ func TestGroupListDetails(t *testing.T) { if err := initClient(); err != nil { t.Fatal(err) } - gs, err := c.GroupListDetails() + gs, err := c.Groups.ListDetails() assert.NoError(t, err) assert.NotEmpty(t, gs) } diff --git a/groupfolders.go b/groupfolders.go index b5b6ec2..ef84723 100644 --- a/groupfolders.go +++ b/groupfolders.go @@ -8,9 +8,26 @@ import ( "strconv" ) -//GroupFoldersList returns the groups folders -func (c *Client) GroupFoldersList() (map[int]types.GroupFolder, error) { - res, err := c.baseRequest(http.MethodGet, routes.groupfolders, nil) +//GroupFoldersI available methods +type GroupFoldersI interface { + List() (map[int]types.GroupFolder, error) + Get(id int) (types.GroupFolder, error) + Create(name string) (id int, err error) + Rename(groupID int, name string) error + AddGroup(folderID int, groupName string) error + RemoveGroup(folderID int, groupName string) error + SetGroupPermissions(folderID int, groupName string, permission types.SharePermission) error + SetQuota(folderID int, quota int) error +} + +//GroupFolders contains all Groups Folders available actions +type GroupFolders struct { + c *Client +} + +//List returns the groups folders +func (g *GroupFolders) List() (map[int]types.GroupFolder, error) { + res, err := g.c.baseRequest(http.MethodGet, routes.groupfolders, nil) if err != nil { return nil, err } @@ -20,9 +37,9 @@ func (c *Client) GroupFoldersList() (map[int]types.GroupFolder, error) { return gfs, nil } -//GroupFolders returns the group folder details -func (c *Client) GroupFolders(id int) (types.GroupFolder, error) { - res, err := c.baseRequest(http.MethodGet, routes.groupfolders, nil, strconv.Itoa(id)) +//Get returns the group folder details +func (g *GroupFolders) Get(id int) (types.GroupFolder, error) { + res, err := g.c.baseRequest(http.MethodGet, routes.groupfolders, nil, strconv.Itoa(id)) if err != nil { return types.GroupFolder{}, err } @@ -34,15 +51,15 @@ func (c *Client) GroupFolders(id int) (types.GroupFolder, error) { return r.Ocs.Data.FormatGroupFolder(), nil } -//GroupFoldersCreate creates a group folder -func (c *Client) GroupFoldersCreate(name string) (id int, err error) { +//Create creates a group folder +func (g *GroupFolders) Create(name string) (id int, err error) { // TODO: Validate Folder name ro := &req.RequestOptions{ Data: map[string]string{ "mountpoint": name, }, } - res, err := c.baseRequest(http.MethodPost, routes.groupfolders, ro) + res, err := g.c.baseRequest(http.MethodPost, routes.groupfolders, ro) if err != nil { return 0, err } @@ -52,15 +69,15 @@ func (c *Client) GroupFoldersCreate(name string) (id int, err error) { return id, nil } -//GroupFoldersRename renames the group folder -func (c *Client) GroupFoldersRename(groupID int, name string) error { +//Rename renames the group folder +func (g *GroupFolders) Rename(groupID int, name string) error { ro := &req.RequestOptions{ Data: map[string]string{ "mountpoint": name, }, } // GroupFolders's response does not give any clues about success or failure - _, err := c.baseRequest(http.MethodPost, routes.groupfolders, ro, strconv.Itoa(groupID), "mountpoint") + _, err := g.c.baseRequest(http.MethodPost, routes.groupfolders, ro, strconv.Itoa(groupID), "mountpoint") if err != nil { return err } @@ -69,55 +86,55 @@ func (c *Client) GroupFoldersRename(groupID int, name string) error { //TODO func (c *Client) GroupFoldersDelete(id int) error { -//GroupFoldersAddGroup adds group to folder -func (c *Client) GroupFoldersAddGroup(folderID int, groupName string) error { +//AddGroup adds group to folder +func (g *GroupFolders) AddGroup(folderID int, groupName string) error { ro := &req.RequestOptions{ Data: map[string]string{ "group": groupName, }, } // GroupFolders's response does not give any clues about success or failure - _, err := c.baseRequest(http.MethodPost, routes.groupfolders, ro, strconv.Itoa(folderID), "groups") + _, err := g.c.baseRequest(http.MethodPost, routes.groupfolders, ro, strconv.Itoa(folderID), "groups") if err != nil { return err } return nil } -//GroupFoldersRemoveGroup remove a group from the group folder -func (c *Client) GroupFoldersRemoveGroup(folderID int, groupName string) error { +//RemoveGroup remove a group from the group folder +func (g *GroupFolders) RemoveGroup(folderID int, groupName string) error { // GroupFolders's response does not give any clues about success or failure - _, err := c.baseRequest(http.MethodDelete, routes.groupfolders, nil, strconv.Itoa(folderID), "groups", groupName) + _, err := g.c.baseRequest(http.MethodDelete, routes.groupfolders, nil, strconv.Itoa(folderID), "groups", groupName) if err != nil { return err } return nil } -//GroupFoldersSetGroupPermissions set groups permissions -func (c *Client) GroupFoldersSetGroupPermissions(folderID int, groupName string, permission types.SharePermission) error { +//SetGroupPermissions set groups permissions +func (g *GroupFolders) SetGroupPermissions(folderID int, groupName string, permission types.SharePermission) error { ro := &req.RequestOptions{ Data: map[string]string{ "permissions": strconv.Itoa(int(permission)), }, } // GroupFolders's response does not give any clues about success or failure - _, err := c.baseRequest(http.MethodPost, routes.groupfolders, ro, strconv.Itoa(folderID), "groups", groupName) + _, err := g.c.baseRequest(http.MethodPost, routes.groupfolders, ro, strconv.Itoa(folderID), "groups", groupName) if err != nil { return err } return nil } -//GroupFoldersSetQuota set quota on the group folder. quota in bytes, use -3 for unlimited -func (c *Client) GroupFoldersSetQuota(folderID int, quota int) error { +//SetQuota set quota on the group folder. quota in bytes, use -3 for unlimited +func (g *GroupFolders) SetQuota(folderID int, quota int) error { ro := &req.RequestOptions{ Data: map[string]string{ "quota": strconv.Itoa(int(quota)), }, } // GroupFolders's response does not give any clues about success or failure - _, err := c.baseRequest(http.MethodPost, routes.groupfolders, ro, strconv.Itoa(folderID), "quota") + _, err := g.c.baseRequest(http.MethodPost, routes.groupfolders, ro, strconv.Itoa(folderID), "quota") if err != nil { return err } diff --git a/groupfolders_test.go b/groupfolders_test.go index a8a007a..78c0a2b 100644 --- a/groupfolders_test.go +++ b/groupfolders_test.go @@ -16,14 +16,14 @@ var ( func(t *testing.T) { // Recreate client var err error - groupID, err = c.GroupFoldersCreate("API") + groupID, err = c.GroupFolders.Create("API") assert.NoError(t, err) }, }, { "TestGroupFoldersList", func(t *testing.T) { - gfs, err := c.GroupFoldersList() + gfs, err := c.GroupFolders.List() assert.NoError(t, err) assert.NotNil(t, gfs[groupID]) }, @@ -31,7 +31,7 @@ var ( { "TestGroupFolders", func(t *testing.T) { - gf, err := c.GroupFolders(groupID) + gf, err := c.GroupFolders.Get(groupID) assert.NoError(t, err) assert.NotNil(t, gf) }, @@ -39,35 +39,35 @@ var ( { "TestGroupFolderRename", func(t *testing.T) { - err := c.GroupFoldersRename(groupID, "API_Renamed") + err := c.GroupFolders.Rename(groupID, "API_Renamed") assert.NoError(t, err) }, }, { "TestGroupFoldersAddGroup", func(t *testing.T) { - err := c.GroupFoldersAddGroup(groupID, "admin") + err := c.GroupFolders.AddGroup(groupID, "admin") assert.NoError(t, err) }, }, { "TestGroupFoldersSetGroupPermissions", func(t *testing.T) { - err := c.GroupFoldersSetGroupPermissions(groupID, "admin", types.ReadPermission) + err := c.GroupFolders.SetGroupPermissions(groupID, "admin", types.ReadPermission) assert.NoError(t, err) }, }, { "TestGroupFoldersSetQuota", func(t *testing.T) { - err := c.GroupFoldersSetQuota(groupID, 100) + err := c.GroupFolders.SetQuota(groupID, 100) assert.NoError(t, err) }, }, { "TestGroupFolderRemoveGroup", func(t *testing.T) { - err := c.GroupFoldersRemoveGroup(groupID, "admin") + err := c.GroupFolders.RemoveGroup(groupID, "admin") assert.NoError(t, err) }, }, diff --git a/groups.go b/groups.go index 6f8c2a2..7c68871 100644 --- a/groups.go +++ b/groups.go @@ -6,9 +6,25 @@ import ( "net/http" ) -//GroupList lists the Nextcloud groups -func (c *Client) GroupList() ([]string, error) { - res, err := c.baseRequest(http.MethodGet, routes.groups, nil) +//GroupsI available methods +type GroupsI interface { + List() ([]string, error) + ListDetails() ([]types.Group, error) + Users(name string) ([]string, error) + Search(search string) ([]string, error) + Create(name string) error + Delete(name string) error + SubAdminList(name string) ([]string, error) +} + +//Groups contains all Groups available actions +type Groups struct { + c *Client +} + +//List lists the Nextcloud groups +func (g *Groups) List() ([]string, error) { + res, err := g.c.baseRequest(http.MethodGet, routes.groups, nil) if err != nil { return nil, err } @@ -17,9 +33,9 @@ func (c *Client) GroupList() ([]string, error) { return r.Ocs.Data.Groups, nil } -//GroupListDetails lists the Nextcloud groups -func (c *Client) GroupListDetails() ([]types.Group, error) { - res, err := c.baseRequest(http.MethodGet, routes.groups, nil, "details") +//ListDetails lists the Nextcloud groups +func (g *Groups) ListDetails() ([]types.Group, error) { + res, err := g.c.baseRequest(http.MethodGet, routes.groups, nil, "details") if err != nil { return nil, err } @@ -28,9 +44,9 @@ func (c *Client) GroupListDetails() ([]types.Group, error) { return r.Ocs.Data.Groups, nil } -//GroupUsers list the group's users -func (c *Client) GroupUsers(name string) ([]string, error) { - res, err := c.baseRequest(http.MethodGet, routes.groups, nil, name) +//Users list the group's users +func (g *Groups) Users(name string) ([]string, error) { + res, err := g.c.baseRequest(http.MethodGet, routes.groups, nil, name) if err != nil { return nil, err } @@ -39,12 +55,12 @@ func (c *Client) GroupUsers(name string) ([]string, error) { return r.Ocs.Data.Users, nil } -//GroupSearch return the list of groups matching the search string -func (c *Client) GroupSearch(search string) ([]string, error) { +//Search return the list of groups matching the search string +func (g *Groups) Search(search string) ([]string, error) { ro := &req.RequestOptions{ Params: map[string]string{"search": search}, } - res, err := c.baseRequest(http.MethodGet, routes.groups, ro) + res, err := g.c.baseRequest(http.MethodGet, routes.groups, ro) if err != nil { return nil, err } @@ -53,24 +69,24 @@ func (c *Client) GroupSearch(search string) ([]string, error) { return r.Ocs.Data.Groups, nil } -//GroupCreate creates a group -func (c *Client) GroupCreate(name string) error { +//Create creates a group +func (g *Groups) Create(name string) error { ro := &req.RequestOptions{ Data: map[string]string{ "groupid": name, }, } - return c.groupBaseRequest(http.MethodPost, ro) + return g.baseRequest(http.MethodPost, ro) } -//GroupDelete deletes the group -func (c *Client) GroupDelete(name string) error { - return c.groupBaseRequest(http.MethodDelete, nil, name) +//Delete deletes the group +func (g *Groups) Delete(name string) error { + return g.baseRequest(http.MethodDelete, nil, name) } -//GroupSubAdminList lists the group's subadmins -func (c *Client) GroupSubAdminList(name string) ([]string, error) { - res, err := c.baseRequest(http.MethodGet, routes.groups, nil, name, "subadmins") +//SubAdminList lists the group's subadmins +func (g *Groups) SubAdminList(name string) ([]string, error) { + res, err := g.c.baseRequest(http.MethodGet, routes.groups, nil, name, "subadmins") if err != nil { return nil, err } @@ -79,7 +95,7 @@ func (c *Client) GroupSubAdminList(name string) ([]string, error) { return r.Ocs.Data.Users, nil } -func (c *Client) groupBaseRequest(method string, ro *req.RequestOptions, subRoute ...string) error { - _, err := c.baseRequest(method, routes.groups, ro, subRoute...) +func (g *Groups) baseRequest(method string, ro *req.RequestOptions, subRoute ...string) error { + _, err := g.c.baseRequest(method, routes.groups, ro, subRoute...) return err } diff --git a/notifications.go b/notifications.go index 080917a..a1780e2 100644 --- a/notifications.go +++ b/notifications.go @@ -8,12 +8,28 @@ import ( "strconv" ) -//NotificationsList returns all the notifications -func (c *Client) NotificationsList() ([]types.Notification, error) { - if err := c.notificationsAvailable(); err != nil { +//NotificationsI available methods +type NotificationsI interface { + List() ([]types.Notification, error) + Get(id int) (types.Notification, error) + Delete(id int) error + DeleteAll() error + Create(userID, title, message string) error + AdminAvailable() error + Available() error +} + +//Notifications contains all Notifications available actions +type Notifications struct { + c *Client +} + +//List returns all the notifications +func (n *Notifications) List() ([]types.Notification, error) { + if err := n.Available(); err != nil { return nil, err } - res, err := c.baseRequest(http.MethodGet, routes.notifications, nil) + res, err := n.c.baseRequest(http.MethodGet, routes.notifications, nil) if err != nil { return nil, err } @@ -22,12 +38,12 @@ func (c *Client) NotificationsList() ([]types.Notification, error) { return r.Ocs.Data, nil } -//Notifications returns the notification corresponding to the id -func (c *Client) Notifications(id int) (types.Notification, error) { - if err := c.notificationsAvailable(); err != nil { +//Get returns the notification corresponding to the id +func (n *Notifications) Get(id int) (types.Notification, error) { + if err := n.Available(); err != nil { return types.Notification{}, err } - res, err := c.baseRequest(http.MethodGet, routes.notifications, nil, strconv.Itoa(id)) + res, err := n.c.baseRequest(http.MethodGet, routes.notifications, nil, strconv.Itoa(id)) if err != nil { return types.Notification{}, err } @@ -36,27 +52,27 @@ func (c *Client) Notifications(id int) (types.Notification, error) { return r.Ocs.Data, nil } -//NotificationsDelete deletes the notification corresponding to the id -func (c *Client) NotificationsDelete(id int) error { - if err := c.notificationsAvailable(); err != nil { +//Delete deletes the notification corresponding to the id +func (n *Notifications) Delete(id int) error { + if err := n.Available(); err != nil { return err } - _, err := c.baseRequest(http.MethodDelete, routes.notifications, nil, strconv.Itoa(id)) + _, err := n.c.baseRequest(http.MethodDelete, routes.notifications, nil, strconv.Itoa(id)) return err } -//NotificationsDeleteAll deletes all notifications -func (c *Client) NotificationsDeleteAll() error { - if err := c.notificationsAvailable(); err != nil { +//DeleteAll deletes all notifications +func (n *Notifications) DeleteAll() error { + if err := n.Available(); err != nil { return err } - _, err := c.baseRequest(http.MethodDelete, routes.notifications, nil) + _, err := n.c.baseRequest(http.MethodDelete, routes.notifications, nil) return err } -//NotificationsCreate creates a notification (if the user is an admin) -func (c *Client) NotificationsCreate(userID, title, message string) error { - if err := c.adminNotificationsAvailable(); err != nil { +//Create creates a notification (if the user is an admin) +func (n *Notifications) Create(userID, title, message string) error { + if err := n.AdminAvailable(); err != nil { return err } ro := &req.RequestOptions{ @@ -65,18 +81,21 @@ func (c *Client) NotificationsCreate(userID, title, message string) error { "longMessage": message, }, } - _, err := c.baseRequest(http.MethodPost, routes.adminNotifications, ro, userID) + _, err := n.c.baseRequest(http.MethodPost, routes.adminNotifications, ro, userID) return err } -func (c *Client) adminNotificationsAvailable() error { - if len(c.capabilities.Notifications.AdminNotifications) == 0 { +//AdminAvailable returns an error if the admin-notifications app is not installed +func (n *Notifications) AdminAvailable() error { + if len(n.c.capabilities.Notifications.AdminNotifications) == 0 { return errors.New("'admin notifications' not available on this instance") } return nil } -func (c *Client) notificationsAvailable() error { - if len(c.capabilities.Notifications.OcsEndpoints) == 0 { + +//Available returns an error if the notifications app is not installed +func (n *Notifications) Available() error { + if len(n.c.capabilities.Notifications.OcsEndpoints) == 0 { return errors.New("notifications not available on this instance") } return nil diff --git a/notifications_test.go b/notifications_test.go index 4c27002..f305768 100644 --- a/notifications_test.go +++ b/notifications_test.go @@ -17,14 +17,14 @@ var ( { "notificationCreate", func(t *testing.T) { - err := c.NotificationsCreate(config.Login, title, message) + err := c.Notifications.Create(config.Login, title, message) assert.NoError(t, err) }, }, { "notificationDelete", func(t *testing.T) { // Get created Notification ID - ns, err := c.NotificationsList() + ns, err := c.Notifications.List() if err != nil { t.SkipNow() } @@ -37,7 +37,7 @@ var ( if createdID == 0 { t.SkipNow() } - err = c.NotificationsDelete(createdID) + err = c.Notifications.Delete(createdID) assert.NoError(t, err) }, }, @@ -49,10 +49,10 @@ func TestNotificationsList(t *testing.T) { if err := initClient(); err != nil { t.Fatal(err) } - if err := c.notificationsAvailable(); err != nil { + if err := c.Notifications.Available(); err != nil { t.SkipNow() } - ns, err := c.NotificationsList() + ns, err := c.Notifications.List() assert.NoError(t, err) if len(ns) > 0 { notificationID = ns[0].NotificationID @@ -67,10 +67,10 @@ func TestNotifications(t *testing.T) { if err := initClient(); err != nil { t.Fatal(err) } - if err := c.notificationsAvailable(); err != nil { + if err := c.Notifications.Available(); err != nil { t.SkipNow() } - n, err := c.Notifications(notificationID) + n, err := c.Notifications.Get(notificationID) assert.NoError(t, err) assert.NotEmpty(t, n) } @@ -81,7 +81,7 @@ func TestNotifications(t *testing.T) { // if err := initClient(); err != nil { // t.Fatal(err) // } -// if err := c.adminNotificationsAvailable(); err != nil { +// if err := c.AdminAvailable(); err != nil { // t.SkipNow() // } // for _, test := range tests { diff --git a/shares.go b/shares.go index 6823860..a8ac256 100644 --- a/shares.go +++ b/shares.go @@ -9,9 +9,35 @@ import ( "sync" ) -//SharesList list all shares of the logged in user -func (c *Client) SharesList() ([]types.Share, error) { - res, err := c.baseRequest(http.MethodGet, routes.shares, nil) +//SharesI available methods +type SharesI interface { + List() ([]types.Share, error) + GetFromPath(path string, reshares bool, subfiles bool) ([]types.Share, error) + Get(shareID string) (types.Share, error) + Create( + path string, + shareType types.ShareType, + permission types.SharePermission, + shareWith string, + publicUpload bool, + password string, + ) (types.Share, error) + Delete(shareID int) error + Update(shareUpdate types.ShareUpdate) error + UpdateExpireDate(shareID int, expireDate string) error + UpdatePublicUpload(shareID int, public bool) error + UpdatePassword(shareID int, password string) error + UpdatePermissions(shareID int, permissions types.SharePermission) error +} + +//Shares contains all Shares available actions +type Shares struct { + c *Client +} + +//List list all shares of the logged in user +func (s *Shares) List() ([]types.Share, error) { + res, err := s.c.baseRequest(http.MethodGet, routes.shares, nil) if err != nil { return nil, err } @@ -20,8 +46,8 @@ func (c *Client) SharesList() ([]types.Share, error) { return r.Ocs.Data, nil } -//Shares return shares from a specific file or folder -func (c *Client) Shares(path string, reshares bool, subfiles bool) ([]types.Share, error) { +//GetFromPath return shares from a specific file or folder +func (s *Shares) GetFromPath(path string, reshares bool, subfiles bool) ([]types.Share, error) { ro := &req.RequestOptions{ Params: map[string]string{ "path": path, @@ -29,7 +55,7 @@ func (c *Client) Shares(path string, reshares bool, subfiles bool) ([]types.Shar "subfiles": strconv.FormatBool(subfiles), }, } - res, err := c.baseRequest(http.MethodGet, routes.shares, ro) + res, err := s.c.baseRequest(http.MethodGet, routes.shares, ro) if err != nil { return nil, err } @@ -38,9 +64,9 @@ func (c *Client) Shares(path string, reshares bool, subfiles bool) ([]types.Shar return r.Ocs.Data, nil } -//Share Get information about a known Share -func (c *Client) Share(shareID string) (types.Share, error) { - res, err := c.baseRequest(http.MethodGet, routes.shares, nil, shareID) +//Get information about a known Share +func (s *Shares) Get(shareID string) (types.Share, error) { + res, err := s.c.baseRequest(http.MethodGet, routes.shares, nil, shareID) if err != nil { return types.Share{}, err } @@ -49,8 +75,8 @@ func (c *Client) Share(shareID string) (types.Share, error) { return r.Ocs.Data[0], nil } -//ShareCreate create a share -func (c *Client) ShareCreate( +//Create create a share +func (s *Shares) Create( path string, shareType types.ShareType, permission types.SharePermission, @@ -72,7 +98,7 @@ func (c *Client) ShareCreate( "permissions": strconv.Itoa(int(permission)), }, } - res, err := c.baseRequest(http.MethodPost, routes.shares, ro) + res, err := s.c.baseRequest(http.MethodPost, routes.shares, ro) if err != nil { return types.Share{}, err } @@ -81,21 +107,21 @@ func (c *Client) ShareCreate( return r.Ocs.Data, nil } -//ShareDelete Remove the given share. -func (c *Client) ShareDelete(shareID int) error { - _, err := c.baseRequest(http.MethodDelete, routes.shares, nil, strconv.Itoa(shareID)) +//Delete Remove the given share. +func (s *Shares) Delete(shareID int) error { + _, err := s.c.baseRequest(http.MethodDelete, routes.shares, nil, strconv.Itoa(shareID)) return err } -// ShareUpdate update share details +// Update update share details // expireDate expireDate expects a well formatted date string, e.g. ‘YYYY-MM-DD’ -func (c *Client) ShareUpdate(shareUpdate types.ShareUpdate) error { +func (s *Shares) Update(shareUpdate types.ShareUpdate) error { errs := make(chan types.UpdateError) var wg sync.WaitGroup wg.Add(4) go func() { defer wg.Done() - if err := c.ShareUpdatePassword(shareUpdate.ShareID, shareUpdate.Password); err != nil { + if err := s.UpdatePassword(shareUpdate.ShareID, shareUpdate.Password); err != nil { errs <- types.UpdateError{ Field: "password", Error: err, @@ -104,7 +130,7 @@ func (c *Client) ShareUpdate(shareUpdate types.ShareUpdate) error { }() go func() { defer wg.Done() - if err := c.ShareUpdateExpireDate(shareUpdate.ShareID, shareUpdate.ExpireDate); err != nil { + if err := s.UpdateExpireDate(shareUpdate.ShareID, shareUpdate.ExpireDate); err != nil { errs <- types.UpdateError{ Field: "expireDate", Error: err, @@ -113,7 +139,7 @@ func (c *Client) ShareUpdate(shareUpdate types.ShareUpdate) error { }() go func() { defer wg.Done() - if err := c.ShareUpdatePermissions(shareUpdate.ShareID, shareUpdate.Permissions); err != nil { + if err := s.UpdatePermissions(shareUpdate.ShareID, shareUpdate.Permissions); err != nil { errs <- types.UpdateError{ Field: "permissions", Error: err, @@ -122,7 +148,7 @@ func (c *Client) ShareUpdate(shareUpdate types.ShareUpdate) error { }() go func() { defer wg.Done() - if err := c.ShareUpdatePublicUpload(shareUpdate.ShareID, shareUpdate.PublicUpload); err != nil { + if err := s.UpdatePublicUpload(shareUpdate.ShareID, shareUpdate.PublicUpload); err != nil { errs <- types.UpdateError{ Field: "publicUpload", Error: err, @@ -136,31 +162,31 @@ func (c *Client) ShareUpdate(shareUpdate types.ShareUpdate) error { return types.NewUpdateError(errs) } -// ShareUpdateExpireDate updates the share's expire date +//UpdateExpireDate updates the share's expire date // expireDate expects a well formatted date string, e.g. ‘YYYY-MM-DD’ -func (c *Client) ShareUpdateExpireDate(shareID int, expireDate string) error { - return c.baseShareUpdate(strconv.Itoa(shareID), "expireDate", expireDate) +func (s *Shares) UpdateExpireDate(shareID int, expireDate string) error { + return s.baseShareUpdate(strconv.Itoa(shareID), "expireDate", expireDate) } -//ShareUpdatePublicUpload enable or disable public upload -func (c *Client) ShareUpdatePublicUpload(shareID int, public bool) error { - return c.baseShareUpdate(strconv.Itoa(shareID), "publicUpload", strconv.FormatBool(public)) +//UpdatePublicUpload enable or disable public upload +func (s *Shares) UpdatePublicUpload(shareID int, public bool) error { + return s.baseShareUpdate(strconv.Itoa(shareID), "publicUpload", strconv.FormatBool(public)) } -//ShareUpdatePassword updates share password -func (c *Client) ShareUpdatePassword(shareID int, password string) error { - return c.baseShareUpdate(strconv.Itoa(shareID), "password", password) +//UpdatePassword updates share password +func (s *Shares) UpdatePassword(shareID int, password string) error { + return s.baseShareUpdate(strconv.Itoa(shareID), "password", password) } -//ShareUpdatePermissions update permissions -func (c *Client) ShareUpdatePermissions(shareID int, permissions types.SharePermission) error { - return c.baseShareUpdate(strconv.Itoa(shareID), "permissions", strconv.Itoa(int(permissions))) +//UpdatePermissions update permissions +func (s *Shares) UpdatePermissions(shareID int, permissions types.SharePermission) error { + return s.baseShareUpdate(strconv.Itoa(shareID), "permissions", strconv.Itoa(int(permissions))) } -func (c *Client) baseShareUpdate(shareID string, key string, value string) error { +func (s *Shares) baseShareUpdate(shareID string, key string, value string) error { ro := &req.RequestOptions{ Data: map[string]string{key: value}, } - _, err := c.baseRequest(http.MethodPut, routes.shares, ro, shareID) + _, err := s.c.baseRequest(http.MethodPut, routes.shares, ro, shareID) return err } diff --git a/types/user.go b/types/user.go index 67cb8ec..b443f95 100644 --- a/types/user.go +++ b/types/user.go @@ -1,6 +1,6 @@ package types -//User +//Users type User struct { Enabled bool `json:"enabled"` ID string `json:"id"` diff --git a/users.go b/users.go index 3e440c7..6f0dc6d 100644 --- a/users.go +++ b/users.go @@ -13,9 +13,43 @@ import ( "sync" ) -// UserList return the Nextcloud'user list -func (c *Client) UserList() ([]string, error) { - res, err := c.baseRequest(http.MethodGet, routes.users, nil) +//UsersI available methods +type UsersI interface { + List() ([]string, error) + ListDetails() (map[string]types.User, error) + Get(name string) (*types.User, error) + Search(search string) ([]string, error) + Create(username string, password string, user *types.User) error + CreateWithoutPassword(username, email, displayName string) error + Delete(name string) error + Enable(name string) error + Disable(name string) error + SendWelcomeEmail(name string) error + Update(user *types.User) error + UpdateEmail(name string, email string) error + UpdateDisplayName(name string, displayName string) error + UpdatePhone(name string, phone string) error + UpdateAddress(name string, address string) error + UpdateWebSite(name string, website string) error + UpdateTwitter(name string, twitter string) error + UpdatePassword(name string, password string) error + UpdateQuota(name string, quota int) error + GroupList(name string) ([]string, error) + GroupAdd(name string, group string) error + GroupRemove(name string, group string) error + GroupPromote(name string, group string) error + GroupDemote(name string, group string) error + GroupSubAdminList(name string) ([]string, error) +} + +//Users contains all Users available actions +type Users struct { + c *Client +} + +// List return the Nextcloud'user list +func (u *Users) List() ([]string, error) { + res, err := u.c.baseRequest(http.MethodGet, routes.users, nil) //res, err := c.session.Get(u.String(), nil) if err != nil { return nil, err @@ -25,9 +59,9 @@ func (c *Client) UserList() ([]string, error) { return r.Ocs.Data.Users, nil } -//UserListDetails return a map of user with details -func (c *Client) UserListDetails() (map[string]types.User, error) { - res, err := c.baseRequest(http.MethodGet, routes.users, nil, "details") +//ListDetails return a map of user with details +func (u *Users) ListDetails() (map[string]types.User, error) { + res, err := u.c.baseRequest(http.MethodGet, routes.users, nil, "details") //res, err := c.session.Get(u.String(), nil) if err != nil { return nil, err @@ -37,12 +71,12 @@ func (c *Client) UserListDetails() (map[string]types.User, error) { return r.Ocs.Data.Users, nil } -// User return the details about the specified user -func (c *Client) User(name string) (*types.User, error) { +// Get return the details about the specified user +func (u *Users) Get(name string) (*types.User, error) { if name == "" { return nil, &types.APIError{Message: "name cannot be empty"} } - res, err := c.baseRequest(http.MethodGet, routes.users, nil, name) + res, err := u.c.baseRequest(http.MethodGet, routes.users, nil, name) if err != nil { return nil, err } @@ -56,12 +90,12 @@ func (c *Client) User(name string) (*types.User, error) { return &r.Ocs.Data, nil } -// UserSearch returns the users whose name match the search string -func (c *Client) UserSearch(search string) ([]string, error) { +// Search returns the users whose name match the search string +func (u *Users) Search(search string) ([]string, error) { ro := &req.RequestOptions{ Params: map[string]string{"search": search}, } - res, err := c.baseRequest(http.MethodGet, routes.users, ro) + res, err := u.c.baseRequest(http.MethodGet, routes.users, ro) if err != nil { return nil, err } @@ -70,16 +104,16 @@ func (c *Client) UserSearch(search string) ([]string, error) { return r.Ocs.Data.Users, nil } -// UserCreate create a new user -func (c *Client) UserCreate(username string, password string, user *types.User) error { - // Create base User +// Create create a new user +func (u *Users) Create(username string, password string, user *types.User) error { + // Create base Users ro := &req.RequestOptions{ Data: map[string]string{ "userid": username, "password": password, }, } - if err := c.userBaseRequest(http.MethodPost, ro); err != nil { + if err := u.baseRequest(http.MethodPost, ro); err != nil { return err } // Check if we need to add user details information @@ -87,13 +121,13 @@ func (c *Client) UserCreate(username string, password string, user *types.User) return nil } // Add user details information - return c.UserUpdate(user) + return u.Update(user) } -// UserCreateWithoutPassword create a user without provisioning a password, the email address must be provided to send +// CreateWithoutPassword create a user without provisioning a password, the email address must be provided to send // an init password email -func (c *Client) UserCreateWithoutPassword(username, email, displayName string) error { - if c.version.Major < 14 { +func (u *Users) CreateWithoutPassword(username, email, displayName string) error { + if u.c.version.Major < 14 { return errors.New("unsupported method: requires Nextcloud 14+") } if username == "" || email == "" { @@ -107,40 +141,40 @@ func (c *Client) UserCreateWithoutPassword(username, email, displayName string) }, } - if err := c.userBaseRequest(http.MethodPost, ro); err != nil { + if err := u.baseRequest(http.MethodPost, ro); err != nil { return err } return nil } -//UserDelete delete the user -func (c *Client) UserDelete(name string) error { - return c.userBaseRequest(http.MethodDelete, nil, name) +//Delete delete the user +func (u *Users) Delete(name string) error { + return u.baseRequest(http.MethodDelete, nil, name) } -//UserEnable enables the user -func (c *Client) UserEnable(name string) error { +//Enable enables the user +func (u *Users) Enable(name string) error { ro := &req.RequestOptions{ Data: map[string]string{}, } - return c.userBaseRequest(http.MethodPut, ro, name, "enable") + return u.baseRequest(http.MethodPut, ro, name, "enable") } -//UserDisable disables the user -func (c *Client) UserDisable(name string) error { +//Disable disables the user +func (u *Users) Disable(name string) error { ro := &req.RequestOptions{ Data: map[string]string{}, } - return c.userBaseRequest(http.MethodPut, ro, name, "disable") + return u.baseRequest(http.MethodPut, ro, name, "disable") } -//UserSendWelcomeEmail (re)send the welcome mail to the user (return an error if the user has not configured his email) -func (c *Client) UserSendWelcomeEmail(name string) error { - return c.userBaseRequest(http.MethodPost, nil, name, "welcome") +//SendWelcomeEmail (re)send the welcome mail to the user (return an error if the user has not configured his email) +func (u *Users) SendWelcomeEmail(name string) error { + return u.baseRequest(http.MethodPost, nil, name, "welcome") } -//UserUpdate takes a *types.User struct to update the user's information -func (c *Client) UserUpdate(user *types.User) error { +//Update takes a *types.Users struct to update the user's information +func (u *Users) Update(user *types.User) error { m := structs.Map(user) errs := make(chan types.UpdateError) var wg sync.WaitGroup @@ -149,7 +183,7 @@ func (c *Client) UserUpdate(user *types.User) error { wg.Add(1) go func(key string, value string) { defer wg.Done() - if err := c.userUpdateAttribute(user.ID, strings.ToLower(key), value); err != nil { + if err := u.updateAttribute(user.ID, strings.ToLower(key), value); err != nil { errs <- types.UpdateError{ Field: key, Error: err, @@ -165,49 +199,49 @@ func (c *Client) UserUpdate(user *types.User) error { return types.NewUpdateError(errs) } -//UserUpdateEmail update the user's email -func (c *Client) UserUpdateEmail(name string, email string) error { - return c.userUpdateAttribute(name, "email", email) +//UpdateEmail update the user's email +func (u *Users) UpdateEmail(name string, email string) error { + return u.updateAttribute(name, "email", email) } -//UserUpdateDisplayName update the user's display name -func (c *Client) UserUpdateDisplayName(name string, displayName string) error { - return c.userUpdateAttribute(name, "displayname", displayName) +//UpdateDisplayName update the user's display name +func (u *Users) UpdateDisplayName(name string, displayName string) error { + return u.updateAttribute(name, "displayname", displayName) } -//UserUpdatePhone update the user's phone -func (c *Client) UserUpdatePhone(name string, phone string) error { - return c.userUpdateAttribute(name, "phone", phone) +//UpdatePhone update the user's phone +func (u *Users) UpdatePhone(name string, phone string) error { + return u.updateAttribute(name, "phone", phone) } -//UserUpdateAddress update the user's address -func (c *Client) UserUpdateAddress(name string, address string) error { - return c.userUpdateAttribute(name, "address", address) +//UpdateAddress update the user's address +func (u *Users) UpdateAddress(name string, address string) error { + return u.updateAttribute(name, "address", address) } -//UserUpdateWebSite update the user's website -func (c *Client) UserUpdateWebSite(name string, website string) error { - return c.userUpdateAttribute(name, "website", website) +//UpdateWebSite update the user's website +func (u *Users) UpdateWebSite(name string, website string) error { + return u.updateAttribute(name, "website", website) } -//UserUpdateTwitter update the user's twitter -func (c *Client) UserUpdateTwitter(name string, twitter string) error { - return c.userUpdateAttribute(name, "twitter", twitter) +//UpdateTwitter update the user's twitter +func (u *Users) UpdateTwitter(name string, twitter string) error { + return u.updateAttribute(name, "twitter", twitter) } -//UserUpdatePassword update the user's password -func (c *Client) UserUpdatePassword(name string, password string) error { - return c.userUpdateAttribute(name, "password", password) +//UpdatePassword update the user's password +func (u *Users) UpdatePassword(name string, password string) error { + return u.updateAttribute(name, "password", password) } -//UserUpdateQuota update the user's quota (bytes) -func (c *Client) UserUpdateQuota(name string, quota int) error { - return c.userUpdateAttribute(name, "quota", strconv.Itoa(quota)) +//UpdateQuota update the user's quota (bytes) +func (u *Users) UpdateQuota(name string, quota int) error { + return u.updateAttribute(name, "quota", strconv.Itoa(quota)) } -//UserGroupList lists the user's groups -func (c *Client) UserGroupList(name string) ([]string, error) { - res, err := c.baseRequest(http.MethodGet, routes.users, nil, name, "groups") +//GroupList lists the user's groups +func (u *Users) GroupList(name string) ([]string, error) { + res, err := u.c.baseRequest(http.MethodGet, routes.users, nil, name, "groups") if err != nil { return nil, err } @@ -216,54 +250,54 @@ func (c *Client) UserGroupList(name string) ([]string, error) { return r.Ocs.Data.Groups, nil } -//UserGroupAdd adds a the user to the group -func (c *Client) UserGroupAdd(name string, group string) error { +//GroupAdd adds a the user to the group +func (u *Users) GroupAdd(name string, group string) error { ro := &req.RequestOptions{ Data: map[string]string{ "groupid": group, }, } - return c.userBaseRequest(http.MethodPost, ro, name, "groups") + return u.baseRequest(http.MethodPost, ro, name, "groups") } -//UserGroupRemove removes the user from the group -func (c *Client) UserGroupRemove(name string, group string) error { +//GroupRemove removes the user from the group +func (u *Users) GroupRemove(name string, group string) error { ro := &req.RequestOptions{ Data: map[string]string{ "groupid": group, }, } - return c.userBaseRequest(http.MethodDelete, ro, name, "groups") + return u.baseRequest(http.MethodDelete, ro, name, "groups") } -//UserGroupPromote promotes the user as group admin -func (c *Client) UserGroupPromote(name string, group string) error { +//GroupPromote promotes the user as group admin +func (u *Users) GroupPromote(name string, group string) error { ro := &req.RequestOptions{ Data: map[string]string{ "groupid": group, }, } - return c.userBaseRequest(http.MethodPost, ro, name, "subadmins") + return u.baseRequest(http.MethodPost, ro, name, "subadmins") } -//UserGroupDemote demotes the user -func (c *Client) UserGroupDemote(name string, group string) error { +//GroupDemote demotes the user +func (u *Users) GroupDemote(name string, group string) error { ro := &req.RequestOptions{ Data: map[string]string{ "groupid": group, }, } - return c.userBaseRequest(http.MethodDelete, ro, name, "subadmins") + return u.baseRequest(http.MethodDelete, ro, name, "subadmins") } -//UserGroupSubAdminList lists the groups where he is subadmin -func (c *Client) UserGroupSubAdminList(name string) ([]string, error) { - if !c.loggedIn() { +//GroupSubAdminList lists the groups where he is subadmin +func (u *Users) GroupSubAdminList(name string) ([]string, error) { + if !u.c.loggedIn() { return nil, errUnauthorized } - u := c.baseURL.ResolveReference(routes.users) - u.Path = path.Join(u.Path, name, "subadmins") - res, err := c.session.Get(u.String(), nil) + ur := u.c.baseURL.ResolveReference(routes.users) + ur.Path = path.Join(ur.Path, name, "subadmins") + res, err := u.c.session.Get(ur.String(), nil) if err != nil { return nil, err } @@ -272,18 +306,18 @@ func (c *Client) UserGroupSubAdminList(name string) ([]string, error) { return r.Ocs.Data, nil } -func (c *Client) userUpdateAttribute(name string, key string, value string) error { +func (u *Users) updateAttribute(name string, key string, value string) error { ro := &req.RequestOptions{ Data: map[string]string{ "key": key, "value": value, }, } - return c.userBaseRequest(http.MethodPut, ro, name) + return u.baseRequest(http.MethodPut, ro, name) } -func (c *Client) userBaseRequest(method string, ro *req.RequestOptions, subRoutes ...string) error { - _, err := c.baseRequest(method, routes.users, ro, subRoutes...) +func (u *Users) baseRequest(method string, ro *req.RequestOptions, subRoutes ...string) error { + _, err := u.c.baseRequest(method, routes.users, ro, subRoutes...) return err }