Skip to content

Commit dc47838

Browse files
committed
Added LDAP object commands
1 parent 5542df7 commit dc47838

File tree

12 files changed

+529
-128
lines changed

12 files changed

+529
-128
lines changed

pkg/httpresponse/error.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ const (
3030
ErrInternalError = Err(http.StatusInternalServerError)
3131
ErrNotAuthorized = Err(http.StatusUnauthorized)
3232
ErrForbidden = Err(http.StatusForbidden)
33+
ErrGatewayError = Err(http.StatusBadGateway)
3334
)
3435

3536
///////////////////////////////////////////////////////////////////////////////

pkg/ldap/client/object.go

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

pkg/ldap/client/objects.go

Lines changed: 0 additions & 31 deletions
This file was deleted.

pkg/ldap/cmd/object.go

Lines changed: 105 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package cmd
33
import (
44
"context"
55
"fmt"
6+
"net/url"
7+
"strings"
68

79
// Packages
810
server "github.com/mutablelogic/go-server"
@@ -14,25 +16,124 @@ import (
1416
// TYPES
1517

1618
type ObjectCommands struct {
17-
Objects ObjectListCommand `cmd:"" group:"LDAP" help:"List queues"`
19+
Objects ObjectListCommand `cmd:"" group:"LDAP" help:"List queues"`
20+
Object ObjectGetCommand `cmd:"" group:"LDAP" help:"Get object by DN"`
21+
CreateObject ObjectCreateCommand `cmd:"" group:"LDAP" help:"Create object"`
22+
UpdateObject ObjectUpdateCommand `cmd:"" group:"LDAP" help:"Update object attributes by DN"`
23+
DeleteObject ObjectDeleteCommand `cmd:"" group:"LDAP" help:"Delete object by DN"`
1824
}
1925

2026
type ObjectListCommand struct {
2127
schema.ObjectListRequest
2228
}
2329

30+
type ObjectGetCommand struct {
31+
DN string `arg:"" help:"Distingushed Name"`
32+
}
33+
34+
type ObjectCreateCommand struct {
35+
ObjectGetCommand
36+
Attr []string `arg:"" help:"attribute=value,value,..."`
37+
}
38+
39+
type ObjectUpdateCommand struct {
40+
ObjectCreateCommand
41+
}
42+
43+
type ObjectDeleteCommand struct {
44+
ObjectGetCommand
45+
}
46+
2447
///////////////////////////////////////////////////////////////////////////////
2548
// PUBLIC METHODS
2649

2750
func (cmd ObjectListCommand) Run(ctx server.Cmd) error {
2851
return run(ctx, func(ctx context.Context, provider *client.Client) error {
29-
queues, err := provider.ListObjects(ctx, client.WithFilter(cmd.Filter), client.WithAttr(cmd.Attr...), client.WithOffsetLimit(cmd.Offset, cmd.Limit))
52+
objects, err := provider.ListObjects(ctx, client.WithFilter(cmd.Filter), client.WithAttr(cmd.Attr...), client.WithOffsetLimit(cmd.Offset, cmd.Limit))
53+
if err != nil {
54+
return err
55+
}
56+
57+
// Print objects
58+
fmt.Println(objects)
59+
return nil
60+
})
61+
}
62+
63+
func (cmd ObjectCreateCommand) Run(ctx server.Cmd) error {
64+
return run(ctx, func(ctx context.Context, provider *client.Client) error {
65+
// Decode attributes
66+
attrs := url.Values{}
67+
for _, attr := range cmd.Attr {
68+
parts := strings.SplitN(attr, "=", 2)
69+
if len(parts) != 2 {
70+
return fmt.Errorf("invalid attribute: %s", attr)
71+
}
72+
name := parts[0]
73+
if values := strings.Split(parts[1], ","); len(values) > 0 {
74+
attrs[name] = values
75+
}
76+
}
77+
78+
// Create object
79+
object, err := provider.CreateObject(ctx, schema.Object{
80+
DN: cmd.DN,
81+
Values: attrs,
82+
})
3083
if err != nil {
3184
return err
3285
}
3386

34-
// Print queues
35-
fmt.Println(queues)
87+
// Print object
88+
fmt.Println(object)
3689
return nil
3790
})
3891
}
92+
93+
func (cmd ObjectUpdateCommand) Run(ctx server.Cmd) error {
94+
return run(ctx, func(ctx context.Context, provider *client.Client) error {
95+
// Decode attributes
96+
attrs := url.Values{}
97+
for _, attr := range cmd.Attr {
98+
parts := strings.SplitN(attr, "=", 2)
99+
name := parts[0]
100+
if len(parts) == 1 {
101+
attrs[name] = []string{}
102+
} else {
103+
attrs[name] = strings.Split(parts[1], ",")
104+
}
105+
}
106+
107+
// Update object
108+
object, err := provider.UpdateObject(ctx, schema.Object{
109+
DN: cmd.DN,
110+
Values: attrs,
111+
})
112+
if err != nil {
113+
return err
114+
}
115+
116+
// Print object
117+
fmt.Println(object)
118+
return nil
119+
})
120+
}
121+
122+
func (cmd ObjectGetCommand) Run(ctx server.Cmd) error {
123+
return run(ctx, func(ctx context.Context, provider *client.Client) error {
124+
object, err := provider.GetObject(ctx, cmd.DN)
125+
if err != nil {
126+
return err
127+
}
128+
129+
// Print object
130+
fmt.Println(object)
131+
return nil
132+
})
133+
}
134+
135+
func (cmd ObjectDeleteCommand) Run(ctx server.Cmd) error {
136+
return run(ctx, func(ctx context.Context, provider *client.Client) error {
137+
return provider.DeleteObject(ctx, cmd.DN)
138+
})
139+
}

pkg/ldap/handler/handler.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,26 @@ func registerObject(ctx context.Context, router server.HTTPRouter, prefix string
2929
_ = httpresponse.Empty(w, http.StatusOK)
3030
case http.MethodGet:
3131
_ = objectList(w, r, manager)
32+
case http.MethodPost:
33+
_ = objectCreate(w, r, manager)
34+
default:
35+
_ = httpresponse.Error(w, httpresponse.Err(http.StatusMethodNotAllowed), r.Method)
36+
}
37+
})
38+
39+
router.HandleFunc(ctx, types.JoinPath(prefix, "object/{dn...}"), func(w http.ResponseWriter, r *http.Request) {
40+
defer r.Body.Close()
41+
httpresponse.Cors(w, r, router.Origin(), http.MethodGet, http.MethodDelete)
42+
43+
switch r.Method {
44+
case http.MethodOptions:
45+
_ = httpresponse.Empty(w, http.StatusOK)
46+
case http.MethodGet:
47+
_ = objectGet(w, r, manager, r.PathValue("dn"))
48+
case http.MethodDelete:
49+
_ = objectDelete(w, r, manager, r.PathValue("dn"))
50+
case http.MethodPatch:
51+
_ = objectUpdate(w, r, manager, r.PathValue("dn"))
3252
default:
3353
_ = httpresponse.Error(w, httpresponse.Err(http.StatusMethodNotAllowed), r.Method)
3454
}

pkg/ldap/handler/object.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,60 @@ func objectList(w http.ResponseWriter, r *http.Request, manager *ldap.Manager) e
2929
// Return success
3030
return httpresponse.JSON(w, http.StatusOK, httprequest.Indent(r), response)
3131
}
32+
33+
func objectCreate(w http.ResponseWriter, r *http.Request, manager *ldap.Manager) error {
34+
// Parse request
35+
var req schema.Object
36+
if err := httprequest.Read(r, &req); err != nil {
37+
return httpresponse.Error(w, err)
38+
}
39+
40+
// Create the object
41+
response, err := manager.Create(r.Context(), req.DN, req.Values)
42+
if err != nil {
43+
return httpresponse.Error(w, err)
44+
}
45+
46+
// Return success
47+
return httpresponse.JSON(w, http.StatusCreated, httprequest.Indent(r), response)
48+
}
49+
50+
func objectGet(w http.ResponseWriter, r *http.Request, manager *ldap.Manager, dn string) error {
51+
// Get the object
52+
response, err := manager.Get(r.Context(), dn)
53+
if err != nil {
54+
return httpresponse.Error(w, err)
55+
}
56+
57+
// Return success
58+
return httpresponse.JSON(w, http.StatusOK, httprequest.Indent(r), response)
59+
}
60+
61+
func objectDelete(w http.ResponseWriter, r *http.Request, manager *ldap.Manager, dn string) error {
62+
// Delete the object
63+
_, err := manager.Delete(r.Context(), dn)
64+
if err != nil {
65+
return httpresponse.Error(w, err)
66+
}
67+
68+
// Return success
69+
return httpresponse.Empty(w, http.StatusOK)
70+
}
71+
72+
func objectUpdate(w http.ResponseWriter, r *http.Request, manager *ldap.Manager, dn string) error {
73+
// Parse request
74+
var req schema.Object
75+
if err := httprequest.Read(r, &req); err != nil {
76+
return httpresponse.Error(w, err)
77+
}
78+
79+
// Update the attributes
80+
// TODO: Need to support adding and removing attributes, and changing the DN
81+
response, err := manager.Update(r.Context(), dn, req.Values)
82+
if err != nil {
83+
return httpresponse.Error(w, err)
84+
}
85+
86+
// Return success
87+
return httpresponse.JSON(w, http.StatusOK, httprequest.Indent(r), response)
88+
}

0 commit comments

Comments
 (0)