Commit 27f0846b authored by Adphi's avatar Adphi

implemented User's CreateBatchWithoutPassoword

parent fc966d87
Pipeline #557 failed with stage
in 2 minutes and 2 seconds
......@@ -52,30 +52,37 @@ func NewClient(hostname string) (*Client, error) {
return c, nil
}
//Apps return the Apps client Interface
func (c *Client) Apps() types.Apps {
return c.apps
}
//AppsConfig return the AppsConfig client Interface
func (c *Client) AppsConfig() types.AppsConfig {
return c.appsConfig
}
//GroupFolders return the GroupFolders client Interface
func (c *Client) GroupFolders() types.GroupFolders {
return c.groupFolders
}
//Notifications return the Notifications client Interface
func (c *Client) Notifications() types.Notifications {
return c.notifications
}
//Shares return the Shares client Interface
func (c *Client) Shares() types.Shares {
return c.shares
}
//Users return the Users client Interface
func (c *Client) Users() types.Users {
return c.users
}
//Groups return the Groups client Interface
func (c *Client) Groups() types.Groups {
return c.groups
}
......@@ -12,6 +12,7 @@ import (
"os"
"strconv"
"strings"
"sync"
"testing"
"time"
)
......@@ -488,6 +489,41 @@ func TestUserCreateWithoutPassword(t *testing.T) {
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) {
c = nil
if err := initClient(); err != nil {
......
......@@ -45,16 +45,14 @@ func (e *UserUpdateError) Error() string {
//NewUpdateError returns an UpdateError based on an UpdateError channel
func NewUpdateError(errors chan UpdateError) *UserUpdateError {
empty := true
var ue UserUpdateError
for e := range errors {
if ue.Errors == nil {
empty = false
ue.Errors = map[string]error{e.Field: e.Error}
}
ue.Errors[e.Field] = e.Error
}
if !empty {
if len(ue.Errors) > 0 {
return &ue
}
return nil
......
......@@ -95,16 +95,17 @@ type Shares interface {
//Users available methods
type Users interface {
List() ([]string, error)
ListDetails() (map[string]User, error)
Get(name string) (*User, error)
ListDetails() (map[string]UserDetails, error)
Get(name string) (*UserDetails, 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
CreateBatchWithoutPassword(users []User) error
Delete(name string) error
Enable(name string) error
Disable(name string) error
SendWelcomeEmail(name string) error
Update(user *User) error
Update(user *UserDetails) error
UpdateEmail(name string, email string) error
UpdateDisplayName(name string, displayName string) error
UpdatePhone(name string, phone string) error
......
......@@ -31,7 +31,7 @@ type UserListDetailsResponse struct {
Ocs struct {
Meta Meta `json:"meta"`
Data struct {
Users map[string]User `json:"users"`
Users map[string]UserDetails `json:"users"`
} `json:"data"`
} `json:"ocs"`
}
......@@ -39,8 +39,8 @@ type UserListDetailsResponse struct {
//UserResponse
type UserResponse struct {
Ocs struct {
Meta Meta `json:"meta"`
Data User `json:"data"`
Meta Meta `json:"meta"`
Data UserDetails `json:"data"`
} `json:"ocs"`
}
......
package types
//Users
//User encapsulate the data needed to create a new Nextcloud's User
type User struct {
Enabled bool `json:"enabled"`
ID string `json:"id"`
Quota struct {
Free int64 `json:"free"`
Used int `json:"used"`
Total int64 `json:"total"`
Relative float64 `json:"relative"`
Quota int `json:"quota"`
} `json:"quota"`
Username string
Email string
DisplayName string
Quota string
Language string
Groups []string
}
//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"`
Displayname string `json:"displayname"`
Phone string `json:"phone"`
......@@ -26,3 +30,11 @@ type User struct {
Subadmin []interface{} `json:"subadmin,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"`
}
......@@ -5,6 +5,7 @@ import (
"github.com/fatih/structs"
req "github.com/levigross/grequests"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"gitlab.bertha.cloud/partitio/Nextcloud-Partitio/gonextcloud/types"
"net/http"
"net/url"
......@@ -32,7 +33,7 @@ func (u *Users) List() ([]string, error) {
}
//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 := c.session.Get(u.String(), 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
func (u *Users) Get(name string) (*types.User, error) {
func (u *Users) Get(name string) (*types.UserDetails, error) {
if name == "" {
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
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
ro := &req.RequestOptions{
Data: map[string]string{
......@@ -132,6 +133,36 @@ func (u *Users) CreateWithoutPassword(username, email, displayName, quota, langu
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
func (u *Users) Delete(name string) error {
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
func (u *Users) Update(user *types.User) error {
func (u *Users) Update(user *types.UserDetails) error {
m := structs.Map(user)
errs := make(chan types.UpdateError)
var wg sync.WaitGroup
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment