Skip to content

Commit c2d438d

Browse files
committed
Added users and groups
1 parent 59be088 commit c2d438d

File tree

13 files changed

+665
-78
lines changed

13 files changed

+665
-78
lines changed

cmd/server/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ type CLI struct {
4646
ldap.ObjectCommands
4747
ldap.AuthCommands
4848
ldap.UserCommands
49+
ldap.GroupCommands
4950
} `cmd:""`
5051

5152
VersionCommands

cmd/server/service.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,10 @@ func (cmd *ServiceRunCommand) Run(app server.Cmd) error {
216216
ldap.UserSchema.Field = "uid"
217217
ldap.UserSchema.ObjectClasses = "top,inetOrgPerson,person,posixAccount"
218218

219+
ldap.GroupSchema.RDN = "cn=groups,cn=accounts"
220+
ldap.GroupSchema.Field = "cn"
221+
ldap.GroupSchema.ObjectClasses = "top,groupOfNames,nestedGroup,posixGroup"
222+
219223
return nil
220224
}))
221225

pkg/ldap/client/group.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package client
2+
3+
import (
4+
"context"
5+
6+
// Packages
7+
client "github.com/mutablelogic/go-client"
8+
schema "github.com/mutablelogic/go-server/pkg/ldap/schema"
9+
)
10+
11+
///////////////////////////////////////////////////////////////////////////////
12+
// PUBLIC METHODS
13+
14+
func (c *Client) ListGroups(ctx context.Context, opts ...Opt) (*schema.ObjectList, error) {
15+
req := client.NewRequest()
16+
17+
// Apply options
18+
opt, err := applyOpts(opts...)
19+
if err != nil {
20+
return nil, err
21+
}
22+
23+
// Perform request
24+
var response schema.ObjectList
25+
if err := c.DoWithContext(ctx, req, &response, client.OptPath("group"), client.OptQuery(opt.Values)); err != nil {
26+
return nil, err
27+
}
28+
29+
// Return the responses
30+
return &response, nil
31+
}
32+
33+
func (c *Client) CreateGroup(ctx context.Context, meta schema.Object) (*schema.Object, error) {
34+
req, err := client.NewJSONRequest(meta)
35+
if err != nil {
36+
return nil, err
37+
}
38+
39+
// Perform request
40+
var response schema.Object
41+
if err := c.DoWithContext(ctx, req, &response, client.OptPath("group")); err != nil {
42+
return nil, err
43+
}
44+
45+
// Return the responses
46+
return &response, nil
47+
}
48+
49+
func (c *Client) GetGroup(ctx context.Context, user string) (*schema.Object, error) {
50+
var resp schema.Object
51+
52+
// Perform request
53+
if err := c.DoWithContext(ctx, client.MethodGet, &resp, client.OptPath("group", user)); err != nil {
54+
return nil, err
55+
}
56+
57+
// Return the response
58+
return &resp, nil
59+
}
60+
61+
func (c *Client) DeleteGroup(ctx context.Context, user string) error {
62+
// Perform request
63+
return c.DoWithContext(ctx, client.MethodDelete, nil, client.OptPath("group", user))
64+
}

