Skip to content

Commit 9eb90dd

Browse files
Copilotnomeguy
andcommitted
docs: add comprehensive examples and LDIF setup guide
Co-authored-by: nomeguy <85475922+nomeguy@users.noreply.github.com>
1 parent c20d0c6 commit 9eb90dd

File tree

5 files changed

+280
-0
lines changed

5 files changed

+280
-0
lines changed

examples/README.md

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# Examples
2+
3+
This directory contains examples demonstrating how to use the LDAP Role Manager with Casbin.
4+
5+
## Files
6+
7+
- **main.go** - A simple example showing how to integrate LDAP role manager with Casbin
8+
- **rbac_model.conf** - Casbin RBAC model configuration
9+
- **rbac_policy.csv** - Sample policies for role-based access control
10+
- **example.ldif** - Sample LDIF file for populating an LDAP directory
11+
12+
## Running the Example
13+
14+
### 1. Set up an LDAP Server
15+
16+
You can use OpenLDAP or any other LDAP server. For testing, you can use Docker:
17+
18+
```bash
19+
docker run -d \
20+
--name openldap \
21+
-p 389:389 \
22+
-e LDAP_ORGANISATION="Example Inc." \
23+
-e LDAP_DOMAIN="example.com" \
24+
-e LDAP_ADMIN_PASSWORD="admin" \
25+
osixia/openldap:latest
26+
```
27+
28+
### 2. Populate the LDAP Directory
29+
30+
Load the example LDIF file into your LDAP server:
31+
32+
```bash
33+
# Using ldapadd
34+
ldapadd -x -D "cn=admin,dc=example,dc=com" -w admin -f example.ldif
35+
36+
# Or using Docker
37+
docker exec openldap ldapadd -x -D "cn=admin,dc=example,dc=com" -w admin -f /tmp/example.ldif
38+
```
39+
40+
You may need to copy the LDIF file into the container first:
41+
42+
```bash
43+
docker cp example.ldif openldap:/tmp/example.ldif
44+
```
45+
46+
### 3. Run the Example
47+
48+
Update the connection details in `main.go` if needed, then run:
49+
50+
```bash
51+
cd examples
52+
go run main.go
53+
```
54+
55+
## Expected Output
56+
57+
The example will check permissions for alice (admin) and bob (user):
58+
59+
```
60+
✓ alice can read data1
61+
✓ alice can write data1
62+
✓ bob can read data1
63+
✗ bob cannot write data1
64+
65+
Roles for alice: [admin user]
66+
Roles for bob: [user]
67+
```
68+
69+
## Verifying LDAP Setup
70+
71+
You can verify your LDAP setup using ldapsearch:
72+
73+
```bash
74+
# Search for all users
75+
ldapsearch -x -D "cn=admin,dc=example,dc=com" -w admin -b "ou=users,dc=example,dc=com"
76+
77+
# Search for all groups
78+
ldapsearch -x -D "cn=admin,dc=example,dc=com" -w admin -b "ou=groups,dc=example,dc=com"
79+
80+
# Search for alice's groups
81+
ldapsearch -x -D "cn=admin,dc=example,dc=com" -w admin -b "dc=example,dc=com" "(member=uid=alice,ou=users,dc=example,dc=com)"
82+
```
83+
84+
## Customization
85+
86+
You can customize the example by:
87+
88+
1. Modifying the LDAP connection parameters in `main.go`
89+
2. Adding more users and groups to `example.ldif`
90+
3. Creating different policies in `rbac_policy.csv`
91+
4. Adjusting the model in `rbac_model.conf`
92+
93+
## Active Directory Example
94+
95+
For Active Directory, you would use different filters and configuration:
96+
97+
```go
98+
opts := &ldaprolemanager.LDAPOptions{
99+
URL: "ldaps://ad.example.com:636",
100+
BaseDN: "dc=example,dc=com",
101+
UserFilter: "(sAMAccountName=%s)",
102+
GroupFilter: "(member=%s)",
103+
RoleAttr: "cn",
104+
BindDN: "cn=service-account,ou=users,dc=example,dc=com",
105+
BindPassword: "password",
106+
UseTLS: true,
107+
}
108+
```

