mirror of
https://github.com/absmach/supermq.git
synced 2026-06-23 07:20:19 +00:00
NOISSUE - Implementation of Group removal (#161)
* add: group delete flow Signed-off-by: Arvindh <arvindh91@gmail.com> * sync with master Signed-off-by: Arvindh <arvindh91@gmail.com> * improved grpc error handling Signed-off-by: Arvindh <arvindh91@gmail.com> * gofumpt -ed Signed-off-by: Arvindh <arvindh91@gmail.com> * changed database unassign parent group id Signed-off-by: Arvindh <arvindh91@gmail.com> * seperate event for delete group Signed-off-by: Arvindh <arvindh91@gmail.com> * change group event name Signed-off-by: Arvindh <arvindh91@gmail.com> * update channel remove events Signed-off-by: Arvindh <arvindh91@gmail.com> * fix: channels event Signed-off-by: Arvindh <arvindh91@gmail.com> * add: sdk, sdk_tet, cli Signed-off-by: Arvindh <arvindh91@gmail.com> * fix: sdk mock Signed-off-by: Arvindh <arvindh91@gmail.com> * mockery Signed-off-by: Arvindh <arvindh91@gmail.com> * convert to inline case Signed-off-by: Arvindh <arvindh91@gmail.com> * change in group delete flow Signed-off-by: Arvindh <arvindh91@gmail.com> * change return error in delete Signed-off-by: Arvindh <arvindh91@gmail.com> * add: openapi Signed-off-by: Arvindh <arvindh91@gmail.com> * rename events: from channel delete to channel remove Signed-off-by: Arvindh <arvindh91@gmail.com> --------- Signed-off-by: Arvindh <arvindh91@gmail.com>
This commit is contained in:
@@ -466,6 +466,26 @@ paths:
|
||||
description: Missing or invalid content type.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
delete:
|
||||
summary: Delete channel for given channel id.
|
||||
description: |
|
||||
Delete channel remove given channel id from repo
|
||||
and removes all the policies related to channel.
|
||||
tags:
|
||||
- Channels
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/chanID"
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
"204":
|
||||
$ref: "#/components/responses/ChannelDeleteRes"
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"403":
|
||||
description: Unauthorized access to thing id.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
/channels/{chanID}/enable:
|
||||
post:
|
||||
@@ -1751,6 +1771,9 @@ components:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Channel"
|
||||
|
||||
ChannelDeleteRes:
|
||||
description: Channel Deleted.
|
||||
|
||||
ChannelPageRes:
|
||||
description: Data retrieved.
|
||||
content:
|
||||
|
||||
+24
-24
@@ -175,7 +175,7 @@ func (client grpcClient) Issue(ctx context.Context, req *magistrala.IssueReq, _
|
||||
|
||||
res, err := client.issue(ctx, issueReq{userID: req.GetUserId(), domainID: req.GetDomainId(), keyType: auth.KeyType(req.Type)})
|
||||
if err != nil {
|
||||
return nil, decodeError(err)
|
||||
return &magistrala.Token{}, decodeError(err)
|
||||
}
|
||||
return res.(*magistrala.Token), nil
|
||||
}
|
||||
@@ -195,7 +195,7 @@ func (client grpcClient) Refresh(ctx context.Context, req *magistrala.RefreshReq
|
||||
|
||||
res, err := client.refresh(ctx, refreshReq{refreshToken: req.GetRefreshToken(), domainID: req.GetDomainId()})
|
||||
if err != nil {
|
||||
return nil, decodeError(err)
|
||||
return &magistrala.Token{}, decodeError(err)
|
||||
}
|
||||
return res.(*magistrala.Token), nil
|
||||
}
|
||||
@@ -215,7 +215,7 @@ func (client grpcClient) Identify(ctx context.Context, token *magistrala.Identit
|
||||
|
||||
res, err := client.identify(ctx, identityReq{token: token.GetToken()})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return &magistrala.IdentityRes{}, decodeError(err)
|
||||
}
|
||||
ir := res.(identityRes)
|
||||
return &magistrala.IdentityRes{Id: ir.id, UserId: ir.userID, DomainId: ir.domainID}, nil
|
||||
@@ -246,11 +246,11 @@ func (client grpcClient) Authorize(ctx context.Context, req *magistrala.Authoriz
|
||||
Object: req.GetObject(),
|
||||
})
|
||||
if err != nil {
|
||||
return &magistrala.AuthorizeRes{}, err
|
||||
return &magistrala.AuthorizeRes{}, decodeError(err)
|
||||
}
|
||||
|
||||
ar := res.(authorizeRes)
|
||||
return &magistrala.AuthorizeRes{Authorized: ar.authorized, Id: ar.id}, err
|
||||
return &magistrala.AuthorizeRes{Authorized: ar.authorized, Id: ar.id}, nil
|
||||
}
|
||||
|
||||
func decodeAuthorizeResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
@@ -288,11 +288,11 @@ func (client grpcClient) AddPolicy(ctx context.Context, in *magistrala.AddPolicy
|
||||
Object: in.GetObject(),
|
||||
})
|
||||
if err != nil {
|
||||
return &magistrala.AddPolicyRes{}, err
|
||||
return &magistrala.AddPolicyRes{}, decodeError(err)
|
||||
}
|
||||
|
||||
apr := res.(addPolicyRes)
|
||||
return &magistrala.AddPolicyRes{Authorized: apr.authorized}, err
|
||||
return &magistrala.AddPolicyRes{Authorized: apr.authorized}, nil
|
||||
}
|
||||
|
||||
func decodeAddPolicyResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
@@ -337,11 +337,11 @@ func (client grpcClient) AddPolicies(ctx context.Context, in *magistrala.AddPoli
|
||||
|
||||
res, err := client.addPolicies(ctx, r)
|
||||
if err != nil {
|
||||
return &magistrala.AddPoliciesRes{}, err
|
||||
return &magistrala.AddPoliciesRes{}, decodeError(err)
|
||||
}
|
||||
|
||||
apr := res.(addPoliciesRes)
|
||||
return &magistrala.AddPoliciesRes{Authorized: apr.authorized}, err
|
||||
return &magistrala.AddPoliciesRes{Authorized: apr.authorized}, nil
|
||||
}
|
||||
|
||||
func decodeAddPoliciesResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
@@ -386,11 +386,11 @@ func (client grpcClient) DeletePolicy(ctx context.Context, in *magistrala.Delete
|
||||
Object: in.GetObject(),
|
||||
})
|
||||
if err != nil {
|
||||
return &magistrala.DeletePolicyRes{}, err
|
||||
return &magistrala.DeletePolicyRes{}, decodeError(err)
|
||||
}
|
||||
|
||||
dpr := res.(deletePolicyRes)
|
||||
return &magistrala.DeletePolicyRes{Deleted: dpr.deleted}, err
|
||||
return &magistrala.DeletePolicyRes{Deleted: dpr.deleted}, nil
|
||||
}
|
||||
|
||||
func decodeDeletePolicyResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
@@ -435,11 +435,11 @@ func (client grpcClient) DeletePolicies(ctx context.Context, in *magistrala.Dele
|
||||
}
|
||||
res, err := client.deletePolicies(ctx, r)
|
||||
if err != nil {
|
||||
return &magistrala.DeletePoliciesRes{}, err
|
||||
return &magistrala.DeletePoliciesRes{}, decodeError(err)
|
||||
}
|
||||
|
||||
dpr := res.(deletePoliciesRes)
|
||||
return &magistrala.DeletePoliciesRes{Deleted: dpr.deleted}, err
|
||||
return &magistrala.DeletePoliciesRes{Deleted: dpr.deleted}, nil
|
||||
}
|
||||
|
||||
func decodeDeletePoliciesResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
@@ -482,11 +482,11 @@ func (client grpcClient) ListObjects(ctx context.Context, in *magistrala.ListObj
|
||||
Object: in.GetObject(),
|
||||
})
|
||||
if err != nil {
|
||||
return &magistrala.ListObjectsRes{}, err
|
||||
return &magistrala.ListObjectsRes{}, decodeError(err)
|
||||
}
|
||||
|
||||
lpr := res.(listObjectsRes)
|
||||
return &magistrala.ListObjectsRes{Policies: lpr.policies}, err
|
||||
return &magistrala.ListObjectsRes{Policies: lpr.policies}, nil
|
||||
}
|
||||
|
||||
func decodeListObjectsResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
@@ -521,11 +521,11 @@ func (client grpcClient) ListAllObjects(ctx context.Context, in *magistrala.List
|
||||
Object: in.GetObject(),
|
||||
})
|
||||
if err != nil {
|
||||
return &magistrala.ListObjectsRes{}, err
|
||||
return &magistrala.ListObjectsRes{}, decodeError(err)
|
||||
}
|
||||
|
||||
lpr := res.(listObjectsRes)
|
||||
return &magistrala.ListObjectsRes{Policies: lpr.policies}, err
|
||||
return &magistrala.ListObjectsRes{Policies: lpr.policies}, nil
|
||||
}
|
||||
|
||||
func (client grpcClient) CountObjects(ctx context.Context, in *magistrala.CountObjectsReq, opts ...grpc.CallOption) (*magistrala.CountObjectsRes, error) {
|
||||
@@ -542,11 +542,11 @@ func (client grpcClient) CountObjects(ctx context.Context, in *magistrala.CountO
|
||||
Object: in.GetObject(),
|
||||
})
|
||||
if err != nil {
|
||||
return &magistrala.CountObjectsRes{}, err
|
||||
return &magistrala.CountObjectsRes{}, decodeError(err)
|
||||
}
|
||||
|
||||
cp := res.(countObjectsRes)
|
||||
return &magistrala.CountObjectsRes{Count: int64(cp.count)}, err
|
||||
return &magistrala.CountObjectsRes{Count: int64(cp.count)}, nil
|
||||
}
|
||||
|
||||
func decodeCountObjectsResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
@@ -582,11 +582,11 @@ func (client grpcClient) ListSubjects(ctx context.Context, in *magistrala.ListSu
|
||||
NextPageToken: in.GetNextPageToken(),
|
||||
})
|
||||
if err != nil {
|
||||
return &magistrala.ListSubjectsRes{}, err
|
||||
return &magistrala.ListSubjectsRes{}, decodeError(err)
|
||||
}
|
||||
|
||||
lpr := res.(listSubjectsRes)
|
||||
return &magistrala.ListSubjectsRes{Policies: lpr.policies}, err
|
||||
return &magistrala.ListSubjectsRes{Policies: lpr.policies}, nil
|
||||
}
|
||||
|
||||
func decodeListSubjectsResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
@@ -621,11 +621,11 @@ func (client grpcClient) ListAllSubjects(ctx context.Context, in *magistrala.Lis
|
||||
Object: in.GetObject(),
|
||||
})
|
||||
if err != nil {
|
||||
return &magistrala.ListSubjectsRes{}, err
|
||||
return &magistrala.ListSubjectsRes{}, decodeError(err)
|
||||
}
|
||||
|
||||
lpr := res.(listSubjectsRes)
|
||||
return &magistrala.ListSubjectsRes{Policies: lpr.policies}, err
|
||||
return &magistrala.ListSubjectsRes{Policies: lpr.policies}, nil
|
||||
}
|
||||
|
||||
func (client grpcClient) CountSubjects(ctx context.Context, in *magistrala.CountSubjectsReq, opts ...grpc.CallOption) (*magistrala.CountSubjectsRes, error) {
|
||||
@@ -681,7 +681,7 @@ func (client grpcClient) ListPermissions(ctx context.Context, in *magistrala.Lis
|
||||
FilterPermissions: in.GetFilterPermissions(),
|
||||
})
|
||||
if err != nil {
|
||||
return &magistrala.ListPermissionsRes{}, err
|
||||
return &magistrala.ListPermissionsRes{}, decodeError(err)
|
||||
}
|
||||
|
||||
lp := res.(listPermissionsRes)
|
||||
|
||||
@@ -94,18 +94,6 @@ type policyReq struct {
|
||||
}
|
||||
|
||||
func (req policyReq) validate() error {
|
||||
if req.Subject == "" || req.SubjectType == "" {
|
||||
return apiutil.ErrMissingPolicySub
|
||||
}
|
||||
|
||||
if req.Object == "" || req.ObjectType == "" {
|
||||
return apiutil.ErrMissingPolicyObj
|
||||
}
|
||||
|
||||
if req.Relation == "" && req.Permission == "" {
|
||||
return apiutil.ErrMalformedPolicyRel
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -540,11 +540,13 @@ func encodeError(err error) error {
|
||||
err == apiutil.ErrMalformedPolicyAct:
|
||||
return status.Error(codes.InvalidArgument, err.Error())
|
||||
case errors.Contains(err, errors.ErrAuthentication),
|
||||
errors.Contains(err, svcerr.ErrAuthentication),
|
||||
errors.Contains(err, auth.ErrKeyExpired),
|
||||
err == apiutil.ErrMissingEmail,
|
||||
err == apiutil.ErrBearerToken:
|
||||
return status.Error(codes.Unauthenticated, err.Error())
|
||||
case errors.Contains(err, errors.ErrAuthorization),
|
||||
errors.Contains(err, svcerr.ErrAuthorization),
|
||||
errors.Contains(err, errors.ErrDomainAuthorization):
|
||||
return status.Error(codes.PermissionDenied, err.Error())
|
||||
case errors.Contains(err, errors.ErrNotFound):
|
||||
|
||||
+1
-1
@@ -153,7 +153,7 @@ func (svc service) Identify(ctx context.Context, token string) (Key, error) {
|
||||
return Key{}, errors.Wrap(ErrAPIKeyExpired, err)
|
||||
}
|
||||
if err != nil {
|
||||
return Key{}, errors.Wrap(errIdentify, err)
|
||||
return Key{}, errors.Wrap(svcerr.ErrAuthentication, errors.Wrap(errIdentify, err))
|
||||
}
|
||||
|
||||
switch key.Type {
|
||||
|
||||
@@ -17,7 +17,7 @@ const (
|
||||
thingRemove = "thing.remove"
|
||||
thingDisconnect = "policy.delete"
|
||||
|
||||
channelPrefix = "channel."
|
||||
channelPrefix = "group."
|
||||
channelUpdate = channelPrefix + "update"
|
||||
channelRemove = channelPrefix + "remove"
|
||||
)
|
||||
@@ -95,20 +95,8 @@ func decodeUpdateChannel(event map[string]interface{}) updateChannelEvent {
|
||||
}
|
||||
|
||||
func decodeRemoveChannel(event map[string]interface{}) removeEvent {
|
||||
status := read(event, "status", "")
|
||||
st, err := clients.ToStatus(status)
|
||||
if err != nil {
|
||||
return removeEvent{}
|
||||
}
|
||||
switch st {
|
||||
case clients.EnabledStatus:
|
||||
return removeEvent{}
|
||||
case clients.DisabledStatus:
|
||||
return removeEvent{
|
||||
id: read(event, "id", ""),
|
||||
}
|
||||
default:
|
||||
return removeEvent{}
|
||||
return removeEvent{
|
||||
id: read(event, "id", ""),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ const (
|
||||
thingUpdateConnections = thingPrefix + "update_connections"
|
||||
thingDisconnect = thingPrefix + "disconnect"
|
||||
|
||||
channelPrefix = "channel."
|
||||
channelPrefix = "group."
|
||||
channelHandlerRemove = channelPrefix + "remove_handler"
|
||||
channelUpdateHandler = channelPrefix + "update_handler"
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ const (
|
||||
thingUpdateConnections = thingPrefix + "update_connections"
|
||||
thingDisconnect = thingPrefix + "disconnect"
|
||||
|
||||
channelPrefix = "channel."
|
||||
channelPrefix = "group."
|
||||
channelHandlerRemove = channelPrefix + "remove_handler"
|
||||
channelUpdateHandler = channelPrefix + "update_handler"
|
||||
|
||||
|
||||
@@ -81,6 +81,24 @@ var cmdChannels = []cobra.Command{
|
||||
logJSON(c)
|
||||
},
|
||||
},
|
||||
{
|
||||
Use: "delete <channel_id> <user_auth_token>",
|
||||
Short: "Delete channel",
|
||||
Long: "Delete channel by id.\n" +
|
||||
"Usage:\n" +
|
||||
"\tmagistrala-cli channels delete <channel_id> $USERTOKEN - delete the given channel ID\n",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if len(args) != 2 {
|
||||
logUsage(cmd.Use)
|
||||
return
|
||||
}
|
||||
if err := sdk.DeleteChannel(args[0], args[1]); err != nil {
|
||||
logError(err)
|
||||
return
|
||||
}
|
||||
logOK()
|
||||
},
|
||||
},
|
||||
{
|
||||
Use: "update <channel_id> <JSON_string> <user_auth_token>",
|
||||
Short: "Update channel",
|
||||
|
||||
@@ -141,6 +141,24 @@ var cmdGroups = []cobra.Command{
|
||||
logJSON(t)
|
||||
},
|
||||
},
|
||||
{
|
||||
Use: "delete <group_id> <user_auth_token>",
|
||||
Short: "Delete group",
|
||||
Long: "Delete group by id.\n" +
|
||||
"Usage:\n" +
|
||||
"\tmagistrala-cli groups delete <group_id> $USERTOKEN - delete the given group ID\n",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if len(args) != 2 {
|
||||
logUsage(cmd.Use)
|
||||
return
|
||||
}
|
||||
if err := sdk.DeleteGroup(args[0], args[1]); err != nil {
|
||||
logError(err)
|
||||
return
|
||||
}
|
||||
logOK()
|
||||
},
|
||||
},
|
||||
{
|
||||
Use: "assign user <relation> <user_ids> <group_id> <user_auth_token>",
|
||||
Short: "Assign user",
|
||||
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
redisclient "github.com/absmach/magistrala/internal/clients/redis"
|
||||
mggroups "github.com/absmach/magistrala/internal/groups"
|
||||
gapi "github.com/absmach/magistrala/internal/groups/api"
|
||||
gevents "github.com/absmach/magistrala/internal/groups/events"
|
||||
gpostgres "github.com/absmach/magistrala/internal/groups/postgres"
|
||||
gtracing "github.com/absmach/magistrala/internal/groups/tracing"
|
||||
"github.com/absmach/magistrala/internal/postgres"
|
||||
@@ -58,6 +59,8 @@ const (
|
||||
defDB = "things"
|
||||
defSvcHTTPPort = "9000"
|
||||
defSvcAuthGRPCPort = "7000"
|
||||
|
||||
streamID = "magistrala.things"
|
||||
)
|
||||
|
||||
type config struct {
|
||||
@@ -232,6 +235,11 @@ func newService(ctx context.Context, db *sqlx.DB, dbConfig pgclient.Config, auth
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
gsvc, err = gevents.NewEventStoreMiddleware(ctx, gsvc, esURL, streamID)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
csvc = ctracing.New(csvc, tracer)
|
||||
csvc = api.LoggingMiddleware(csvc, logger)
|
||||
counter, latency := internal.MakeMetrics(svcName, "api")
|
||||
|
||||
+3
-1
@@ -55,6 +55,8 @@ const (
|
||||
envPrefixAuth = "MG_AUTH_GRPC_"
|
||||
defDB = "users"
|
||||
defSvcHTTPPort = "9002"
|
||||
|
||||
streamID = "magistrala.users"
|
||||
)
|
||||
|
||||
type config struct {
|
||||
@@ -210,7 +212,7 @@ func newService(ctx context.Context, authClient magistrala.AuthServiceClient, db
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
gsvc, err = gevents.NewEventStoreMiddleware(ctx, gsvc, c.ESURL)
|
||||
gsvc, err = gevents.NewEventStoreMiddleware(ctx, gsvc, c.ESURL, streamID)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
@@ -108,6 +108,7 @@ func EncodeError(_ context.Context, err error, w http.ResponseWriter) {
|
||||
switch {
|
||||
case errors.Contains(err, apiutil.ErrInvalidSecret),
|
||||
errors.Contains(err, svcerr.ErrMalformedEntity),
|
||||
errors.Contains(err, errors.ErrMalformedEntity),
|
||||
errors.Contains(err, apiutil.ErrMissingID),
|
||||
errors.Contains(err, apiutil.ErrEmptyList),
|
||||
errors.Contains(err, apiutil.ErrMissingMemberType),
|
||||
@@ -121,13 +122,14 @@ func EncodeError(_ context.Context, err error, w http.ResponseWriter) {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
case errors.Contains(err, svcerr.ErrNotFound):
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
case errors.Contains(err, svcerr.ErrConflict):
|
||||
case errors.Contains(err, svcerr.ErrConflict),
|
||||
errors.Contains(err, postgres.ErrMemberAlreadyAssigned),
|
||||
errors.Contains(err, errors.ErrConflict):
|
||||
w.WriteHeader(http.StatusConflict)
|
||||
case errors.Contains(err, svcerr.ErrAuthorization),
|
||||
errors.Contains(err, errors.ErrAuthorization),
|
||||
errors.Contains(err, errors.ErrDomainAuthorization):
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
case errors.Contains(err, postgres.ErrMemberAlreadyAssigned):
|
||||
w.WriteHeader(http.StatusConflict)
|
||||
case errors.Contains(err, apiutil.ErrUnsupportedContentType):
|
||||
w.WriteHeader(http.StatusUnsupportedMediaType)
|
||||
case errors.Contains(err, svcerr.ErrCreateEntity),
|
||||
|
||||
@@ -198,6 +198,19 @@ func UnassignMembersEndpoint(svc groups.Service, relation, memberKind string) en
|
||||
}
|
||||
}
|
||||
|
||||
func DeleteGroupEndpoint(svc groups.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
req := request.(groupReq)
|
||||
if err := req.validate(); err != nil {
|
||||
return nil, errors.Wrap(apiutil.ErrValidation, err)
|
||||
}
|
||||
if err := svc.DeleteGroup(ctx, req.token, req.id); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return deleteGroupRes{}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func buildGroupsResponseTree(page groups.Page) groupPageRes {
|
||||
groupsMap := map[string]*groups.Group{}
|
||||
// Parents' map keeps its array of children.
|
||||
|
||||
@@ -161,3 +161,15 @@ func (lm *loggingMiddleware) Unassign(ctx context.Context, token, groupID, relat
|
||||
|
||||
return lm.svc.Unassign(ctx, token, groupID, relation, memberKind, memberIDs...)
|
||||
}
|
||||
|
||||
func (lm *loggingMiddleware) DeleteGroup(ctx context.Context, token, id string) (err error) {
|
||||
defer func(begin time.Time) {
|
||||
message := fmt.Sprintf("Method delete_group for group with id %s using token %s took %s to complete", id, token, time.Since(begin))
|
||||
if err != nil {
|
||||
lm.logger.Warn(fmt.Sprintf("%s with error: %s.", message, err))
|
||||
return
|
||||
}
|
||||
lm.logger.Info(fmt.Sprintf("%s without errors.", message))
|
||||
}(time.Now())
|
||||
return lm.svc.DeleteGroup(ctx, token, id)
|
||||
}
|
||||
|
||||
@@ -119,3 +119,11 @@ func (ms *metricsMiddleware) Unassign(ctx context.Context, token, groupID, relat
|
||||
|
||||
return ms.svc.Unassign(ctx, token, groupID, relation, memberKind, memberIDs...)
|
||||
}
|
||||
|
||||
func (ms *metricsMiddleware) DeleteGroup(ctx context.Context, token, id string) (err error) {
|
||||
defer func(begin time.Time) {
|
||||
ms.counter.With("method", "delete_group").Add(1)
|
||||
ms.latency.With("method", "delete_group").Observe(time.Since(begin).Seconds())
|
||||
}(time.Now())
|
||||
return ms.svc.DeleteGroup(ctx, token, id)
|
||||
}
|
||||
|
||||
@@ -215,3 +215,17 @@ func (res listMembersRes) Headers() map[string]string {
|
||||
func (res listMembersRes) Empty() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
type deleteGroupRes struct{}
|
||||
|
||||
func (res deleteGroupRes) Code() int {
|
||||
return http.StatusNoContent
|
||||
}
|
||||
|
||||
func (res deleteGroupRes) Headers() map[string]string {
|
||||
return map[string]string{}
|
||||
}
|
||||
|
||||
func (res deleteGroupRes) Empty() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -15,18 +15,20 @@ const (
|
||||
groupPrefix = "group."
|
||||
groupCreate = groupPrefix + "create"
|
||||
groupUpdate = groupPrefix + "update"
|
||||
groupRemove = groupPrefix + "remove"
|
||||
groupChangeStatus = groupPrefix + "change_status"
|
||||
groupView = groupPrefix + "view"
|
||||
groupViewPerms = groupPrefix + "view_perms"
|
||||
groupList = groupPrefix + "list"
|
||||
groupListMemberships = groupPrefix + "list_by_user"
|
||||
groupRemove = groupPrefix + "remove"
|
||||
)
|
||||
|
||||
var (
|
||||
_ events.Event = (*createGroupEvent)(nil)
|
||||
_ events.Event = (*updateGroupEvent)(nil)
|
||||
_ events.Event = (*removeGroupEvent)(nil)
|
||||
_ events.Event = (*changeStatusGroupEvent)(nil)
|
||||
_ events.Event = (*viewGroupEvent)(nil)
|
||||
_ events.Event = (*deleteGroupEvent)(nil)
|
||||
_ events.Event = (*viewGroupEvent)(nil)
|
||||
_ events.Event = (*listGroupEvent)(nil)
|
||||
_ events.Event = (*listGroupMembershipEvent)(nil)
|
||||
@@ -115,16 +117,16 @@ func (uge updateGroupEvent) Encode() (map[string]interface{}, error) {
|
||||
return val, nil
|
||||
}
|
||||
|
||||
type removeGroupEvent struct {
|
||||
type changeStatusGroupEvent struct {
|
||||
id string
|
||||
status string
|
||||
updatedAt time.Time
|
||||
updatedBy string
|
||||
}
|
||||
|
||||
func (rge removeGroupEvent) Encode() (map[string]interface{}, error) {
|
||||
func (rge changeStatusGroupEvent) Encode() (map[string]interface{}, error) {
|
||||
return map[string]interface{}{
|
||||
"operation": groupRemove,
|
||||
"operation": groupChangeStatus,
|
||||
"id": rge.id,
|
||||
"status": rge.status,
|
||||
"updated_at": rge.updatedAt,
|
||||
@@ -242,3 +244,14 @@ func (lgme listGroupMembershipEvent) Encode() (map[string]interface{}, error) {
|
||||
|
||||
return val, nil
|
||||
}
|
||||
|
||||
type deleteGroupEvent struct {
|
||||
id string
|
||||
}
|
||||
|
||||
func (rge deleteGroupEvent) Encode() (map[string]interface{}, error) {
|
||||
return map[string]interface{}{
|
||||
"operation": groupRemove,
|
||||
"id": rge.id,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -11,8 +11,6 @@ import (
|
||||
"github.com/absmach/magistrala/pkg/groups"
|
||||
)
|
||||
|
||||
const streamID = "magistrala.users"
|
||||
|
||||
var _ groups.Service = (*eventStore)(nil)
|
||||
|
||||
type eventStore struct {
|
||||
@@ -22,7 +20,7 @@ type eventStore struct {
|
||||
|
||||
// NewEventStoreMiddleware returns wrapper around things service that sends
|
||||
// events to event store.
|
||||
func NewEventStoreMiddleware(ctx context.Context, svc groups.Service, url string) (groups.Service, error) {
|
||||
func NewEventStoreMiddleware(ctx context.Context, svc groups.Service, url, streamID string) (groups.Service, error) {
|
||||
publisher, err := store.NewPublisher(ctx, url, streamID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -138,7 +136,7 @@ func (es eventStore) EnableGroup(ctx context.Context, token, id string) (groups.
|
||||
return group, err
|
||||
}
|
||||
|
||||
return es.delete(ctx, group)
|
||||
return es.changeStatus(ctx, group)
|
||||
}
|
||||
|
||||
func (es eventStore) Assign(ctx context.Context, token, groupID, relation, memberKind string, memberIDs ...string) error {
|
||||
@@ -155,11 +153,11 @@ func (es eventStore) DisableGroup(ctx context.Context, token, id string) (groups
|
||||
return group, err
|
||||
}
|
||||
|
||||
return es.delete(ctx, group)
|
||||
return es.changeStatus(ctx, group)
|
||||
}
|
||||
|
||||
func (es eventStore) delete(ctx context.Context, group groups.Group) (groups.Group, error) {
|
||||
event := removeGroupEvent{
|
||||
func (es eventStore) changeStatus(ctx context.Context, group groups.Group) (groups.Group, error) {
|
||||
event := changeStatusGroupEvent{
|
||||
id: group.ID,
|
||||
updatedAt: group.UpdatedAt,
|
||||
updatedBy: group.UpdatedBy,
|
||||
@@ -172,3 +170,13 @@ func (es eventStore) delete(ctx context.Context, group groups.Group) (groups.Gro
|
||||
|
||||
return group, nil
|
||||
}
|
||||
|
||||
func (es eventStore) DeleteGroup(ctx context.Context, token, id string) error {
|
||||
if err := es.svc.DeleteGroup(ctx, token, id); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := es.Publish(ctx, deleteGroupEvent{id}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -97,3 +97,11 @@ func (m *Repository) AssignParentGroup(ctx context.Context, parentGroupID string
|
||||
|
||||
return ret.Error(0)
|
||||
}
|
||||
|
||||
func (m *Repository) Delete(ctx context.Context, groupID string) error {
|
||||
ret := m.Called(ctx, groupID)
|
||||
if groupID == WrongID {
|
||||
return repoerr.ErrNotFound
|
||||
}
|
||||
return ret.Error(0)
|
||||
}
|
||||
|
||||
@@ -303,6 +303,14 @@ func (repo groupRepository) UnassignParentGroup(ctx context.Context, parentGroup
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo groupRepository) Delete(ctx context.Context, groupID string) error {
|
||||
q := "DELETE FROM groups AS g WHERE g.id = $1 ;"
|
||||
if _, err := repo.db.ExecContext(ctx, q, groupID); err != nil {
|
||||
return postgres.HandleError(repoerr.ErrRemoveEntity, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func buildHierachy(gm mggroups.Page) string {
|
||||
query := ""
|
||||
switch {
|
||||
|
||||
@@ -26,7 +26,7 @@ func Migration() *migrate.MemoryMigrationSource {
|
||||
updated_by VARCHAR(254),
|
||||
status SMALLINT NOT NULL DEFAULT 0 CHECK (status >= 0),
|
||||
UNIQUE (owner_id, name),
|
||||
FOREIGN KEY (parent_id) REFERENCES groups (id) ON DELETE CASCADE
|
||||
FOREIGN KEY (parent_id) REFERENCES groups (id) ON DELETE SET NULL
|
||||
)`,
|
||||
},
|
||||
Down: []string{
|
||||
|
||||
@@ -463,7 +463,7 @@ func (svc service) assignParentGroup(ctx context.Context, domain, parentGroupID
|
||||
var deletePolicies magistrala.DeletePoliciesReq
|
||||
for _, group := range groupsPage.Groups {
|
||||
if group.Parent != "" {
|
||||
return fmt.Errorf("%s group already have parent", group.ID)
|
||||
return errors.Wrap(errors.ErrConflict, fmt.Errorf("%s group already have parent", group.ID))
|
||||
}
|
||||
addPolicies.AddPoliciesReq = append(addPolicies.AddPoliciesReq, &magistrala.AddPolicyReq{
|
||||
Domain: domain,
|
||||
@@ -601,6 +601,59 @@ func (svc service) Unassign(ctx context.Context, token, groupID, relation, membe
|
||||
return nil
|
||||
}
|
||||
|
||||
func (svc service) DeleteGroup(ctx context.Context, token, groupID string) error {
|
||||
res, err := svc.identify(ctx, token)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := svc.authorizeKind(ctx, auth.UserType, auth.UsersKind, res.GetId(), auth.DeletePermission, auth.GroupType, groupID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Remove policy of child groups
|
||||
if _, err := svc.auth.DeletePolicy(ctx, &magistrala.DeletePolicyReq{
|
||||
SubjectType: auth.GroupType,
|
||||
Subject: groupID,
|
||||
ObjectType: auth.GroupType,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Remove policy of things
|
||||
if _, err := svc.auth.DeletePolicy(ctx, &magistrala.DeletePolicyReq{
|
||||
SubjectType: auth.GroupType,
|
||||
Subject: groupID,
|
||||
ObjectType: auth.ThingType,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Remove policy from domain
|
||||
if _, err := svc.auth.DeletePolicy(ctx, &magistrala.DeletePolicyReq{
|
||||
SubjectType: auth.DomainType,
|
||||
Object: groupID,
|
||||
ObjectType: auth.GroupType,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Remove group from database
|
||||
if err := svc.groups.Delete(ctx, groupID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Remove policy of users
|
||||
if _, err := svc.auth.DeletePolicy(ctx, &magistrala.DeletePolicyReq{
|
||||
SubjectType: auth.UserType,
|
||||
Object: groupID,
|
||||
ObjectType: auth.GroupType,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (svc service) filterAllowedGroupIDsOfUserID(ctx context.Context, userID, permission string, groupIDs []string) ([]string, error) {
|
||||
var ids []string
|
||||
allowedIDs, err := svc.listAllGroupsOfUserID(ctx, userID, permission)
|
||||
|
||||
@@ -102,3 +102,11 @@ func (tm *tracingMiddleware) Unassign(ctx context.Context, token, groupID, relat
|
||||
|
||||
return tm.gsvc.Unassign(ctx, token, groupID, relation, memberKind, memberIDs...)
|
||||
}
|
||||
|
||||
// DeleteGroup traces the "DeleteGroup" operation of the wrapped groups.Service.
|
||||
func (tm *tracingMiddleware) DeleteGroup(ctx context.Context, token, id string) error {
|
||||
ctx, span := tm.tracer.Start(ctx, "svc_delete_group", trace.WithAttributes(attribute.String("id", id)))
|
||||
defer span.End()
|
||||
|
||||
return tm.gsvc.DeleteGroup(ctx, token, id)
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ const (
|
||||
thingConnect = thingPrefix + "connect"
|
||||
thingDisconnect = thingPrefix + "disconnect"
|
||||
|
||||
channelPrefix = "channel."
|
||||
channelPrefix = "group."
|
||||
channelCreate = channelPrefix + "create"
|
||||
channelUpdate = channelPrefix + "update"
|
||||
channelRemove = channelPrefix + "remove"
|
||||
|
||||
@@ -24,7 +24,7 @@ const (
|
||||
thingConnect = thingPrefix + "connect"
|
||||
thingDisconnect = thingPrefix + "disconnect"
|
||||
|
||||
channelPrefix = "channel."
|
||||
channelPrefix = "group."
|
||||
channelCreate = channelPrefix + "create"
|
||||
channelUpdate = channelPrefix + "update"
|
||||
channelRemove = channelPrefix + "remove"
|
||||
|
||||
@@ -85,9 +85,14 @@ type Repository interface {
|
||||
// ChangeStatus changes groups status to active or inactive
|
||||
ChangeStatus(ctx context.Context, group Group) (Group, error)
|
||||
|
||||
// AssignParentGroup assigns parent group id to a given group id
|
||||
AssignParentGroup(ctx context.Context, parentGroupID string, groupIDs ...string) error
|
||||
|
||||
// UnassignParentGroup unassign parent group id fr given group id
|
||||
UnassignParentGroup(ctx context.Context, parentGroupID string, groupIDs ...string) error
|
||||
|
||||
// Delete a group
|
||||
Delete(ctx context.Context, groupID string) error
|
||||
}
|
||||
|
||||
type Service interface {
|
||||
@@ -115,6 +120,9 @@ type Service interface {
|
||||
// DisableGroup logically disables the group identified with the provided ID.
|
||||
DisableGroup(ctx context.Context, token, id string) (Group, error)
|
||||
|
||||
// DeleteGroup delete the given group id
|
||||
DeleteGroup(ctx context.Context, token, id string) error
|
||||
|
||||
// Assign member to group
|
||||
Assign(ctx context.Context, token, groupID, relation, memberKind string, memberIDs ...string) (err error)
|
||||
|
||||
|
||||
@@ -295,6 +295,12 @@ func (sdk mgSDK) DisableChannel(id, token string) (Channel, errors.SDKError) {
|
||||
return sdk.changeChannelStatus(id, disableEndpoint, token)
|
||||
}
|
||||
|
||||
func (sdk mgSDK) DeleteChannel(id, token string) errors.SDKError {
|
||||
url := fmt.Sprintf("%s/%s/%s", sdk.thingsURL, channelsEndpoint, id)
|
||||
_, _, sdkerr := sdk.processRequest(http.MethodDelete, url, token, nil, nil, http.StatusNoContent)
|
||||
return sdkerr
|
||||
}
|
||||
|
||||
func (sdk mgSDK) changeChannelStatus(id, status, token string) (Channel, errors.SDKError) {
|
||||
url := fmt.Sprintf("%s/%s/%s/%s", sdk.thingsURL, channelsEndpoint, id, status)
|
||||
|
||||
|
||||
@@ -755,6 +755,48 @@ func TestDisableChannel(t *testing.T) {
|
||||
repoCall2.Unset()
|
||||
}
|
||||
|
||||
func TestDeleteChannel(t *testing.T) {
|
||||
ts, grepo, auth := newChannelsServer()
|
||||
defer ts.Close()
|
||||
|
||||
conf := sdk.Config{
|
||||
ThingsURL: ts.URL,
|
||||
}
|
||||
mgsdk := sdk.NewSDK(conf)
|
||||
|
||||
creationTime := time.Now().UTC()
|
||||
channel := sdk.Channel{
|
||||
ID: generateUUID(t),
|
||||
Name: gName,
|
||||
OwnerID: generateUUID(t),
|
||||
CreatedAt: creationTime,
|
||||
UpdatedAt: creationTime,
|
||||
Status: mgclients.Enabled,
|
||||
}
|
||||
|
||||
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, nil)
|
||||
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: false}, nil)
|
||||
repoCall2 := grepo.On("Delete", mock.Anything, mock.Anything).Return(nil)
|
||||
err := mgsdk.DeleteChannel("wrongID", validToken)
|
||||
assert.Equal(t, err, errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden), fmt.Sprintf("Delete channel with wrong id: expected %v got %v", svcerr.ErrNotFound, err))
|
||||
repoCall.Unset()
|
||||
repoCall1.Unset()
|
||||
repoCall2.Unset()
|
||||
|
||||
repoCall = auth.On("DeletePolicy", mock.Anything, mock.Anything, mock.Anything).Return(&magistrala.DeletePolicyRes{Deleted: true}, nil)
|
||||
repoCall1 = auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, nil)
|
||||
repoCall2 = auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
|
||||
repoCall3 := grepo.On("Delete", mock.Anything, mock.Anything).Return(nil)
|
||||
err = mgsdk.DeleteChannel(channel.ID, validToken)
|
||||
assert.Nil(t, err, fmt.Sprintf("Delete channel with correct id: expected %v got %v", nil, err))
|
||||
ok := repoCall3.Parent.AssertCalled(t, "Delete", mock.Anything, channel.ID)
|
||||
assert.True(t, ok, "Delete was not called on deleting channel with correct id")
|
||||
repoCall.Unset()
|
||||
repoCall1.Unset()
|
||||
repoCall2.Unset()
|
||||
repoCall3.Unset()
|
||||
}
|
||||
|
||||
func toIDs(objects interface{}) []string {
|
||||
v := reflect.ValueOf(objects)
|
||||
if v.Kind() != reflect.Slice {
|
||||
|
||||
@@ -220,6 +220,12 @@ func (sdk mgSDK) ListGroupChannels(groupID string, pm PageMetadata, token string
|
||||
return gp, nil
|
||||
}
|
||||
|
||||
func (sdk mgSDK) DeleteGroup(id, token string) errors.SDKError {
|
||||
url := fmt.Sprintf("%s/%s/%s", sdk.usersURL, groupsEndpoint, id)
|
||||
_, _, sdkerr := sdk.processRequest(http.MethodDelete, url, token, nil, nil, http.StatusNoContent)
|
||||
return sdkerr
|
||||
}
|
||||
|
||||
func (sdk mgSDK) changeGroupStatus(id, status, token string) (Group, errors.SDKError) {
|
||||
url := fmt.Sprintf("%s/%s/%s/%s", sdk.usersURL, groupsEndpoint, id, status)
|
||||
|
||||
|
||||
@@ -889,3 +889,45 @@ func TestDisableGroup(t *testing.T) {
|
||||
repoCall1.Unset()
|
||||
repoCall2.Unset()
|
||||
}
|
||||
|
||||
func TestDeleteGroup(t *testing.T) {
|
||||
ts, grepo, auth := newGroupsServer()
|
||||
defer ts.Close()
|
||||
|
||||
conf := sdk.Config{
|
||||
UsersURL: ts.URL,
|
||||
}
|
||||
mgsdk := sdk.NewSDK(conf)
|
||||
|
||||
creationTime := time.Now().UTC()
|
||||
group := sdk.Group{
|
||||
ID: generateUUID(t),
|
||||
Name: gName,
|
||||
OwnerID: generateUUID(t),
|
||||
CreatedAt: creationTime,
|
||||
UpdatedAt: creationTime,
|
||||
Status: clients.Enabled,
|
||||
}
|
||||
|
||||
repoCall := auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, nil)
|
||||
repoCall1 := auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: false}, nil)
|
||||
repoCall2 := grepo.On("Delete", mock.Anything, mock.Anything).Return(nil)
|
||||
err := mgsdk.DeleteGroup("wrongID", validToken)
|
||||
assert.Equal(t, err, errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden), fmt.Sprintf("Delete group with wrong id: expected %v got %v", svcerr.ErrNotFound, err))
|
||||
repoCall.Unset()
|
||||
repoCall1.Unset()
|
||||
repoCall2.Unset()
|
||||
|
||||
repoCall = auth.On("DeletePolicy", mock.Anything, mock.Anything, mock.Anything).Return(&magistrala.DeletePolicyRes{Deleted: true}, nil)
|
||||
repoCall1 = auth.On("Identify", mock.Anything, &magistrala.IdentityReq{Token: validToken}).Return(&magistrala.IdentityRes{Id: validID, DomainId: testsutil.GenerateUUID(t)}, nil)
|
||||
repoCall2 = auth.On("Authorize", mock.Anything, mock.Anything).Return(&magistrala.AuthorizeRes{Authorized: true}, nil)
|
||||
repoCall3 := grepo.On("Delete", mock.Anything, mock.Anything).Return(nil)
|
||||
err = mgsdk.DeleteGroup(group.ID, validToken)
|
||||
assert.Nil(t, err, fmt.Sprintf("Delete group with correct id: expected %v got %v", nil, err))
|
||||
ok := repoCall3.Parent.AssertCalled(t, "Delete", mock.Anything, group.ID)
|
||||
assert.True(t, ok, "Delete was not called on deleting group with correct id")
|
||||
repoCall.Unset()
|
||||
repoCall1.Unset()
|
||||
repoCall2.Unset()
|
||||
repoCall3.Unset()
|
||||
}
|
||||
|
||||
@@ -590,6 +590,13 @@ type SDK interface {
|
||||
// fmt.Println(groups)
|
||||
ListGroupChannels(groupID string, pm PageMetadata, token string) (GroupsPage, errors.SDKError)
|
||||
|
||||
// DeleteGroup delete given group id.
|
||||
//
|
||||
// example:
|
||||
// err := sdk.DeleteGroup("groupID", "token")
|
||||
// fmt.Println(err)
|
||||
DeleteGroup(id, token string) errors.SDKError
|
||||
|
||||
// CreateChannel creates new channel and returns its id.
|
||||
//
|
||||
// example:
|
||||
@@ -756,6 +763,13 @@ type SDK interface {
|
||||
// fmt.Println(groups)
|
||||
ListChannelUserGroups(channelID string, pm PageMetadata, token string) (GroupsPage, errors.SDKError)
|
||||
|
||||
// DeleteChannel delete given group id.
|
||||
//
|
||||
// example:
|
||||
// err := sdk.DeleteChannel("channelID", "token")
|
||||
// fmt.Println(err)
|
||||
DeleteChannel(id, token string) errors.SDKError
|
||||
|
||||
// Connect bulk connects things to channels specified by id.
|
||||
//
|
||||
// example:
|
||||
|
||||
@@ -700,6 +700,46 @@ func (_m *SDK) CreateUser(user sdk.User, token string) (sdk.User, errors.SDKErro
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// DeleteChannel provides a mock function with given fields: id, token
|
||||
func (_m *SDK) DeleteChannel(id string, token string) errors.SDKError {
|
||||
ret := _m.Called(id, token)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for DeleteChannel")
|
||||
}
|
||||
|
||||
var r0 errors.SDKError
|
||||
if rf, ok := ret.Get(0).(func(string, string) errors.SDKError); ok {
|
||||
r0 = rf(id, token)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(errors.SDKError)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// DeleteGroup provides a mock function with given fields: id, token
|
||||
func (_m *SDK) DeleteGroup(id string, token string) errors.SDKError {
|
||||
ret := _m.Called(id, token)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for DeleteGroup")
|
||||
}
|
||||
|
||||
var r0 errors.SDKError
|
||||
if rf, ok := ret.Get(0).(func(string, string) errors.SDKError); ok {
|
||||
r0 = rf(id, token)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(errors.SDKError)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// DeleteInvitation provides a mock function with given fields: userID, domainID, token
|
||||
func (_m *SDK) DeleteInvitation(userID string, domainID string, token string) error {
|
||||
ret := _m.Called(userID, domainID, token)
|
||||
|
||||
@@ -40,6 +40,13 @@ func groupsHandler(svc groups.Service, r *chi.Mux, logger mglog.Logger) http.Han
|
||||
opts...,
|
||||
), "view_channel").ServeHTTP)
|
||||
|
||||
r.Delete("/{groupID}", otelhttp.NewHandler(kithttp.NewServer(
|
||||
gapi.DeleteGroupEndpoint(svc),
|
||||
gapi.DecodeGroupRequest,
|
||||
api.EncodeResponse,
|
||||
opts...,
|
||||
), "delete_channel").ServeHTTP)
|
||||
|
||||
r.Get("/{groupID}/permissions", otelhttp.NewHandler(kithttp.NewServer(
|
||||
gapi.ViewGroupPermsEndpoint(svc),
|
||||
gapi.DecodeGroupPermsRequest,
|
||||
|
||||
@@ -42,6 +42,13 @@ func groupsHandler(svc groups.Service, r *chi.Mux, logger mglog.Logger) http.Han
|
||||
opts...,
|
||||
), "view_group").ServeHTTP)
|
||||
|
||||
r.Delete("/{groupID}", otelhttp.NewHandler(kithttp.NewServer(
|
||||
gapi.DeleteGroupEndpoint(svc),
|
||||
gapi.DecodeGroupRequest,
|
||||
api.EncodeResponse,
|
||||
opts...,
|
||||
), "delete_group").ServeHTTP)
|
||||
|
||||
r.Get("/{groupID}/permissions", otelhttp.NewHandler(kithttp.NewServer(
|
||||
gapi.ViewGroupPermsEndpoint(svc),
|
||||
gapi.DecodeGroupPermsRequest,
|
||||
|
||||
Reference in New Issue
Block a user