wgcl/internal/federate/ldap.go
2025-11-20 11:47:00 +08:00

80 lines
1.8 KiB
Go

package federate
import (
"errors"
"fmt"
"git.jasinco.work/wgcl/internal/logger"
"github.com/go-ldap/ldap/v3"
)
type FedLDAP struct {
Base_dn string
User_filter string
endpoint *ldap.Conn
Group_wg_filter string
auth_endpoint *ldap.Conn
}
func (l *FedLDAP) Init(endpoint string) {
var err error
l.endpoint, err = ldap.DialURL(endpoint)
if err != nil {
logger.Logger.Fatal(err.Error())
}
l.auth_endpoint, err = ldap.DialURL(endpoint)
if err != nil {
logger.Logger.Fatal(err.Error())
}
}
func (l *FedLDAP) AuthBind(user string, pass string) error {
return l.endpoint.Bind(user, pass)
}
func (l *FedLDAP) IsUser(name string) (string, error) {
req := ldap.NewSearchRequest(l.Base_dn, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases,
1, 0, false,
fmt.Sprintf(l.User_filter, ldap.EscapeFilter(name)), []string{"dn"}, nil)
resp, err := l.endpoint.Search(req)
if err != nil {
return "", err
}
if len(resp.Entries) != 1 {
return "", ErrAUTHNoUser
}
return resp.Entries[0].DN, nil
}
func (l *FedLDAP) UserAuthorizeWG(user_dn string) (bool, error) {
req := ldap.NewSearchRequest(l.Base_dn, ldap.ScopeBaseObject, ldap.NeverDerefAliases,
1, 0, false,
fmt.Sprintf(l.Group_wg_filter, user_dn), []string{"dn"}, nil)
resp, err := l.endpoint.Search(req)
if err != nil {
return false, err
}
return len(resp.Entries) > 0, nil
}
func (l *FedLDAP) UserAuthenticate(name string, password string) (string, error) {
// find user
userdn, err := l.IsUser(name)
if err != nil {
return "", err
}
req := ldap.NewSimpleBindRequest(userdn, ldap.EscapeFilter(password), nil)
_, err = l.auth_endpoint.SimpleBind(req)
var ldaperr *ldap.Error
if errors.As(err, &ldaperr) && ldaperr.ResultCode == ldap.LDAPResultInvalidCredentials {
return "", ErrAUTHAuthenticateInvalidPassword
}
if err != nil {
return "", err
}
return userdn, nil
}