forked from Nixius/authelia
1
0
Fork 0

Ensure customers group exists (EnsureGroup), move group logic to groups.go; improve subscription error log

Made-with: Cursor
This commit is contained in:
Leopere 2026-03-04 20:18:04 -05:00
parent 00e6320b99
commit 3798265511
Signed by: colin
SSH Key Fingerprint: SHA256:nRPCQTeMFLdGytxRQmPVK9VXY3/ePKQ5lGRyJhT5DY8
3 changed files with 123 additions and 82 deletions

View File

@ -151,7 +151,7 @@ func (a *App) handleSuccess(w http.ResponseWriter, r *http.Request) {
// Grant active subscription: add to customers group so dashboard shows subscribed.
if err := a.ldap.AddToGroup(result.Username, "customers"); err != nil {
log.Printf("ldap add to customers failed for %s: %v", result.Username, err)
log.Printf("ldap add to customers failed for %s: %v (create group 'customers' in LLDAP admin if missing)", result.Username, err)
}
inGroup, _ := a.ldap.IsInGroup(result.Username, "customers")

View File

@ -117,62 +117,6 @@ func (c *Client) EnsureUser(username, email, stripeCustomerID, phone string) err
return err
}
func (c *Client) AddToGroup(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!) { 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
}
func (c *Client) SetStripeCustomerID(username, customerID string) error {
query := `mutation($userId: String!, $attrs: [AttributeValueInput!]!) {
updateUser(user: { id: $userId, insertAttributes: $attrs }) { ok }
@ -327,31 +271,6 @@ func (c *Client) CountCustomers() (int, error) {
return n, nil
}
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)
}
func (c *Client) userExists(conn *goldap.Conn, username string) (bool, error) {
searchReq := goldap.NewSearchRequest(
fmt.Sprintf("ou=people,%s", c.cfg.LDAPBaseDN),

View File

@ -0,0 +1,122 @@
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
}