mirror of
https://github.com/absmach/supermq.git
synced 2026-06-23 07:20:19 +00:00
ee3716623c
Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com> Signed-off-by: Rodney Osodo <socials@rodneyosodo.com> Signed-off-by: rodneyosodo <blackd0t@protonmail.com>
2584 lines
76 KiB
Go
2584 lines
76 KiB
Go
// Copyright (c) Abstract Machines
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package groups_test
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/0x6flab/namegenerator"
|
|
"github.com/absmach/magistrala"
|
|
"github.com/absmach/magistrala/auth"
|
|
authmocks "github.com/absmach/magistrala/auth/mocks"
|
|
"github.com/absmach/magistrala/internal/groups"
|
|
"github.com/absmach/magistrala/internal/testsutil"
|
|
"github.com/absmach/magistrala/pkg/apiutil"
|
|
"github.com/absmach/magistrala/pkg/clients"
|
|
"github.com/absmach/magistrala/pkg/errors"
|
|
repoerr "github.com/absmach/magistrala/pkg/errors/repository"
|
|
svcerr "github.com/absmach/magistrala/pkg/errors/service"
|
|
mggroups "github.com/absmach/magistrala/pkg/groups"
|
|
"github.com/absmach/magistrala/pkg/groups/mocks"
|
|
"github.com/absmach/magistrala/pkg/uuid"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/mock"
|
|
)
|
|
|
|
var (
|
|
idProvider = uuid.New()
|
|
token = "token"
|
|
namegen = namegenerator.NewGenerator()
|
|
validGroup = mggroups.Group{
|
|
Name: namegen.Generate(),
|
|
Description: namegen.Generate(),
|
|
Metadata: map[string]interface{}{
|
|
"key": "value",
|
|
},
|
|
Status: clients.Status(groups.EnabledStatus),
|
|
}
|
|
allowedIDs = []string{
|
|
testsutil.GenerateUUID(&testing.T{}),
|
|
testsutil.GenerateUUID(&testing.T{}),
|
|
testsutil.GenerateUUID(&testing.T{}),
|
|
}
|
|
)
|
|
|
|
func TestCreateGroup(t *testing.T) {
|
|
repo := new(mocks.Repository)
|
|
authsvc := new(authmocks.AuthClient)
|
|
svc := groups.NewService(repo, idProvider, authsvc)
|
|
|
|
cases := []struct {
|
|
desc string
|
|
token string
|
|
kind string
|
|
group mggroups.Group
|
|
idResp *magistrala.IdentityRes
|
|
idErr error
|
|
authzResp *magistrala.AuthorizeRes
|
|
authzErr error
|
|
authzTknResp *magistrala.AuthorizeRes
|
|
authzTknErr error
|
|
repoResp mggroups.Group
|
|
repoErr error
|
|
addPolResp *magistrala.AddPoliciesRes
|
|
addPolErr error
|
|
deletePolResp *magistrala.DeletePolicyRes
|
|
deletePolErr error
|
|
err error
|
|
}{
|
|
{
|
|
desc: "successfully",
|
|
token: token,
|
|
kind: auth.NewGroupKind,
|
|
group: validGroup,
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
authzTknResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
repoResp: mggroups.Group{
|
|
ID: testsutil.GenerateUUID(t),
|
|
CreatedAt: time.Now(),
|
|
Domain: testsutil.GenerateUUID(t),
|
|
},
|
|
addPolResp: &magistrala.AddPoliciesRes{
|
|
Added: true,
|
|
},
|
|
},
|
|
{
|
|
desc: "with invalid token",
|
|
token: token,
|
|
kind: auth.NewGroupKind,
|
|
group: validGroup,
|
|
idResp: &magistrala.IdentityRes{},
|
|
idErr: svcerr.ErrAuthentication,
|
|
err: svcerr.ErrAuthentication,
|
|
},
|
|
{
|
|
desc: "with empty id or domain id but with no grpc error",
|
|
token: token,
|
|
kind: auth.NewGroupKind,
|
|
group: validGroup,
|
|
idResp: &magistrala.IdentityRes{},
|
|
idErr: nil,
|
|
err: svcerr.ErrDomainAuthorization,
|
|
},
|
|
{
|
|
desc: "with failed to authorize domain membership",
|
|
token: token,
|
|
kind: auth.NewGroupKind,
|
|
group: validGroup,
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: false,
|
|
},
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
{
|
|
desc: "with failed to authorize domain membership with grpc error",
|
|
token: token,
|
|
kind: auth.NewGroupKind,
|
|
group: validGroup,
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: false,
|
|
},
|
|
authzErr: svcerr.ErrAuthorization,
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
{
|
|
desc: "with invalid status",
|
|
token: token,
|
|
kind: auth.NewGroupKind,
|
|
group: mggroups.Group{
|
|
Name: namegen.Generate(),
|
|
Description: namegen.Generate(),
|
|
Status: clients.Status(100),
|
|
},
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
err: svcerr.ErrInvalidStatus,
|
|
},
|
|
{
|
|
desc: "successfully with parent",
|
|
token: token,
|
|
kind: auth.NewGroupKind,
|
|
group: mggroups.Group{
|
|
Name: namegen.Generate(),
|
|
Description: namegen.Generate(),
|
|
Status: clients.Status(groups.EnabledStatus),
|
|
Parent: testsutil.GenerateUUID(t),
|
|
},
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
authzTknResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
repoResp: mggroups.Group{
|
|
ID: testsutil.GenerateUUID(t),
|
|
CreatedAt: time.Now(),
|
|
Domain: testsutil.GenerateUUID(t),
|
|
Parent: testsutil.GenerateUUID(t),
|
|
},
|
|
addPolResp: &magistrala.AddPoliciesRes{
|
|
Added: true,
|
|
},
|
|
},
|
|
{
|
|
desc: "unsuccessfully with parent due to authorization error",
|
|
token: token,
|
|
kind: auth.NewGroupKind,
|
|
group: mggroups.Group{
|
|
Name: namegen.Generate(),
|
|
Description: namegen.Generate(),
|
|
Status: clients.Status(groups.EnabledStatus),
|
|
Parent: testsutil.GenerateUUID(t),
|
|
},
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
authzTknResp: &magistrala.AuthorizeRes{},
|
|
authzTknErr: svcerr.ErrAuthorization,
|
|
repoResp: mggroups.Group{
|
|
ID: testsutil.GenerateUUID(t),
|
|
Parent: testsutil.GenerateUUID(t),
|
|
},
|
|
addPolResp: &magistrala.AddPoliciesRes{
|
|
Added: true,
|
|
},
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
{
|
|
desc: "with repo error",
|
|
token: token,
|
|
kind: auth.NewGroupKind,
|
|
group: validGroup,
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
authzTknResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
repoResp: mggroups.Group{},
|
|
repoErr: errors.ErrMalformedEntity,
|
|
err: errors.ErrMalformedEntity,
|
|
},
|
|
{
|
|
desc: "with failed to add policies",
|
|
token: token,
|
|
kind: auth.NewGroupKind,
|
|
group: validGroup,
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
authzTknResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
repoResp: mggroups.Group{
|
|
ID: testsutil.GenerateUUID(t),
|
|
},
|
|
addPolResp: &magistrala.AddPoliciesRes{},
|
|
addPolErr: svcerr.ErrAuthorization,
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
{
|
|
desc: "with failed to delete policies response",
|
|
token: token,
|
|
kind: auth.NewGroupKind,
|
|
group: mggroups.Group{
|
|
Name: namegen.Generate(),
|
|
Description: namegen.Generate(),
|
|
Status: clients.Status(groups.EnabledStatus),
|
|
Parent: testsutil.GenerateUUID(t),
|
|
},
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
authzTknResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
repoErr: errors.ErrMalformedEntity,
|
|
addPolResp: &magistrala.AddPoliciesRes{Added: true},
|
|
deletePolErr: svcerr.ErrAuthorization,
|
|
err: errors.ErrMalformedEntity,
|
|
},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
t.Run(tc.desc, func(t *testing.T) {
|
|
authcall := authsvc.On("Identify", context.Background(), &magistrala.IdentityReq{Token: tc.token}).Return(tc.idResp, tc.idErr)
|
|
authcall1 := authsvc.On("Authorize", context.Background(), &magistrala.AuthorizeReq{
|
|
SubjectType: auth.UserType,
|
|
SubjectKind: auth.UsersKind,
|
|
Subject: tc.idResp.GetId(),
|
|
Permission: auth.CreatePermission,
|
|
Object: tc.idResp.GetDomainId(),
|
|
ObjectType: auth.DomainType,
|
|
}).Return(tc.authzResp, tc.authzErr)
|
|
authcall2 := authsvc.On("Authorize", context.Background(), &magistrala.AuthorizeReq{
|
|
SubjectType: auth.UserType,
|
|
SubjectKind: auth.TokenKind,
|
|
Subject: tc.token,
|
|
Permission: auth.EditPermission,
|
|
Object: tc.group.Parent,
|
|
ObjectType: auth.GroupType,
|
|
}).Return(tc.authzTknResp, tc.authzTknErr)
|
|
repocall := repo.On("Save", context.Background(), mock.Anything).Return(tc.repoResp, tc.repoErr)
|
|
authcall3 := authsvc.On("AddPolicies", context.Background(), mock.Anything).Return(tc.addPolResp, tc.addPolErr)
|
|
authCall4 := authsvc.On("DeletePolicies", mock.Anything, mock.Anything).Return(tc.deletePolResp, tc.deletePolErr)
|
|
got, err := svc.CreateGroup(context.Background(), tc.token, tc.kind, tc.group)
|
|
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("expected error %v to contain %v", err, tc.err))
|
|
if err == nil {
|
|
assert.NotEmpty(t, got.ID)
|
|
assert.NotEmpty(t, got.CreatedAt)
|
|
assert.NotEmpty(t, got.Domain)
|
|
assert.WithinDuration(t, time.Now(), got.CreatedAt, 2*time.Second)
|
|
ok := repocall.Parent.AssertCalled(t, "Save", context.Background(), mock.Anything)
|
|
assert.True(t, ok, fmt.Sprintf("Save was not called on %s", tc.desc))
|
|
}
|
|
authcall.Unset()
|
|
authcall1.Unset()
|
|
authcall2.Unset()
|
|
repocall.Unset()
|
|
authcall3.Unset()
|
|
authCall4.Unset()
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestViewGroup(t *testing.T) {
|
|
repo := new(mocks.Repository)
|
|
authsvc := new(authmocks.AuthClient)
|
|
svc := groups.NewService(repo, idProvider, authsvc)
|
|
|
|
cases := []struct {
|
|
desc string
|
|
token string
|
|
id string
|
|
authzResp *magistrala.AuthorizeRes
|
|
authzErr error
|
|
repoResp mggroups.Group
|
|
repoErr error
|
|
err error
|
|
}{
|
|
{
|
|
desc: "successfully",
|
|
token: token,
|
|
id: testsutil.GenerateUUID(t),
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
repoResp: validGroup,
|
|
},
|
|
{
|
|
desc: "with invalid token",
|
|
token: token,
|
|
id: testsutil.GenerateUUID(t),
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: false,
|
|
},
|
|
authzErr: svcerr.ErrAuthorization,
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
{
|
|
desc: "with failed to authorize",
|
|
token: token,
|
|
id: testsutil.GenerateUUID(t),
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: false,
|
|
},
|
|
authzErr: nil,
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
t.Run(tc.desc, func(t *testing.T) {
|
|
authsvc.On("Authorize", context.Background(), &magistrala.AuthorizeReq{
|
|
SubjectType: auth.UserType,
|
|
SubjectKind: auth.TokenKind,
|
|
Subject: tc.token,
|
|
Permission: auth.ViewPermission,
|
|
Object: tc.id,
|
|
ObjectType: auth.GroupType,
|
|
}).Return(tc.authzResp, tc.authzErr)
|
|
repo.On("RetrieveByID", context.Background(), tc.id).Return(tc.repoResp, tc.repoErr)
|
|
got, err := svc.ViewGroup(context.Background(), tc.token, tc.id)
|
|
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("expected error %v to contain %v", err, tc.err))
|
|
if err == nil {
|
|
assert.Equal(t, tc.repoResp, got)
|
|
ok := repo.AssertCalled(t, "RetrieveByID", context.Background(), tc.id)
|
|
assert.True(t, ok, fmt.Sprintf("RetrieveByID was not called on %s", tc.desc))
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestViewGroupPerms(t *testing.T) {
|
|
repo := new(mocks.Repository)
|
|
authsvc := new(authmocks.AuthClient)
|
|
svc := groups.NewService(repo, idProvider, authsvc)
|
|
|
|
cases := []struct {
|
|
desc string
|
|
token string
|
|
id string
|
|
idResp *magistrala.IdentityRes
|
|
idErr error
|
|
listResp *magistrala.ListPermissionsRes
|
|
listErr error
|
|
err error
|
|
}{
|
|
{
|
|
desc: "successfully",
|
|
token: token,
|
|
id: testsutil.GenerateUUID(t),
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
listResp: &magistrala.ListPermissionsRes{
|
|
Permissions: []string{
|
|
auth.ViewPermission,
|
|
auth.EditPermission,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "with invalid token",
|
|
token: token,
|
|
id: testsutil.GenerateUUID(t),
|
|
idResp: &magistrala.IdentityRes{},
|
|
idErr: svcerr.ErrAuthentication,
|
|
err: svcerr.ErrAuthentication,
|
|
},
|
|
{
|
|
desc: "with failed to list permissions",
|
|
token: token,
|
|
id: testsutil.GenerateUUID(t),
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
listErr: svcerr.ErrAuthorization,
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
{
|
|
desc: "with empty permissions",
|
|
token: token,
|
|
id: testsutil.GenerateUUID(t),
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
listResp: &magistrala.ListPermissionsRes{
|
|
Permissions: []string{},
|
|
},
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
t.Run(tc.desc, func(t *testing.T) {
|
|
authcall := authsvc.On("Identify", context.Background(), &magistrala.IdentityReq{Token: tc.token}).Return(tc.idResp, tc.idErr)
|
|
authcall1 := authsvc.On("ListPermissions", context.Background(), &magistrala.ListPermissionsReq{
|
|
SubjectType: auth.UserType,
|
|
Subject: tc.idResp.GetId(),
|
|
Object: tc.id,
|
|
ObjectType: auth.GroupType,
|
|
}).Return(tc.listResp, tc.listErr)
|
|
got, err := svc.ViewGroupPerms(context.Background(), tc.token, tc.id)
|
|
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("expected error %v to contain %v", err, tc.err))
|
|
if err == nil {
|
|
assert.Equal(t, tc.listResp.Permissions, got)
|
|
}
|
|
authcall.Unset()
|
|
authcall1.Unset()
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestUpdateGroup(t *testing.T) {
|
|
repo := new(mocks.Repository)
|
|
authsvc := new(authmocks.AuthClient)
|
|
svc := groups.NewService(repo, idProvider, authsvc)
|
|
|
|
cases := []struct {
|
|
desc string
|
|
token string
|
|
group mggroups.Group
|
|
authzResp *magistrala.AuthorizeRes
|
|
authzErr error
|
|
repoResp mggroups.Group
|
|
repoErr error
|
|
err error
|
|
}{
|
|
{
|
|
desc: "successfully",
|
|
token: token,
|
|
group: mggroups.Group{
|
|
ID: testsutil.GenerateUUID(t),
|
|
Name: namegen.Generate(),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
repoResp: validGroup,
|
|
},
|
|
{
|
|
desc: "with invalid token",
|
|
token: token,
|
|
group: mggroups.Group{
|
|
ID: testsutil.GenerateUUID(t),
|
|
Name: namegen.Generate(),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: false,
|
|
},
|
|
authzErr: svcerr.ErrAuthorization,
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
{
|
|
desc: "with failed to authorize",
|
|
token: token,
|
|
group: mggroups.Group{
|
|
ID: testsutil.GenerateUUID(t),
|
|
Name: namegen.Generate(),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: false,
|
|
},
|
|
authzErr: nil,
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
t.Run(tc.desc, func(t *testing.T) {
|
|
authsvc.On("Authorize", context.Background(), &magistrala.AuthorizeReq{
|
|
SubjectType: auth.UserType,
|
|
SubjectKind: auth.TokenKind,
|
|
Subject: tc.token,
|
|
Permission: auth.EditPermission,
|
|
Object: tc.group.ID,
|
|
ObjectType: auth.GroupType,
|
|
}).Return(tc.authzResp, tc.authzErr)
|
|
repo.On("Update", context.Background(), mock.Anything).Return(tc.repoResp, tc.repoErr)
|
|
got, err := svc.UpdateGroup(context.Background(), tc.token, tc.group)
|
|
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("expected error %v to contain %v", err, tc.err))
|
|
if err == nil {
|
|
assert.Equal(t, tc.repoResp, got)
|
|
ok := repo.AssertCalled(t, "Update", context.Background(), mock.Anything)
|
|
assert.True(t, ok, fmt.Sprintf("Update was not called on %s", tc.desc))
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestEnableGroup(t *testing.T) {
|
|
repo := new(mocks.Repository)
|
|
authsvc := new(authmocks.AuthClient)
|
|
svc := groups.NewService(repo, idProvider, authsvc)
|
|
|
|
cases := []struct {
|
|
desc string
|
|
token string
|
|
id string
|
|
authzResp *magistrala.AuthorizeRes
|
|
authzErr error
|
|
retrieveResp mggroups.Group
|
|
retrieveErr error
|
|
changeResp mggroups.Group
|
|
changeErr error
|
|
err error
|
|
}{
|
|
{
|
|
desc: "successfully",
|
|
token: token,
|
|
id: testsutil.GenerateUUID(t),
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
retrieveResp: mggroups.Group{
|
|
Status: clients.Status(groups.DisabledStatus),
|
|
},
|
|
changeResp: validGroup,
|
|
},
|
|
{
|
|
desc: "with invalid token",
|
|
token: token,
|
|
id: testsutil.GenerateUUID(t),
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: false,
|
|
},
|
|
authzErr: svcerr.ErrAuthorization,
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
{
|
|
desc: "with failed to authorize",
|
|
token: token,
|
|
id: testsutil.GenerateUUID(t),
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: false,
|
|
},
|
|
authzErr: nil,
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
{
|
|
desc: "with enabled group",
|
|
token: token,
|
|
id: testsutil.GenerateUUID(t),
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
retrieveResp: mggroups.Group{
|
|
Status: clients.Status(groups.EnabledStatus),
|
|
},
|
|
err: errors.ErrStatusAlreadyAssigned,
|
|
},
|
|
{
|
|
desc: "with retrieve error",
|
|
token: token,
|
|
id: testsutil.GenerateUUID(t),
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
retrieveResp: mggroups.Group{},
|
|
retrieveErr: repoerr.ErrNotFound,
|
|
err: repoerr.ErrNotFound,
|
|
},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
t.Run(tc.desc, func(t *testing.T) {
|
|
authcall := authsvc.On("Authorize", context.Background(), &magistrala.AuthorizeReq{
|
|
SubjectType: auth.UserType,
|
|
SubjectKind: auth.TokenKind,
|
|
Subject: tc.token,
|
|
Permission: auth.EditPermission,
|
|
Object: tc.id,
|
|
ObjectType: auth.GroupType,
|
|
}).Return(tc.authzResp, tc.authzErr)
|
|
repocall := repo.On("RetrieveByID", context.Background(), tc.id).Return(tc.retrieveResp, tc.retrieveErr)
|
|
repocall1 := repo.On("ChangeStatus", context.Background(), mock.Anything).Return(tc.changeResp, tc.changeErr)
|
|
got, err := svc.EnableGroup(context.Background(), tc.token, tc.id)
|
|
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("expected error %v to contain %v", err, tc.err))
|
|
if err == nil {
|
|
assert.Equal(t, tc.changeResp, got)
|
|
ok := repo.AssertCalled(t, "RetrieveByID", context.Background(), tc.id)
|
|
assert.True(t, ok, fmt.Sprintf("RetrieveByID was not called on %s", tc.desc))
|
|
}
|
|
authcall.Unset()
|
|
repocall.Unset()
|
|
repocall1.Unset()
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDisableGroup(t *testing.T) {
|
|
repo := new(mocks.Repository)
|
|
authsvc := new(authmocks.AuthClient)
|
|
svc := groups.NewService(repo, idProvider, authsvc)
|
|
|
|
cases := []struct {
|
|
desc string
|
|
token string
|
|
id string
|
|
authzResp *magistrala.AuthorizeRes
|
|
authzErr error
|
|
retrieveResp mggroups.Group
|
|
retrieveErr error
|
|
changeResp mggroups.Group
|
|
changeErr error
|
|
err error
|
|
}{
|
|
{
|
|
desc: "successfully",
|
|
token: token,
|
|
id: testsutil.GenerateUUID(t),
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
retrieveResp: mggroups.Group{
|
|
Status: clients.Status(groups.EnabledStatus),
|
|
},
|
|
changeResp: validGroup,
|
|
},
|
|
{
|
|
desc: "with invalid token",
|
|
token: token,
|
|
id: testsutil.GenerateUUID(t),
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: false,
|
|
},
|
|
authzErr: svcerr.ErrAuthorization,
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
{
|
|
desc: "with failed to authorize",
|
|
token: token,
|
|
id: testsutil.GenerateUUID(t),
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: false,
|
|
},
|
|
authzErr: nil,
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
{
|
|
desc: "with enabled group",
|
|
token: token,
|
|
id: testsutil.GenerateUUID(t),
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
retrieveResp: mggroups.Group{
|
|
Status: clients.Status(groups.DisabledStatus),
|
|
},
|
|
err: errors.ErrStatusAlreadyAssigned,
|
|
},
|
|
{
|
|
desc: "with retrieve error",
|
|
token: token,
|
|
id: testsutil.GenerateUUID(t),
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
retrieveResp: mggroups.Group{},
|
|
retrieveErr: repoerr.ErrNotFound,
|
|
err: repoerr.ErrNotFound,
|
|
},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
t.Run(tc.desc, func(t *testing.T) {
|
|
authcall := authsvc.On("Authorize", context.Background(), &magistrala.AuthorizeReq{
|
|
SubjectType: auth.UserType,
|
|
SubjectKind: auth.TokenKind,
|
|
Subject: tc.token,
|
|
Permission: auth.EditPermission,
|
|
Object: tc.id,
|
|
ObjectType: auth.GroupType,
|
|
}).Return(tc.authzResp, tc.authzErr)
|
|
repocall := repo.On("RetrieveByID", context.Background(), tc.id).Return(tc.retrieveResp, tc.retrieveErr)
|
|
repocall1 := repo.On("ChangeStatus", context.Background(), mock.Anything).Return(tc.changeResp, tc.changeErr)
|
|
got, err := svc.DisableGroup(context.Background(), tc.token, tc.id)
|
|
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("expected error %v to contain %v", err, tc.err))
|
|
if err == nil {
|
|
assert.Equal(t, tc.changeResp, got)
|
|
ok := repo.AssertCalled(t, "RetrieveByID", context.Background(), tc.id)
|
|
assert.True(t, ok, fmt.Sprintf("RetrieveByID was not called on %s", tc.desc))
|
|
}
|
|
authcall.Unset()
|
|
repocall.Unset()
|
|
repocall1.Unset()
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestListMembers(t *testing.T) {
|
|
repo := new(mocks.Repository)
|
|
authsvc := new(authmocks.AuthClient)
|
|
svc := groups.NewService(repo, idProvider, authsvc)
|
|
|
|
cases := []struct {
|
|
desc string
|
|
token string
|
|
groupID string
|
|
permission string
|
|
memberKind string
|
|
authzResp *magistrala.AuthorizeRes
|
|
authzErr error
|
|
listSubjectResp *magistrala.ListSubjectsRes
|
|
listSubjectErr error
|
|
listObjectResp *magistrala.ListObjectsRes
|
|
listObjectErr error
|
|
err error
|
|
}{
|
|
{
|
|
desc: "successfully with things kind",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
memberKind: auth.ThingsKind,
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
listObjectResp: &magistrala.ListObjectsRes{
|
|
Policies: []string{
|
|
testsutil.GenerateUUID(t),
|
|
testsutil.GenerateUUID(t),
|
|
testsutil.GenerateUUID(t),
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "successfully with users kind",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
memberKind: auth.UsersKind,
|
|
permission: auth.ViewPermission,
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
listSubjectResp: &magistrala.ListSubjectsRes{
|
|
Policies: []string{
|
|
testsutil.GenerateUUID(t),
|
|
testsutil.GenerateUUID(t),
|
|
testsutil.GenerateUUID(t),
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "with invalid kind",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
memberKind: auth.GroupsKind,
|
|
permission: auth.ViewPermission,
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
err: errors.New("invalid member kind"),
|
|
},
|
|
{
|
|
desc: "with invalid token",
|
|
token: token,
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: false,
|
|
},
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
{
|
|
desc: "failed to list objects with things kind",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
memberKind: auth.ThingsKind,
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
listObjectResp: &magistrala.ListObjectsRes{
|
|
Policies: []string{},
|
|
},
|
|
listObjectErr: svcerr.ErrAuthorization,
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
{
|
|
desc: "failed to list subjects with users kind",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
memberKind: auth.UsersKind,
|
|
permission: auth.ViewPermission,
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
listSubjectResp: &magistrala.ListSubjectsRes{
|
|
Policies: []string{},
|
|
},
|
|
listSubjectErr: svcerr.ErrAuthorization,
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
t.Run(tc.desc, func(t *testing.T) {
|
|
authcall := authsvc.On("Authorize", context.Background(), &magistrala.AuthorizeReq{
|
|
SubjectType: auth.UserType,
|
|
SubjectKind: auth.TokenKind,
|
|
Subject: tc.token,
|
|
Permission: auth.ViewPermission,
|
|
Object: tc.groupID,
|
|
ObjectType: auth.GroupType,
|
|
}).Return(tc.authzResp, tc.authzErr)
|
|
authcall1 := authsvc.On("ListAllObjects", context.Background(), &magistrala.ListObjectsReq{
|
|
SubjectType: auth.GroupType,
|
|
Subject: tc.groupID,
|
|
Relation: auth.GroupRelation,
|
|
ObjectType: auth.ThingType,
|
|
}).Return(tc.listObjectResp, tc.listObjectErr)
|
|
authcall2 := authsvc.On("ListAllSubjects", context.Background(), &magistrala.ListSubjectsReq{
|
|
SubjectType: auth.UserType,
|
|
Permission: tc.permission,
|
|
Object: tc.groupID,
|
|
ObjectType: auth.GroupType,
|
|
}).Return(tc.listSubjectResp, tc.listSubjectErr)
|
|
got, err := svc.ListMembers(context.Background(), tc.token, tc.groupID, tc.permission, tc.memberKind)
|
|
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("expected error %v to contain %v", err, tc.err))
|
|
if err == nil {
|
|
assert.NotEmpty(t, got)
|
|
}
|
|
authcall.Unset()
|
|
authcall1.Unset()
|
|
authcall2.Unset()
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestListGroups(t *testing.T) {
|
|
repo := new(mocks.Repository)
|
|
authsvc := new(authmocks.AuthClient)
|
|
svc := groups.NewService(repo, idProvider, authsvc)
|
|
|
|
cases := []struct {
|
|
desc string
|
|
token string
|
|
memberKind string
|
|
memberID string
|
|
page mggroups.Page
|
|
idResp *magistrala.IdentityRes
|
|
idErr error
|
|
authzResp *magistrala.AuthorizeRes
|
|
authzErr error
|
|
listSubjectResp *magistrala.ListSubjectsRes
|
|
listSubjectErr error
|
|
listObjectResp *magistrala.ListObjectsRes
|
|
listObjectErr error
|
|
listObjectFilterResp *magistrala.ListObjectsRes
|
|
listObjectFilterErr error
|
|
authSuperAdminResp *magistrala.AuthorizeRes
|
|
authSuperAdminErr error
|
|
repoResp mggroups.Page
|
|
repoErr error
|
|
listPermResp *magistrala.ListPermissionsRes
|
|
listPermErr error
|
|
err error
|
|
}{
|
|
{
|
|
desc: "successfully with things kind",
|
|
token: token,
|
|
memberID: testsutil.GenerateUUID(t),
|
|
memberKind: auth.ThingsKind,
|
|
page: mggroups.Page{
|
|
Permission: auth.ViewPermission,
|
|
ListPerms: true,
|
|
},
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
listSubjectResp: &magistrala.ListSubjectsRes{
|
|
Policies: allowedIDs,
|
|
},
|
|
listObjectFilterResp: &magistrala.ListObjectsRes{
|
|
Policies: allowedIDs,
|
|
},
|
|
repoResp: mggroups.Page{
|
|
Groups: []mggroups.Group{
|
|
validGroup,
|
|
validGroup,
|
|
validGroup,
|
|
},
|
|
},
|
|
listPermResp: &magistrala.ListPermissionsRes{
|
|
Permissions: []string{
|
|
auth.ViewPermission,
|
|
auth.EditPermission,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "successfully with groups kind",
|
|
token: token,
|
|
memberID: testsutil.GenerateUUID(t),
|
|
memberKind: auth.GroupsKind,
|
|
page: mggroups.Page{
|
|
Permission: auth.ViewPermission,
|
|
ListPerms: true,
|
|
},
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
listObjectResp: &magistrala.ListObjectsRes{
|
|
Policies: allowedIDs,
|
|
},
|
|
listObjectFilterResp: &magistrala.ListObjectsRes{
|
|
Policies: allowedIDs,
|
|
},
|
|
repoResp: mggroups.Page{
|
|
Groups: []mggroups.Group{
|
|
validGroup,
|
|
validGroup,
|
|
validGroup,
|
|
},
|
|
},
|
|
listPermResp: &magistrala.ListPermissionsRes{
|
|
Permissions: []string{
|
|
auth.ViewPermission,
|
|
auth.EditPermission,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "successfully with channels kind",
|
|
token: token,
|
|
memberID: testsutil.GenerateUUID(t),
|
|
memberKind: auth.ChannelsKind,
|
|
page: mggroups.Page{
|
|
Permission: auth.ViewPermission,
|
|
ListPerms: true,
|
|
},
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
listSubjectResp: &magistrala.ListSubjectsRes{
|
|
Policies: allowedIDs,
|
|
},
|
|
listObjectFilterResp: &magistrala.ListObjectsRes{
|
|
Policies: allowedIDs,
|
|
},
|
|
repoResp: mggroups.Page{
|
|
Groups: []mggroups.Group{
|
|
validGroup,
|
|
validGroup,
|
|
validGroup,
|
|
},
|
|
},
|
|
listPermResp: &magistrala.ListPermissionsRes{
|
|
Permissions: []string{
|
|
auth.ViewPermission,
|
|
auth.EditPermission,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "successfully with users kind non admin",
|
|
token: token,
|
|
memberID: testsutil.GenerateUUID(t),
|
|
memberKind: auth.UsersKind,
|
|
page: mggroups.Page{
|
|
Permission: auth.ViewPermission,
|
|
ListPerms: true,
|
|
},
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
listObjectResp: &magistrala.ListObjectsRes{
|
|
Policies: allowedIDs,
|
|
},
|
|
listObjectFilterResp: &magistrala.ListObjectsRes{
|
|
Policies: allowedIDs,
|
|
},
|
|
repoResp: mggroups.Page{
|
|
Groups: []mggroups.Group{
|
|
validGroup,
|
|
validGroup,
|
|
validGroup,
|
|
},
|
|
},
|
|
listPermResp: &magistrala.ListPermissionsRes{
|
|
Permissions: []string{
|
|
auth.ViewPermission,
|
|
auth.EditPermission,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "successfully with users kind admin",
|
|
token: token,
|
|
memberKind: auth.UsersKind,
|
|
page: mggroups.Page{
|
|
Permission: auth.ViewPermission,
|
|
ListPerms: true,
|
|
},
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
UserId: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
listObjectResp: &magistrala.ListObjectsRes{
|
|
Policies: allowedIDs,
|
|
},
|
|
listObjectFilterResp: &magistrala.ListObjectsRes{
|
|
Policies: allowedIDs,
|
|
},
|
|
repoResp: mggroups.Page{
|
|
Groups: []mggroups.Group{
|
|
validGroup,
|
|
validGroup,
|
|
validGroup,
|
|
},
|
|
},
|
|
listPermResp: &magistrala.ListPermissionsRes{
|
|
Permissions: []string{
|
|
auth.ViewPermission,
|
|
auth.EditPermission,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "unsuccessfully with users kind admin",
|
|
token: token,
|
|
memberKind: auth.UsersKind,
|
|
page: mggroups.Page{
|
|
Permission: auth.ViewPermission,
|
|
ListPerms: true,
|
|
},
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
UserId: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: false,
|
|
},
|
|
authzErr: svcerr.ErrAuthorization,
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
{
|
|
desc: "unsuccessfully with users kind admin with nil error",
|
|
token: token,
|
|
memberKind: auth.UsersKind,
|
|
page: mggroups.Page{
|
|
Permission: auth.ViewPermission,
|
|
ListPerms: true,
|
|
},
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
UserId: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: false,
|
|
},
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
{
|
|
desc: "unsuccessfully with things kind due to failed to authorize",
|
|
token: token,
|
|
memberID: testsutil.GenerateUUID(t),
|
|
memberKind: auth.ThingsKind,
|
|
page: mggroups.Page{
|
|
Permission: auth.ViewPermission,
|
|
ListPerms: true,
|
|
},
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: false,
|
|
},
|
|
authzErr: svcerr.ErrAuthorization,
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
{
|
|
desc: "unsuccessfully with things kind due to failed to list subjects",
|
|
token: token,
|
|
memberID: testsutil.GenerateUUID(t),
|
|
memberKind: auth.ThingsKind,
|
|
page: mggroups.Page{
|
|
Permission: auth.ViewPermission,
|
|
ListPerms: true,
|
|
},
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
listSubjectResp: &magistrala.ListSubjectsRes{},
|
|
listSubjectErr: svcerr.ErrAuthorization,
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
{
|
|
desc: "unsuccessfully with things kind due to failed to list filtered objects",
|
|
token: token,
|
|
memberID: testsutil.GenerateUUID(t),
|
|
memberKind: auth.ThingsKind,
|
|
page: mggroups.Page{
|
|
Permission: auth.ViewPermission,
|
|
ListPerms: true,
|
|
},
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
listSubjectResp: &magistrala.ListSubjectsRes{
|
|
Policies: allowedIDs,
|
|
},
|
|
listObjectFilterResp: &magistrala.ListObjectsRes{},
|
|
listObjectFilterErr: svcerr.ErrAuthorization,
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
{
|
|
desc: "unsuccessfully with groups kind due to failed to authorize",
|
|
token: token,
|
|
memberID: testsutil.GenerateUUID(t),
|
|
memberKind: auth.GroupsKind,
|
|
page: mggroups.Page{
|
|
Permission: auth.ViewPermission,
|
|
ListPerms: true,
|
|
},
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: false,
|
|
},
|
|
authzErr: svcerr.ErrAuthorization,
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
{
|
|
desc: "unsuccessfully with groups kind due to failed to list subjects",
|
|
token: token,
|
|
memberID: testsutil.GenerateUUID(t),
|
|
memberKind: auth.GroupsKind,
|
|
page: mggroups.Page{
|
|
Permission: auth.ViewPermission,
|
|
ListPerms: true,
|
|
},
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
listObjectResp: &magistrala.ListObjectsRes{},
|
|
listObjectErr: svcerr.ErrAuthorization,
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
{
|
|
desc: "unsuccessfully with groups kind due to failed to list filtered objects",
|
|
token: token,
|
|
memberID: testsutil.GenerateUUID(t),
|
|
memberKind: auth.GroupsKind,
|
|
page: mggroups.Page{
|
|
Permission: auth.ViewPermission,
|
|
ListPerms: true,
|
|
},
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
listObjectResp: &magistrala.ListObjectsRes{
|
|
Policies: allowedIDs,
|
|
},
|
|
listObjectFilterResp: &magistrala.ListObjectsRes{},
|
|
listObjectFilterErr: svcerr.ErrAuthorization,
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
{
|
|
desc: "unsuccessfully with channels kind due to failed to authorize",
|
|
token: token,
|
|
memberID: testsutil.GenerateUUID(t),
|
|
memberKind: auth.ChannelsKind,
|
|
page: mggroups.Page{
|
|
Permission: auth.ViewPermission,
|
|
ListPerms: true,
|
|
},
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: false,
|
|
},
|
|
authzErr: svcerr.ErrAuthorization,
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
{
|
|
desc: "unsuccessfully with channels kind due to failed to list subjects",
|
|
token: token,
|
|
memberID: testsutil.GenerateUUID(t),
|
|
memberKind: auth.ChannelsKind,
|
|
page: mggroups.Page{
|
|
Permission: auth.ViewPermission,
|
|
ListPerms: true,
|
|
},
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
listSubjectResp: &magistrala.ListSubjectsRes{},
|
|
listSubjectErr: svcerr.ErrAuthorization,
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
{
|
|
desc: "unsuccessfully with channels kind due to failed to list filtered objects",
|
|
token: token,
|
|
memberID: testsutil.GenerateUUID(t),
|
|
memberKind: auth.ChannelsKind,
|
|
page: mggroups.Page{
|
|
Permission: auth.ViewPermission,
|
|
ListPerms: true,
|
|
},
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
listSubjectResp: &magistrala.ListSubjectsRes{
|
|
Policies: allowedIDs,
|
|
},
|
|
listObjectFilterResp: &magistrala.ListObjectsRes{},
|
|
listObjectFilterErr: svcerr.ErrAuthorization,
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
{
|
|
desc: "unsuccessfully with users kind due to failed to authorize",
|
|
token: token,
|
|
memberID: testsutil.GenerateUUID(t),
|
|
memberKind: auth.UsersKind,
|
|
page: mggroups.Page{
|
|
Permission: auth.ViewPermission,
|
|
ListPerms: true,
|
|
},
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: false,
|
|
},
|
|
authzErr: svcerr.ErrAuthorization,
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
{
|
|
desc: "unsuccessfully with users kind due to failed to list subjects",
|
|
token: token,
|
|
memberID: testsutil.GenerateUUID(t),
|
|
memberKind: auth.UsersKind,
|
|
page: mggroups.Page{
|
|
Permission: auth.ViewPermission,
|
|
ListPerms: true,
|
|
},
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
listObjectResp: &magistrala.ListObjectsRes{},
|
|
listObjectErr: svcerr.ErrAuthorization,
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
{
|
|
desc: "unsuccessfully with users kind due to failed to list filtered objects",
|
|
token: token,
|
|
memberID: testsutil.GenerateUUID(t),
|
|
memberKind: auth.UsersKind,
|
|
page: mggroups.Page{
|
|
Permission: auth.ViewPermission,
|
|
ListPerms: true,
|
|
},
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
listObjectResp: &magistrala.ListObjectsRes{
|
|
Policies: allowedIDs,
|
|
},
|
|
listObjectFilterResp: &magistrala.ListObjectsRes{},
|
|
listObjectFilterErr: svcerr.ErrAuthorization,
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
{
|
|
desc: "successfully with users kind admin",
|
|
token: token,
|
|
memberKind: auth.UsersKind,
|
|
page: mggroups.Page{
|
|
Permission: auth.ViewPermission,
|
|
ListPerms: true,
|
|
},
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
UserId: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
listObjectResp: &magistrala.ListObjectsRes{
|
|
Policies: allowedIDs,
|
|
},
|
|
listObjectFilterResp: &magistrala.ListObjectsRes{
|
|
Policies: allowedIDs,
|
|
},
|
|
repoResp: mggroups.Page{
|
|
Groups: []mggroups.Group{
|
|
validGroup,
|
|
validGroup,
|
|
validGroup,
|
|
},
|
|
},
|
|
listPermResp: &magistrala.ListPermissionsRes{
|
|
Permissions: []string{
|
|
auth.ViewPermission,
|
|
auth.EditPermission,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "unsuccessfully with invalid kind",
|
|
token: token,
|
|
memberID: testsutil.GenerateUUID(t),
|
|
memberKind: "invalid",
|
|
page: mggroups.Page{
|
|
Permission: auth.ViewPermission,
|
|
ListPerms: true,
|
|
},
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
err: errors.New("invalid member kind"),
|
|
},
|
|
{
|
|
desc: "unsuccessfully with things kind due to repo error",
|
|
token: token,
|
|
memberID: testsutil.GenerateUUID(t),
|
|
memberKind: auth.ThingsKind,
|
|
page: mggroups.Page{
|
|
Permission: auth.ViewPermission,
|
|
ListPerms: true,
|
|
},
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
listSubjectResp: &magistrala.ListSubjectsRes{
|
|
Policies: allowedIDs,
|
|
},
|
|
listObjectFilterResp: &magistrala.ListObjectsRes{
|
|
Policies: allowedIDs,
|
|
},
|
|
repoResp: mggroups.Page{},
|
|
repoErr: repoerr.ErrViewEntity,
|
|
err: repoerr.ErrViewEntity,
|
|
},
|
|
{
|
|
desc: "unsuccessfully with things kind due to failed to list permissions",
|
|
token: token,
|
|
memberID: testsutil.GenerateUUID(t),
|
|
memberKind: auth.ThingsKind,
|
|
page: mggroups.Page{
|
|
Permission: auth.ViewPermission,
|
|
ListPerms: true,
|
|
},
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
listSubjectResp: &magistrala.ListSubjectsRes{
|
|
Policies: allowedIDs,
|
|
},
|
|
listObjectFilterResp: &magistrala.ListObjectsRes{
|
|
Policies: allowedIDs,
|
|
},
|
|
repoResp: mggroups.Page{
|
|
Groups: []mggroups.Group{
|
|
validGroup,
|
|
validGroup,
|
|
validGroup,
|
|
},
|
|
},
|
|
listPermResp: &magistrala.ListPermissionsRes{},
|
|
listPermErr: svcerr.ErrAuthorization,
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
{
|
|
desc: "unsuccessfully with invalid token",
|
|
token: token,
|
|
memberID: testsutil.GenerateUUID(t),
|
|
memberKind: auth.ThingsKind,
|
|
page: mggroups.Page{
|
|
Permission: auth.ViewPermission,
|
|
ListPerms: true,
|
|
},
|
|
idResp: &magistrala.IdentityRes{},
|
|
idErr: svcerr.ErrAuthentication,
|
|
err: svcerr.ErrAuthentication,
|
|
},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
t.Run(tc.desc, func(t *testing.T) {
|
|
authcall := authsvc.On("Identify", context.Background(), &magistrala.IdentityReq{Token: tc.token}).Return(tc.idResp, tc.idErr)
|
|
authcall1 := &mock.Call{}
|
|
authcall2 := &mock.Call{}
|
|
authcall3 := &mock.Call{}
|
|
adminCheck := &mock.Call{}
|
|
switch tc.memberKind {
|
|
case auth.ThingsKind:
|
|
authcall1 = authsvc.On("Authorize", context.Background(), &magistrala.AuthorizeReq{
|
|
Domain: tc.idResp.GetDomainId(),
|
|
SubjectType: auth.UserType,
|
|
SubjectKind: auth.UsersKind,
|
|
Subject: tc.idResp.GetId(),
|
|
Permission: auth.ViewPermission,
|
|
Object: tc.memberID,
|
|
ObjectType: auth.ThingType,
|
|
}).Return(tc.authzResp, tc.authzErr)
|
|
authcall2 = authsvc.On("ListAllSubjects", context.Background(), &magistrala.ListSubjectsReq{
|
|
SubjectType: auth.GroupType,
|
|
Permission: auth.GroupRelation,
|
|
ObjectType: auth.ThingType,
|
|
Object: tc.memberID,
|
|
}).Return(tc.listSubjectResp, tc.listSubjectErr)
|
|
authcall3 = authsvc.On("ListAllObjects", context.Background(), &magistrala.ListObjectsReq{
|
|
SubjectType: auth.UserType,
|
|
Subject: tc.idResp.GetId(),
|
|
Permission: tc.page.Permission,
|
|
ObjectType: auth.GroupType,
|
|
}).Return(tc.listObjectFilterResp, tc.listObjectFilterErr)
|
|
case auth.GroupsKind:
|
|
authcall1 = authsvc.On("Authorize", context.Background(), &magistrala.AuthorizeReq{
|
|
Domain: tc.idResp.GetDomainId(),
|
|
SubjectType: auth.UserType,
|
|
SubjectKind: auth.UsersKind,
|
|
Subject: tc.idResp.GetId(),
|
|
Permission: tc.page.Permission,
|
|
Object: tc.memberID,
|
|
ObjectType: auth.GroupType,
|
|
}).Return(tc.authzResp, tc.authzErr)
|
|
authcall2 = authsvc.On("ListAllObjects", context.Background(), &magistrala.ListObjectsReq{
|
|
SubjectType: auth.GroupType,
|
|
Subject: tc.memberID,
|
|
Permission: auth.ParentGroupRelation,
|
|
ObjectType: auth.GroupType,
|
|
}).Return(tc.listObjectResp, tc.listObjectErr)
|
|
authcall3 = authsvc.On("ListAllObjects", context.Background(), &magistrala.ListObjectsReq{
|
|
SubjectType: auth.UserType,
|
|
Subject: tc.idResp.GetId(),
|
|
Permission: tc.page.Permission,
|
|
ObjectType: auth.GroupType,
|
|
}).Return(tc.listObjectFilterResp, tc.listObjectFilterErr)
|
|
case auth.ChannelsKind:
|
|
authcall1 = authsvc.On("Authorize", context.Background(), &magistrala.AuthorizeReq{
|
|
Domain: tc.idResp.GetDomainId(),
|
|
SubjectType: auth.UserType,
|
|
SubjectKind: auth.UsersKind,
|
|
Subject: tc.idResp.GetId(),
|
|
Permission: auth.ViewPermission,
|
|
Object: tc.memberID,
|
|
ObjectType: auth.GroupType,
|
|
}).Return(tc.authzResp, tc.authzErr)
|
|
authcall2 = authsvc.On("ListAllSubjects", context.Background(), &magistrala.ListSubjectsReq{
|
|
SubjectType: auth.GroupType,
|
|
Permission: auth.ParentGroupRelation,
|
|
ObjectType: auth.GroupType,
|
|
Object: tc.memberID,
|
|
}).Return(tc.listSubjectResp, tc.listSubjectErr)
|
|
authcall3 = authsvc.On("ListAllObjects", context.Background(), &magistrala.ListObjectsReq{
|
|
SubjectType: auth.UserType,
|
|
Subject: tc.idResp.GetId(),
|
|
Permission: tc.page.Permission,
|
|
ObjectType: auth.GroupType,
|
|
}).Return(tc.listObjectFilterResp, tc.listObjectFilterErr)
|
|
case auth.UsersKind:
|
|
adminCheckReq := &magistrala.AuthorizeReq{
|
|
SubjectType: auth.UserType,
|
|
Subject: tc.idResp.GetUserId(),
|
|
Permission: auth.AdminPermission,
|
|
Object: auth.MagistralaObject,
|
|
ObjectType: auth.PlatformType,
|
|
}
|
|
adminCheck = authsvc.On("Authorize", context.Background(), adminCheckReq).Return(tc.authzResp, tc.authzErr)
|
|
authReq := &magistrala.AuthorizeReq{
|
|
Domain: tc.idResp.GetDomainId(),
|
|
SubjectType: auth.UserType,
|
|
SubjectKind: auth.UsersKind,
|
|
Subject: tc.idResp.GetId(),
|
|
Permission: auth.AdminPermission,
|
|
Object: tc.idResp.GetDomainId(),
|
|
ObjectType: auth.DomainType,
|
|
}
|
|
if tc.memberID == "" {
|
|
authReq.Domain = ""
|
|
authReq.Permission = auth.MembershipPermission
|
|
}
|
|
authcall1 = authsvc.On("Authorize", context.Background(), authReq).Return(tc.authzResp, tc.authzErr)
|
|
authcall2 = authsvc.On("ListAllObjects", context.Background(), &magistrala.ListObjectsReq{
|
|
SubjectType: auth.UserType,
|
|
Subject: auth.EncodeDomainUserID(tc.idResp.GetDomainId(), tc.memberID),
|
|
Permission: tc.page.Permission,
|
|
ObjectType: auth.GroupType,
|
|
}).Return(tc.listObjectResp, tc.listObjectErr)
|
|
authcall3 = authsvc.On("ListAllObjects", context.Background(), &magistrala.ListObjectsReq{
|
|
SubjectType: auth.UserType,
|
|
Subject: tc.idResp.GetId(),
|
|
Permission: tc.page.Permission,
|
|
ObjectType: auth.GroupType,
|
|
}).Return(tc.listObjectFilterResp, tc.listObjectFilterErr)
|
|
}
|
|
repocall := repo.On("RetrieveByIDs", context.Background(), mock.Anything, mock.Anything).Return(tc.repoResp, tc.repoErr)
|
|
authcall4 := authsvc.On("ListPermissions", mock.Anything, mock.Anything).Return(tc.listPermResp, tc.listPermErr)
|
|
got, err := svc.ListGroups(context.Background(), tc.token, tc.memberKind, tc.memberID, tc.page)
|
|
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("expected error %v to contain %v", err, tc.err))
|
|
if err == nil {
|
|
assert.NotEmpty(t, got)
|
|
}
|
|
authcall.Unset()
|
|
repocall.Unset()
|
|
switch tc.memberKind {
|
|
case auth.ThingsKind, auth.GroupsKind, auth.ChannelsKind, auth.UsersKind:
|
|
authcall1.Unset()
|
|
authcall2.Unset()
|
|
authcall3.Unset()
|
|
authcall4.Unset()
|
|
if tc.memberID == "" {
|
|
adminCheck.Unset()
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestAssign(t *testing.T) {
|
|
repo := new(mocks.Repository)
|
|
authsvc := new(authmocks.AuthClient)
|
|
svc := groups.NewService(repo, idProvider, authsvc)
|
|
|
|
cases := []struct {
|
|
desc string
|
|
token string
|
|
groupID string
|
|
relation string
|
|
memberKind string
|
|
memberIDs []string
|
|
idResp *magistrala.IdentityRes
|
|
idErr error
|
|
authzResp *magistrala.AuthorizeRes
|
|
authzErr error
|
|
addPoliciesRes *magistrala.AddPoliciesRes
|
|
addPoliciesErr error
|
|
repoResp mggroups.Page
|
|
repoErr error
|
|
addParentPoliciesRes *magistrala.AddPoliciesRes
|
|
addParentPoliciesErr error
|
|
deleteParentPoliciesRes *magistrala.DeletePolicyRes
|
|
deleteParentPoliciesErr error
|
|
repoParentGroupErr error
|
|
err error
|
|
}{
|
|
{
|
|
desc: "successfully with things kind",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
relation: auth.ContributorRelation,
|
|
memberKind: auth.ThingsKind,
|
|
memberIDs: allowedIDs,
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
addPoliciesRes: &magistrala.AddPoliciesRes{
|
|
Added: true,
|
|
},
|
|
},
|
|
{
|
|
desc: "successfully with channels kind",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
relation: auth.ContributorRelation,
|
|
memberKind: auth.ChannelsKind,
|
|
memberIDs: allowedIDs,
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
addPoliciesRes: &magistrala.AddPoliciesRes{
|
|
Added: true,
|
|
},
|
|
},
|
|
{
|
|
desc: "successfully with groups kind",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
relation: auth.ContributorRelation,
|
|
memberKind: auth.GroupsKind,
|
|
memberIDs: allowedIDs,
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
repoResp: mggroups.Page{
|
|
Groups: []mggroups.Group{
|
|
validGroup,
|
|
validGroup,
|
|
validGroup,
|
|
},
|
|
},
|
|
addPoliciesRes: &magistrala.AddPoliciesRes{
|
|
Added: true,
|
|
},
|
|
repoParentGroupErr: nil,
|
|
},
|
|
{
|
|
desc: "successfully with users kind",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
relation: auth.ContributorRelation,
|
|
memberKind: auth.UsersKind,
|
|
memberIDs: allowedIDs,
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
addPoliciesRes: &magistrala.AddPoliciesRes{
|
|
Added: true,
|
|
},
|
|
},
|
|
{
|
|
desc: "unsuccessfully with groups kind due to repo err",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
relation: auth.ContributorRelation,
|
|
memberKind: auth.GroupsKind,
|
|
memberIDs: allowedIDs,
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
repoResp: mggroups.Page{},
|
|
repoErr: repoerr.ErrViewEntity,
|
|
err: repoerr.ErrViewEntity,
|
|
},
|
|
{
|
|
desc: "unsuccessfully with groups kind due to empty page",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
relation: auth.ContributorRelation,
|
|
memberKind: auth.GroupsKind,
|
|
memberIDs: allowedIDs,
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
repoResp: mggroups.Page{
|
|
Groups: []mggroups.Group{},
|
|
},
|
|
err: errors.New("invalid group ids"),
|
|
},
|
|
{
|
|
desc: "unsuccessfully with groups kind due to non empty parent",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
relation: auth.ContributorRelation,
|
|
memberKind: auth.GroupsKind,
|
|
memberIDs: allowedIDs,
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
repoResp: mggroups.Page{
|
|
Groups: []mggroups.Group{
|
|
{
|
|
ID: testsutil.GenerateUUID(t),
|
|
Parent: testsutil.GenerateUUID(t),
|
|
},
|
|
},
|
|
},
|
|
err: repoerr.ErrConflict,
|
|
},
|
|
{
|
|
desc: "unsuccessfully with groups kind due to failed to add policies",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
relation: auth.ContributorRelation,
|
|
memberKind: auth.GroupsKind,
|
|
memberIDs: allowedIDs,
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
repoResp: mggroups.Page{
|
|
Groups: []mggroups.Group{
|
|
validGroup,
|
|
validGroup,
|
|
validGroup,
|
|
},
|
|
},
|
|
addPoliciesRes: &magistrala.AddPoliciesRes{
|
|
Added: false,
|
|
},
|
|
addPoliciesErr: svcerr.ErrAuthorization,
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
{
|
|
desc: "unsuccessfully with groups kind due to failed to assign parent",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
relation: auth.ContributorRelation,
|
|
memberKind: auth.GroupsKind,
|
|
memberIDs: allowedIDs,
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
repoResp: mggroups.Page{
|
|
Groups: []mggroups.Group{
|
|
validGroup,
|
|
validGroup,
|
|
validGroup,
|
|
},
|
|
},
|
|
addPoliciesRes: &magistrala.AddPoliciesRes{
|
|
Added: true,
|
|
},
|
|
repoParentGroupErr: repoerr.ErrConflict,
|
|
err: repoerr.ErrConflict,
|
|
},
|
|
{
|
|
desc: "unsuccessfully with groups kind due to failed to assign parent and delete policy",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
relation: auth.ContributorRelation,
|
|
memberKind: auth.GroupsKind,
|
|
memberIDs: allowedIDs,
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
repoResp: mggroups.Page{
|
|
Groups: []mggroups.Group{
|
|
validGroup,
|
|
validGroup,
|
|
validGroup,
|
|
},
|
|
},
|
|
addPoliciesRes: &magistrala.AddPoliciesRes{
|
|
Added: true,
|
|
},
|
|
deleteParentPoliciesRes: &magistrala.DeletePolicyRes{
|
|
Deleted: false,
|
|
},
|
|
deleteParentPoliciesErr: svcerr.ErrAuthorization,
|
|
repoParentGroupErr: repoerr.ErrConflict,
|
|
err: apiutil.ErrRollbackTx,
|
|
},
|
|
{
|
|
desc: "unsuccessfully with invalid kind",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
relation: auth.ContributorRelation,
|
|
memberKind: "invalid",
|
|
memberIDs: allowedIDs,
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
err: errors.New("invalid member kind"),
|
|
},
|
|
{
|
|
desc: "unsuccessfully with invalid token",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
relation: auth.ContributorRelation,
|
|
memberKind: auth.UsersKind,
|
|
memberIDs: allowedIDs,
|
|
idResp: &magistrala.IdentityRes{},
|
|
idErr: svcerr.ErrAuthentication,
|
|
err: svcerr.ErrAuthentication,
|
|
},
|
|
{
|
|
desc: "unsuccessfully with failed to authorize",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
relation: auth.ContributorRelation,
|
|
memberKind: auth.ThingsKind,
|
|
memberIDs: allowedIDs,
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: false,
|
|
},
|
|
authzErr: svcerr.ErrAuthorization,
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
{
|
|
desc: "unsuccessfully with failed to add policies",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
relation: auth.ContributorRelation,
|
|
memberKind: auth.ThingsKind,
|
|
memberIDs: allowedIDs,
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
addPoliciesRes: &magistrala.AddPoliciesRes{
|
|
Added: false,
|
|
},
|
|
addPoliciesErr: svcerr.ErrAuthorization,
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
t.Run(tc.desc, func(t *testing.T) {
|
|
authcall := authsvc.On("Identify", context.Background(), &magistrala.IdentityReq{Token: tc.token}).Return(tc.idResp, tc.idErr)
|
|
authcall1 := authsvc.On("Authorize", context.Background(), &magistrala.AuthorizeReq{
|
|
Domain: tc.idResp.GetDomainId(),
|
|
SubjectType: auth.UserType,
|
|
SubjectKind: auth.UsersKind,
|
|
Subject: tc.idResp.GetId(),
|
|
Permission: auth.EditPermission,
|
|
Object: tc.groupID,
|
|
ObjectType: auth.GroupType,
|
|
}).Return(tc.authzResp, tc.authzErr)
|
|
retrieveByIDsCall := &mock.Call{}
|
|
deletePoliciesCall := &mock.Call{}
|
|
assignParentCall := &mock.Call{}
|
|
policies := magistrala.AddPoliciesReq{}
|
|
switch tc.memberKind {
|
|
case auth.ThingsKind:
|
|
for _, memberID := range tc.memberIDs {
|
|
policies.AddPoliciesReq = append(policies.AddPoliciesReq, &magistrala.AddPolicyReq{
|
|
Domain: tc.idResp.GetDomainId(),
|
|
SubjectType: auth.GroupType,
|
|
SubjectKind: auth.ChannelsKind,
|
|
Subject: tc.groupID,
|
|
Relation: tc.relation,
|
|
ObjectType: auth.ThingType,
|
|
Object: memberID,
|
|
})
|
|
}
|
|
case auth.GroupsKind:
|
|
retrieveByIDsCall = repo.On("RetrieveByIDs", context.Background(), mggroups.Page{PageMeta: mggroups.PageMeta{Limit: 1<<63 - 1}}, mock.Anything).Return(tc.repoResp, tc.repoErr)
|
|
var deletePolicies magistrala.DeletePoliciesReq
|
|
for _, group := range tc.repoResp.Groups {
|
|
policies.AddPoliciesReq = append(policies.AddPoliciesReq, &magistrala.AddPolicyReq{
|
|
Domain: tc.idResp.GetDomainId(),
|
|
SubjectType: auth.GroupType,
|
|
Subject: tc.groupID,
|
|
Relation: auth.ParentGroupRelation,
|
|
ObjectType: auth.GroupType,
|
|
Object: group.ID,
|
|
})
|
|
deletePolicies.DeletePoliciesReq = append(deletePolicies.DeletePoliciesReq, &magistrala.DeletePolicyReq{
|
|
Domain: tc.idResp.GetDomainId(),
|
|
SubjectType: auth.GroupType,
|
|
Subject: tc.groupID,
|
|
Relation: auth.ParentGroupRelation,
|
|
ObjectType: auth.GroupType,
|
|
Object: group.ID,
|
|
})
|
|
}
|
|
deletePoliciesCall = authsvc.On("DeletePolicies", context.Background(), &deletePolicies).Return(tc.deleteParentPoliciesRes, tc.deleteParentPoliciesErr)
|
|
assignParentCall = repo.On("AssignParentGroup", context.Background(), tc.groupID, tc.memberIDs).Return(tc.repoParentGroupErr)
|
|
case auth.ChannelsKind:
|
|
for _, memberID := range tc.memberIDs {
|
|
policies.AddPoliciesReq = append(policies.AddPoliciesReq, &magistrala.AddPolicyReq{
|
|
Domain: tc.idResp.GetDomainId(),
|
|
SubjectType: auth.GroupType,
|
|
Subject: memberID,
|
|
Relation: tc.relation,
|
|
ObjectType: auth.GroupType,
|
|
Object: tc.groupID,
|
|
})
|
|
}
|
|
case auth.UsersKind:
|
|
for _, memberID := range tc.memberIDs {
|
|
policies.AddPoliciesReq = append(policies.AddPoliciesReq, &magistrala.AddPolicyReq{
|
|
Domain: tc.idResp.GetDomainId(),
|
|
SubjectType: auth.UserType,
|
|
Subject: auth.EncodeDomainUserID(tc.idResp.GetDomainId(), memberID),
|
|
Relation: tc.relation,
|
|
ObjectType: auth.GroupType,
|
|
Object: tc.groupID,
|
|
})
|
|
}
|
|
}
|
|
authcall2 := authsvc.On("AddPolicies", context.Background(), &policies).Return(tc.addPoliciesRes, tc.addPoliciesErr)
|
|
err := svc.Assign(context.Background(), tc.token, tc.groupID, tc.relation, tc.memberKind, tc.memberIDs...)
|
|
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("expected error %v to contain %v", err, tc.err))
|
|
authcall.Unset()
|
|
authcall1.Unset()
|
|
authcall2.Unset()
|
|
if tc.memberKind == auth.GroupsKind {
|
|
retrieveByIDsCall.Unset()
|
|
deletePoliciesCall.Unset()
|
|
assignParentCall.Unset()
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestUnassign(t *testing.T) {
|
|
repo := new(mocks.Repository)
|
|
authsvc := new(authmocks.AuthClient)
|
|
svc := groups.NewService(repo, idProvider, authsvc)
|
|
|
|
cases := []struct {
|
|
desc string
|
|
token string
|
|
groupID string
|
|
relation string
|
|
memberKind string
|
|
memberIDs []string
|
|
idResp *magistrala.IdentityRes
|
|
idErr error
|
|
authzResp *magistrala.AuthorizeRes
|
|
authzErr error
|
|
deletePoliciesRes *magistrala.DeletePolicyRes
|
|
deletePoliciesErr error
|
|
repoResp mggroups.Page
|
|
repoErr error
|
|
addParentPoliciesRes *magistrala.AddPoliciesRes
|
|
addParentPoliciesErr error
|
|
deleteParentPoliciesRes *magistrala.DeletePolicyRes
|
|
deleteParentPoliciesErr error
|
|
repoParentGroupErr error
|
|
err error
|
|
}{
|
|
{
|
|
desc: "successfully with things kind",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
relation: auth.ContributorRelation,
|
|
memberKind: auth.ThingsKind,
|
|
memberIDs: allowedIDs,
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
deletePoliciesRes: &magistrala.DeletePolicyRes{
|
|
Deleted: true,
|
|
},
|
|
},
|
|
{
|
|
desc: "successfully with channels kind",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
relation: auth.ContributorRelation,
|
|
memberKind: auth.ChannelsKind,
|
|
memberIDs: allowedIDs,
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
deletePoliciesRes: &magistrala.DeletePolicyRes{
|
|
Deleted: true,
|
|
},
|
|
},
|
|
{
|
|
desc: "successfully with groups kind",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
relation: auth.ContributorRelation,
|
|
memberKind: auth.GroupsKind,
|
|
memberIDs: allowedIDs,
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
repoResp: mggroups.Page{
|
|
Groups: []mggroups.Group{
|
|
validGroup,
|
|
validGroup,
|
|
validGroup,
|
|
},
|
|
},
|
|
deletePoliciesRes: &magistrala.DeletePolicyRes{
|
|
Deleted: true,
|
|
},
|
|
repoParentGroupErr: nil,
|
|
},
|
|
{
|
|
desc: "successfully with users kind",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
relation: auth.ContributorRelation,
|
|
memberKind: auth.UsersKind,
|
|
memberIDs: allowedIDs,
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
deletePoliciesRes: &magistrala.DeletePolicyRes{
|
|
Deleted: true,
|
|
},
|
|
},
|
|
{
|
|
desc: "unsuccessfully with groups kind due to repo err",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
relation: auth.ContributorRelation,
|
|
memberKind: auth.GroupsKind,
|
|
memberIDs: allowedIDs,
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
repoResp: mggroups.Page{},
|
|
repoErr: repoerr.ErrViewEntity,
|
|
err: repoerr.ErrViewEntity,
|
|
},
|
|
{
|
|
desc: "unsuccessfully with groups kind due to empty page",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
relation: auth.ContributorRelation,
|
|
memberKind: auth.GroupsKind,
|
|
memberIDs: allowedIDs,
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
repoResp: mggroups.Page{
|
|
Groups: []mggroups.Group{},
|
|
},
|
|
err: errors.New("invalid group ids"),
|
|
},
|
|
{
|
|
desc: "unsuccessfully with groups kind due to non empty parent",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
relation: auth.ContributorRelation,
|
|
memberKind: auth.GroupsKind,
|
|
memberIDs: allowedIDs,
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
repoResp: mggroups.Page{
|
|
Groups: []mggroups.Group{
|
|
{
|
|
ID: testsutil.GenerateUUID(t),
|
|
Parent: testsutil.GenerateUUID(t),
|
|
},
|
|
},
|
|
},
|
|
err: repoerr.ErrConflict,
|
|
},
|
|
{
|
|
desc: "unsuccessfully with groups kind due to failed to add policies",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
relation: auth.ContributorRelation,
|
|
memberKind: auth.GroupsKind,
|
|
memberIDs: allowedIDs,
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
repoResp: mggroups.Page{
|
|
Groups: []mggroups.Group{
|
|
validGroup,
|
|
validGroup,
|
|
validGroup,
|
|
},
|
|
},
|
|
deletePoliciesRes: &magistrala.DeletePolicyRes{
|
|
Deleted: false,
|
|
},
|
|
deletePoliciesErr: svcerr.ErrAuthorization,
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
{
|
|
desc: "unsuccessfully with groups kind due to failed to unassign parent",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
relation: auth.ContributorRelation,
|
|
memberKind: auth.GroupsKind,
|
|
memberIDs: allowedIDs,
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
repoResp: mggroups.Page{
|
|
Groups: []mggroups.Group{
|
|
validGroup,
|
|
validGroup,
|
|
validGroup,
|
|
},
|
|
},
|
|
deletePoliciesRes: &magistrala.DeletePolicyRes{
|
|
Deleted: true,
|
|
},
|
|
repoParentGroupErr: repoerr.ErrConflict,
|
|
err: repoerr.ErrConflict,
|
|
},
|
|
{
|
|
desc: "unsuccessfully with groups kind due to failed to unassign parent and add policy",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
relation: auth.ContributorRelation,
|
|
memberKind: auth.GroupsKind,
|
|
memberIDs: allowedIDs,
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
repoResp: mggroups.Page{
|
|
Groups: []mggroups.Group{
|
|
validGroup,
|
|
validGroup,
|
|
validGroup,
|
|
},
|
|
},
|
|
deletePoliciesRes: &magistrala.DeletePolicyRes{
|
|
Deleted: true,
|
|
},
|
|
repoParentGroupErr: repoerr.ErrConflict,
|
|
addParentPoliciesRes: &magistrala.AddPoliciesRes{
|
|
Added: false,
|
|
},
|
|
addParentPoliciesErr: svcerr.ErrAuthorization,
|
|
err: repoerr.ErrConflict,
|
|
},
|
|
{
|
|
desc: "unsuccessfully with invalid kind",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
relation: auth.ContributorRelation,
|
|
memberKind: "invalid",
|
|
memberIDs: allowedIDs,
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
err: errors.New("invalid member kind"),
|
|
},
|
|
{
|
|
desc: "unsuccessfully with invalid token",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
relation: auth.ContributorRelation,
|
|
memberKind: auth.UsersKind,
|
|
memberIDs: allowedIDs,
|
|
idResp: &magistrala.IdentityRes{},
|
|
idErr: svcerr.ErrAuthentication,
|
|
err: svcerr.ErrAuthentication,
|
|
},
|
|
{
|
|
desc: "unsuccessfully with failed to authorize",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
relation: auth.ContributorRelation,
|
|
memberKind: auth.ThingsKind,
|
|
memberIDs: allowedIDs,
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: false,
|
|
},
|
|
authzErr: svcerr.ErrAuthorization,
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
{
|
|
desc: "unsuccessfully with failed to add policies",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
relation: auth.ContributorRelation,
|
|
memberKind: auth.ThingsKind,
|
|
memberIDs: allowedIDs,
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
deletePoliciesRes: &magistrala.DeletePolicyRes{
|
|
Deleted: false,
|
|
},
|
|
deletePoliciesErr: svcerr.ErrAuthorization,
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
t.Run(tc.desc, func(t *testing.T) {
|
|
authcall := authsvc.On("Identify", context.Background(), &magistrala.IdentityReq{Token: tc.token}).Return(tc.idResp, tc.idErr)
|
|
authcall1 := authsvc.On("Authorize", context.Background(), &magistrala.AuthorizeReq{
|
|
Domain: tc.idResp.GetDomainId(),
|
|
SubjectType: auth.UserType,
|
|
SubjectKind: auth.UsersKind,
|
|
Subject: tc.idResp.GetId(),
|
|
Permission: auth.EditPermission,
|
|
Object: tc.groupID,
|
|
ObjectType: auth.GroupType,
|
|
}).Return(tc.authzResp, tc.authzErr)
|
|
retrieveByIDsCall := &mock.Call{}
|
|
addPoliciesCall := &mock.Call{}
|
|
assignParentCall := &mock.Call{}
|
|
policies := magistrala.DeletePoliciesReq{}
|
|
switch tc.memberKind {
|
|
case auth.ThingsKind:
|
|
for _, memberID := range tc.memberIDs {
|
|
policies.DeletePoliciesReq = append(policies.DeletePoliciesReq, &magistrala.DeletePolicyReq{
|
|
Domain: tc.idResp.GetDomainId(),
|
|
SubjectType: auth.GroupType,
|
|
SubjectKind: auth.ChannelsKind,
|
|
Subject: tc.groupID,
|
|
Relation: tc.relation,
|
|
ObjectType: auth.ThingType,
|
|
Object: memberID,
|
|
})
|
|
}
|
|
case auth.GroupsKind:
|
|
retrieveByIDsCall = repo.On("RetrieveByIDs", context.Background(), mggroups.Page{PageMeta: mggroups.PageMeta{Limit: 1<<63 - 1}}, mock.Anything).Return(tc.repoResp, tc.repoErr)
|
|
var addPolicies magistrala.AddPoliciesReq
|
|
for _, group := range tc.repoResp.Groups {
|
|
policies.DeletePoliciesReq = append(policies.DeletePoliciesReq, &magistrala.DeletePolicyReq{
|
|
Domain: tc.idResp.GetDomainId(),
|
|
SubjectType: auth.GroupType,
|
|
Subject: tc.groupID,
|
|
Relation: auth.ParentGroupRelation,
|
|
ObjectType: auth.GroupType,
|
|
Object: group.ID,
|
|
})
|
|
addPolicies.AddPoliciesReq = append(addPolicies.AddPoliciesReq, &magistrala.AddPolicyReq{
|
|
Domain: tc.idResp.GetDomainId(),
|
|
SubjectType: auth.GroupType,
|
|
Subject: tc.groupID,
|
|
Relation: auth.ParentGroupRelation,
|
|
ObjectType: auth.GroupType,
|
|
Object: group.ID,
|
|
})
|
|
}
|
|
addPoliciesCall = authsvc.On("AddPolicies", context.Background(), &addPolicies).Return(tc.addParentPoliciesRes, tc.addParentPoliciesErr)
|
|
assignParentCall = repo.On("UnassignParentGroup", context.Background(), tc.groupID, tc.memberIDs).Return(tc.repoParentGroupErr)
|
|
case auth.ChannelsKind:
|
|
for _, memberID := range tc.memberIDs {
|
|
policies.DeletePoliciesReq = append(policies.DeletePoliciesReq, &magistrala.DeletePolicyReq{
|
|
Domain: tc.idResp.GetDomainId(),
|
|
SubjectType: auth.GroupType,
|
|
Subject: memberID,
|
|
Relation: tc.relation,
|
|
ObjectType: auth.GroupType,
|
|
Object: tc.groupID,
|
|
})
|
|
}
|
|
case auth.UsersKind:
|
|
for _, memberID := range tc.memberIDs {
|
|
policies.DeletePoliciesReq = append(policies.DeletePoliciesReq, &magistrala.DeletePolicyReq{
|
|
Domain: tc.idResp.GetDomainId(),
|
|
SubjectType: auth.UserType,
|
|
Subject: auth.EncodeDomainUserID(tc.idResp.GetDomainId(), memberID),
|
|
Relation: tc.relation,
|
|
ObjectType: auth.GroupType,
|
|
Object: tc.groupID,
|
|
})
|
|
}
|
|
}
|
|
authcall2 := authsvc.On("DeletePolicies", context.Background(), &policies).Return(tc.deletePoliciesRes, tc.deletePoliciesErr)
|
|
err := svc.Unassign(context.Background(), tc.token, tc.groupID, tc.relation, tc.memberKind, tc.memberIDs...)
|
|
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("expected error %v to contain %v", err, tc.err))
|
|
authcall.Unset()
|
|
authcall1.Unset()
|
|
authcall2.Unset()
|
|
if tc.memberKind == auth.GroupsKind {
|
|
retrieveByIDsCall.Unset()
|
|
addPoliciesCall.Unset()
|
|
assignParentCall.Unset()
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDeleteGroup(t *testing.T) {
|
|
repo := new(mocks.Repository)
|
|
authsvc := new(authmocks.AuthClient)
|
|
svc := groups.NewService(repo, idProvider, authsvc)
|
|
|
|
cases := []struct {
|
|
desc string
|
|
token string
|
|
groupID string
|
|
idResp *magistrala.IdentityRes
|
|
idErr error
|
|
authzResp *magistrala.AuthorizeRes
|
|
authzErr error
|
|
deletePoliciesRes *magistrala.DeletePolicyRes
|
|
deletePoliciesErr error
|
|
repoErr error
|
|
err error
|
|
}{
|
|
{
|
|
desc: "successfully",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
deletePoliciesRes: &magistrala.DeletePolicyRes{
|
|
Deleted: true,
|
|
},
|
|
},
|
|
{
|
|
desc: "unsuccessfully with invalid token",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
idResp: &magistrala.IdentityRes{},
|
|
deletePoliciesRes: &magistrala.DeletePolicyRes{},
|
|
idErr: svcerr.ErrAuthentication,
|
|
err: svcerr.ErrAuthentication,
|
|
},
|
|
{
|
|
desc: "unsuccessfully with authorization error",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: false,
|
|
},
|
|
deletePoliciesRes: &magistrala.DeletePolicyRes{},
|
|
authzErr: svcerr.ErrAuthorization,
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
{
|
|
desc: "unsuccessfully with failed to remove policy",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
deletePoliciesRes: &magistrala.DeletePolicyRes{
|
|
Deleted: false,
|
|
},
|
|
deletePoliciesErr: svcerr.ErrAuthorization,
|
|
err: svcerr.ErrAuthorization,
|
|
},
|
|
{
|
|
desc: "unsuccessfully with repo err",
|
|
token: token,
|
|
groupID: testsutil.GenerateUUID(t),
|
|
idResp: &magistrala.IdentityRes{
|
|
Id: testsutil.GenerateUUID(t),
|
|
DomainId: testsutil.GenerateUUID(t),
|
|
},
|
|
authzResp: &magistrala.AuthorizeRes{
|
|
Authorized: true,
|
|
},
|
|
deletePoliciesRes: &magistrala.DeletePolicyRes{
|
|
Deleted: true,
|
|
},
|
|
repoErr: repoerr.ErrNotFound,
|
|
err: repoerr.ErrNotFound,
|
|
},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
t.Run(tc.desc, func(t *testing.T) {
|
|
authcall := authsvc.On("Identify", context.Background(), &magistrala.IdentityReq{Token: tc.token}).Return(tc.idResp, tc.idErr)
|
|
authcall1 := authsvc.On("Authorize", context.Background(), &magistrala.AuthorizeReq{
|
|
Domain: tc.idResp.GetDomainId(),
|
|
SubjectType: auth.UserType,
|
|
SubjectKind: auth.UsersKind,
|
|
Subject: tc.idResp.GetId(),
|
|
Permission: auth.DeletePermission,
|
|
Object: tc.groupID,
|
|
ObjectType: auth.GroupType,
|
|
}).Return(tc.authzResp, tc.authzErr)
|
|
authcall2 := authsvc.On("DeleteEntityPolicies", context.Background(), &magistrala.DeleteEntityPoliciesReq{
|
|
EntityType: auth.GroupType,
|
|
Id: tc.groupID,
|
|
}).Return(tc.deletePoliciesRes, tc.deletePoliciesErr)
|
|
repocall := repo.On("Delete", context.Background(), tc.groupID).Return(tc.repoErr)
|
|
err := svc.DeleteGroup(context.Background(), tc.token, tc.groupID)
|
|
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("expected error %v to contain %v", err, tc.err))
|
|
authcall.Unset()
|
|
authcall1.Unset()
|
|
authcall2.Unset()
|
|
repocall.Unset()
|
|
})
|
|
}
|
|
}
|