Fix #1 and #2 : Added groupfolders API client

This commit is contained in:
Philippe-Adrien Nousse 2018-09-03 12:17:02 +02:00
parent 3c45f09874
commit 359e15bfb2
14 changed files with 380 additions and 104 deletions

View File

@ -11,10 +11,10 @@ lint: ## Lint the files
@golint -set_exit_status ${PKG_LIST} @golint -set_exit_status ${PKG_LIST}
test: ## Run unittests test: ## Run unittests
@go test ${PKG_LIST} @go test -v ${PKG_LIST}
race: dep ## Run data race detector race: dep ## Run data race detector
@go test -race ${PKG_LIST} @go test -v -race ${PKG_LIST}
msan: dep ## Run memory sanitizer msan: dep ## Run memory sanitizer
@go test -msan -short ${PKG_LIST} @go test -msan -short ${PKG_LIST}

17
apps.go
View File

@ -8,7 +8,7 @@ import (
//AppList return the list of the Nextcloud Apps //AppList return the list of the Nextcloud Apps
func (c *Client) AppList() ([]string, error) { func (c *Client) AppList() ([]string, error) {
res, err := c.baseRequest(routes.apps, "", "", nil, http.MethodGet) res, err := c.baseRequest(http.MethodGet, routes.apps, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -22,7 +22,7 @@ func (c *Client) AppListEnabled() ([]string, error) {
ro := &req.RequestOptions{ ro := &req.RequestOptions{
Params: map[string]string{"filter": "enabled"}, Params: map[string]string{"filter": "enabled"},
} }
res, err := c.baseRequest(routes.apps, "", "", ro, http.MethodGet) res, err := c.baseRequest(http.MethodGet, routes.apps, ro)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -36,7 +36,7 @@ func (c *Client) AppListDisabled() ([]string, error) {
ro := &req.RequestOptions{ ro := &req.RequestOptions{
Params: map[string]string{"filter": "disabled"}, Params: map[string]string{"filter": "disabled"},
} }
res, err := c.baseRequest(routes.apps, "", "", ro, http.MethodGet) res, err := c.baseRequest(http.MethodGet, routes.apps, ro)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -47,7 +47,7 @@ func (c *Client) AppListDisabled() ([]string, error) {
//AppInfos return the app's details //AppInfos return the app's details
func (c *Client) AppInfos(name string) (types.App, error) { func (c *Client) AppInfos(name string) (types.App, error) {
res, err := c.baseRequest(routes.apps, name, "", nil, http.MethodGet) res, err := c.baseRequest(http.MethodGet, routes.apps, nil, name)
if err != nil { if err != nil {
return types.App{}, err return types.App{}, err
} }
@ -58,17 +58,12 @@ func (c *Client) AppInfos(name string) (types.App, error) {
//AppEnable enables an app //AppEnable enables an app
func (c *Client) AppEnable(name string) error { func (c *Client) AppEnable(name string) error {
_, err := c.baseRequest(routes.apps, name, "", nil, http.MethodPut) _, err := c.baseRequest(http.MethodPut, routes.apps, nil, name)
return err return err
} }
//AppDisable disables an app //AppDisable disables an app
func (c *Client) AppDisable(name string) error { func (c *Client) AppDisable(name string) error {
_, err := c.baseRequest(routes.apps, name, "", nil, http.MethodDelete) _, err := c.baseRequest(http.MethodDelete, routes.apps, nil, name)
return err
}
func (c *Client) appsBaseRequest(name string, route string, ro *req.RequestOptions, method string) error {
_, err := c.baseRequest(routes.apps, name, route, ro, method)
return err return err
} }

View File

@ -37,7 +37,6 @@ For example, to list all the Nextcloud's instance users:
fmt.Println("Users :", users) fmt.Println("Users :", users)
} }
*/ */
package gonextcloud package gonextcloud
import ( import (

View File

@ -1,10 +0,0 @@
url: $NEXTCLOUD_URL
login: admin
password: $NEXTCLOUD_PASSWORD
app-name: testapp
groups-to-create:
- grp1
- grp2
- grp3
not-existing-user: this-user-should-not-exist
not-existing-group: this-group-should-not-exist

View File

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"github.com/fatih/structs" "github.com/fatih/structs"
"github.com/partitio/gonextcloud/types" "github.com/partitio/gonextcloud/types"
"github.com/partitio/swarmmanager/libnextcloudpartitio/utils"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"gopkg.in/yaml.v2" "gopkg.in/yaml.v2"
"io/ioutil" "io/ioutil"
@ -44,13 +45,13 @@ func LoadConfig() error {
func TestLoadConfig(t *testing.T) { func TestLoadConfig(t *testing.T) {
err := LoadConfig() err := LoadConfig()
assert.Nil(t, err) assert.NoError(t, err)
} }
func TestClient(t *testing.T) { func TestClient(t *testing.T) {
var err error var err error
c, err = NewClient(config.URL) c, err = NewClient(config.URL)
assert.Nil(t, err, "aie") assert.NoError(t, err, "aie")
} }
func TestLoginFail(t *testing.T) { func TestLoginFail(t *testing.T) {
@ -60,19 +61,19 @@ func TestLoginFail(t *testing.T) {
func TestLogin(t *testing.T) { func TestLogin(t *testing.T) {
err := c.Login(config.Login, config.Password) err := c.Login(config.Login, config.Password)
assert.Nil(t, err) assert.NoError(t, err)
} }
func TestUserList(t *testing.T) { func TestUserList(t *testing.T) {
us, err := c.UserList() us, err := c.UserList()
assert.Nil(t, err) assert.NoError(t, err)
assert.Contains(t, us, config.Login) assert.Contains(t, us, config.Login)
} }
func TestExistingUser(t *testing.T) { func TestExistingUser(t *testing.T) {
u, err := c.User(config.Login) u, err := c.User(config.Login)
assert.Nil(t, err) assert.NoError(t, err)
assert.NotNil(t, u) assert.NotNil(t, u)
} }
@ -89,13 +90,13 @@ func TestNonExistingUser(t *testing.T) {
func TestUserSearch(t *testing.T) { func TestUserSearch(t *testing.T) {
us, err := c.UserSearch(config.Login) us, err := c.UserSearch(config.Login)
assert.Nil(t, err) assert.NoError(t, err)
assert.Contains(t, us, config.Login) assert.Contains(t, us, config.Login)
} }
func TestUserCreate(t *testing.T) { func TestUserCreate(t *testing.T) {
err := c.UserCreate(config.NotExistingUser, password, nil) err := c.UserCreate(config.NotExistingUser, password, nil)
assert.Nil(t, err) assert.NoError(t, err)
} }
func TestUserCreateFull(t *testing.T) { func TestUserCreateFull(t *testing.T) {
@ -115,7 +116,7 @@ func TestUserCreateFull(t *testing.T) {
err := c.UserCreate(username, password, user) err := c.UserCreate(username, password, user)
assert.Nil(t, err) assert.Nil(t, err)
u, err := c.User(username) u, err := c.User(username)
assert.Nil(t, err) assert.NoError(t, err)
o := structs.Map(user) o := structs.Map(user)
r := structs.Map(u) r := structs.Map(u)
for k := range o { for k := range o {
@ -126,7 +127,7 @@ func TestUserCreateFull(t *testing.T) {
} }
// Clean up // Clean up
err = c.UserDelete(u.ID) err = c.UserDelete(u.ID)
assert.Nil(t, err) assert.NoError(t, err)
} }
func TestUserUpdate(t *testing.T) { func TestUserUpdate(t *testing.T) {
@ -159,23 +160,23 @@ func TestUserUpdate(t *testing.T) {
} }
// Clean up // Clean up
err = c.UserDelete(u.ID) err = c.UserDelete(u.ID)
assert.Nil(t, err) assert.NoError(t, err)
} }
func TestUserCreateExisting(t *testing.T) { func TestUserCreateExisting(t *testing.T) {
err := c.UserCreate(config.NotExistingUser, password, nil) err := c.UserCreate(config.NotExistingUser, password, nil)
assert.NotNil(t, err) assert.Error(t, err)
} }
func TestGroupList(t *testing.T) { func TestGroupList(t *testing.T) {
gs, err := c.GroupList() gs, err := c.GroupList()
assert.Nil(t, err) assert.NoError(t, err)
assert.Contains(t, gs, "admin") assert.Contains(t, gs, "admin")
} }
func TestGroupCreate(t *testing.T) { func TestGroupCreate(t *testing.T) {
err := c.GroupCreate(config.NotExistingGroup) err := c.GroupCreate(config.NotExistingGroup)
assert.Nil(t, err) assert.NoError(t, err)
} }
func TestUserUpdateEmail(t *testing.T) { func TestUserUpdateEmail(t *testing.T) {
@ -183,7 +184,7 @@ func TestUserUpdateEmail(t *testing.T) {
err := c.UserUpdateEmail(config.NotExistingUser, email) err := c.UserUpdateEmail(config.NotExistingUser, email)
assert.Nil(t, err) assert.Nil(t, err)
u, err := c.User(config.NotExistingUser) u, err := c.User(config.NotExistingUser)
assert.Nil(t, err) assert.NoError(t, err)
assert.Equal(t, email, u.Email) assert.Equal(t, email, u.Email)
} }
@ -192,7 +193,7 @@ func TestUserUpdateDisplayName(t *testing.T) {
err := c.UserUpdateDisplayName(config.NotExistingUser, displayName) err := c.UserUpdateDisplayName(config.NotExistingUser, displayName)
assert.Nil(t, err) assert.Nil(t, err)
u, err := c.User(config.NotExistingUser) u, err := c.User(config.NotExistingUser)
assert.Nil(t, err) assert.NoError(t, err)
assert.Equal(t, displayName, u.Displayname) assert.Equal(t, displayName, u.Displayname)
} }
@ -201,41 +202,41 @@ func TestUserUpdatePhone(t *testing.T) {
err := c.UserUpdatePhone(config.NotExistingUser, phone) err := c.UserUpdatePhone(config.NotExistingUser, phone)
assert.Nil(t, err) assert.Nil(t, err)
u, err := c.User(config.NotExistingUser) u, err := c.User(config.NotExistingUser)
assert.Nil(t, err) assert.NoError(t, err)
assert.Equal(t, phone, u.Phone) assert.Equal(t, phone, u.Phone)
} }
func TestUserUpdateAddress(t *testing.T) { func TestUserUpdateAddress(t *testing.T) {
address := "Main Street, Galifrey" address := "Main Street, Galifrey"
err := c.UserUpdateAddress(config.NotExistingUser, address) err := c.UserUpdateAddress(config.NotExistingUser, address)
assert.Nil(t, err) assert.NoError(t, err)
u, err := c.User(config.NotExistingUser) u, err := c.User(config.NotExistingUser)
assert.Nil(t, err) assert.NoError(t, err)
assert.Equal(t, address, u.Address) assert.Equal(t, address, u.Address)
} }
func TestUserUpdateWebSite(t *testing.T) { func TestUserUpdateWebSite(t *testing.T) {
website := "www.doctor.who" website := "www.doctor.who"
err := c.UserUpdateWebSite(config.NotExistingUser, website) err := c.UserUpdateWebSite(config.NotExistingUser, website)
assert.Nil(t, err) assert.NoError(t, err)
u, err := c.User(config.NotExistingUser) u, err := c.User(config.NotExistingUser)
assert.Nil(t, err) assert.NoError(t, err)
assert.Equal(t, website, u.Website) assert.Equal(t, website, u.Website)
} }
func TestUserUpdateTwitter(t *testing.T) { func TestUserUpdateTwitter(t *testing.T) {
twitter := "@doctorwho" twitter := "@doctorwho"
err := c.UserUpdateTwitter(config.NotExistingUser, twitter) err := c.UserUpdateTwitter(config.NotExistingUser, twitter)
assert.Nil(t, err) assert.NoError(t, err)
u, err := c.User(config.NotExistingUser) u, err := c.User(config.NotExistingUser)
assert.Nil(t, err) assert.NoError(t, err)
assert.Equal(t, twitter, u.Twitter) assert.Equal(t, twitter, u.Twitter)
} }
func TestUserUpdateQuota(t *testing.T) { func TestUserUpdateQuota(t *testing.T) {
quota := 1024 * 1024 * 1024 quota := 1024 * 1024 * 1024
err := c.UserUpdateQuota(config.NotExistingUser, quota) err := c.UserUpdateQuota(config.NotExistingUser, quota)
assert.Nil(t, err) assert.NoError(t, err)
// TODO : Find better verification : A never connected User does not have quota available // TODO : Find better verification : A never connected User does not have quota available
//u, err := c.User(config.NotExistingUser) //u, err := c.User(config.NotExistingUser)
//assert.Nil(t, err) //assert.Nil(t, err)
@ -245,20 +246,20 @@ func TestUserUpdateQuota(t *testing.T) {
func TestUserUpdatePassword(t *testing.T) { func TestUserUpdatePassword(t *testing.T) {
password := "newcomplexpassword" password := "newcomplexpassword"
err := c.UserUpdatePassword(config.NotExistingUser, password) err := c.UserUpdatePassword(config.NotExistingUser, password)
assert.Nil(t, err) assert.NoError(t, err)
} }
func TestUserGroupAdd(t *testing.T) { func TestUserGroupAdd(t *testing.T) {
err := c.UserGroupAdd(config.NotExistingUser, config.NotExistingGroup) err := c.UserGroupAdd(config.NotExistingUser, config.NotExistingGroup)
assert.Nil(t, err) assert.Nil(t, err)
gs, err := c.UserGroupList(config.NotExistingUser) gs, err := c.UserGroupList(config.NotExistingUser)
assert.Nil(t, err) assert.NoError(t, err)
assert.Contains(t, gs, config.NotExistingGroup) assert.Contains(t, gs, config.NotExistingGroup)
} }
func TestUserGroupSubAdminList(t *testing.T) { func TestUserGroupSubAdminList(t *testing.T) {
gs, err := c.UserGroupSubAdminList(config.NotExistingUser) gs, err := c.UserGroupSubAdminList(config.NotExistingUser)
assert.Nil(t, err) assert.NoError(t, err)
assert.Empty(t, gs) assert.Empty(t, gs)
} }
@ -266,13 +267,13 @@ func TestUserGroupPromote(t *testing.T) {
err := c.UserGroupPromote(config.NotExistingUser, config.NotExistingGroup) err := c.UserGroupPromote(config.NotExistingUser, config.NotExistingGroup)
assert.Nil(t, err) assert.Nil(t, err)
gs, err := c.UserGroupSubAdminList(config.NotExistingUser) gs, err := c.UserGroupSubAdminList(config.NotExistingUser)
assert.Nil(t, err) assert.NoError(t, err)
assert.Contains(t, gs, config.NotExistingGroup) assert.Contains(t, gs, config.NotExistingGroup)
} }
func TestUserGroupDemote(t *testing.T) { func TestUserGroupDemote(t *testing.T) {
err := c.UserGroupDemote(config.NotExistingUser, config.NotExistingGroup) err := c.UserGroupDemote(config.NotExistingUser, config.NotExistingGroup)
assert.Nil(t, err) assert.NoError(t, err)
//gs, err := c.UserGroupSubAdminList(config.NotExistingUser) //gs, err := c.UserGroupSubAdminList(config.NotExistingUser)
//assert.Nil(t, err) //assert.Nil(t, err)
//assert.Empty(t, gs) //assert.Empty(t, gs)
@ -282,7 +283,7 @@ func TestUserDisable(t *testing.T) {
err := c.UserDisable(config.NotExistingUser) err := c.UserDisable(config.NotExistingUser)
assert.Nil(t, err) assert.Nil(t, err)
u, err := c.User(config.NotExistingUser) u, err := c.User(config.NotExistingUser)
assert.Nil(t, err) assert.NoError(t, err)
assert.False(t, u.Enabled) assert.False(t, u.Enabled)
} }
@ -290,7 +291,7 @@ func TestUserEnable(t *testing.T) {
err := c.UserEnable(config.NotExistingUser) err := c.UserEnable(config.NotExistingUser)
assert.Nil(t, err) assert.Nil(t, err)
u, err := c.User(config.NotExistingUser) u, err := c.User(config.NotExistingUser)
assert.Nil(t, err) assert.NoError(t, err)
assert.True(t, u.Enabled) assert.True(t, u.Enabled)
} }
@ -301,12 +302,12 @@ func TestGroupDelete(t *testing.T) {
func TestUserDelete(t *testing.T) { func TestUserDelete(t *testing.T) {
err := c.UserDelete(config.NotExistingUser) err := c.UserDelete(config.NotExistingUser)
assert.Nil(t, err) assert.NoError(t, err)
} }
func TestInvalidBaseRequest(t *testing.T) { func TestInvalidBaseRequest(t *testing.T) {
c.baseURL = &url.URL{} c.baseURL = &url.URL{}
_, err := c.baseRequest(routes.capabilities, "admin", "invalid", nil, http.MethodGet) _, err := c.baseRequest(http.MethodGet, routes.capabilities, nil, "admin", "invalid")
c = nil c = nil
assert.Error(t, err) assert.Error(t, err)
} }
@ -316,13 +317,13 @@ func TestShareList(t *testing.T) {
return return
} }
s, err := c.SharesList() s, err := c.SharesList()
assert.Nil(t, err) assert.NoError(t, err)
assert.NotNil(t, s) assert.NotNil(t, s)
} }
func TestLogout(t *testing.T) { func TestLogout(t *testing.T) {
err := c.Logout() err := c.Logout()
assert.Nil(t, err) assert.NoError(t, err)
assert.Nil(t, c.session.HTTPClient.Jar) assert.Nil(t, c.session.HTTPClient.Jar)
} }
@ -340,10 +341,89 @@ func TestLoginInvalidURL(t *testing.T) {
func TestBaseRequest(t *testing.T) { func TestBaseRequest(t *testing.T) {
c, _ = NewClient("") c, _ = NewClient("")
_, err := c.baseRequest(routes.capabilities, "admin", "invalid", nil, http.MethodGet) _, err := c.baseRequest(http.MethodGet, routes.capabilities, nil, "admin", "invalid")
assert.Error(t, err) assert.Error(t, err)
} }
var groupID = 37
func TestGroupFoldersCreate(t *testing.T) {
c = nil
if err := initClient(); err != nil {
return
}
var err error
groupID, err = c.GroupFoldersCreate("API")
assert.NoError(t, err)
}
func TestGroupFoldersList(t *testing.T) {
c = nil
if err := initClient(); err != nil {
return
}
gfs, err := c.GroupFoldersList()
assert.NoError(t, err)
utils.PrettyPrint(gfs)
assert.NotNil(t, gfs[groupID])
}
func TestGroupFolders(t *testing.T) {
c = nil
if err := initClient(); err != nil {
return
}
gf, err := c.GroupFolders(groupID)
assert.NoError(t, err)
utils.PrettyPrint(gf)
assert.NotNil(t, gf)
}
func TestGroupFolderRename(t *testing.T) {
c = nil
if err := initClient(); err != nil {
return
}
err := c.GroupFoldersRename(groupID, "API_Renamed")
assert.NoError(t, err)
}
func TestGroupFoldersAddGroup(t *testing.T) {
c = nil
if err := initClient(); err != nil {
return
}
err := c.GroupFoldersAddGroup(groupID, "admin")
assert.NoError(t, err)
}
func TestGroupFoldersSetGroupPermissions(t *testing.T) {
c = nil
if err := initClient(); err != nil {
return
}
err := c.GroupFoldersSetGroupPermissions(groupID, "admin", types.ReadPermission)
assert.NoError(t, err)
}
func TestGroupFoldersSetQuota(t *testing.T) {
c = nil
if err := initClient(); err != nil {
return
}
err := c.GroupFoldersSetQuota(groupID, 100)
assert.NoError(t, err)
}
func TestGroupFolderRemoveGroup(t *testing.T) {
c = nil
if err := initClient(); err != nil {
return
}
err := c.GroupFoldersRemoveGroup(groupID, "admin")
assert.NoError(t, err)
}
func initClient() error { func initClient() error {
if c == nil { if c == nil {
if err := LoadConfig(); err != nil { if err := LoadConfig(); err != nil {

131
groupfolders.go Normal file
View File

@ -0,0 +1,131 @@
package gonextcloud
import (
"fmt"
req "github.com/levigross/grequests"
"github.com/partitio/gonextcloud/types"
"net/http"
"strconv"
)
func (c *Client) GroupFoldersList() (map[int]types.GroupFolder, error) {
res, err := c.baseRequest(http.MethodGet, routes.groupfolders, nil)
if err != nil {
return nil, err
}
var r types.GroupFoldersListResponse
res.JSON(&r)
gfs := formatBadIDAndGroups(r.Ocs.Data)
return gfs, nil
}
func (c *Client) GroupFolders(id int) (types.GroupFolder, error) {
res, err := c.baseRequest(http.MethodGet, routes.groupfolders, nil, strconv.Itoa(id))
if err != nil {
return types.GroupFolder{}, err
}
var r types.GroupFoldersResponse
res.JSON(&r)
if r.Ocs.Data.ID == 0 {
return types.GroupFolder{}, fmt.Errorf("%d is not a valid groupfolder's id", id)
}
return r.Ocs.Data.FormatGroupFolder(), nil
}
func (c *Client) GroupFoldersCreate(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)
if err != nil {
return 0, err
}
var r types.GroupFoldersCreateResponse
res.JSON(&r)
id, _ = strconv.Atoi(r.Ocs.Data.ID)
return id, nil
}
func (c *Client) GroupFoldersRename(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")
if err != nil {
return err
}
return nil
}
//TODO func (c *Client) GroupFoldersDelete(id int) error {
// // GroupFolders's response does not give any clues about success or failure
// return nil
//}
func (c *Client) GroupFoldersAddGroup(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")
if err != nil {
return err
}
return nil
}
func (c *Client) GroupFoldersRemoveGroup(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)
if err != nil {
return err
}
return nil
}
func (c *Client) GroupFoldersSetGroupPermissions(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)
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 {
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")
if err != nil {
return err
}
return nil
}
func formatBadIDAndGroups(g map[string]types.GroupFolderBadFormatIDAndGroups) map[int]types.GroupFolder {
var gfs = map[int]types.GroupFolder{}
for k := range g {
i, _ := strconv.Atoi(k)
d := g[k]
gfs[i] = d.FormatGroupFolder()
}
return gfs
}

View File

@ -8,7 +8,7 @@ import (
//GroupList lists the Nextcloud groups //GroupList lists the Nextcloud groups
func (c *Client) GroupList() ([]string, error) { func (c *Client) GroupList() ([]string, error) {
res, err := c.baseRequest(routes.groups, "", "", nil, http.MethodGet) res, err := c.baseRequest(http.MethodGet, routes.groups, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -19,7 +19,7 @@ func (c *Client) GroupList() ([]string, error) {
//GroupUsers list the group's users //GroupUsers list the group's users
func (c *Client) GroupUsers(name string) ([]string, error) { func (c *Client) GroupUsers(name string) ([]string, error) {
res, err := c.baseRequest(routes.groups, name, "", nil, http.MethodGet) res, err := c.baseRequest(http.MethodGet, routes.groups, nil, name)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -33,7 +33,7 @@ func (c *Client) GroupSearch(search string) ([]string, error) {
ro := &req.RequestOptions{ ro := &req.RequestOptions{
Params: map[string]string{"search": search}, Params: map[string]string{"search": search},
} }
res, err := c.baseRequest(routes.groups, "", "", ro, http.MethodGet) res, err := c.baseRequest(http.MethodGet, routes.groups, ro)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -49,17 +49,17 @@ func (c *Client) GroupCreate(name string) error {
"groupid": name, "groupid": name,
}, },
} }
return c.groupBaseRequest("", "", ro, http.MethodPost) return c.groupBaseRequest(http.MethodPost, ro)
} }
//GroupDelete deletes the group //GroupDelete deletes the group
func (c *Client) GroupDelete(name string) error { func (c *Client) GroupDelete(name string) error {
return c.groupBaseRequest(name, "", nil, http.MethodDelete) return c.groupBaseRequest(http.MethodDelete, nil, name)
} }
//GroupSubAdminList lists the group's subadmins //GroupSubAdminList lists the group's subadmins
func (c *Client) GroupSubAdminList(name string) ([]string, error) { func (c *Client) GroupSubAdminList(name string) ([]string, error) {
res, err := c.baseRequest(routes.groups, name, "subadmins", nil, http.MethodGet) res, err := c.baseRequest(http.MethodGet, routes.groups, nil, name, "subadmins")
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -68,7 +68,7 @@ func (c *Client) GroupSubAdminList(name string) ([]string, error) {
return r.Ocs.Data.Users, nil return r.Ocs.Data.Users, nil
} }
func (c *Client) groupBaseRequest(name string, route string, ro *req.RequestOptions, method string) error { func (c *Client) groupBaseRequest(method string, ro *req.RequestOptions, subRoute ...string) error {
_, err := c.baseRequest(routes.groups, name, route, ro, method) _, err := c.baseRequest(method, routes.groups, ro, subRoute...)
return err return err
} }

View File

@ -7,7 +7,7 @@ import (
//Monitoring return nextcloud monitoring statistics //Monitoring return nextcloud monitoring statistics
func (c *Client) Monitoring() (*types.Monitoring, error) { func (c *Client) Monitoring() (*types.Monitoring, error) {
res, err := c.baseRequest(routes.monitor, "", "", nil, http.MethodGet) res, err := c.baseRequest(http.MethodGet, routes.monitor, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -10,6 +10,7 @@ type Routes struct {
apps *url.URL apps *url.URL
monitor *url.URL monitor *url.URL
shares *url.URL shares *url.URL
groupfolders *url.URL
} }
const badRequest = 998 const badRequest = 998
@ -23,5 +24,6 @@ var (
apps: &url.URL{Path: apiPath.Path + "/cloud/apps"}, apps: &url.URL{Path: apiPath.Path + "/cloud/apps"},
monitor: &url.URL{Path: apiPath.Path + "/apps/serverinfo/api/v1/info"}, monitor: &url.URL{Path: apiPath.Path + "/apps/serverinfo/api/v1/info"},
shares: &url.URL{Path: apiPath.Path + "/apps/files_sharing/api/v1/shares"}, shares: &url.URL{Path: apiPath.Path + "/apps/files_sharing/api/v1/shares"},
groupfolders: &url.URL{Path: "apps/groupfolders/folders"},
} }
) )

View File

@ -10,7 +10,7 @@ import (
) )
func (c *Client) SharesList() ([]types.Share, error) { func (c *Client) SharesList() ([]types.Share, error) {
res, err := c.baseRequest(routes.shares, "", "", nil, http.MethodGet) res, err := c.baseRequest(http.MethodGet, routes.shares, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -27,7 +27,7 @@ func (c *Client) Shares(path string, reshares bool, subfiles bool) ([]types.Shar
"subfiles": strconv.FormatBool(subfiles), "subfiles": strconv.FormatBool(subfiles),
}, },
} }
res, err := c.baseRequest(routes.shares, "", "", ro, http.MethodGet) res, err := c.baseRequest(http.MethodGet, routes.shares, ro)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -37,7 +37,7 @@ func (c *Client) Shares(path string, reshares bool, subfiles bool) ([]types.Shar
} }
func (c *Client) Share(shareID string) (types.Share, error) { func (c *Client) Share(shareID string) (types.Share, error) {
res, err := c.baseRequest(routes.shares, shareID, "", nil, http.MethodGet) res, err := c.baseRequest(http.MethodGet, routes.shares, nil, shareID)
if err != nil { if err != nil {
return types.Share{}, err return types.Share{}, err
} }
@ -68,7 +68,7 @@ func (c *Client) ShareCreate(
"permissions": strconv.Itoa(int(permission)), "permissions": strconv.Itoa(int(permission)),
}, },
} }
res, err := c.baseRequest(routes.shares, "", "", ro, http.MethodPost) res, err := c.baseRequest(http.MethodPost, routes.shares, ro)
if err != nil { if err != nil {
return types.Share{}, err return types.Share{}, err
} }
@ -78,7 +78,7 @@ func (c *Client) ShareCreate(
} }
func (c *Client) ShareDelete(shareID int) error { func (c *Client) ShareDelete(shareID int) error {
_, err := c.baseRequest(routes.shares, strconv.Itoa(shareID), "", nil, http.MethodDelete) _, err := c.baseRequest(http.MethodDelete, routes.shares, nil, strconv.Itoa(shareID))
return err return err
} }
@ -151,6 +151,6 @@ func (c *Client) baseShareUpdate(shareID string, key string, value string) error
ro := &req.RequestOptions{ ro := &req.RequestOptions{
Data: map[string]string{key: value}, Data: map[string]string{key: value},
} }
_, err := c.baseRequest(routes.shares, shareID, "", ro, http.MethodPut) _, err := c.baseRequest(http.MethodPut, routes.shares, ro, shareID)
return err return err
} }

57
types/groupfolders.go Normal file
View File

@ -0,0 +1,57 @@
package types
import "strconv"
type GroupFolderBadFormatIDAndGroups struct {
ID string `json:"id"`
MountPoint string `json:"mount_point"`
Groups map[string]string `json:"groups"`
Quota string `json:"quota"`
Size int `json:"size"`
}
type GroupFolderBadFormatGroups struct {
ID int `json:"id"`
MountPoint string `json:"mount_point"`
Groups map[string]string `json:"groups"`
Quota string `json:"quota"`
Size int `json:"size"`
}
type GroupFolder struct {
ID int `json:"id"`
MountPoint string `json:"mount_point"`
Groups map[string]SharePermission `json:"groups"`
Quota int `json:"quota"`
Size int `json:"size"`
}
func (gf *GroupFolderBadFormatGroups) FormatGroupFolder() GroupFolder {
g := GroupFolder{}
g.ID = gf.ID
g.MountPoint = gf.MountPoint
g.Groups = map[string]SharePermission{}
for k, v := range gf.Groups {
p, _ := strconv.Atoi(v)
g.Groups[k] = SharePermission(p)
}
q, _ := strconv.Atoi(gf.Quota)
g.Quota = q
g.Size = gf.Size
return g
}
func (gf *GroupFolderBadFormatIDAndGroups) FormatGroupFolder() GroupFolder {
g := GroupFolder{}
g.ID, _ = strconv.Atoi(gf.ID)
g.MountPoint = gf.MountPoint
g.Groups = map[string]SharePermission{}
for k, v := range gf.Groups {
p, _ := strconv.Atoi(v)
g.Groups[k] = SharePermission(p)
}
q, _ := strconv.Atoi(gf.Quota)
g.Quota = q
g.Size = gf.Size
return g
}

View File

@ -108,3 +108,24 @@ type SharesResponse struct {
Data Share `json:"data"` Data Share `json:"data"`
} `json:"ocs"` } `json:"ocs"`
} }
type GroupFoldersListResponse struct {
Ocs struct {
Meta Meta `json:"meta"`
Data map[string]GroupFolderBadFormatIDAndGroups `json:"data"`
} `json:"ocs"`
}
type GroupFoldersCreateResponse struct {
Ocs struct {
Meta Meta `json:"meta"`
Data GroupFolderBadFormatIDAndGroups `json:"data"`
} `json:"ocs"`
}
type GroupFoldersResponse struct {
Ocs struct {
Meta Meta `json:"meta"`
Data GroupFolderBadFormatGroups `json:"data"`
} `json:"ocs"`
}

View File

@ -14,7 +14,7 @@ import (
// UserList return the Nextcloud'user list // UserList return the Nextcloud'user list
func (c *Client) UserList() ([]string, error) { func (c *Client) UserList() ([]string, error) {
res, err := c.baseRequest(routes.users, "", "", nil, http.MethodGet) res, err := c.baseRequest(http.MethodGet, routes.users, nil)
//res, err := c.session.Get(u.String(), nil) //res, err := c.session.Get(u.String(), nil)
if err != nil { if err != nil {
return nil, err return nil, err
@ -29,7 +29,7 @@ func (c *Client) User(name string) (*types.User, error) {
if name == "" { if name == "" {
return nil, &types.APIError{Message: "name cannot be empty"} return nil, &types.APIError{Message: "name cannot be empty"}
} }
res, err := c.baseRequest(routes.users, name, "", nil, http.MethodGet) res, err := c.baseRequest(http.MethodGet, routes.users, nil, name)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -48,7 +48,7 @@ func (c *Client) UserSearch(search string) ([]string, error) {
ro := &req.RequestOptions{ ro := &req.RequestOptions{
Params: map[string]string{"search": search}, Params: map[string]string{"search": search},
} }
res, err := c.baseRequest(routes.users, "", "", ro, http.MethodGet) res, err := c.baseRequest(http.MethodGet, routes.users, ro)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -65,7 +65,7 @@ func (c *Client) UserCreate(username string, password string, user *types.User)
"password": password, "password": password,
}, },
} }
if err := c.userBaseRequest("", "", ro, http.MethodPost); err != nil { if err := c.userBaseRequest(http.MethodPost, ro); err != nil {
return err return err
} }
if user == nil { if user == nil {
@ -76,7 +76,7 @@ func (c *Client) UserCreate(username string, password string, user *types.User)
//UserDelete delete the user //UserDelete delete the user
func (c *Client) UserDelete(name string) error { func (c *Client) UserDelete(name string) error {
return c.userBaseRequest(name, "", nil, http.MethodDelete) return c.userBaseRequest(http.MethodDelete, nil, name)
} }
//UserEnable enables the user //UserEnable enables the user
@ -84,7 +84,7 @@ func (c *Client) UserEnable(name string) error {
ro := &req.RequestOptions{ ro := &req.RequestOptions{
Data: map[string]string{}, Data: map[string]string{},
} }
return c.userBaseRequest(name, "enable", ro, http.MethodPut) return c.userBaseRequest(http.MethodPut, ro, name, "enable")
} }
//UserDisable disables the user //UserDisable disables the user
@ -92,12 +92,12 @@ func (c *Client) UserDisable(name string) error {
ro := &req.RequestOptions{ ro := &req.RequestOptions{
Data: map[string]string{}, Data: map[string]string{},
} }
return c.userBaseRequest(name, "disable", ro, http.MethodPut) return c.userBaseRequest(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) //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 { func (c *Client) UserSendWelcomeEmail(name string) error {
return c.userBaseRequest(name, "welcome", nil, http.MethodPost) return c.userBaseRequest(http.MethodPost, nil, name, "welcome")
} }
//UserUpdate takes a *types.User struct to update the user's information //UserUpdate takes a *types.User struct to update the user's information
@ -168,7 +168,7 @@ func (c *Client) UserUpdateQuota(name string, quota int) error {
//UserGroupList lists the user's groups //UserGroupList lists the user's groups
func (c *Client) UserGroupList(name string) ([]string, error) { func (c *Client) UserGroupList(name string) ([]string, error) {
res, err := c.baseRequest(routes.users, name, "groups", nil, http.MethodGet) res, err := c.baseRequest(http.MethodGet, routes.users, nil, name, "groups")
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -184,7 +184,7 @@ func (c *Client) UserGroupAdd(name string, group string) error {
"groupid": group, "groupid": group,
}, },
} }
return c.userBaseRequest(name, "groups", ro, http.MethodPost) return c.userBaseRequest(http.MethodPost, ro, name, "groups")
} }
//UserGroupRemove removes the user from the group //UserGroupRemove removes the user from the group
@ -194,7 +194,7 @@ func (c *Client) UserGroupRemove(name string, group string) error {
"groupid": group, "groupid": group,
}, },
} }
return c.userBaseRequest(name, "groups", ro, http.MethodDelete) return c.userBaseRequest(http.MethodDelete, ro, name, "groups")
} }
//UserGroupPromote promotes the user as group admin //UserGroupPromote promotes the user as group admin
@ -204,7 +204,7 @@ func (c *Client) UserGroupPromote(name string, group string) error {
"groupid": group, "groupid": group,
}, },
} }
return c.userBaseRequest(name, "subadmins", ro, http.MethodPost) return c.userBaseRequest(http.MethodPost, ro, name, "subadmins")
} }
//UserGroupDemote demotes the user //UserGroupDemote demotes the user
@ -214,7 +214,7 @@ func (c *Client) UserGroupDemote(name string, group string) error {
"groupid": group, "groupid": group,
}, },
} }
return c.userBaseRequest(name, "subadmins", ro, http.MethodDelete) return c.userBaseRequest(http.MethodDelete, ro, name, "subadmins")
} }
//UserGroupSubAdminList lists the groups where he is subadmin //UserGroupSubAdminList lists the groups where he is subadmin
@ -240,11 +240,11 @@ func (c *Client) userUpdateAttribute(name string, key string, value string) erro
"value": value, "value": value,
}, },
} }
return c.userBaseRequest(name, "", ro, http.MethodPut) return c.userBaseRequest(http.MethodPut, ro, name)
} }
func (c *Client) userBaseRequest(name string, route string, ro *req.RequestOptions, method string) error { func (c *Client) userBaseRequest(method string, ro *req.RequestOptions, subRoutes ...string) error {
_, err := c.baseRequest(routes.users, name, route, ro, method) _, err := c.baseRequest(method, routes.users, ro, subRoutes...)
return err return err
} }

View File

@ -10,28 +10,29 @@ import (
"strings" "strings"
) )
func (c *Client) baseRequest(route *url.URL, name string, subroute string, ro *req.RequestOptions, method string) (*req.Response, error) { func (c *Client) baseRequest(method string, route *url.URL, ro *req.RequestOptions, subRoutes ...string) (*req.Response, error) {
if !c.loggedIn() { if !c.loggedIn() {
return nil, errUnauthorized return nil, errUnauthorized
} }
u := c.baseURL.ResolveReference(route) u := c.baseURL.ResolveReference(route)
if name != "" {
u.Path = path.Join(u.Path, name) for _, sr := range subRoutes {
if sr != "" {
u.Path = path.Join(u.Path, sr)
} }
if subroute != "" {
u.Path = path.Join(u.Path, subroute)
} }
var ( var (
res *req.Response res *req.Response
err error err error
) )
if method == http.MethodGet { switch method {
case http.MethodGet:
res, err = c.session.Get(u.String(), ro) res, err = c.session.Get(u.String(), ro)
} else if method == http.MethodPost { case http.MethodPost:
res, err = c.session.Post(u.String(), ro) res, err = c.session.Post(u.String(), ro)
} else if method == http.MethodPut { case http.MethodPut:
res, err = c.session.Put(u.String(), ro) res, err = c.session.Put(u.String(), ro)
} else if method == http.MethodDelete { case http.MethodDelete:
res, err = c.session.Delete(u.String(), ro) res, err = c.session.Delete(u.String(), ro)
} }
if err != nil { if err != nil {
@ -41,11 +42,11 @@ func (c *Client) baseRequest(route *url.URL, name string, subroute string, ro *r
js := res.String() js := res.String()
var r types.BaseResponse var r types.BaseResponse
json.Unmarshal([]byte(js), &r) json.Unmarshal([]byte(js), &r)
if r.Ocs.Meta.Statuscode != 200 { if r.Ocs.Meta.Statuscode == 200 || r.Ocs.Meta.Statuscode == 100 {
err := types.ErrorFromMeta(r.Ocs.Meta)
return nil, err
}
return res, nil return res, nil
}
err = types.ErrorFromMeta(r.Ocs.Meta)
return nil, err
} }
func reformatJSON(json string) string { func reformatJSON(json string) string {