mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-03-14 13:18:58 -04:00
Merge pull request #112 from owncloud/permission-check-tests
[tests-only] tests for account management permission checks
This commit is contained in:
@@ -189,8 +189,6 @@ func buildRoleServiceMock() settings.RoleService {
|
||||
return settings.MockRoleService{
|
||||
AssignRoleToUserFunc: func(ctx context.Context, req *settings.AssignRoleToUserRequest, opts ...client.CallOption) (res *settings.AssignRoleToUserResponse, err error) {
|
||||
mockedRoleAssignment[req.AccountUuid] = req.RoleId
|
||||
fmt.Println(mockedRoleAssignment)
|
||||
fmt.Println("asdf blablabla")
|
||||
return &settings.AssignRoleToUserResponse{
|
||||
Assignment: &settings.UserRoleAssignment{
|
||||
AccountUuid: req.AccountUuid,
|
||||
|
||||
366
pkg/service/v0/accounts_permission_test.go
Normal file
366
pkg/service/v0/accounts_permission_test.go
Normal file
@@ -0,0 +1,366 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/golang/protobuf/ptypes/empty"
|
||||
"github.com/micro/go-micro/v2/client"
|
||||
merrors "github.com/micro/go-micro/v2/errors"
|
||||
"github.com/micro/go-micro/v2/metadata"
|
||||
"github.com/owncloud/ocis-accounts/pkg/config"
|
||||
"github.com/owncloud/ocis-accounts/pkg/proto/v0"
|
||||
olog "github.com/owncloud/ocis-pkg/v2/log"
|
||||
"github.com/owncloud/ocis-pkg/v2/middleware"
|
||||
"github.com/owncloud/ocis-pkg/v2/roles"
|
||||
settings "github.com/owncloud/ocis-settings/pkg/proto/v0"
|
||||
ssvc "github.com/owncloud/ocis-settings/pkg/service/v0"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
const dataPath = "/var/tmp/ocis-accounts-tests"
|
||||
|
||||
var (
|
||||
roleServiceMock settings.RoleService
|
||||
s *Service
|
||||
)
|
||||
|
||||
func init() {
|
||||
cfg := config.New()
|
||||
cfg.Server.Name = "accounts"
|
||||
cfg.Server.AccountsDataPath = dataPath
|
||||
logger := olog.NewLogger(olog.Color(true), olog.Pretty(true))
|
||||
roleServiceMock = buildRoleServiceMock()
|
||||
roleManager := roles.NewManager(
|
||||
roles.Logger(logger),
|
||||
roles.RoleService(roleServiceMock),
|
||||
roles.CacheTTL(time.Hour),
|
||||
roles.CacheSize(1024),
|
||||
)
|
||||
s, _ = New(
|
||||
Logger(logger),
|
||||
Config(cfg),
|
||||
RoleService(roleServiceMock),
|
||||
RoleManager(&roleManager),
|
||||
)
|
||||
}
|
||||
|
||||
func setup() (teardown func()) {
|
||||
return func() {
|
||||
if err := os.RemoveAll(dataPath); err != nil {
|
||||
log.Printf("could not delete data root: %s", dataPath)
|
||||
} else {
|
||||
log.Println("data root deleted")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestPermissionsListAccounts checks permission handling on ListAccounts
|
||||
func TestPermissionsListAccounts(t *testing.T) {
|
||||
var scenarios = []struct {
|
||||
name string
|
||||
roleIDs []string
|
||||
query string
|
||||
permissionError error
|
||||
}{
|
||||
// TODO: remove this test when https://github.com/owncloud/ocis-accounts/pull/111 is merged
|
||||
// replace with two tests:
|
||||
// 1: "ListAccounts fails with 403 when roleIDs don't exist in context"
|
||||
// 2: "ListAccounts fails with 403 when ('no admin role in context' AND 'empty query')"
|
||||
{
|
||||
"ListAccounts succeeds when no roleIDs in context",
|
||||
nil,
|
||||
"",
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"ListAccounts fails when no admin roleID in context",
|
||||
[]string{ssvc.BundleUUIDRoleUser, ssvc.BundleUUIDRoleGuest},
|
||||
"",
|
||||
merrors.Forbidden(s.id, "no permission for ListAccounts"),
|
||||
},
|
||||
{
|
||||
"ListAccounts succeeds when admin roleID in context",
|
||||
[]string{ssvc.BundleUUIDRoleAdmin},
|
||||
"",
|
||||
nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, scenario := range scenarios {
|
||||
t.Run(scenario.name, func(t *testing.T) {
|
||||
teardown := setup()
|
||||
defer teardown()
|
||||
|
||||
ctx := buildTestCtx(t, scenario.roleIDs)
|
||||
request := &proto.ListAccountsRequest{
|
||||
Query: scenario.query,
|
||||
}
|
||||
response := &proto.ListAccountsResponse{}
|
||||
err := s.ListAccounts(ctx, request, response)
|
||||
if scenario.permissionError != nil {
|
||||
assert.Equal(t, scenario.permissionError, err)
|
||||
} else if err != nil {
|
||||
// we are only checking permissions here, so just check that the error code is not 403
|
||||
merr := merrors.FromError(err)
|
||||
assert.NotEqual(t, http.StatusForbidden, merr.GetCode())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestPermissionsGetAccount checks permission handling on GetAccount
|
||||
// TODO: remove this test function entirely, when https://github.com/owncloud/ocis-accounts/pull/111 is merged. GetAccount will not have permission checks for the time being.
|
||||
func TestPermissionsGetAccount(t *testing.T) {
|
||||
var scenarios = []struct {
|
||||
name string
|
||||
roleIDs []string
|
||||
permissionError error
|
||||
}{
|
||||
{
|
||||
"GetAccount succeeds when no role IDs in context",
|
||||
nil,
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"GetAccount fails when no admin roleID in context",
|
||||
[]string{ssvc.BundleUUIDRoleUser, ssvc.BundleUUIDRoleGuest},
|
||||
merrors.Forbidden(s.id, "no permission for GetAccount"),
|
||||
},
|
||||
{
|
||||
"GetAccount succeeds when admin roleID in context",
|
||||
[]string{ssvc.BundleUUIDRoleAdmin},
|
||||
nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, scenario := range scenarios {
|
||||
t.Run(scenario.name, func(t *testing.T) {
|
||||
teardown := setup()
|
||||
defer teardown()
|
||||
|
||||
ctx := buildTestCtx(t, scenario.roleIDs)
|
||||
request := &proto.GetAccountRequest{}
|
||||
response := &proto.Account{}
|
||||
err := s.GetAccount(ctx, request, response)
|
||||
if scenario.permissionError != nil {
|
||||
assert.Equal(t, scenario.permissionError, err)
|
||||
} else if err != nil {
|
||||
// we are only checking permissions here, so just check that the error code is not 403
|
||||
merr := merrors.FromError(err)
|
||||
assert.NotEqual(t, http.StatusForbidden, merr.GetCode())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestPermissionsCreateAccount checks permission handling on CreateAccount
|
||||
func TestPermissionsCreateAccount(t *testing.T) {
|
||||
var scenarios = []struct {
|
||||
name string
|
||||
roleIDs []string
|
||||
permissionError error
|
||||
}{
|
||||
// TODO: remove this test when https://github.com/owncloud/ocis-accounts/pull/111 is merged
|
||||
// replace with two tests:
|
||||
// 1: "CreateAccount fails with 403 when roleIDs don't exist in context"
|
||||
// 2: "CreateAccount fails with 403 when no admin role in context"
|
||||
{
|
||||
"CreateAccount succeeds when no role IDs in context",
|
||||
nil,
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"CreateAccount fails when no admin roleID in context",
|
||||
[]string{ssvc.BundleUUIDRoleUser, ssvc.BundleUUIDRoleGuest},
|
||||
merrors.Forbidden(s.id, "no permission for CreateAccount"),
|
||||
},
|
||||
{
|
||||
"CreateAccount succeeds when admin roleID in context",
|
||||
[]string{ssvc.BundleUUIDRoleAdmin},
|
||||
nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, scenario := range scenarios {
|
||||
t.Run(scenario.name, func(t *testing.T) {
|
||||
teardown := setup()
|
||||
defer teardown()
|
||||
|
||||
ctx := buildTestCtx(t, scenario.roleIDs)
|
||||
request := &proto.CreateAccountRequest{}
|
||||
response := &proto.Account{}
|
||||
err := s.CreateAccount(ctx, request, response)
|
||||
if scenario.permissionError != nil {
|
||||
assert.Equal(t, scenario.permissionError, err)
|
||||
} else if err != nil {
|
||||
// we are only checking permissions here, so just check that the error code is not 403
|
||||
merr := merrors.FromError(err)
|
||||
assert.NotEqual(t, http.StatusForbidden, merr.GetCode())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestPermissionsUpdateAccount checks permission handling on UpdateAccount
|
||||
func TestPermissionsUpdateAccount(t *testing.T) {
|
||||
var scenarios = []struct {
|
||||
name string
|
||||
roleIDs []string
|
||||
permissionError error
|
||||
}{
|
||||
// TODO: remove this test when https://github.com/owncloud/ocis-accounts/pull/111 is merged
|
||||
// replace with two tests:
|
||||
// 1: "UpdateAccount fails with 403 when roleIDs don't exist in context"
|
||||
// 2: "UpdateAccount fails with 403 when no admin role in context"
|
||||
{
|
||||
"UpdateAccount succeeds when no role IDs in context",
|
||||
nil,
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"UpdateAccount fails when no admin roleID in context",
|
||||
[]string{ssvc.BundleUUIDRoleUser, ssvc.BundleUUIDRoleGuest},
|
||||
merrors.Forbidden(s.id, "no permission for UpdateAccount"),
|
||||
},
|
||||
{
|
||||
"UpdateAccount succeeds when admin roleID in context",
|
||||
[]string{ssvc.BundleUUIDRoleAdmin},
|
||||
nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, scenario := range scenarios {
|
||||
t.Run(scenario.name, func(t *testing.T) {
|
||||
teardown := setup()
|
||||
defer teardown()
|
||||
|
||||
ctx := buildTestCtx(t, scenario.roleIDs)
|
||||
request := &proto.UpdateAccountRequest{}
|
||||
response := &proto.Account{}
|
||||
err := s.UpdateAccount(ctx, request, response)
|
||||
if scenario.permissionError != nil {
|
||||
assert.Equal(t, scenario.permissionError, err)
|
||||
} else if err != nil {
|
||||
// we are only checking permissions here, so just check that the error code is not 403
|
||||
merr := merrors.FromError(err)
|
||||
assert.NotEqual(t, http.StatusForbidden, merr.GetCode())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestPermissionsDeleteAccount checks permission handling on DeleteAccount
|
||||
func TestPermissionsDeleteAccount(t *testing.T) {
|
||||
var scenarios = []struct {
|
||||
name string
|
||||
roleIDs []string
|
||||
permissionError error
|
||||
}{
|
||||
// TODO: remove this test when https://github.com/owncloud/ocis-accounts/pull/111 is merged
|
||||
// replace with two tests:
|
||||
// 1: "DeleteAccount fails with 403 when roleIDs don't exist in context"
|
||||
// 2: "DeleteAccount fails with 403 when no admin role in context"
|
||||
{
|
||||
"DeleteAccount succeeds when no role IDs in context",
|
||||
nil,
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"DeleteAccount fails when no admin roleID in context",
|
||||
[]string{ssvc.BundleUUIDRoleUser, ssvc.BundleUUIDRoleGuest},
|
||||
merrors.Forbidden(s.id, "no permission for DeleteAccount"),
|
||||
},
|
||||
{
|
||||
"DeleteAccount succeeds when admin roleID in context",
|
||||
[]string{ssvc.BundleUUIDRoleAdmin},
|
||||
nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, scenario := range scenarios {
|
||||
t.Run(scenario.name, func(t *testing.T) {
|
||||
teardown := setup()
|
||||
defer teardown()
|
||||
|
||||
ctx := buildTestCtx(t, scenario.roleIDs)
|
||||
request := &proto.DeleteAccountRequest{}
|
||||
response := &empty.Empty{}
|
||||
err := s.DeleteAccount(ctx, request, response)
|
||||
if scenario.permissionError != nil {
|
||||
assert.Equal(t, scenario.permissionError, err)
|
||||
} else if err != nil {
|
||||
// we are only checking permissions here, so just check that the error code is not 403
|
||||
merr := merrors.FromError(err)
|
||||
assert.NotEqual(t, http.StatusForbidden, merr.GetCode())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func buildTestCtx(t *testing.T, roleIDs []string) context.Context {
|
||||
ctx := context.Background()
|
||||
if roleIDs != nil {
|
||||
roleIDs, err := json.Marshal(roleIDs)
|
||||
assert.NoError(t, err)
|
||||
ctx = metadata.Set(ctx, middleware.RoleIDs, string(roleIDs))
|
||||
}
|
||||
return ctx
|
||||
}
|
||||
|
||||
func buildRoleServiceMock() settings.RoleService {
|
||||
defaultRoles := map[string]*settings.Bundle{
|
||||
ssvc.BundleUUIDRoleAdmin: {
|
||||
Id: ssvc.BundleUUIDRoleAdmin,
|
||||
Type: settings.Bundle_TYPE_ROLE,
|
||||
Resource: &settings.Resource{
|
||||
Type: settings.Resource_TYPE_SYSTEM,
|
||||
},
|
||||
Settings: []*settings.Setting{
|
||||
{
|
||||
Id: AccountManagementPermissionID,
|
||||
},
|
||||
},
|
||||
},
|
||||
ssvc.BundleUUIDRoleUser: {
|
||||
Id: ssvc.BundleUUIDRoleUser,
|
||||
Type: settings.Bundle_TYPE_ROLE,
|
||||
Resource: &settings.Resource{
|
||||
Type: settings.Resource_TYPE_SYSTEM,
|
||||
},
|
||||
Settings: []*settings.Setting{},
|
||||
},
|
||||
ssvc.BundleUUIDRoleGuest: {
|
||||
Id: ssvc.BundleUUIDRoleGuest,
|
||||
Type: settings.Bundle_TYPE_ROLE,
|
||||
Resource: &settings.Resource{
|
||||
Type: settings.Resource_TYPE_SYSTEM,
|
||||
},
|
||||
Settings: []*settings.Setting{},
|
||||
},
|
||||
}
|
||||
return settings.MockRoleService{
|
||||
ListRolesFunc: func(ctx context.Context, req *settings.ListBundlesRequest, opts ...client.CallOption) (res *settings.ListBundlesResponse, err error) {
|
||||
payload := make([]*settings.Bundle, 0)
|
||||
for _, roleID := range req.BundleIds {
|
||||
if defaultRoles[roleID] != nil {
|
||||
payload = append(payload, defaultRoles[roleID])
|
||||
}
|
||||
}
|
||||
return &settings.ListBundlesResponse{
|
||||
Bundles: payload,
|
||||
}, nil
|
||||
},
|
||||
AssignRoleToUserFunc: func(ctx context.Context, req *settings.AssignRoleToUserRequest, opts ...client.CallOption) (res *settings.AssignRoleToUserResponse, err error) {
|
||||
// mock can be empty. function is called during service start. actual role assignments not needed for the tests.
|
||||
return &settings.AssignRoleToUserResponse{
|
||||
Assignment: &settings.UserRoleAssignment{},
|
||||
}, nil
|
||||
},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user