Using the new Permissions object, we can build a list of the level of access a user should have based on the grants they've been given, meaining we don't need to fetch all resources from the database to then remove the ones the user shouldn't be able to see. This commit also removes some unused options in `ListTargets` for the sake of simplicity.
311 lines
7.5 KiB
Go
311 lines
7.5 KiB
Go
package target
|
|
|
|
import (
|
|
"database/sql"
|
|
"testing"
|
|
|
|
"github.com/hashicorp/boundary/internal/db"
|
|
"github.com/hashicorp/boundary/internal/kms"
|
|
"github.com/hashicorp/boundary/internal/perms"
|
|
"github.com/hashicorp/boundary/internal/types/action"
|
|
"github.com/hashicorp/boundary/internal/types/resource"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestNewRepository(t *testing.T) {
|
|
t.Parallel()
|
|
conn, _ := db.TestSetup(t, "postgres")
|
|
rw := db.New(conn)
|
|
wrapper := db.TestWrapper(t)
|
|
testKms := kms.TestKms(t, conn, wrapper)
|
|
type args struct {
|
|
r db.Reader
|
|
w db.Writer
|
|
kms *kms.Kms
|
|
opts []Option
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want *Repository
|
|
wantErr bool
|
|
wantErrString string
|
|
}{
|
|
{
|
|
name: "valid",
|
|
args: args{
|
|
r: rw,
|
|
w: rw,
|
|
kms: testKms,
|
|
},
|
|
want: &Repository{
|
|
reader: rw,
|
|
writer: rw,
|
|
kms: testKms,
|
|
defaultLimit: db.DefaultLimit,
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "nil-kms",
|
|
args: args{
|
|
r: rw,
|
|
w: rw,
|
|
kms: nil,
|
|
},
|
|
want: nil,
|
|
wantErr: true,
|
|
wantErrString: "target.NewRepository: nil kms: parameter violation: error #100",
|
|
},
|
|
{
|
|
name: "nil-writer",
|
|
args: args{
|
|
r: rw,
|
|
w: nil,
|
|
kms: testKms,
|
|
},
|
|
want: nil,
|
|
wantErr: true,
|
|
wantErrString: "target.NewRepository: nil writer: parameter violation: error #100",
|
|
},
|
|
{
|
|
name: "nil-reader",
|
|
args: args{
|
|
r: nil,
|
|
w: rw,
|
|
kms: testKms,
|
|
},
|
|
want: nil,
|
|
wantErr: true,
|
|
wantErrString: "target.NewRepository: nil reader: parameter violation: error #100",
|
|
},
|
|
{
|
|
name: "WithPermissions sets object to `permissions`",
|
|
args: args{
|
|
r: rw,
|
|
w: rw,
|
|
kms: testKms,
|
|
opts: []Option{
|
|
WithPermissions([]perms.Permission{
|
|
{ScopeId: "test1", Resource: resource.Target},
|
|
{ScopeId: "test2", Resource: resource.Target},
|
|
}),
|
|
},
|
|
},
|
|
want: &Repository{
|
|
reader: rw,
|
|
writer: rw,
|
|
kms: testKms,
|
|
defaultLimit: db.DefaultLimit,
|
|
permissions: []perms.Permission{
|
|
{ScopeId: "test1", Resource: resource.Target},
|
|
{ScopeId: "test2", Resource: resource.Target},
|
|
},
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Don't accept permissions that aren't for the Target resource",
|
|
args: args{
|
|
r: rw,
|
|
w: rw,
|
|
kms: testKms,
|
|
opts: []Option{
|
|
WithPermissions([]perms.Permission{
|
|
{ScopeId: "test1", Resource: resource.Target},
|
|
{ScopeId: "test2", Resource: resource.Host},
|
|
}),
|
|
},
|
|
},
|
|
want: nil,
|
|
wantErr: true,
|
|
wantErrString: "target.NewRepository: permission for incorrect resource found: parameter violation: error #100",
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
assert, require := assert.New(t), require.New(t)
|
|
got, err := NewRepository(tt.args.r, tt.args.w, tt.args.kms, tt.args.opts...)
|
|
if tt.wantErr {
|
|
require.Error(err)
|
|
assert.Equal(tt.wantErrString, err.Error())
|
|
return
|
|
}
|
|
require.NoError(err)
|
|
assert.NotNil(got)
|
|
assert.Equal(tt.want, got)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRepositoryListPermissionWhereClauses(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
perms []perms.Permission
|
|
expWhere []string
|
|
expArgs []any
|
|
}{
|
|
{
|
|
name: "nilPerms",
|
|
perms: nil,
|
|
expWhere: []string{},
|
|
expArgs: []any{},
|
|
},
|
|
{
|
|
name: "emptyPerms",
|
|
perms: []perms.Permission{},
|
|
expWhere: []string{},
|
|
expArgs: []any{},
|
|
},
|
|
{
|
|
name: "noListActionPerms",
|
|
perms: []perms.Permission{
|
|
{
|
|
ScopeId: "scope_a",
|
|
Action: action.Create,
|
|
},
|
|
{
|
|
ScopeId: "scope_b",
|
|
Action: action.Read,
|
|
},
|
|
{
|
|
ScopeId: "scope_c",
|
|
Action: action.Delete,
|
|
},
|
|
},
|
|
expWhere: []string{},
|
|
expArgs: []any{},
|
|
},
|
|
{
|
|
name: "onePermissionAllResources",
|
|
perms: []perms.Permission{
|
|
{
|
|
ScopeId: "scope_a",
|
|
Action: action.List,
|
|
},
|
|
},
|
|
expWhere: []string{"(project_id = @project_id_1)"},
|
|
expArgs: []any{sql.Named("project_id_1", "scope_a")},
|
|
},
|
|
{
|
|
name: "onePermissionAllResourcesNonListIgnored",
|
|
perms: []perms.Permission{
|
|
{
|
|
ScopeId: "scope_a",
|
|
Action: action.List,
|
|
},
|
|
{
|
|
ScopeId: "scope_b",
|
|
Action: action.Create,
|
|
},
|
|
},
|
|
expWhere: []string{"(project_id = @project_id_1)"},
|
|
expArgs: []any{sql.Named("project_id_1", "scope_a")},
|
|
},
|
|
{
|
|
name: "onePermissionResourceIds",
|
|
perms: []perms.Permission{
|
|
{
|
|
ScopeId: "scope_a",
|
|
Action: action.List,
|
|
ResourceIds: []string{"resourceid1", "resourceid2"},
|
|
},
|
|
},
|
|
expWhere: []string{"(project_id = @project_id_1 and public_id = any(@public_id_1))"},
|
|
expArgs: []any{
|
|
sql.Named("project_id_1", "scope_a"),
|
|
sql.Named("public_id_1", "{resourceid1,resourceid2}"),
|
|
},
|
|
},
|
|
{
|
|
name: "multiplePermissionsAllResources",
|
|
perms: []perms.Permission{
|
|
{ScopeId: "scope_a", Action: action.List},
|
|
{ScopeId: "scope_b", Action: action.List},
|
|
{ScopeId: "scope_c", Action: action.List},
|
|
{ScopeId: "scope_d", Action: action.List},
|
|
},
|
|
expWhere: []string{
|
|
"(project_id = @project_id_1)",
|
|
"(project_id = @project_id_2)",
|
|
"(project_id = @project_id_3)",
|
|
"(project_id = @project_id_4)",
|
|
},
|
|
expArgs: []any{
|
|
sql.Named("project_id_1", "scope_a"),
|
|
sql.Named("project_id_2", "scope_b"),
|
|
sql.Named("project_id_3", "scope_c"),
|
|
sql.Named("project_id_4", "scope_d"),
|
|
},
|
|
},
|
|
{
|
|
name: "multiplePermissionsResourceIds",
|
|
perms: []perms.Permission{
|
|
{
|
|
ScopeId: "scope_a",
|
|
Action: action.List,
|
|
ResourceIds: []string{"resourceid1", "resourceid2"},
|
|
},
|
|
{
|
|
ScopeId: "scope_b",
|
|
Action: action.List,
|
|
ResourceIds: []string{"resourceid3", "resourceid4"},
|
|
},
|
|
},
|
|
expWhere: []string{
|
|
"(project_id = @project_id_1 and public_id = any(@public_id_1))",
|
|
"(project_id = @project_id_2 and public_id = any(@public_id_2))",
|
|
},
|
|
expArgs: []any{
|
|
sql.Named("project_id_1", "scope_a"),
|
|
sql.Named("project_id_2", "scope_b"),
|
|
sql.Named("public_id_1", "{resourceid1,resourceid2}"),
|
|
sql.Named("public_id_2", "{resourceid3,resourceid4}"),
|
|
},
|
|
},
|
|
{
|
|
name: "multiplePermissionsMix",
|
|
perms: []perms.Permission{
|
|
{
|
|
ScopeId: "scope_a",
|
|
Action: action.List,
|
|
ResourceIds: []string{"resourceid1", "resourceid2"},
|
|
},
|
|
{
|
|
ScopeId: "scope_b",
|
|
Action: action.List,
|
|
ResourceIds: []string{"resourceid3", "resourceid4"},
|
|
},
|
|
{ScopeId: "scope_c", Action: action.List},
|
|
{ScopeId: "scope_d", Action: action.List},
|
|
},
|
|
expWhere: []string{
|
|
"(project_id = @project_id_1 and public_id = any(@public_id_1))",
|
|
"(project_id = @project_id_2 and public_id = any(@public_id_2))",
|
|
"(project_id = @project_id_3)",
|
|
"(project_id = @project_id_4)",
|
|
},
|
|
expArgs: []any{
|
|
sql.Named("project_id_1", "scope_a"),
|
|
sql.Named("public_id_1", "{resourceid1,resourceid2}"),
|
|
sql.Named("project_id_2", "scope_b"),
|
|
sql.Named("public_id_2", "{resourceid3,resourceid4}"),
|
|
sql.Named("project_id_3", "scope_c"),
|
|
sql.Named("project_id_4", "scope_d"),
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
repo := Repository{}
|
|
repo.permissions = tt.perms
|
|
|
|
where, args := repo.listPermissionWhereClauses()
|
|
require.ElementsMatch(t, tt.expWhere, where)
|
|
require.ElementsMatch(t, tt.expArgs, args)
|
|
})
|
|
}
|
|
}
|