Implement deleting a Group

This implements DELETE request on the graph/v1.0/groups/{groupid}
endpoint. Allowing to remove an entire group.
This commit is contained in:
Ralf Haferkamp
2022-01-25 13:06:41 +01:00
parent c0d486f3a5
commit eb3ace8629
8 changed files with 70 additions and 1 deletions

View File

@@ -21,8 +21,10 @@ type Backend interface {
GetUser(ctx context.Context, nameOrID string) (*libregraph.User, error)
GetUsers(ctx context.Context, queryParam url.Values) ([]*libregraph.User, error)
// Create Group creates the supplied group in the identity backend.
// CreateGroup creates the supplied group in the identity backend.
CreateGroup(ctx context.Context, group libregraph.Group) (*libregraph.Group, error)
// DeleteGroup deletes a given group, identified by id
DeleteGroup(ctx context.Context, id string) error
GetGroup(ctx context.Context, nameOrID string) (*libregraph.Group, error)
GetGroups(ctx context.Context, queryParam url.Values) ([]*libregraph.Group, error)
GetGroupMembers(ctx context.Context, id string) ([]*libregraph.User, error)

View File

@@ -174,6 +174,11 @@ func (i *CS3) GetGroup(ctx context.Context, groupID string) (*libregraph.Group,
return createGroupModelFromCS3(res.Group), nil
}
// DeleteGroup implements the Backend Interface. It's currently not supported for the CS3 backend
func (i *CS3) DeleteGroup(ctx context.Context, id string) error {
return errorcode.New(errorcode.NotSupported, "not implemented")
}
// GetGroupMembers implements the Backend Interface. It's currently not supported for the CS3 backend
func (i *CS3) GetGroupMembers(ctx context.Context, groupID string) ([]*libregraph.User, error) {
return nil, errorcode.New(errorcode.NotSupported, "not implemented")

View File

@@ -552,6 +552,22 @@ func (i *LDAP) CreateGroup(ctx context.Context, group libregraph.Group) (*libreg
return i.createGroupModelFromLDAP(e), nil
}
// DeleteGroup implements the Backend Interface.
func (i *LDAP) DeleteGroup(ctx context.Context, id string) error {
if !i.writeEnabled {
return errorcode.New(errorcode.NotAllowed, "server is configured read-only")
}
e, err := i.getLDAPGroupByID(id, false)
if err != nil {
return err
}
dr := ldap.DelRequest{DN: e.DN}
if err = i.conn.Del(&dr); err != nil {
return err
}
return nil
}
// AddMemberToGroup implements the Backend Interface for the LDAP backend.
// Currently it is limited to adding Users as Group members. Adding other groups
// as members is not yet implemented

View File

@@ -88,6 +88,35 @@ func (g Graph) GetGroup(w http.ResponseWriter, r *http.Request) {
render.JSON(w, r, group)
}
// DeleteGroup implements the Service interface.
func (g Graph) DeleteGroup(w http.ResponseWriter, r *http.Request) {
groupID := chi.URLParam(r, "groupID")
groupID, err := url.PathUnescape(groupID)
if err != nil {
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "unescaping group id failed")
return
}
if groupID == "" {
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "missing group id")
return
}
err = g.identityBackend.DeleteGroup(r.Context(), groupID)
if err != nil {
var errcode errorcode.Error
if errors.As(err, &errcode) {
errcode.Render(w, r)
} else {
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error())
}
return
}
render.Status(r, http.StatusNoContent)
render.NoContent(w, r)
}
func (g Graph) GetGroupMembers(w http.ResponseWriter, r *http.Request) {
groupID := chi.URLParam(r, "groupID")
groupID, err := url.PathUnescape(groupID)

View File

@@ -69,6 +69,11 @@ func (i instrument) PostGroup(w http.ResponseWriter, r *http.Request) {
i.next.PostGroup(w, r)
}
// DeleteGroup implements the Service interface.
func (i instrument) DeleteGroup(w http.ResponseWriter, r *http.Request) {
i.next.DeleteGroup(w, r)
}
// GetGroupMembers implements the Service interface.
func (i instrument) GetGroupMembers(w http.ResponseWriter, r *http.Request) {
i.next.GetGroupMembers(w, r)

View File

@@ -69,6 +69,11 @@ func (l logging) PostGroup(w http.ResponseWriter, r *http.Request) {
l.next.PostGroup(w, r)
}
// DeleteGroup implements the Service interface.
func (l logging) DeleteGroup(w http.ResponseWriter, r *http.Request) {
l.next.DeleteGroup(w, r)
}
// GetGroupMembers implements the Service interface.
func (l logging) GetGroupMembers(w http.ResponseWriter, r *http.Request) {
l.next.GetGroupMembers(w, r)

View File

@@ -34,6 +34,7 @@ type Service interface {
GetGroups(http.ResponseWriter, *http.Request)
GetGroup(http.ResponseWriter, *http.Request)
PostGroup(http.ResponseWriter, *http.Request)
DeleteGroup(http.ResponseWriter, *http.Request)
GetGroupMembers(http.ResponseWriter, *http.Request)
PostGroupMember(http.ResponseWriter, *http.Request)
@@ -118,6 +119,7 @@ func NewService(opts ...Option) Service {
r.Post("/", svc.PostGroup)
r.Route("/{groupID}", func(r chi.Router) {
r.Get("/", svc.GetGroup)
r.Delete("/", svc.DeleteGroup)
r.Route("/members", func(r chi.Router) {
r.Get("/", svc.GetGroupMembers)
r.Post("/$ref", svc.PostGroupMember)

View File

@@ -65,6 +65,11 @@ func (t tracing) PostGroup(w http.ResponseWriter, r *http.Request) {
t.next.PostGroup(w, r)
}
// DeleteGroup implements the Service interface.
func (t tracing) DeleteGroup(w http.ResponseWriter, r *http.Request) {
t.next.DeleteGroup(w, r)
}
// GetGroupMembers implements the Service interface.
func (t tracing) GetGroupMembers(w http.ResponseWriter, r *http.Request) {
t.next.GetGroupMembers(w, r)