Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/jimlambrt/gldap
Build LDAP services w/ Go
https://github.com/jimlambrt/gldap
go golang ldap ldap-library ldap-server ldap-service ldap-testing
Last synced: 19 days ago
JSON representation
Build LDAP services w/ Go
- Host: GitHub
- URL: https://github.com/jimlambrt/gldap
- Owner: jimlambrt
- License: mit
- Created: 2022-01-11T23:57:45.000Z (almost 3 years ago)
- Default Branch: main
- Last Pushed: 2024-10-18T22:33:06.000Z (about 2 months ago)
- Last Synced: 2024-11-13T11:15:41.670Z (29 days ago)
- Topics: go, golang, ldap, ldap-library, ldap-server, ldap-service, ldap-testing
- Language: Go
- Homepage:
- Size: 230 KB
- Stars: 110
- Watchers: 4
- Forks: 4
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING-add-commands.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
- Security: SECURITY.md
Awesome Lists containing this project
- awesome-go - gldap - gldap provides an ldap server implementation and you provide handlers for its ldap operations. (Networking / Transliteration)
- zero-alloc-awesome-go - gldap - gldap provides an ldap server implementation and you provide handlers for its ldap operations. (Networking / Transliteration)
- go-awesome - gldap - LDAP service (Open source library / The Internet)
- awesome-golang-repositories - gldap
- awesome-go-extra - gldap - 01-11T23:57:45Z|2022-06-01T13:18:36Z| (Networking / Uncategorized)
README
# gldap
[![Go Reference](https://pkg.go.dev/badge/github.com/jimlambrt/gldap/gldap.svg)](https://pkg.go.dev/github.com/jimlambrt/gldap)
[![Go Coverage](https://raw.githack.com/jimlambrt/gldap/main/coverage/coverage.svg)](https://raw.githack.com/jimlambrt/gldap/main/coverage/coverage.html)
[![Go Report Card](https://goreportcard.com/badge/github.com/jimlambrt/gldap)](https://goreportcard.com/report/github.com/jimlambrt/gldap)
`gldap` is a framework for building LDAP services. Among other things, it defines abstractions for:
* `Server`: supports both LDAP and LDAPS (TLS) protocols as well as the StartTLS
requests.
* `Request`: represents an LDAP request (bind, search, extended, etc) along with
the inbound request message.
* `ResponseWriter`: allows you to compose request responses.
* `Mux`: an ldap request multiplexer. It matches the inbound request against a
list of registered route handlers.
* `HandlerFunc`: handlers provided to the Mux which serve individual ldap requests.
Example:
```go
package mainimport (
"context"
"log"
"os"
"os/signal"
"syscall""github.com/jimlambrt/gldap"
)func main() {
// create a new server
s, err := gldap.NewServer()
if err != nil {
log.Fatalf("unable to create server: %s", err.Error())
}// create a router and add a bind handler
r, err := gldap.NewMux()
if err != nil {
log.Fatalf("unable to create router: %s", err.Error())
}
r.Bind(bindHandler)
r.Search(searchHandler)
s.Router(r)
go s.Run(":10389") // listen on port 10389// stop server gracefully when ctrl-c, sigint or sigterm occurs
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
defer stop()
select {
case <-ctx.Done():
log.Printf("\nstopping directory")
s.Stop()
}
}func bindHandler(w *gldap.ResponseWriter, r *gldap.Request) {
resp := r.NewBindResponse(
gldap.WithResponseCode(gldap.ResultInvalidCredentials),
)
defer func() {
w.Write(resp)
}()m, err := r.GetSimpleBindMessage()
if err != nil {
log.Printf("not a simple bind message: %s", err)
return
}if m.UserName == "alice" {
resp.SetResultCode(gldap.ResultSuccess)
log.Println("bind success")
return
}func searchHandler(w *gldap.ResponseWriter, r *gldap.Request) {
resp := r.NewSearchDoneResponse()
defer func() {
w.Write(resp)
}()
m, err := r.GetSearchMessage()
if err != nil {
log.Printf("not a search message: %s", err)
return
}
log.Printf("search base dn: %s", m.BaseDN)
log.Printf("search scope: %d", m.Scope)
log.Printf("search filter: %s", m.Filter)if strings.Contains(m.Filter, "uid=alice") || m.BaseDN == "uid=alice,ou=people,cn=example,dc=org" {
entry := r.NewSearchResponseEntry(
"uid=alice,ou=people,cn=example,dc=org",
gldap.WithAttributes(map[string][]string{
"objectclass": {"top", "person", "organizationalPerson", "inetOrgPerson"},
"uid": {"alice"},
"cn": {"alice eve smith"},
"givenname": {"alice"},
"sn": {"smith"},
"ou": {"people"},
"description": {"friend of Rivest, Shamir and Adleman"},
"password": {"{SSHA}U3waGJVC7MgXYc0YQe7xv7sSePuTP8zN"},
}),
)
entry.AddAttribute("email", []string{"[email protected]"})
w.Write(entry)
resp.SetResultCode(gldap.ResultSuccess)
}
if m.BaseDN == "ou=people,cn=example,dc=org" {
entry := r.NewSearchResponseEntry(
"ou=people,cn=example,dc=org",
gldap.WithAttributes(map[string][]string{
"objectclass": {"organizationalUnit"},
"ou": {"people"},
}),
)
w.Write(entry)
resp.SetResultCode(gldap.ResultSuccess)
}
return
}
```
## Road map
### Currently supported features:
* `ldap`, `ldaps` and `mTLS` connections
* StartTLS Requests
* Bind Requests
* Simple Auth (user/pass)
* Search Requests
* Modify Requests
* Add Requests
* Delete Requests
* Unbind Requests### Future features
At this point, we may wait until issues are opened before planning new features
given that all the basic LDAP operations are supported.
## [gldap.testdirectory](testdirectory/README.md)
[![Go
Reference](https://pkg.go.dev/badge/github.com/jimlambrt/gldap/testdirectory.svg)](https://pkg.go.dev/github.com/jimlambrt/gldap/testdirectory)The `testdirectory` package built using `gldap` which provides an in-memory test
LDAP service with capabilities which make writing tests that depend on an LDAP
service much easier.`testdirectory` is also a great working example of how you can use `gldap` to build a custom
ldap server to meet your specific needs.Example:
```go
// this testdirectory example demonstrates how can start a test directory for
// your unit tests which will automatically stop when the test is complete.
func TestExample(t *testing.T) {// start a test directory running ldaps on an available free port (defaults)
// that allows anon binds (a default override)
td := testdirectory.Start(t,
testdirectory.WithDefaults(&testdirectory.Defaults{AllowAnonymousBind: true}),
)
// create some test new user entries (using defaults for ou, password, etc)
users := testdirectory.NewUsers(t, []string{"alice", "bob"})
// set the test directories user entries
td.SetUsers(users...)// INSERT your tests here....
}
```