2023-06-14 12:40:37 +02:00
|
|
|
// Copyright (c) Mainflux
|
|
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
|
|
|
|
package api
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
|
|
|
|
"github.com/go-kit/kit/endpoint"
|
2023-08-10 02:32:44 +05:30
|
|
|
"github.com/mainflux/mainflux/internal/apiutil"
|
|
|
|
"github.com/mainflux/mainflux/pkg/errors"
|
2023-06-14 12:40:37 +02:00
|
|
|
mfgroups "github.com/mainflux/mainflux/pkg/groups"
|
|
|
|
"github.com/mainflux/mainflux/users/groups"
|
|
|
|
)
|
|
|
|
|
|
|
|
func createGroupEndpoint(svc groups.Service) endpoint.Endpoint {
|
|
|
|
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
|
|
|
req := request.(createGroupReq)
|
|
|
|
if err := req.validate(); err != nil {
|
2023-08-10 02:32:44 +05:30
|
|
|
return createGroupRes{}, errors.Wrap(apiutil.ErrValidation, err)
|
2023-06-14 12:40:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
group, err := svc.CreateGroup(ctx, req.token, req.Group)
|
|
|
|
if err != nil {
|
|
|
|
return createGroupRes{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return createGroupRes{created: true, Group: group}, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func viewGroupEndpoint(svc groups.Service) endpoint.Endpoint {
|
|
|
|
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
|
|
|
req := request.(groupReq)
|
|
|
|
if err := req.validate(); err != nil {
|
2023-08-10 02:32:44 +05:30
|
|
|
return viewGroupRes{}, errors.Wrap(apiutil.ErrValidation, err)
|
2023-06-14 12:40:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
group, err := svc.ViewGroup(ctx, req.token, req.id)
|
|
|
|
if err != nil {
|
|
|
|
return viewGroupRes{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return viewGroupRes{Group: group}, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func updateGroupEndpoint(svc groups.Service) endpoint.Endpoint {
|
|
|
|
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
|
|
|
req := request.(updateGroupReq)
|
|
|
|
if err := req.validate(); err != nil {
|
2023-08-10 02:32:44 +05:30
|
|
|
return updateGroupRes{}, errors.Wrap(apiutil.ErrValidation, err)
|
2023-06-14 12:40:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
group := mfgroups.Group{
|
|
|
|
ID: req.id,
|
|
|
|
Name: req.Name,
|
|
|
|
Description: req.Description,
|
|
|
|
Metadata: req.Metadata,
|
|
|
|
}
|
|
|
|
|
|
|
|
group, err := svc.UpdateGroup(ctx, req.token, group)
|
|
|
|
if err != nil {
|
|
|
|
return updateGroupRes{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return updateGroupRes{Group: group}, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func enableGroupEndpoint(svc groups.Service) endpoint.Endpoint {
|
|
|
|
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
|
|
|
req := request.(changeGroupStatusReq)
|
|
|
|
if err := req.validate(); err != nil {
|
2023-08-10 02:32:44 +05:30
|
|
|
return nil, errors.Wrap(apiutil.ErrValidation, err)
|
2023-06-14 12:40:37 +02:00
|
|
|
}
|
|
|
|
group, err := svc.EnableGroup(ctx, req.token, req.id)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return changeStatusRes{Group: group}, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func disableGroupEndpoint(svc groups.Service) endpoint.Endpoint {
|
|
|
|
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
|
|
|
req := request.(changeGroupStatusReq)
|
|
|
|
if err := req.validate(); err != nil {
|
2023-08-10 02:32:44 +05:30
|
|
|
return nil, errors.Wrap(apiutil.ErrValidation, err)
|
2023-06-14 12:40:37 +02:00
|
|
|
}
|
|
|
|
group, err := svc.DisableGroup(ctx, req.token, req.id)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return changeStatusRes{Group: group}, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func listGroupsEndpoint(svc groups.Service) endpoint.Endpoint {
|
|
|
|
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
|
|
|
req := request.(listGroupsReq)
|
|
|
|
if err := req.validate(); err != nil {
|
2023-08-10 02:32:44 +05:30
|
|
|
return groupPageRes{}, errors.Wrap(apiutil.ErrValidation, err)
|
2023-06-14 12:40:37 +02:00
|
|
|
}
|
|
|
|
page, err := svc.ListGroups(ctx, req.token, req.GroupsPage)
|
|
|
|
if err != nil {
|
|
|
|
return groupPageRes{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if req.tree {
|
|
|
|
return buildGroupsResponseTree(page), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return buildGroupsResponse(page), nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func listMembershipsEndpoint(svc groups.Service) endpoint.Endpoint {
|
|
|
|
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
|
|
|
req := request.(listMembershipReq)
|
|
|
|
if err := req.validate(); err != nil {
|
2023-08-10 02:32:44 +05:30
|
|
|
return membershipPageRes{}, errors.Wrap(apiutil.ErrValidation, err)
|
2023-06-14 12:40:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
page, err := svc.ListMemberships(ctx, req.token, req.clientID, req.GroupsPage)
|
|
|
|
if err != nil {
|
|
|
|
return membershipPageRes{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
res := membershipPageRes{
|
|
|
|
pageRes: pageRes{
|
|
|
|
Total: page.Total,
|
|
|
|
Offset: page.Offset,
|
|
|
|
Limit: page.Limit,
|
|
|
|
},
|
|
|
|
Memberships: []viewMembershipRes{},
|
|
|
|
}
|
|
|
|
for _, g := range page.Memberships {
|
|
|
|
res.Memberships = append(res.Memberships, viewMembershipRes{Group: g})
|
|
|
|
}
|
|
|
|
|
|
|
|
return res, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func buildGroupsResponseTree(page mfgroups.GroupsPage) groupPageRes {
|
|
|
|
groupsMap := map[string]*mfgroups.Group{}
|
|
|
|
// Parents' map keeps its array of children.
|
|
|
|
parentsMap := map[string][]*mfgroups.Group{}
|
|
|
|
for i := range page.Groups {
|
|
|
|
if _, ok := groupsMap[page.Groups[i].ID]; !ok {
|
|
|
|
groupsMap[page.Groups[i].ID] = &page.Groups[i]
|
|
|
|
parentsMap[page.Groups[i].ID] = make([]*mfgroups.Group, 0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, group := range groupsMap {
|
|
|
|
if children, ok := parentsMap[group.Parent]; ok {
|
|
|
|
children = append(children, group)
|
|
|
|
parentsMap[group.Parent] = children
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
res := groupPageRes{
|
|
|
|
pageRes: pageRes{
|
|
|
|
Limit: page.Limit,
|
|
|
|
Offset: page.Offset,
|
|
|
|
Total: page.Total,
|
|
|
|
Level: page.Level,
|
|
|
|
},
|
|
|
|
Groups: []viewGroupRes{},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, group := range groupsMap {
|
|
|
|
if children, ok := parentsMap[group.ID]; ok {
|
|
|
|
group.Children = children
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, group := range groupsMap {
|
|
|
|
view := toViewGroupRes(*group)
|
|
|
|
if children, ok := parentsMap[group.Parent]; len(children) == 0 || !ok {
|
|
|
|
res.Groups = append(res.Groups, view)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return res
|
|
|
|
}
|
|
|
|
|
|
|
|
func toViewGroupRes(group mfgroups.Group) viewGroupRes {
|
|
|
|
view := viewGroupRes{
|
|
|
|
Group: group,
|
|
|
|
}
|
|
|
|
return view
|
|
|
|
}
|
|
|
|
|
|
|
|
func buildGroupsResponse(gp mfgroups.GroupsPage) groupPageRes {
|
|
|
|
res := groupPageRes{
|
|
|
|
pageRes: pageRes{
|
|
|
|
Total: gp.Total,
|
|
|
|
Level: gp.Level,
|
|
|
|
},
|
|
|
|
Groups: []viewGroupRes{},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, group := range gp.Groups {
|
|
|
|
view := viewGroupRes{
|
|
|
|
Group: group,
|
|
|
|
}
|
|
|
|
res.Groups = append(res.Groups, view)
|
|
|
|
}
|
|
|
|
|
|
|
|
return res
|
|
|
|
}
|