forked from Nixius/authelia
Ensure customers group exists (EnsureGroup), move group logic to groups.go; improve subscription error log
Made-with: Cursor
This commit is contained in:
parent
00e6320b99
commit
3798265511
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
Loading…
Reference in New Issue