ldaprolemanager

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 13, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

README

LDAP Role Manager

Go Report Card Go Coverage Status Godoc Release Discord

LDAP Role Manager is an LDAP-based role manager for Casbin. With this library, Casbin can load role hierarchies and user-role mappings from LDAP directories like Active Directory, OpenLDAP, etc.

Installation

go get github.com/casbin/ldap-role-manager

Simple Example

package main

import (
	"fmt"
	"log"

	"github.com/casbin/casbin/v2"
	ldaprolemanager "github.com/casbin/ldap-role-manager"
)

func main() {
	// Initialize LDAP role manager
	opts := &ldaprolemanager.LDAPOptions{
		URL:               "ldap://localhost:389",
		BaseDN:            "dc=example,dc=com",
		UserFilter:        "(uid=%s)",
		GroupFilter:       "(member=%s)",
		RoleAttr:          "cn",
		BindDN:            "cn=admin,dc=example,dc=com",
		BindPassword:      "password",
		MaxHierarchyLevel: 10,
	}

	rm, err := ldaprolemanager.NewRoleManager(opts)
	if err != nil {
		log.Fatalf("Failed to create role manager: %v", err)
	}
	defer rm.Close()

	// Create a new enforcer
	e, err := casbin.NewEnforcer("examples/rbac_model.conf", "examples/rbac_policy.csv")
	if err != nil {
		log.Fatalf("Failed to create enforcer: %v", err)
	}

	// Set the role manager
	e.SetRoleManager(rm)

	// Load policy
	err = e.LoadPolicy()
	if err != nil {
		log.Fatalf("Failed to load policy: %v", err)
	}

	// Check permissions
	if res, _ := e.Enforce("alice", "data1", "read"); res {
		fmt.Println("alice can read data1")
	} else {
		fmt.Println("alice cannot read data1")
	}
}

Configuration Options

