crtman/internal/accounting/ldap_fed.go
2025-10-12 20:01:19 +08:00

117 lines
2.5 KiB
Go

package accounting
import (
"fmt"
"log"
"github.com/go-ldap/ldap/v3"
)
type LDAP_Config struct {
Base_DN string `mapstructure:"base_dn"`
User_iden string `mapstructure:"user_identify"`
User_objclass string `mapstructure:"user_objectclass"`
Group_iden string `mapstructure:"group_identify"`
Group_base string `mapstructure:"group_base_dn"`
Group_objclass string `mapstructure:"group_objectclass"`
Auth_username string `mapstructure:"auth_user"`
Auth_password string `mapstructure:"auth_password"`
Base_URL string `mapstructure:"base_url"`
}
type LDAP struct {
conn *ldap.Conn
cfg LDAP_Config
}
func (l *LDAP) build_query(filter string) *ldap.SearchRequest {
return ldap.NewSearchRequest(l.cfg.Base_DN,
ldap.ScopeSingleLevel, ldap.NeverDerefAliases, 0, 0, false,
filter,
[]string{"dn"}, nil)
}
func (l *LDAP) IsUser(name string) bool {
req := l.build_query(
fmt.Sprintf("(&(objectClass=%s)(%s=%s))",
l.cfg.User_objclass, l.cfg.User_iden, ldap.EscapeFilter(name),
),
)
sr, err := l.conn.Search(req)
if err != nil {
log.Println(err)
return false
}
if len(sr.Entries) != 1 {
log.Println("Found multiple entries for single user")
return false
}
return true
}
func (l *LDAP) IsGroup(name string) bool {
log.Printf("LDAP: Checking if group %s exists...\n", name)
req := l.build_query(
fmt.Sprintf("(&(objectClass=%s)(%s=%s))",
l.cfg.Group_objclass, l.cfg.Group_iden, ldap.EscapeFilter(name),
),
)
sr, err := l.conn.Search(req)
if err != nil {
log.Println(err)
return false
}
if len(sr.Entries) != 1 {
log.Println("Found multiple entries for single group")
return false
}
return true
}
func (l *LDAP) UserInGroup(user string, group string) bool {
log.Printf("LDAP: Checking if user %s is in group %s...\n", user, group)
req := l.build_query(
fmt.Sprintf("(&(objectClass=%s)(%s=%s)(memberof=%s=%s,%s))",
l.cfg.User_objclass,
l.cfg.User_iden,
ldap.EscapeFilter(user),
l.cfg.Group_iden,
ldap.EscapeFilter(group),
l.cfg.Group_base,
),
)
sr, err := l.conn.Search(req)
if err != nil {
log.Println(err)
return false
}
return len(sr.Entries) != 1
}
func (l *LDAP) AuthUser(name string, password string) bool {
log.Printf("LDAP: Attempting authentication for user %s...\n", name)
return true
}
func NewLDAP(config LDAP_Config) LDAP {
new_dial, err := ldap.DialURL(config.Base_URL)
if err != nil {
log.Fatal(err)
}
err = new_dial.Bind(config.Auth_username, config.Auth_password)
if err != nil {
log.Fatal(err)
}
return LDAP{
conn: new_dial,
cfg: config,
}
}