Skip to content
/ adc Public

Active Directory Golang client library

License

Notifications You must be signed in to change notification settings

dlampsi/adc

Repository files navigation

adc

build-img doc-img coverage-img

Active Directory client library.

The library is a wrapper around go-ldap/ldap module that provides a more convient client for Active Directory.

Usage

Import module in your go app:

import "github.com/dlampsi/adc"

Getting started

// Init client
cl := adc.New(&adc.Config{
    URL:         "ldaps://my.ad.site:636",
    SearchBase:  "OU=some,DC=company,DC=com",
    Bind: &adc.BindAccount{
        DN:       "CN=admin,DC=company,DC=com",
        Password: "***",
    },
})

// Connect
if err := cl.Connect(); err != nil {
    // Handle error
}

// Search for a user
user, err := cl.GetUser(adc.GetUserArgs{Id:"userId"})
if err != nil {
    // Handle error
}
if user == nil {
    // Handle not found
}
fmt.Println(user)

// Search for a group
group, err := cl.GetGroup(adc.GetGroupArgs{Id:"groupId"})
if err != nil {
    // Handle error
}
if group == nil {
    // Handle not found
}
fmt.Println(group)

// Add new users to group members
added, err := cl.AddGroupMembers("groupId", "newUserId1", "newUserId2", "newUserId3")
if err != nil {
    // Handle error
}
fmt.Printf("Added %d members", added)


// Delete users from group members
deleted, err := cl.DeleteGroupMembers("groupId", "userId1", "userId2")
if err != nil {
    // Handle error
}
fmt.Printf("Deleted %d users from group members", deleted)

Custom logger

You can specifiy custom logger for client. Logger must implement Logger interface. Provide logger during client init:

cl := New(cfg, adc.WithLogger(myCustomLogger))

Custom search base

You can set custom search base for user/group in config:

cfg := &adc.Config{
    URL:         "ldaps://my.ad.site:636",
    SearchBase:  "OU=some,DC=company,DC=com",
    Bind: &adc.BindAccount{DN: "CN=admin,DC=company,DC=com", Password: "***"},
    Users: &adc.UsersConfigs{
        SearchBase: "OU=users_base,DC=company,DC=com",,
    },
}

cl := New(cfg)

if err := cl.Connect(); err != nil {
    // Handle error
}

Custom entries attributes

You can parse custom attributes to client config to fetch those attributes during users or groups fetch:

// Append new attributes to existsing user attributes
cl.Config.AppendUsesAttributes("manager")

// Search for a user
user, err := cl.GetUser(adc.GetUserArgs{Id:"userId"})
if err != nil {
    // Handle error
}
if user == nil {
    // Handle not found
}

// Get custom attribute
userManager := exists.GetStringAttribute("manager")
fmt.Println(userManager)

Also you can parse custom attributes during each get requests:

user, err := cl.GetUser(adc.GetUserArgs{Id: "userId", Attributes: []string{"manager"}})
if err != nil {
    // Handle error
}
// Get custom attribute
userManager := exists.GetStringAttribute("manager")
fmt.Println(userManager)

Custom search filters

You can parse custom search filters to client config:

cfg := &adc.Config{
    URL:         "ldaps://my.ad.site:636",
    SearchBase:  "OU=some,DC=company,DC=com",
    Bind: &adc.BindAccount{DN: "CN=admin,DC=company,DC=com", Password: "***"},
    Users: &adc.UsersConfigs{
        FilterById: "(&(objectClass=person)(cn=%v))",
    },
    Groups: &adc.GroupsConfigs{
        FilterById: "(&(objectClass=group)(cn=%v))",
    },
}
cl := New(cfg)
if err := cl.Connect(); err != nil {
    // Handle error
}

Also, you can provide a custom search filter for direct searches:

// Init client
cl := adc.New(&adc.Config{
    URL:         "ldaps://my.ad.site:636",
    SearchBase:  "OU=some,DC=company,DC=com",
    Bind: &adc.BindAccount{
        DN:       "CN=admin,DC=company,DC=com",
        Password: "***",
    },
})

// Connect
if err := cl.Connect(); err != nil {
    // Handle error
}

// Search for a user
user, err := cl.GetUser(adc.GetUserArgs{Filter:"(&(objectClass=person)(sAMAccountName=someID))"})
if err != nil {
    // Handle error
}
if user == nil {
    // Handle not found
}
fmt.Println(user)

Note that provided Filter argument int GetUserArgs overwrites Id and Dn arguments usage.

Reconnect

Client has reconnect method, that validates connection to server and reconnects to it with provided ticker interval and retries attempts count.

Exxample for recconect each 5 secconds with 24 retrie attempts:

if err := cl.Reconnect(ctx, time.NewTicker(5*time.Second), 24); err != nil {
    // Handle error
}

Contributing

  1. Create new PR from main branch
  2. Request review from maintainers

License

MIT License.