From 2a697a4df3bf52e8ec0f76c9822713635e036681 Mon Sep 17 00:00:00 2001 From: Luther Monson Date: Fri, 25 Aug 2023 19:04:05 -0700 Subject: [PATCH] adding groups --- access.go | 72 +++++++++++++++++++++++++++++------- access_test.go | 25 +++++++++++++ tests/mocks/pve7x/access.go | 41 +++++++++++++++----- tests/mocks/pve7x/proxmox.go | 2 - types.go | 9 +++++ 5 files changed, 124 insertions(+), 25 deletions(-) diff --git a/access.go b/access.go index e8a6445..fcb02f7 100644 --- a/access.go +++ b/access.go @@ -44,18 +44,19 @@ func (c *Client) Permissions(o *PermissionsOptions) (permissions Permissions, er } func (c *Client) Password(userid, password string) error { - var res string - return c.Post("/access/password", map[string]string{"userid": userid, "password": password}, &res) + return c.Post("/access/password", map[string]string{ + "userid": userid, + "password": password, + }, nil) } -func (c *Client) Domains() (domains Domains, err error) { - err = c.Get("/access/domains", &domains) - if nil == err { - for _, d := range domains { - d.client = c - } - } - return +// NewDomain create a new domain with the required two parameters pull it and use domain.Update to configure +// t is an enum: ad, ldap, openid, pam, pve +func (c *Client) NewDomain(realm, t string) error { + return c.Post("/access/domains", map[string]string{ + "realm": realm, + "type": t, + }, nil) } func (c *Client) Domain(realm string) (domain *Domain, err error) { @@ -67,6 +68,16 @@ func (c *Client) Domain(realm string) (domain *Domain, err error) { return } +func (c *Client) Domains() (domains Domains, err error) { + err = c.Get("/access/domains", &domains) + if nil == err { + for _, d := range domains { + d.client = c + } + } + return +} + func (d *Domain) Update() error { if d.Realm == "" { return errors.New("realm can not be empty") @@ -78,14 +89,47 @@ func (d *Domain) Delete() error { if d.Realm == "" { return errors.New("realm can not be empty") } - var ret string - return d.client.Delete(fmt.Sprintf("/access/domains/%s", d.Realm), &ret) + return d.client.Delete(fmt.Sprintf("/access/domains/%s", d.Realm), nil) } func (d *Domain) Sync(options DomainSyncOptions) error { if d.Realm == "" { return errors.New("realm can not be empty") } - var ret string - return d.client.Post(fmt.Sprintf("/access/domains/%s", d.Realm), options, &ret) + return d.client.Post(fmt.Sprintf("/access/domains/%s", d.Realm), options, nil) +} + +// NewGroup makes a new group, comment is option and can be left empty +func (c *Client) NewGroup(groupid, comment string) error { + return c.Post("/access/groups", map[string]string{ + "groupid": groupid, + "comment": comment, + }, nil) +} + +func (c *Client) Group(groupid string) (group *Group, err error) { + err = c.Get(fmt.Sprintf("/access/groups/%s", groupid), &group) + if nil == err { + group.GroupID = groupid + group.client = c + } + return +} + +func (c *Client) Groups() (groups Groups, err error) { + err = c.Get("/access/groups", &groups) + if nil == err { + for _, g := range groups { + g.client = c + } + } + return +} + +func (g *Group) Update() error { + return g.client.Put(fmt.Sprintf("/access/groups/%s", g.GroupID), g, nil) +} + +func (g *Group) Delete() error { + return g.client.Delete(fmt.Sprintf("/access/groups/%s", g.GroupID), nil) } diff --git a/access_test.go b/access_test.go index f2f8cff..5594cd2 100644 --- a/access_test.go +++ b/access_test.go @@ -85,3 +85,28 @@ func TestDomain(t *testing.T) { assert.Equal(t, d.Realm, "test") assert.False(t, bool(d.AutoCreate)) } + +func TestGroup(t *testing.T) { + mocks.On(mockConfig) + defer mocks.Off() + client := mockClient() + + g, err := client.Group("test") + assert.Nil(t, err) + assert.Equal(t, g.GroupID, "test") + assert.Len(t, g.Members, 2) +} + +func TestGroups(t *testing.T) { + mocks.On(mockConfig) + defer mocks.Off() + client := mockClient() + + gs, err := client.Groups() + assert.Nil(t, err) + assert.Len(t, gs, 2) + for _, g := range gs { + assert.Len(t, g.Members, 0) // empty from lister + assert.NotEmpty(t, g.Users) + } +} diff --git a/tests/mocks/pve7x/access.go b/tests/mocks/pve7x/access.go index 630cf7f..5f0112c 100644 --- a/tests/mocks/pve7x/access.go +++ b/tests/mocks/pve7x/access.go @@ -438,7 +438,7 @@ func access() { // user with no access gock.New(config.C.URI). - Get("^/access/permissions"). + Get("^/access/permissions$"). MatchParams(map[string]string{ "userid": "userid", }). @@ -453,7 +453,7 @@ func access() { // user with no access gock.New(config.C.URI). - Get("^/access/permissions"). + Get("^/access/permissions$"). MatchParams(map[string]string{ "path": "path", "userid": "userid", @@ -468,12 +468,10 @@ func access() { }`) gock.New(config.C.URI). - Post("^/access/password"). + Post("^/access/password$"). Reply(200). JSON(`{"success":1,"data":null}`) -} -func ticket() { gock.New(config.C.URI). Get("^/access/ticket$"). Reply(200). @@ -546,11 +544,8 @@ func ticket() { "ticket": "PVE:root@pam:64E10CBA::yTMqV7BmOXUCzb0ODceFH7F+Uy3gQTlp3sepUzIicpL2KeJ4finWjuZ9SBZg/iTz7tACDGvnX0biv6JMZvYBuqzWu0S3eF6xrLX4A3YLahhWaMJJ4Dw8hIquSO5AMQr3Ea3xdN5CcLIuW8hPOLHrPFzDC2MDk6e6VtJ9lWF5htz8nq6ge+kcwZBgB80ZABc+lIwtcB1UcJ8NY5EYGS9czcEXSse2xmG1j2F1+gMfoF+4O7wiCV0iHGabG+8n3oEBZUE89jhzjQoVCGCzVpmxYpag+5I4+W+POZm8DzQCdvPmynH9fAT6bSD8Vu+le8aHGigoKz81xNMsFxIjd1Zr2g==" } }`) -} - -func user() { gock.New(config.C.URI). - Get("/access/user"). + Get("^/access/user$"). Reply(200). JSON(` { @@ -584,4 +579,32 @@ func user() { } ] }`) + + gock.New(config.C.URI). + Get("^/access/groups$"). + Reply(200). + JSON(`{ + "data": [ + { + "groupid": "cloud-init", + "users": "root@pam,user1@pve" + }, + { + "groupid": "test", + "users": "root@pam,user2@pve" + } + ] +}`) + gock.New(config.C.URI). + Get("^/access/groups/test$"). + Reply(200). + JSON(`{ + "data": { + "members": [ + "user2@pve", + "root@pam" + ] + } +}`) + } diff --git a/tests/mocks/pve7x/proxmox.go b/tests/mocks/pve7x/proxmox.go index 7216340..ab5339d 100644 --- a/tests/mocks/pve7x/proxmox.go +++ b/tests/mocks/pve7x/proxmox.go @@ -3,8 +3,6 @@ package pve7x func Load() { version() access() - user() - ticket() nodes() cluster() pool() diff --git a/types.go b/types.go index 402a1f4..2981b5d 100644 --- a/types.go +++ b/types.go @@ -995,3 +995,12 @@ type DomainSyncOptions struct { RemoveVanished string `json:"remove-vanished,omitempty"` Scope string `json:"scope,omitempty"` // users, groups, both } + +type Groups []*Group +type Group struct { + client *Client + GroupID string `json:"groupid,omitempty"` + Comment string `json:"comment,omitempty"` + Users string `json:"users,omitempty"` // only populated via Groups lister + Members []string `json:"members,omitempty"` // only populated via Group read +}