mirror of
https://gitlab.bertha.cloud/partitio/Nextcloud-Partitio/gonextcloud
synced 2024-11-22 00:06:25 +00:00
implemented User's CreateBatchWithoutPassoword
This commit is contained in:
parent
fc966d8703
commit
27f0846b45
@ -52,30 +52,37 @@ func NewClient(hostname string) (*Client, error) {
|
|||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Apps return the Apps client Interface
|
||||||
func (c *Client) Apps() types.Apps {
|
func (c *Client) Apps() types.Apps {
|
||||||
return c.apps
|
return c.apps
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//AppsConfig return the AppsConfig client Interface
|
||||||
func (c *Client) AppsConfig() types.AppsConfig {
|
func (c *Client) AppsConfig() types.AppsConfig {
|
||||||
return c.appsConfig
|
return c.appsConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//GroupFolders return the GroupFolders client Interface
|
||||||
func (c *Client) GroupFolders() types.GroupFolders {
|
func (c *Client) GroupFolders() types.GroupFolders {
|
||||||
return c.groupFolders
|
return c.groupFolders
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Notifications return the Notifications client Interface
|
||||||
func (c *Client) Notifications() types.Notifications {
|
func (c *Client) Notifications() types.Notifications {
|
||||||
return c.notifications
|
return c.notifications
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Shares return the Shares client Interface
|
||||||
func (c *Client) Shares() types.Shares {
|
func (c *Client) Shares() types.Shares {
|
||||||
return c.shares
|
return c.shares
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Users return the Users client Interface
|
||||||
func (c *Client) Users() types.Users {
|
func (c *Client) Users() types.Users {
|
||||||
return c.users
|
return c.users
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Groups return the Groups client Interface
|
||||||
func (c *Client) Groups() types.Groups {
|
func (c *Client) Groups() types.Groups {
|
||||||
return c.groups
|
return c.groups
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@ -488,6 +489,41 @@ func TestUserCreateWithoutPassword(t *testing.T) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUserCreateBatchWithoutPassword(t *testing.T) {
|
||||||
|
c = nil
|
||||||
|
if err := initClient(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if c.version.Major < 14 {
|
||||||
|
t.SkipNow()
|
||||||
|
}
|
||||||
|
var us []types.User
|
||||||
|
for i := 0; i < 5; i++ {
|
||||||
|
u := fmt.Sprintf(config.NotExistingUser+"_%d", i)
|
||||||
|
us = append(us, types.User{
|
||||||
|
Username: u,
|
||||||
|
DisplayName: strings.Title(u),
|
||||||
|
Groups: []string{"admin"},
|
||||||
|
Email: config.Email,
|
||||||
|
Language: "fr",
|
||||||
|
Quota: "100024",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
err := c.Users().CreateBatchWithoutPassword(us)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
// Cleaning
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
for _, u := range us {
|
||||||
|
wg.Add(1)
|
||||||
|
go func(n string) {
|
||||||
|
defer wg.Done()
|
||||||
|
c.Users().Delete(n)
|
||||||
|
}(u.Username)
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
func TestUserListDetails(t *testing.T) {
|
func TestUserListDetails(t *testing.T) {
|
||||||
c = nil
|
c = nil
|
||||||
if err := initClient(); err != nil {
|
if err := initClient(); err != nil {
|
||||||
|
@ -45,16 +45,14 @@ func (e *UserUpdateError) Error() string {
|
|||||||
|
|
||||||
//NewUpdateError returns an UpdateError based on an UpdateError channel
|
//NewUpdateError returns an UpdateError based on an UpdateError channel
|
||||||
func NewUpdateError(errors chan UpdateError) *UserUpdateError {
|
func NewUpdateError(errors chan UpdateError) *UserUpdateError {
|
||||||
empty := true
|
|
||||||
var ue UserUpdateError
|
var ue UserUpdateError
|
||||||
for e := range errors {
|
for e := range errors {
|
||||||
if ue.Errors == nil {
|
if ue.Errors == nil {
|
||||||
empty = false
|
|
||||||
ue.Errors = map[string]error{e.Field: e.Error}
|
ue.Errors = map[string]error{e.Field: e.Error}
|
||||||
}
|
}
|
||||||
ue.Errors[e.Field] = e.Error
|
ue.Errors[e.Field] = e.Error
|
||||||
}
|
}
|
||||||
if !empty {
|
if len(ue.Errors) > 0 {
|
||||||
return &ue
|
return &ue
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -95,16 +95,17 @@ type Shares interface {
|
|||||||
//Users available methods
|
//Users available methods
|
||||||
type Users interface {
|
type Users interface {
|
||||||
List() ([]string, error)
|
List() ([]string, error)
|
||||||
ListDetails() (map[string]User, error)
|
ListDetails() (map[string]UserDetails, error)
|
||||||
Get(name string) (*User, error)
|
Get(name string) (*UserDetails, error)
|
||||||
Search(search string) ([]string, error)
|
Search(search string) ([]string, error)
|
||||||
Create(username string, password string, user *User) error
|
Create(username string, password string, user *UserDetails) error
|
||||||
CreateWithoutPassword(username, email, displayName, quota, language string, groups ...string) error
|
CreateWithoutPassword(username, email, displayName, quota, language string, groups ...string) error
|
||||||
|
CreateBatchWithoutPassword(users []User) error
|
||||||
Delete(name string) error
|
Delete(name string) error
|
||||||
Enable(name string) error
|
Enable(name string) error
|
||||||
Disable(name string) error
|
Disable(name string) error
|
||||||
SendWelcomeEmail(name string) error
|
SendWelcomeEmail(name string) error
|
||||||
Update(user *User) error
|
Update(user *UserDetails) error
|
||||||
UpdateEmail(name string, email string) error
|
UpdateEmail(name string, email string) error
|
||||||
UpdateDisplayName(name string, displayName string) error
|
UpdateDisplayName(name string, displayName string) error
|
||||||
UpdatePhone(name string, phone string) error
|
UpdatePhone(name string, phone string) error
|
||||||
|
@ -31,7 +31,7 @@ type UserListDetailsResponse struct {
|
|||||||
Ocs struct {
|
Ocs struct {
|
||||||
Meta Meta `json:"meta"`
|
Meta Meta `json:"meta"`
|
||||||
Data struct {
|
Data struct {
|
||||||
Users map[string]User `json:"users"`
|
Users map[string]UserDetails `json:"users"`
|
||||||
} `json:"data"`
|
} `json:"data"`
|
||||||
} `json:"ocs"`
|
} `json:"ocs"`
|
||||||
}
|
}
|
||||||
@ -39,8 +39,8 @@ type UserListDetailsResponse struct {
|
|||||||
//UserResponse
|
//UserResponse
|
||||||
type UserResponse struct {
|
type UserResponse struct {
|
||||||
Ocs struct {
|
Ocs struct {
|
||||||
Meta Meta `json:"meta"`
|
Meta Meta `json:"meta"`
|
||||||
Data User `json:"data"`
|
Data UserDetails `json:"data"`
|
||||||
} `json:"ocs"`
|
} `json:"ocs"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,16 +1,20 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
//Users
|
//User encapsulate the data needed to create a new Nextcloud's User
|
||||||
type User struct {
|
type User struct {
|
||||||
Enabled bool `json:"enabled"`
|
Username string
|
||||||
ID string `json:"id"`
|
Email string
|
||||||
Quota struct {
|
DisplayName string
|
||||||
Free int64 `json:"free"`
|
Quota string
|
||||||
Used int `json:"used"`
|
Language string
|
||||||
Total int64 `json:"total"`
|
Groups []string
|
||||||
Relative float64 `json:"relative"`
|
}
|
||||||
Quota int `json:"quota"`
|
|
||||||
} `json:"quota"`
|
//UserDetails is the raw Nextcloud User response
|
||||||
|
type UserDetails struct {
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
ID string `json:"id"`
|
||||||
|
Quota Quota `json:"quota"`
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
Displayname string `json:"displayname"`
|
Displayname string `json:"displayname"`
|
||||||
Phone string `json:"phone"`
|
Phone string `json:"phone"`
|
||||||
@ -26,3 +30,11 @@ type User struct {
|
|||||||
Subadmin []interface{} `json:"subadmin,omitempty"`
|
Subadmin []interface{} `json:"subadmin,omitempty"`
|
||||||
Locale string `json:"locale,omitempty"`
|
Locale string `json:"locale,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Quota struct {
|
||||||
|
Free int64 `json:"free"`
|
||||||
|
Used int `json:"used"`
|
||||||
|
Total int64 `json:"total"`
|
||||||
|
Relative float64 `json:"relative"`
|
||||||
|
Quota int `json:"quota"`
|
||||||
|
}
|
||||||
|
39
users.go
39
users.go
@ -5,6 +5,7 @@ import (
|
|||||||
"github.com/fatih/structs"
|
"github.com/fatih/structs"
|
||||||
req "github.com/levigross/grequests"
|
req "github.com/levigross/grequests"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
"gitlab.bertha.cloud/partitio/Nextcloud-Partitio/gonextcloud/types"
|
"gitlab.bertha.cloud/partitio/Nextcloud-Partitio/gonextcloud/types"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
@ -32,7 +33,7 @@ func (u *Users) List() ([]string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//ListDetails return a map of user with details
|
//ListDetails return a map of user with details
|
||||||
func (u *Users) ListDetails() (map[string]types.User, error) {
|
func (u *Users) ListDetails() (map[string]types.UserDetails, error) {
|
||||||
res, err := u.c.baseRequest(http.MethodGet, routes.users, nil, "details")
|
res, err := u.c.baseRequest(http.MethodGet, routes.users, nil, "details")
|
||||||
//res, err := c.session.Get(u.String(), nil)
|
//res, err := c.session.Get(u.String(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -44,7 +45,7 @@ func (u *Users) ListDetails() (map[string]types.User, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get return the details about the specified user
|
// Get return the details about the specified user
|
||||||
func (u *Users) Get(name string) (*types.User, error) {
|
func (u *Users) Get(name string) (*types.UserDetails, error) {
|
||||||
if name == "" {
|
if name == "" {
|
||||||
return nil, &types.APIError{Message: "name cannot be empty"}
|
return nil, &types.APIError{Message: "name cannot be empty"}
|
||||||
}
|
}
|
||||||
@ -77,7 +78,7 @@ func (u *Users) Search(search string) ([]string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create create a new user
|
// Create create a new user
|
||||||
func (u *Users) Create(username string, password string, user *types.User) error {
|
func (u *Users) Create(username string, password string, user *types.UserDetails) error {
|
||||||
// Create base Users
|
// Create base Users
|
||||||
ro := &req.RequestOptions{
|
ro := &req.RequestOptions{
|
||||||
Data: map[string]string{
|
Data: map[string]string{
|
||||||
@ -132,6 +133,36 @@ func (u *Users) CreateWithoutPassword(username, email, displayName, quota, langu
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//CreateBatchWithoutPassword create multiple users and send them the init password email
|
||||||
|
func (u *Users) CreateBatchWithoutPassword(users []types.User) error {
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
errs := make(chan error)
|
||||||
|
for _, us := range users {
|
||||||
|
wg.Add(1)
|
||||||
|
go func(user types.User) {
|
||||||
|
logrus.Debugf("creating user %s", user.Username)
|
||||||
|
defer wg.Done()
|
||||||
|
if err := u.CreateWithoutPassword(
|
||||||
|
user.Username, user.Email, user.DisplayName, "", "", user.Groups...,
|
||||||
|
); err != nil {
|
||||||
|
errs <- err
|
||||||
|
}
|
||||||
|
}(us)
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
wg.Wait()
|
||||||
|
close(errs)
|
||||||
|
}()
|
||||||
|
var es []error
|
||||||
|
for err := range errs {
|
||||||
|
es = append(es, err)
|
||||||
|
}
|
||||||
|
if len(es) > 0 {
|
||||||
|
return errors.Errorf("errors occurred while creating users: %v", es)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
//Delete delete the user
|
//Delete delete the user
|
||||||
func (u *Users) Delete(name string) error {
|
func (u *Users) Delete(name string) error {
|
||||||
return u.baseRequest(http.MethodDelete, nil, name)
|
return u.baseRequest(http.MethodDelete, nil, name)
|
||||||
@ -159,7 +190,7 @@ func (u *Users) SendWelcomeEmail(name string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Update takes a *types.Users struct to update the user's information
|
//Update takes a *types.Users struct to update the user's information
|
||||||
func (u *Users) Update(user *types.User) error {
|
func (u *Users) Update(user *types.UserDetails) error {
|
||||||
m := structs.Map(user)
|
m := structs.Map(user)
|
||||||
errs := make(chan types.UpdateError)
|
errs := make(chan types.UpdateError)
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
Loading…
Reference in New Issue
Block a user