forked from Nixius/authelia
1
0
Fork 0
ATLAS/docker/ss-atlas/internal/ldap/groups.go

123 lines
3.5 KiB
Go

package ldap
import (
"encoding/json"
"fmt"
"log"
)
func (c *Client) getGroupID(groupName string) (int, error) {
query := `query { groups { id displayName } }`
data, err := c.gql.exec(query, nil)
if err != nil {
return 0, err
}
var result struct {
Groups []struct {
ID int `json:"id"`
DisplayName string `json:"displayName"`
} `json:"groups"`
}
if err := json.Unmarshal(data, &result); err != nil {
return 0, err
}
for _, g := range result.Groups {
if g.DisplayName == groupName {
return g.ID, nil
}
}
return 0, fmt.Errorf("group %s not found", groupName)
}
// EnsureGroup creates the group in LLDAP if it does not exist (e.g. "customers").
// Idempotent: no-op if group already exists.
func (c *Client) EnsureGroup(displayName string) error {
_, err := c.getGroupID(displayName)
if err == nil {
return nil
}
// Group missing: try to create via GraphQL (LLDAP mutation).
query := `mutation($displayName: String!) { createGroup(displayName: $displayName) { id } }`
data, err := c.gql.exec(query, map[string]any{"displayName": displayName})
if err != nil {
log.Printf("lldap createGroup %q failed: %v (create group manually in LLDAP admin if needed)", displayName, err)
return err
}
var out struct {
CreateGroup struct {
ID int `json:"id"`
} `json:"createGroup"`
}
if err := json.Unmarshal(data, &out); err != nil {
log.Printf("lldap createGroup %q response unmarshal: %v", displayName, err)
return err
}
if out.CreateGroup.ID == 0 {
log.Printf("lldap createGroup %q returned no id", displayName)
return fmt.Errorf("createGroup %s: no id in response", displayName)
}
log.Printf("lldap created group %q (id=%d)", displayName, out.CreateGroup.ID)
return nil
}
func (c *Client) AddToGroup(username, groupName string) error {
if err := c.EnsureGroup(groupName); err != nil {
return fmt.Errorf("ensure group %s: %w", groupName, err)
}
groupID, err := c.getGroupID(groupName)
if err != nil {
return fmt.Errorf("resolve group %s: %w", groupName, err)
}
query := `mutation($userId: String!, $groupId: Int!) { addUserToGroup(userId: $userId, groupId: $groupId) { ok } }`
_, err = c.gql.exec(query, map[string]any{"userId": username, "groupId": groupID})
if err != nil {
return fmt.Errorf("add %s to group %s: %w", username, groupName, err)
}
log.Printf("added %s to group %s", username, groupName)
return nil
}
func (c *Client) RemoveFromGroup(username, groupName string) error {
groupID, err := c.getGroupID(groupName)
if err != nil {
return fmt.Errorf("resolve group %s: %w", groupName, err)
}
query := `mutation($userId: String!, $groupId: Int!) { removeUserFromGroup(userId: $userId, groupId: $groupId) { ok } }`
_, err = c.gql.exec(query, map[string]any{"userId": username, "groupId": groupID})
if err != nil {
return fmt.Errorf("remove %s from group %s: %w", username, groupName, err)
}
log.Printf("removed %s from group %s", username, groupName)
return nil
}
func (c *Client) IsInGroup(username, groupName string) (bool, error) {
query := `query($userId: String!) { user(userId: $userId) { groups { displayName } } }`
data, err := c.gql.exec(query, map[string]any{"userId": username})
if err != nil {
return false, err
}
var result struct {
User struct {
Groups []struct {
DisplayName string `json:"displayName"`
} `json:"groups"`
} `json:"user"`
}
if err := json.Unmarshal(data, &result); err != nil {
return false, err
}
for _, g := range result.User.Groups {
if g.DisplayName == groupName {
return true, nil
}
}
return false, nil
}