implement pool-group and group-user ownership routes,

fix issue with config var scoping,
fix missing return in early exit conditions
This commit is contained in:
2026-03-26 19:35:55 +00:00
parent 8739186089
commit f17ae26506
6 changed files with 303 additions and 46 deletions

View File

@@ -3,7 +3,9 @@ package pve
import (
"context"
"crypto/tls"
"fmt"
"net/http"
"slices"
common "user-manager-api/app/common"
@@ -11,9 +13,11 @@ import (
)
type ProxmoxClient struct {
config *common.PVEConfig
client *proxmox.Client
}
// creates a new client binding with associated permissions
func NewClientFromCredentials(config common.PVEConfig, username common.Username, password string) (*ProxmoxClient, int, error) {
HTTPClient := http.Client{
Transport: &http.Transport{
@@ -30,7 +34,7 @@ func NewClientFromCredentials(config common.PVEConfig, username common.Username,
// todo this should return an error code if the binding failed (ie fetch version to check if the auth was actually ok)
return &ProxmoxClient{client: client}, http.StatusOK, nil
return &ProxmoxClient{config: &config, client: client}, http.StatusOK, nil
}
func (pve ProxmoxClient) SyncRealms() (int, error) {
@@ -115,3 +119,123 @@ func (pve ProxmoxClient) DelGroup(groupname common.Groupname) (int, error) {
return 200, nil
}
}
func (pve ProxmoxClient) AddGroupToPool(groupname common.Groupname, poolname string) (int, error) {
// adds the group to the pool with the predetermined PAAS client role
err := pve.client.UpdateACL(context.Background(), proxmox.ACLOptions{
Path: fmt.Sprintf("/pool/%s", poolname),
Groups: groupname.ToString(),
Roles: pve.config.PAASClientRole,
Propagate: true,
})
if proxmox.IsNotAuthorized(err) {
return 401, err
} else if err != nil {
return 500, err
} else {
return 200, nil
}
}
func (pve ProxmoxClient) DelGroupFromPool(groupname common.Groupname, poolname string) (int, error) {
// removes the group from the pool with the predetermined PAAS client role
err := pve.client.UpdateACL(context.Background(), proxmox.ACLOptions{
Path: fmt.Sprintf("/pool/%s", poolname),
Groups: groupname.ToString(),
Roles: pve.config.PAASClientRole,
Delete: true,
})
if proxmox.IsNotAuthorized(err) {
return 401, err
} else if err != nil {
return 500, err
} else {
return 200, nil
}
}
func (pve ProxmoxClient) NewUser(username common.Username, user common.User) (int, error) {
err := pve.client.NewUser(context.Background(), &proxmox.NewUser{
UserID: username.ToString(),
Firstname: user.CN,
Lastname: user.SN,
Email: user.Mail,
Password: user.Password,
})
if proxmox.IsNotAuthorized(err) {
return 401, err
} else if err != nil {
return 500, err
} else {
return 200, nil
}
}
func (pve ProxmoxClient) DelUser(username common.Username) (int, error) {
user, err := pve.client.User(context.Background(), username.ToString())
if proxmox.IsNotAuthorized(err) {
return 401, err // not authorized to read the user = not authorized to delete the user, this may be slightly different from ldap
} else if err != nil {
return 500, err
}
// assume that user cannot be nil if no error was returned
err = user.Delete(context.Background())
if proxmox.IsNotAuthorized(err) {
return 401, err // not authorized to delete the user
} else if err != nil {
return 500, err
} else {
return 200, nil
}
}
func (pve ProxmoxClient) AddUserToGroup(username common.Username, groupname common.Groupname) (int, error) {
user, err := pve.client.User(context.Background(), groupname.ToString())
if proxmox.IsNotAuthorized(err) {
return 401, err // not authorized to read the user = not authorized to delete the user, this may be slightly different from ldap
} else if err != nil {
return 500, err
}
newGroups := append(user.Groups, groupname.ToString())
err = user.Update(context.Background(), proxmox.UserOptions{
Groups: newGroups,
})
if proxmox.IsNotAuthorized(err) {
return 401, err // not authorized to delete the user
} else if err != nil {
return 500, err
} else {
return 200, nil
}
}
func (pve ProxmoxClient) DelUserFromGroup(username common.Username, groupname common.Groupname) (int, error) {
user, err := pve.client.User(context.Background(), groupname.ToString())
if proxmox.IsNotAuthorized(err) {
return 401, err // not authorized to read the user = not authorized to delete the user, this may be slightly different from ldap
} else if err != nil {
return 500, err
}
idx := slices.Index(user.Groups, groupname.ToString())
if idx < 0 {
return http.StatusBadRequest, fmt.Errorf("Did not find group %s in user groups {%+v}.", groupname.ToString(), user.Groups)
}
newGroups := slices.Delete(user.Groups, idx, idx)
err = user.Update(context.Background(), proxmox.UserOptions{
Groups: newGroups,
})
if proxmox.IsNotAuthorized(err) {
return 401, err // not authorized to delete the user
} else if err != nil {
return 500, err
} else {
return 200, nil
}
}