pkg/ldap/client/user.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,25 @@ import (
1111
///////////////////////////////////////////////////////////////////////////////
1212
// PUBLIC METHODS
1313

14+
func (c *Client) ListUsers(ctx context.Context, opts ...Opt) (*schema.ObjectList, error) {
15+
req := client.NewRequest()
16+
17+
// Apply options
18+
opt, err := applyOpts(opts...)
19+
if err != nil {
20+
return nil, err
21+
}
22+
23+
// Perform request
24+
var response schema.ObjectList
25+
if err := c.DoWithContext(ctx, req, &response, client.OptPath("user"), client.OptQuery(opt.Values)); err != nil {
26+
return nil, err
27+
}
28+
29+
// Return the responses
30+
return &response, nil
31+
}
32+
1433
func (c *Client) CreateUser(ctx context.Context, meta schema.Object) (*schema.Object, error) {
1534
req, err := client.NewJSONRequest(meta)
1635
if err != nil {
@@ -26,3 +45,20 @@ func (c *Client) CreateUser(ctx context.Context, meta schema.Object) (*schema.Ob
2645
// Return the responses
2746
return &response, nil
2847
}
48+
49+
func (c *Client) GetUser(ctx context.Context, user string) (*schema.Object, error) {
50+
var resp schema.Object
51+
52+
// Perform request
53+
if err := c.DoWithContext(ctx, client.MethodGet, &resp, client.OptPath("user", user)); err != nil {
54+
return nil, err
55+
}
56+
57+
// Return the response
58+
return &resp, nil
59+
}
60+
61+
func (c *Client) DeleteUser(ctx context.Context, user string) error {
62+
// Perform request
63+
return c.DoWithContext(ctx, client.MethodDelete, nil, client.OptPath("user", user))
64+
}

pkg/ldap/cmd/group.go

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package cmd
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"net/url"
7+
"strings"
8+
9+
// Packages
10+
server "github.com/mutablelogic/go-server"
11+
client "github.com/mutablelogic/go-server/pkg/ldap/client"
12+
schema "github.com/mutablelogic/go-server/pkg/ldap/schema"
13+
)
14+
15+
///////////////////////////////////////////////////////////////////////////////
16+
// TYPES
17+
18+
type GroupCommands struct {
19+
Groups GroupListCommand `cmd:"" group:"LDAP" help:"List groups"`
20+
Group GroupGetCommand `cmd:"" group:"LDAP" help:"Get group"`
21+
CreateGroup GroupCreateCommand `cmd:"" group:"LDAP" help:"Create group"`
22+
DeleteGroup GroupDeleteCommand `cmd:"" group:"LDAP" help:"Delete group"`
23+
}
24+
25+
type GroupListCommand struct {
26+
schema.ObjectListRequest
27+
}
28+
29+
type GroupGetCommand struct {
30+
Group string `arg:"" help:"Group name"`
31+
}
32+
33+
type GroupCreateCommand struct {
34+
GroupGetCommand
35+
Attr []string `arg:"" help:"attribute=value,value,..."`
36+
}
37+
38+
type GroupDeleteCommand struct {
39+
GroupGetCommand
40+
}
41+
42+
///////////////////////////////////////////////////////////////////////////////
43+
// PUBLIC METHODS
44+
45+
func (cmd GroupListCommand) Run(ctx server.Cmd) error {
46+
return run(ctx, func(ctx context.Context, provider *client.Client) error {
47+
groups, err := provider.ListGroups(ctx, client.WithFilter(cmd.Filter), client.WithAttr(cmd.Attr...), client.WithOffsetLimit(cmd.Offset, cmd.Limit))
48+
if err != nil {
49+
return err
50+
}
51+
52+
// Print groups
53+
fmt.Println(groups)
54+
return nil
55+
})
56+
}
57+
58+
func (cmd GroupGetCommand) Run(ctx server.Cmd) error {
59+
return run(ctx, func(ctx context.Context, provider *client.Client) error {
60+
group, err := provider.GetGroup(ctx, cmd.Group)
61+
if err != nil {
62+
return err
63+
}
64+
65+
// Print group
66+
fmt.Println(group)
67+
return nil
68+
})
69+
}
70+
71+
func (cmd GroupDeleteCommand) Run(ctx server.Cmd) error {
72+
return run(ctx, func(ctx context.Context, provider *client.Client) error {
73+
return provider.DeleteGroup(ctx, cmd.Group)
74+
})
75+
}
76+
77+
func (cmd GroupCreateCommand) Run(ctx server.Cmd) error {
78+
return run(ctx, func(ctx context.Context, provider *client.Client) error {
79+
// Decode attributes
80+
attrs := url.Values{}
81+
for _, attr := range cmd.Attr {
82+
parts := strings.SplitN(attr, "=", 2)
83+
if len(parts) != 2 {
84+
return fmt.Errorf("invalid attribute: %s", attr)
85+
}
86+
name := parts[0]
87+
if values := strings.Split(parts[1], ","); len(values) > 0 {
88+
attrs[name] = values
89+
}
90+
}
91+
92+
// Create group
93+
group, err := provider.CreateGroup(ctx, schema.Object{
94+
DN: cmd.Group,
95+
Values: attrs,
96+
})
97+
if err != nil {
98+
return err
99+
}
100+
101+
// Print group
102+
fmt.Println(group)
103+
return nil
104+
})
105+
}

pkg/ldap/cmd/object.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,23 +27,23 @@ type ObjectListCommand struct {
2727
schema.ObjectListRequest
2828
}
2929

30-
type ObjectGetCommand struct {
31-
DN string `arg:"" help:"Distingushed Name"`
32-
}
33-
3430
type ObjectCreateCommand struct {
3531
ObjectGetCommand
3632
Attr []string `arg:"" help:"attribute=value,value,..."`
3733
}
3834

39-
type ObjectUpdateCommand struct {
40-
ObjectCreateCommand
35+
type ObjectGetCommand struct {
36+
DN string `arg:"" help:"Distingushed Name"`
4137
}
4238

4339
type ObjectDeleteCommand struct {
4440
ObjectGetCommand
4541
}
4642

43+
type ObjectUpdateCommand struct {
44+
ObjectCreateCommand
45+
}
46+
4747
///////////////////////////////////////////////////////////////////////////////
4848
// PUBLIC METHODS
4949

pkg/ldap/cmd/user.go

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,64 @@ import (
1616
// TYPES
1717

1818
type UserCommands struct {
19+
Users UserListCommand `cmd:"" group:"LDAP" help:"List users"`
20+
User UserGetCommand `cmd:"" group:"LDAP" help:"Get user"`
1921
CreateUser UserCreateCommand `cmd:"" group:"LDAP" help:"Create user"`
22+
DeleteUser UserDeleteCommand `cmd:"" group:"LDAP" help:"Delete user"`
23+
}
24+
25+
type UserListCommand struct {
26+
schema.ObjectListRequest
2027
}
2128

2229
type UserGetCommand struct {
23-
DN string `arg:"" help:"Username"`
30+
User string `arg:"" help:"Username"`
2431
}
2532

2633
type UserCreateCommand struct {
2734
UserGetCommand
2835
Attr []string `arg:"" help:"attribute=value,value,..."`
2936
}
3037

38+
type UserDeleteCommand struct {
39+
UserGetCommand
40+
}
41+
3142
///////////////////////////////////////////////////////////////////////////////
3243
// PUBLIC METHODS
3344

45+
func (cmd UserListCommand) Run(ctx server.Cmd) error {
46+
return run(ctx, func(ctx context.Context, provider *client.Client) error {
47+
users, err := provider.ListUsers(ctx, client.WithFilter(cmd.Filter), client.WithAttr(cmd.Attr...), client.WithOffsetLimit(cmd.Offset, cmd.Limit))
48+
if err != nil {
49+
return err
50+
}
51+
52+
// Print users
53+
fmt.Println(users)
54+
return nil
55+
})
56+
}
57+
58+
func (cmd UserGetCommand) Run(ctx server.Cmd) error {
59+
return run(ctx, func(ctx context.Context, provider *client.Client) error {
60+
user, err := provider.GetUser(ctx, cmd.User)
61+
if err != nil {
62+
return err
63+
}
64+
65+
// Print user
66+
fmt.Println(user)
67+
return nil
68+
})
69+
}
70+
71+
func (cmd UserDeleteCommand) Run(ctx server.Cmd) error {
72+
return run(ctx, func(ctx context.Context, provider *client.Client) error {
73+
return provider.DeleteUser(ctx, cmd.User)
74+
})
75+
}
76+
3477
func (cmd UserCreateCommand) Run(ctx server.Cmd) error {
3578
return run(ctx, func(ctx context.Context, provider *client.Client) error {
3679
// Decode attributes
@@ -48,7 +91,7 @@ func (cmd UserCreateCommand) Run(ctx server.Cmd) error {
4891

4992
// Create user
5093
user, err := provider.CreateUser(ctx, schema.Object{
51-
DN: cmd.DN,
94+
DN: cmd.User,
5295
Values: attrs,
5396
})
5497
if err != nil {

pkg/ldap/config/config.go

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,24 @@ import (
1616
// TYPES
1717

1818
type Config struct {
19-
Url *url.URL `env:"LDAP_URL" help:"LDAP connection URL"` // Connection URL
20-
User string `env:"LDAP_USER" help:"User"` // User
21-
Password string `env:"LDAP_PASSWORD" help:"Password"` // Password
22-
BaseDN string `env:"LDAP_BASE_DN" help:"Base DN"` // Base DN
23-
SkipVerify bool `env:"LDAP_SKIPVERIFY" help:"Skip TLS certificate verify"` // Skip verify
24-
Router server.HTTPRouter `kong:"-"` // HTTP Router
19+
Url *url.URL `env:"LDAP_URL" help:"LDAP connection URL"` // Connection URL
20+
User string `env:"LDAP_USER" help:"User"` // User
21+
Password string `env:"LDAP_PASSWORD" help:"Password"` // Password
22+
BaseDN string `env:"LDAP_BASE_DN" help:"Base DN"` // Base DN
23+
SkipVerify bool `env:"LDAP_SKIPVERIFY" help:"Skip TLS certificate verify"` // Skip verify
24+
25+
Router server.HTTPRouter `kong:"-"` // HTTP Router
26+
2527
UserSchema struct {
26-
RDN string `default:"cn=users,cn=account" help:"User root DN"`
28+
RDN string `default:"cn=users,cn=account" help:"User RDN"`
2729
Field string `default:"uid" help:"User field"`
28-
ObjectClasses string `default:"top,inetOrgPerson,posixAccount" help:"User object classes"`
30+
ObjectClasses string `default:"top,person,inetOrgPerson,posixAccount" help:"User object classes"`
31+
}
32+
33+
GroupSchema struct {
34+
RDN string `default:"cn=groups,cn=account" help:"Group RDN"`
35+
Field string `default:"cn" help:"Group field"`
36+
ObjectClasses string `default:"top,groupOfNames,nestedGroup,posixGroup" help:"Group object classes"`
2937
}
3038
}
3139

@@ -51,8 +59,10 @@ func (c Config) New(ctx context.Context) (server.Task, error) {
5159
opts = append(opts, ldap.WithSkipVerify())
5260
}
5361
if c.UserSchema.RDN != "" {
54-
classes := strings.Split(c.UserSchema.ObjectClasses, ",")
55-
opts = append(opts, ldap.WithUserSchema(c.UserSchema.RDN, c.UserSchema.Field, classes...))
62+
opts = append(opts, ldap.WithUserSchema(c.UserSchema.RDN, c.UserSchema.Field, strings.Split(c.UserSchema.ObjectClasses, ",")...))
63+
}
64+
if c.GroupSchema.RDN != "" {
65+
opts = append(opts, ldap.WithGroupSchema(c.GroupSchema.RDN, c.GroupSchema.Field, strings.Split(c.GroupSchema.ObjectClasses, ",")...))
5666
}
5767

5868
// Create a new LDAP manager

0 commit comments

Comments
 (0)