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 }