mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-05-07 20:15:31 -05:00
462 lines
13 KiB
Go
462 lines
13 KiB
Go
package svc
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"testing"
|
|
|
|
"github.com/opencloud-eu/opencloud/pkg/middleware"
|
|
settingsmsg "github.com/opencloud-eu/opencloud/protogen/gen/opencloud/messages/settings/v0"
|
|
v0 "github.com/opencloud-eu/opencloud/protogen/gen/opencloud/services/settings/v0"
|
|
"github.com/opencloud-eu/opencloud/services/settings/pkg/settings/mocks"
|
|
"github.com/opencloud-eu/opencloud/services/settings/pkg/store/defaults"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/mock"
|
|
merrors "go-micro.dev/v4/errors"
|
|
"go-micro.dev/v4/metadata"
|
|
)
|
|
|
|
var (
|
|
ctxWithUUID = metadata.Set(context.Background(), middleware.AccountID, "61445573-4dbe-4d56-88dc-88ab47aceba7")
|
|
ctxWithEmptyUUID = metadata.Set(context.Background(), middleware.AccountID, "")
|
|
emptyCtx = context.Background()
|
|
|
|
scenarios = []struct {
|
|
name string
|
|
accountUUID string
|
|
ctx context.Context
|
|
expect string
|
|
}{
|
|
{
|
|
name: "context with UUID; identifier = 'me'",
|
|
ctx: ctxWithUUID,
|
|
accountUUID: "me",
|
|
expect: "61445573-4dbe-4d56-88dc-88ab47aceba7",
|
|
},
|
|
{
|
|
name: "context with empty UUID; identifier = 'me'",
|
|
ctx: ctxWithEmptyUUID,
|
|
accountUUID: "me",
|
|
expect: "",
|
|
},
|
|
{
|
|
name: "context without UUID; identifier = 'me'",
|
|
ctx: emptyCtx,
|
|
accountUUID: "me",
|
|
expect: "",
|
|
},
|
|
{
|
|
name: "context with UUID; identifier not 'me'",
|
|
ctx: ctxWithUUID,
|
|
accountUUID: "",
|
|
expect: "",
|
|
},
|
|
}
|
|
)
|
|
|
|
func TestGetValidatedAccountUUID(t *testing.T) {
|
|
for _, s := range scenarios {
|
|
scenario := s
|
|
t.Run(scenario.name, func(t *testing.T) {
|
|
got := getValidatedAccountUUID(scenario.ctx, scenario.accountUUID)
|
|
assert.NotPanics(t, func() {
|
|
getValidatedAccountUUID(emptyCtx, scenario.accountUUID)
|
|
})
|
|
assert.Equal(t, scenario.expect, got)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestEditOwnRoleAssignment(t *testing.T) {
|
|
manager := &mocks.Manager{}
|
|
svc := Service{
|
|
manager: manager,
|
|
}
|
|
a := []*settingsmsg.UserRoleAssignment{}
|
|
manager.On("ListRoleAssignments", mock.Anything).Return(a, nil)
|
|
manager.On("WriteRoleAssignment", mock.Anything, mock.Anything).Return(nil, nil)
|
|
// Creating an initial self assignment is expected to succeed for UserRole when no assignment exists yet
|
|
req := v0.AssignRoleToUserRequest{
|
|
AccountUuid: "61445573-4dbe-4d56-88dc-88ab47aceba7",
|
|
RoleId: defaults.BundleUUIDRoleUser,
|
|
}
|
|
res := v0.AssignRoleToUserResponse{}
|
|
err := svc.AssignRoleToUser(ctxWithUUID, &req, &res)
|
|
assert.Nil(t, err)
|
|
|
|
// Creating an initial self assignment is expected to succeed for UserLightRole when no assignment exists yet
|
|
req = v0.AssignRoleToUserRequest{
|
|
AccountUuid: "61445573-4dbe-4d56-88dc-88ab47aceba7",
|
|
RoleId: defaults.BundleUUIDRoleUserLight,
|
|
}
|
|
res = v0.AssignRoleToUserResponse{}
|
|
err = svc.AssignRoleToUser(ctxWithUUID, &req, &res)
|
|
assert.Nil(t, err)
|
|
|
|
// Creating an initial self assignment is expected to fail for non UserRole when no assignment exists yet
|
|
req = v0.AssignRoleToUserRequest{
|
|
AccountUuid: "61445573-4dbe-4d56-88dc-88ab47aceba7",
|
|
RoleId: defaults.BundleUUIDRoleAdmin,
|
|
}
|
|
res = v0.AssignRoleToUserResponse{}
|
|
err = svc.AssignRoleToUser(ctxWithUUID, &req, &res)
|
|
assert.NotNil(t, err)
|
|
|
|
manager = &mocks.Manager{}
|
|
svc = Service{
|
|
manager: manager,
|
|
}
|
|
a = []*settingsmsg.UserRoleAssignment{
|
|
{
|
|
Id: "00000000-0000-0000-0000-000000000001",
|
|
AccountUuid: "61445573-4dbe-4d56-88dc-88ab47aceba7",
|
|
RoleId: "aceb15b8-7486-479f-ae32-c91118e07a39",
|
|
},
|
|
}
|
|
editRolePermission := &settingsmsg.Permission{
|
|
Operation: settingsmsg.Permission_OPERATION_READWRITE,
|
|
Constraint: settingsmsg.Permission_CONSTRAINT_ALL,
|
|
}
|
|
manager.On("ListRoleAssignments", mock.Anything).Return(a, nil)
|
|
manager.On("ReadPermissionByID", mock.Anything, mock.Anything).Return(editRolePermission, nil)
|
|
|
|
// Creating an self assignment is expect to fail if there is already an assingment
|
|
req = v0.AssignRoleToUserRequest{
|
|
AccountUuid: "61445573-4dbe-4d56-88dc-88ab47aceba7",
|
|
RoleId: defaults.BundleUUIDRoleUser,
|
|
}
|
|
res = v0.AssignRoleToUserResponse{}
|
|
err = svc.AssignRoleToUser(ctxWithUUID, &req, &res)
|
|
assert.NotNil(t, err)
|
|
|
|
manager.On("WriteRoleAssignment", mock.Anything, mock.Anything).Return(nil, nil)
|
|
// Creating an assignment for somebody else is expected to succeed, give the right permissions
|
|
req = v0.AssignRoleToUserRequest{
|
|
AccountUuid: "00000000-0000-0000-0000-000000000000",
|
|
RoleId: "aceb15b8-7486-479f-ae32-c91118e07a39",
|
|
}
|
|
res = v0.AssignRoleToUserResponse{}
|
|
err = svc.AssignRoleToUser(ctxWithUUID, &req, &res)
|
|
assert.Nil(t, err)
|
|
}
|
|
|
|
func TestRemoveOwnRoleAssignment(t *testing.T) {
|
|
manager := &mocks.Manager{}
|
|
a := []*settingsmsg.UserRoleAssignment{
|
|
{
|
|
Id: "00000000-0000-0000-0000-000000000001",
|
|
AccountUuid: "61445573-4dbe-4d56-88dc-88ab47aceba7",
|
|
RoleId: "aceb15b8-7486-479f-ae32-c91118e07a39",
|
|
},
|
|
}
|
|
editRolePermission := &settingsmsg.Permission{
|
|
Operation: settingsmsg.Permission_OPERATION_READWRITE,
|
|
Constraint: settingsmsg.Permission_CONSTRAINT_ALL,
|
|
}
|
|
manager.On("ReadPermissionByID", mock.Anything, mock.Anything).Return(editRolePermission, nil)
|
|
manager.On("ListRoleAssignments", mock.Anything).Return(a, nil)
|
|
svc := Service{
|
|
manager: manager,
|
|
}
|
|
|
|
// Removing a role for oneself is expected to fail
|
|
req := v0.RemoveRoleFromUserRequest{
|
|
Id: "00000000-0000-0000-0000-000000000001",
|
|
}
|
|
err := svc.RemoveRoleFromUser(ctxWithUUID, &req, nil)
|
|
assert.NotNil(t, err)
|
|
|
|
manager = &mocks.Manager{}
|
|
manager.On("ListRoleAssignments", mock.Anything).Return(nil, nil)
|
|
manager.On("RemoveRoleAssignment", mock.Anything).Return(nil)
|
|
manager.On("ReadPermissionByID", mock.Anything, mock.Anything).Return(editRolePermission, nil)
|
|
svc = Service{
|
|
manager: manager,
|
|
}
|
|
// Removing a role for someone else is expected to fail
|
|
req = v0.RemoveRoleFromUserRequest{
|
|
Id: "00000000-0000-0000-0000-000000000002",
|
|
}
|
|
err = svc.RemoveRoleFromUser(ctxWithUUID, &req, nil)
|
|
assert.Nil(t, err)
|
|
}
|
|
|
|
func TestListPermissionsOfCurrentUser(t *testing.T) {
|
|
manager := &mocks.Manager{}
|
|
a := []*settingsmsg.UserRoleAssignment{
|
|
{
|
|
Id: "00000000-0000-0000-0000-000000000001",
|
|
AccountUuid: "61445573-4dbe-4d56-88dc-88ab47aceba7",
|
|
RoleId: "aceb15b8-7486-479f-ae32-c91118e07a39",
|
|
},
|
|
}
|
|
manager.On("ListRoleAssignments", mock.Anything).Return(a, nil)
|
|
b := &settingsmsg.Bundle{
|
|
Id: "aceb15b8-7486-479f-ae32-c91118e07a39",
|
|
Settings: []*settingsmsg.Setting{
|
|
{
|
|
Name: "some-permission",
|
|
},
|
|
{
|
|
Name: "other-permission",
|
|
},
|
|
{
|
|
Name: "duplicate-permission",
|
|
},
|
|
{
|
|
Name: "duplicate-permission",
|
|
},
|
|
},
|
|
}
|
|
manager.On("ReadBundle", mock.Anything).Return(b, nil)
|
|
svc := Service{
|
|
manager: manager,
|
|
}
|
|
|
|
// Listing permissions for yourself
|
|
req := v0.ListPermissionsRequest{
|
|
AccountUuid: "61445573-4dbe-4d56-88dc-88ab47aceba7",
|
|
}
|
|
res := v0.ListPermissionsResponse{}
|
|
err := svc.ListPermissions(ctxWithUUID, &req, &res)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, res.Permissions, 3)
|
|
}
|
|
|
|
func TestListPermissionsOfOtherUser(t *testing.T) {
|
|
manager := &mocks.Manager{}
|
|
svc := Service{
|
|
manager: manager,
|
|
}
|
|
|
|
// Listing permissions for another user produces a not found error
|
|
req := v0.ListPermissionsRequest{
|
|
AccountUuid: "66666666-4444-4444-8888-88ab47aceba7",
|
|
}
|
|
res := v0.ListPermissionsResponse{}
|
|
err := svc.ListPermissions(ctxWithUUID, &req, &res)
|
|
assert.Error(t, err)
|
|
|
|
// assert the requested account uuid was not found
|
|
merr, ok := merrors.As(err)
|
|
assert.True(t, ok)
|
|
assert.Equal(t, int32(http.StatusNotFound), merr.Code)
|
|
assert.Contains(t, err.Error(), req.AccountUuid)
|
|
}
|
|
|
|
func TestListRoleAssignmentsFilteredValidation(t *testing.T) {
|
|
manager := &mocks.Manager{}
|
|
svc := Service{
|
|
manager: manager,
|
|
}
|
|
|
|
tests := map[string]struct {
|
|
req *v0.ListRoleAssignmentsFilteredRequest
|
|
statusCode int32
|
|
}{
|
|
"no filters": {
|
|
req: &v0.ListRoleAssignmentsFilteredRequest{},
|
|
statusCode: http.StatusBadRequest,
|
|
},
|
|
"multiple filters": {
|
|
req: &v0.ListRoleAssignmentsFilteredRequest{
|
|
Filters: []*settingsmsg.UserRoleAssignmentFilter{
|
|
{
|
|
Type: settingsmsg.UserRoleAssignmentFilter_TYPE_ACCOUNT,
|
|
Term: &settingsmsg.UserRoleAssignmentFilter_AccountUuid{
|
|
AccountUuid: "uid",
|
|
},
|
|
},
|
|
{
|
|
Type: settingsmsg.UserRoleAssignmentFilter_TYPE_ROLE,
|
|
Term: &settingsmsg.UserRoleAssignmentFilter_RoleId{
|
|
RoleId: "rid",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
statusCode: http.StatusBadRequest,
|
|
},
|
|
"bad filtertype": {
|
|
req: &v0.ListRoleAssignmentsFilteredRequest{
|
|
Filters: []*settingsmsg.UserRoleAssignmentFilter{
|
|
{
|
|
Type: settingsmsg.UserRoleAssignmentFilter_TYPE_UNKNOWN,
|
|
},
|
|
},
|
|
},
|
|
statusCode: http.StatusBadRequest,
|
|
},
|
|
"account filter without term": {
|
|
req: &v0.ListRoleAssignmentsFilteredRequest{
|
|
Filters: []*settingsmsg.UserRoleAssignmentFilter{
|
|
{
|
|
Type: settingsmsg.UserRoleAssignmentFilter_TYPE_ACCOUNT,
|
|
},
|
|
},
|
|
},
|
|
statusCode: http.StatusBadRequest,
|
|
},
|
|
"account filter with invalid term": {
|
|
req: &v0.ListRoleAssignmentsFilteredRequest{
|
|
Filters: []*settingsmsg.UserRoleAssignmentFilter{
|
|
{
|
|
Type: settingsmsg.UserRoleAssignmentFilter_TYPE_ACCOUNT,
|
|
Term: &settingsmsg.UserRoleAssignmentFilter_AccountUuid{
|
|
AccountUuid: "invalid-&*&^%$#",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
statusCode: http.StatusBadRequest,
|
|
},
|
|
"role filter without term": {
|
|
req: &v0.ListRoleAssignmentsFilteredRequest{
|
|
Filters: []*settingsmsg.UserRoleAssignmentFilter{
|
|
{
|
|
Type: settingsmsg.UserRoleAssignmentFilter_TYPE_ROLE,
|
|
},
|
|
},
|
|
},
|
|
statusCode: http.StatusBadRequest,
|
|
},
|
|
"role filter with invalid uuid": {
|
|
req: &v0.ListRoleAssignmentsFilteredRequest{
|
|
Filters: []*settingsmsg.UserRoleAssignmentFilter{
|
|
{
|
|
Type: settingsmsg.UserRoleAssignmentFilter_TYPE_ROLE,
|
|
Term: &settingsmsg.UserRoleAssignmentFilter_RoleId{
|
|
RoleId: "this is no uuid",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
statusCode: http.StatusBadRequest,
|
|
},
|
|
}
|
|
|
|
for name, test := range tests {
|
|
t.Run(name, func(t *testing.T) {
|
|
res := v0.ListRoleAssignmentsResponse{}
|
|
err := svc.ListRoleAssignmentsFiltered(ctxWithUUID, test.req, &res)
|
|
merr, ok := merrors.As(err)
|
|
assert.True(t, ok)
|
|
assert.Equal(t, int32(test.statusCode), merr.Code)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestListRoleAssignmentsFilteredByAccount(t *testing.T) {
|
|
accountUUID := "61445573-4dbe-4d56-88dc-88ab47aceba7"
|
|
|
|
tests := map[string]struct {
|
|
result []*settingsmsg.UserRoleAssignment
|
|
err error
|
|
status int32
|
|
}{
|
|
"handles manager error": {
|
|
result: nil,
|
|
err: assert.AnError,
|
|
status: http.StatusNotFound,
|
|
},
|
|
"succeeds with results": {
|
|
result: []*settingsmsg.UserRoleAssignment{
|
|
{
|
|
Id: "00000000-0000-0000-0000-000000000001",
|
|
AccountUuid: accountUUID,
|
|
RoleId: "aceb15b8-7486-479f-ae32-c91118e07a39",
|
|
},
|
|
},
|
|
err: nil,
|
|
status: http.StatusOK,
|
|
},
|
|
}
|
|
|
|
for name, test := range tests {
|
|
t.Run(name, func(t *testing.T) {
|
|
manager := &mocks.Manager{}
|
|
svc := Service{
|
|
manager: manager,
|
|
}
|
|
manager.On("ListRoleAssignments", mock.Anything).Return(test.result, test.err)
|
|
req := &v0.ListRoleAssignmentsFilteredRequest{
|
|
Filters: []*settingsmsg.UserRoleAssignmentFilter{
|
|
{
|
|
Type: settingsmsg.UserRoleAssignmentFilter_TYPE_ACCOUNT,
|
|
Term: &settingsmsg.UserRoleAssignmentFilter_AccountUuid{
|
|
AccountUuid: accountUUID,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
res := v0.ListRoleAssignmentsResponse{}
|
|
err := svc.ListRoleAssignmentsFiltered(ctxWithUUID, req, &res)
|
|
switch test.err {
|
|
case nil:
|
|
assert.Nil(t, err)
|
|
default:
|
|
merr, ok := merrors.As(err)
|
|
assert.True(t, ok)
|
|
assert.Equal(t, int32(test.status), merr.Code)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestListRoleAssignmentsFilteredByRole(t *testing.T) {
|
|
roleID := "61445573-4dbe-4d56-88dc-88ab47aceba7"
|
|
|
|
tests := map[string]struct {
|
|
result []*settingsmsg.UserRoleAssignment
|
|
err error
|
|
status int32
|
|
}{
|
|
"handles manager error": {
|
|
result: nil,
|
|
err: assert.AnError,
|
|
status: http.StatusNotFound,
|
|
},
|
|
"succeeds with results": {
|
|
result: []*settingsmsg.UserRoleAssignment{
|
|
{
|
|
Id: "00000000-0000-0000-0000-000000000001",
|
|
AccountUuid: "aceb15b8-7486-479f-ae32-c91118e07a39",
|
|
RoleId: roleID,
|
|
},
|
|
},
|
|
err: nil,
|
|
status: http.StatusOK,
|
|
},
|
|
}
|
|
|
|
for name, test := range tests {
|
|
t.Run(name, func(t *testing.T) {
|
|
manager := &mocks.Manager{}
|
|
svc := Service{
|
|
manager: manager,
|
|
}
|
|
manager.On("ListRoleAssignmentsByRole", mock.Anything).Return(test.result, test.err)
|
|
req := &v0.ListRoleAssignmentsFilteredRequest{
|
|
Filters: []*settingsmsg.UserRoleAssignmentFilter{
|
|
{
|
|
Type: settingsmsg.UserRoleAssignmentFilter_TYPE_ROLE,
|
|
Term: &settingsmsg.UserRoleAssignmentFilter_RoleId{
|
|
RoleId: roleID,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
res := v0.ListRoleAssignmentsResponse{}
|
|
err := svc.ListRoleAssignmentsFiltered(ctxWithUUID, req, &res)
|
|
switch test.err {
|
|
case nil:
|
|
assert.Nil(t, err)
|
|
default:
|
|
merr, ok := merrors.As(err)
|
|
assert.True(t, ok)
|
|
assert.Equal(t, int32(test.status), merr.Code)
|
|
}
|
|
})
|
|
}
|
|
}
|