examples/example.ldif

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Example LDIF file for setting up LDAP structure
2+
# This file can be used to populate an LDAP server for testing
3+
4+
# Create organizational units
5+
dn: ou=users,dc=example,dc=com
6+
objectClass: organizationalUnit
7+
ou: users
8+
9+
dn: ou=groups,dc=example,dc=com
10+
objectClass: organizationalUnit
11+
ou: groups
12+
13+
# Create users
14+
dn: uid=alice,ou=users,dc=example,dc=com
15+
objectClass: inetOrgPerson
16+
objectClass: posixAccount
17+
objectClass: top
18+
cn: Alice Smith
19+
sn: Smith
20+
uid: alice
21+
uidNumber: 1001
22+
gidNumber: 1001
23+
homeDirectory: /home/alice
24+
userPassword: password
25+
26+
dn: uid=bob,ou=users,dc=example,dc=com
27+
objectClass: inetOrgPerson
28+
objectClass: posixAccount
29+
objectClass: top
30+
cn: Bob Jones
31+
sn: Jones
32+
uid: bob
33+
uidNumber: 1002
34+
gidNumber: 1002
35+
homeDirectory: /home/bob
36+
userPassword: password
37+
38+
# Create groups
39+
dn: cn=admin,ou=groups,dc=example,dc=com
40+
objectClass: groupOfNames
41+
cn: admin
42+
member: uid=alice,ou=users,dc=example,dc=com
43+
44+
dn: cn=user,ou=groups,dc=example,dc=com
45+
objectClass: groupOfNames
46+
cn: user
47+
member: uid=alice,ou=users,dc=example,dc=com
48+
member: uid=bob,ou=users,dc=example,dc=com

examples/main.go

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// Copyright 2026 The casbin Authors. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package main
16+
17+
import (
18+
"fmt"
19+
"log"
20+
21+
"github.com/casbin/casbin/v2"
22+
ldaprolemanager "github.com/casbin/ldap-role-manager"
23+
)
24+
25+
func main() {
26+
// Initialize LDAP role manager
27+
opts := &ldaprolemanager.LDAPOptions{
28+
URL: "ldap://localhost:389",
29+
BaseDN: "dc=example,dc=com",
30+
UserFilter: "(uid=%s)",
31+
GroupFilter: "(member=%s)",
32+
RoleAttr: "cn",
33+
BindDN: "cn=admin,dc=example,dc=com",
34+
BindPassword: "password",
35+
MaxHierarchyLevel: 10,
36+
}
37+
38+
rm, err := ldaprolemanager.NewRoleManager(opts)
39+
if err != nil {
40+
log.Fatalf("Failed to create role manager: %v", err)
41+
}
42+
defer rm.Close()
43+
44+
// Create a new enforcer
45+
e, err := casbin.NewEnforcer("rbac_model.conf", "rbac_policy.csv")
46+
if err != nil {
47+
log.Fatalf("Failed to create enforcer: %v", err)
48+
}
49+
50+
// Set the role manager
51+
e.SetRoleManager(rm)
52+
53+
// Load policy
54+
err = e.LoadPolicy()
55+
if err != nil {
56+
log.Fatalf("Failed to load policy: %v", err)
57+
}
58+
59+
// Check permissions
60+
// In this example, we assume alice is in the admin group in LDAP
61+
// and bob is in the user group in LDAP
62+
63+
// Alice (admin) can read and write data1
64+
if res, _ := e.Enforce("alice", "data1", "read"); res {
65+
fmt.Println("✓ alice can read data1")
66+
} else {
67+
fmt.Println("✗ alice cannot read data1")
68+
}
69+
70+
if res, _ := e.Enforce("alice", "data1", "write"); res {
71+
fmt.Println("✓ alice can write data1")
72+
} else {
73+
fmt.Println("✗ alice cannot write data1")
74+
}
75+
76+
// Bob (user) can read but not write data1
77+
if res, _ := e.Enforce("bob", "data1", "read"); res {
78+
fmt.Println("✓ bob can read data1")
79+
} else {
80+
fmt.Println("✗ bob cannot read data1")
81+
}
82+
83+
if res, _ := e.Enforce("bob", "data1", "write"); res {
84+
fmt.Println("✓ bob can write data1")
85+
} else {
86+
fmt.Println("✗ bob cannot write data1")
87+
}
88+
89+
// Get roles for alice
90+
roles, err := rm.GetRoles("alice")
91+
if err != nil {
92+
log.Printf("Failed to get roles for alice: %v", err)
93+
} else {
94+
fmt.Printf("\nRoles for alice: %v\n", roles)
95+
}
96+
97+
// Get roles for bob
98+
roles, err = rm.GetRoles("bob")
99+
if err != nil {
100+
log.Printf("Failed to get roles for bob: %v", err)
101+
} else {
102+
fmt.Printf("Roles for bob: %v\n", roles)
103+
}
104+
}

examples/rbac_model.conf

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[request_definition]
2+
r = sub, obj, act
3+
4+
[policy_definition]
5+
p = sub, obj, act
6+
7+
[role_definition]
8+
g = _, _
9+
10+
[policy_effect]
11+
e = some(where (p.eft == allow))
12+
13+
[matchers]
14+
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act

examples/rbac_policy.csv

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
p, admin, data1, read
2+
p, admin, data1, write
3+
p, admin, data2, read
4+
p, admin, data2, write
5+
p, user, data1, read
6+
p, user, data2, read

0 commit comments

Comments
 (0)