opengist/internal/ldap/ldap.go
2024-12-16 13:45:09 +01:00

60 lines
1.3 KiB
Go

package ldap
import (
"fmt"
"github.com/go-ldap/ldap/v3"
"github.com/thomiceli/opengist/internal/config"
)
// Authenticate attempts to authenticate a user against the configured LDAP instance.
func Authenticate(username, password string) (bool, error) {
l, err := ldap.DialURL(config.C.LDAPUrl)
if err != nil {
return false, fmt.Errorf("unable to connect to URI: %v", config.C.LDAPUrl)
}
defer func(l *ldap.Conn) {
_ = l.Close()
}(l)
// First bind with a read only user
err = l.Bind(config.C.LDAPBindDn, config.C.LDAPBindCredentials)
if err != nil {
return false, err
}
searchFilter := fmt.Sprintf(config.C.LDAPSearchFilter, username)
searchRequest := ldap.NewSearchRequest(
config.C.LDAPSearchBase,
ldap.ScopeWholeSubtree,
ldap.NeverDerefAliases,
0,
0,
false,
searchFilter,
[]string{"dn"},
nil,
)
sr, err := l.Search(searchRequest)
if err != nil {
return false, err
}
if len(sr.Entries) != 1 {
return false, nil
}
// Bind as the user to verify their password
err = l.Bind(sr.Entries[0].DN, password)
if err != nil {
return false, nil
}
// Rebind as the read only user for any further queries
err = l.Bind(config.C.LDAPBindDn, config.C.LDAPBindCredentials)
if err != nil {
return false, err
}
return true, nil
}