The LDAPOptions struct supports the following configuration options:

  • URL: LDAP server URL (e.g., ldap://localhost:389 or ldaps://localhost:636)
  • BaseDN: Base distinguished name for searching (e.g., dc=example,dc=com)
  • UserFilter: LDAP filter template for finding users (e.g., (uid=%s))
  • GroupFilter: LDAP filter template for finding groups (e.g., (member=%s))
  • RoleAttr: Attribute name containing role/group names (default: cn)
  • BindDN: Distinguished name for binding to LDAP (optional)
  • BindPassword: Password for binding to LDAP (optional)
  • UseTLS: Enable TLS connection (default: false)
  • SkipTLSVerify: Skip TLS certificate verification (default: false)
  • MaxHierarchyLevel: Maximum depth for role hierarchy traversal (default: 10)

LDAP Schema Requirements

This role manager expects the following LDAP schema:

User Entries
  • Users should be identifiable by the UserFilter (e.g., uid attribute)
  • Example: uid=alice,ou=users,dc=example,dc=com
Group Entries
  • Groups should contain a member attribute listing user DNs
  • Groups should have a role name attribute (configured via RoleAttr, default is cn)
  • Example: cn=admin,ou=groups,dc=example,dc=com
Example LDIF
# User entry
dn: uid=alice,ou=users,dc=example,dc=com
objectClass: inetOrgPerson
uid: alice
cn: Alice Smith
sn: Smith

# Group entry
dn: cn=admin,ou=groups,dc=example,dc=com
objectClass: groupOfNames
cn: admin
member: uid=alice,ou=users,dc=example,dc=com

Active Directory Example

For Active Directory, you might use different filters:

opts := &ldaprolemanager.LDAPOptions{
	URL:          "ldaps://ad.example.com:636",
	BaseDN:       "dc=example,dc=com",
	UserFilter:   "(sAMAccountName=%s)",
	GroupFilter:  "(member=%s)",
	RoleAttr:     "cn",
	BindDN:       "cn=service-account,ou=users,dc=example,dc=com",
	BindPassword: "password",
	UseTLS:       true,
}

Features

  • Read-only Role Management: Roles are managed in LDAP, not in Casbin policies
  • Role Hierarchy Support: Supports nested group memberships up to MaxHierarchyLevel
  • Multiple Group Membership: Users can belong to multiple groups/roles
  • Flexible LDAP Schema: Configurable filters and attributes to match your LDAP schema
  • TLS Support: Secure connections to LDAP servers
  • Thread-safe: Safe for concurrent use

API

The LDAP Role Manager implements the rbac.RoleManager interface:

  • GetRoles(name string, domain ...string) ([]string, error) - Get roles for a user
  • GetUsers(roleName string, domain ...string) ([]string, error) - Get users with a specific role
  • HasLink(name1 string, name2 string, domain ...string) (bool, error) - Check if a user has a role
  • GetImplicitRoles(name string, domain ...string) ([]string, error) - Get all roles including nested ones
  • GetImplicitUsers(roleName string, domain ...string) ([]string, error) - Get all users with a role

Note: Methods like AddLink and DeleteLink are no-ops since roles are managed in LDAP.

Testing

Run the tests with:

go test -v ./...

For tests with coverage:

go test -v -coverprofile=coverage.out ./...
go tool cover -html=coverage.out

Getting Help

License

This project is licensed under the Apache License 2.0. See the LICENSE file for the full license text.

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type LDAPConn

type LDAPConn interface {
	Search(searchRequest *ldap.SearchRequest) (*ldap.SearchResult, error)
	Bind(username, password string) error
	Close() error
}

LDAPConn defines the interface for LDAP operations.

type LDAPOptions

type LDAPOptions struct {
	// LDAP server URL (e.g., "ldap://localhost:389" or "ldaps://localhost:636")
	URL string
	// Base DN for searching (e.g., "dc=example,dc=com")
	BaseDN string
	// User filter template (e.g., "(uid=%s)")
	UserFilter string
	// Group filter template (e.g., "(member=%s)")
	GroupFilter string
	// Attribute containing role/group names (default: "cn")
	RoleAttr string
	// Bind DN for authentication
	BindDN string
	// Bind password
	BindPassword string
	// Use TLS
	UseTLS bool
	// Skip TLS verification
	SkipTLSVerify bool
	// Maximum hierarchy level for role inheritance (default: 10)
	MaxHierarchyLevel int
}

LDAPOptions contains configuration options for LDAP connection.

type RoleManager

type RoleManager struct {
	// contains filtered or unexported fields
}

RoleManager implements the RoleManager interface for LDAP.

func NewRoleManager

func NewRoleManager(opts *LDAPOptions) (*RoleManager, error)

NewRoleManager creates a new RoleManager instance with LDAP connection.

func (*RoleManager) AddDomainMatchingFunc

func (rm *RoleManager) AddDomainMatchingFunc(name string, fn rbac.MatchingFunc)

AddDomainMatchingFunc adds the domain matching function.

func (rm *RoleManager) AddLink(name1 string, name2 string, domain ...string) error

AddLink adds the inheritance link between role: name1 and role: name2. For LDAP role manager, this is a no-op as roles are managed in LDAP.

func (*RoleManager) AddMatchingFunc

func (rm *RoleManager) AddMatchingFunc(name string, fn rbac.MatchingFunc)

AddMatchingFunc adds the matching function.

func (*RoleManager) BuildRelationship

func (rm *RoleManager) BuildRelationship(name1 string, name2 string, domain ...string) error

BuildRelationship builds the relationship between role: name1 and role: name2. Deprecated: BuildRelationship is no longer required

func (*RoleManager) Clear

func (rm *RoleManager) Clear() error

Clear clears all stored data and resets the role manager to the initial state.

func (*RoleManager) Close

func (rm *RoleManager) Close() error

Close closes the LDAP connection.

func (*RoleManager) DeleteDomain

func (rm *RoleManager) DeleteDomain(domain string) error

DeleteDomain deletes all data of a domain in the role manager.

func (rm *RoleManager) DeleteLink(name1 string, name2 string, domain ...string) error

DeleteLink deletes the inheritance link between role: name1 and role: name2. For LDAP role manager, this is a no-op as roles are managed in LDAP.

func (*RoleManager) GetAllDomains

func (rm *RoleManager) GetAllDomains() ([]string, error)

GetAllDomains gets all domains.

func (*RoleManager) GetDomains

func (rm *RoleManager) GetDomains(name string) ([]string, error)

GetDomains gets domains that a user has.

func (*RoleManager) GetImplicitRoles

func (rm *RoleManager) GetImplicitRoles(name string, domain ...string) ([]string, error)

GetImplicitRoles gets the implicit roles that a user inherits, respecting maxHierarchyLevel.

func (*RoleManager) GetImplicitUsers

func (rm *RoleManager) GetImplicitUsers(roleName string, domain ...string) ([]string, error)

GetImplicitUsers gets the implicit users that inherits a role, respecting maxHierarchyLevel.

func (*RoleManager) GetRoles

func (rm *RoleManager) GetRoles(name string, domain ...string) ([]string, error)

GetRoles gets the roles that a user inherits.

Example

Example test demonstrating usage

// Note: This example requires a running LDAP server
opts := &LDAPOptions{
	URL:               "ldap://localhost:389",
	BaseDN:            "dc=example,dc=com",
	UserFilter:        "(uid=%s)",
	GroupFilter:       "(member=%s)",
	RoleAttr:          "cn",
	BindDN:            "cn=admin,dc=example,dc=com",
	BindPassword:      "password",
	MaxHierarchyLevel: 10,
}

rm, err := NewRoleManager(opts)
if err != nil {
	fmt.Printf("Failed to create role manager: %v\n", err)
	return
}
defer rm.Close()

roles, err := rm.GetRoles("alice")
if err != nil {
	fmt.Printf("Failed to get roles: %v\n", err)
	return
}

fmt.Printf("Roles for alice: %v\n", roles)

func (*RoleManager) GetUsers

func (rm *RoleManager) GetUsers(roleName string, domain ...string) ([]string, error)

GetUsers gets the users that inherits a role.

func (rm *RoleManager) HasLink(name1 string, name2 string, domain ...string) (bool, error)

HasLink determines whether role: name1 inherits role: name2.

func (*RoleManager) Match

func (rm *RoleManager) Match(str string, pattern string) bool

Match matches the domain with the pattern.

func (*RoleManager) PrintRoles

func (rm *RoleManager) PrintRoles() error

PrintRoles prints all the roles to log.

func (*RoleManager) SetLogger

func (rm *RoleManager) SetLogger(logger log.Logger)

SetLogger sets role manager's logger.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL