Skip to content

Commit

Permalink
Inline test helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
atburke committed Aug 13, 2024
1 parent 7772600 commit 171ff86
Show file tree
Hide file tree
Showing 4 changed files with 192 additions and 152 deletions.
121 changes: 99 additions & 22 deletions lib/auth/kubewaitingcontainer/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@ import (
kubewaitingcontainerpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/kubewaitingcontainer/v1"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/api/types/kubewaitingcontainer"
"github.com/gravitational/teleport/lib/auth/test"
"github.com/gravitational/teleport/lib/authz"
"github.com/gravitational/teleport/lib/backend/memory"
"github.com/gravitational/teleport/lib/services/local"
"github.com/gravitational/teleport/lib/tlsca"
)

func TestKubeWaitingContainerServiceCRUD(t *testing.T) {
Expand Down Expand Up @@ -71,14 +72,14 @@ func TestKubeWaitingContainerServiceCRUD(t *testing.T) {

tt := []struct {
Name string
Authorizer func(t *testing.T, client test.LocalClient) authz.Authorizer
Authorizer func(t *testing.T, client localClient) authz.Authorizer
Setup func(t *testing.T, ctx context.Context, resourceSvc *Service, wcName string)
Test func(t *testing.T, ctx context.Context, resourceSvc *Service, wcName string)
}{
// List
{
Name: "allowed list access",
Authorizer: func(t *testing.T, client test.LocalClient) authz.Authorizer {
Authorizer: func(t *testing.T, client localClient) authz.Authorizer {
return kubeAuthFn
},
Setup: func(t *testing.T, ctx context.Context, resourceSvc *Service, wcName string) {
Expand All @@ -96,9 +97,9 @@ func TestKubeWaitingContainerServiceCRUD(t *testing.T) {
},
{
Name: "not allowed list access",
Authorizer: func(t *testing.T, client test.LocalClient) authz.Authorizer {
Authorizer: func(t *testing.T, client localClient) authz.Authorizer {
return authz.AuthorizerFunc(func(ctx context.Context) (*authz.Context, error) {
return test.AuthorizerForDummyUser(t, ctx, client, types.KindKubeWaitingContainer, []string{types.VerbRead, types.VerbList}), nil
return authorizerForDummyUser(t, ctx, client, []string{types.VerbRead, types.VerbList}), nil
})
},
Test: func(t *testing.T, ctx context.Context, resourceSvc *Service, wcName string) {
Expand All @@ -111,7 +112,7 @@ func TestKubeWaitingContainerServiceCRUD(t *testing.T) {
// Get
{
Name: "allowed get access",
Authorizer: func(t *testing.T, client test.LocalClient) authz.Authorizer {
Authorizer: func(t *testing.T, client localClient) authz.Authorizer {
return kubeAuthFn
},
Setup: func(t *testing.T, ctx context.Context, resourceSvc *Service, wcName string) {
Expand Down Expand Up @@ -140,9 +141,9 @@ func TestKubeWaitingContainerServiceCRUD(t *testing.T) {
},
{
Name: "not allowed get access",
Authorizer: func(t *testing.T, client test.LocalClient) authz.Authorizer {
Authorizer: func(t *testing.T, client localClient) authz.Authorizer {
return authz.AuthorizerFunc(func(ctx context.Context) (*authz.Context, error) {
return test.AuthorizerForDummyUser(t, ctx, client, types.KindKubeWaitingContainer, []string{types.VerbRead, types.VerbList}), nil
return authorizerForDummyUser(t, ctx, client, []string{types.VerbRead, types.VerbList}), nil
})
},
Test: func(t *testing.T, ctx context.Context, resourceSvc *Service, wcName string) {
Expand All @@ -159,7 +160,7 @@ func TestKubeWaitingContainerServiceCRUD(t *testing.T) {
},
{
Name: "get nonexistent resource",
Authorizer: func(t *testing.T, client test.LocalClient) authz.Authorizer {
Authorizer: func(t *testing.T, client localClient) authz.Authorizer {
return kubeAuthFn
},
Test: func(t *testing.T, ctx context.Context, resourceSvc *Service, wcName string) {
Expand All @@ -178,7 +179,7 @@ func TestKubeWaitingContainerServiceCRUD(t *testing.T) {
// Create
{
Name: "allowed create access",
Authorizer: func(t *testing.T, client test.LocalClient) authz.Authorizer {
Authorizer: func(t *testing.T, client localClient) authz.Authorizer {
return kubeAuthFn
},
Test: func(t *testing.T, ctx context.Context, resourceSvc *Service, wcName string) {
Expand All @@ -197,9 +198,9 @@ func TestKubeWaitingContainerServiceCRUD(t *testing.T) {
},
{
Name: "not allowed create access",
Authorizer: func(t *testing.T, client test.LocalClient) authz.Authorizer {
Authorizer: func(t *testing.T, client localClient) authz.Authorizer {
return authz.AuthorizerFunc(func(ctx context.Context) (*authz.Context, error) {
return test.AuthorizerForDummyUser(t, ctx, client, types.KindKubeWaitingContainer, []string{types.VerbRead, types.VerbList}), nil
return authorizerForDummyUser(t, ctx, client, []string{types.VerbRead, types.VerbList}), nil
})
},
Test: func(t *testing.T, ctx context.Context, resourceSvc *Service, wcName string) {
Expand All @@ -212,7 +213,7 @@ func TestKubeWaitingContainerServiceCRUD(t *testing.T) {
},
{
Name: "create resource twice",
Authorizer: func(t *testing.T, client test.LocalClient) authz.Authorizer {
Authorizer: func(t *testing.T, client localClient) authz.Authorizer {
return kubeAuthFn
},
Setup: func(t *testing.T, ctx context.Context, resourceSvc *Service, wcName string) {
Expand All @@ -233,7 +234,7 @@ func TestKubeWaitingContainerServiceCRUD(t *testing.T) {
// Delete
{
Name: "allowed delete access",
Authorizer: func(t *testing.T, client test.LocalClient) authz.Authorizer {
Authorizer: func(t *testing.T, client localClient) authz.Authorizer {
return kubeAuthFn
},
Setup: func(t *testing.T, ctx context.Context, resourceSvc *Service, wcName string) {
Expand All @@ -255,9 +256,9 @@ func TestKubeWaitingContainerServiceCRUD(t *testing.T) {
},
{
Name: "not allowed delete access",
Authorizer: func(t *testing.T, client test.LocalClient) authz.Authorizer {
Authorizer: func(t *testing.T, client localClient) authz.Authorizer {
return authz.AuthorizerFunc(func(ctx context.Context) (*authz.Context, error) {
return test.AuthorizerForDummyUser(t, ctx, client, types.KindKubeWaitingContainer, []string{types.VerbRead, types.VerbList}), nil
return authorizerForDummyUser(t, ctx, client, []string{types.VerbRead, types.VerbList}), nil
})
},
Test: func(t *testing.T, ctx context.Context, resourceSvc *Service, wcName string) {
Expand All @@ -273,8 +274,8 @@ func TestKubeWaitingContainerServiceCRUD(t *testing.T) {
},
},
{
Name: "delete nonexistent resource",
Authorizer: func(t *testing.T, client test.LocalClient) authz.Authorizer {
Name: "get nonexistent resource",
Authorizer: func(t *testing.T, client localClient) authz.Authorizer {
return kubeAuthFn
},
Test: func(t *testing.T, ctx context.Context, resourceSvc *Service, wcName string) {
Expand All @@ -296,7 +297,7 @@ func TestKubeWaitingContainerServiceCRUD(t *testing.T) {
t.Run(tc.Name, func(t *testing.T) {
t.Parallel()

ctx, resourceSvc := initSvc(t, tc.Authorizer)
ctx, _, resourceSvc := initSvc(t, tc.Authorizer)

wcName := uuid.NewString()
if tc.Setup != nil {
Expand All @@ -308,16 +309,92 @@ func TestKubeWaitingContainerServiceCRUD(t *testing.T) {
}
}

func initSvc(t *testing.T, authorizerFn func(t *testing.T, client test.LocalClient) authz.Authorizer) (context.Context, *Service) {
ctx, client, backend := test.InitRBACServices(t)
func authorizerForDummyUser(t *testing.T, ctx context.Context, localClient localClient, roleVerbs []string) *authz.Context {
const clusterName = "localhost"

// Create role
roleName := "role-" + uuid.NewString()
role, err := types.NewRole(roleName, types.RoleSpecV6{
Allow: types.RoleConditions{Rules: []types.Rule{{
Resources: []string{types.KindKubeWaitingContainer},
Verbs: roleVerbs,
}}},
})
require.NoError(t, err)

role, err = localClient.CreateRole(ctx, role)
require.NoError(t, err)

// Create user
user, err := types.NewUser("user-" + uuid.NewString())
require.NoError(t, err)
user.AddRole(roleName)
user, err = localClient.CreateUser(ctx, user)
require.NoError(t, err)

localUser := authz.LocalUser{
Username: user.GetName(),
Identity: tlsca.Identity{
Username: user.GetName(),
Groups: []string{role.GetName()},
},
}
authCtx, err := authz.ContextForLocalUser(ctx, localUser, localClient, clusterName, true)
require.NoError(t, err)

return authCtx
}

type localClient interface {
authz.AuthorizerAccessPoint

CreateUser(ctx context.Context, user types.User) (types.User, error)
CreateRole(ctx context.Context, role types.Role) (types.Role, error)
}

func initSvc(t *testing.T, authorizerFn func(t *testing.T, client localClient) authz.Authorizer) (context.Context, localClient, *Service) {
ctx := context.Background()
backend, err := memory.New(memory.Config{})
require.NoError(t, err)

roleSvc := local.NewAccessService(backend)
userSvc := local.NewTestIdentityService(backend)
clusterSrv, err := local.NewClusterConfigurationService(backend)
require.NoError(t, err)
caSrv := local.NewCAService(backend)

clusterConfigSvc, err := local.NewClusterConfigurationService(backend)
require.NoError(t, err)
_, err = clusterConfigSvc.UpsertAuthPreference(ctx, types.DefaultAuthPreference())
require.NoError(t, err)
_, err = clusterConfigSvc.UpsertClusterAuditConfig(ctx, types.DefaultClusterAuditConfig())
require.NoError(t, err)
_, err = clusterConfigSvc.UpsertClusterNetworkingConfig(ctx, types.DefaultClusterNetworkingConfig())
require.NoError(t, err)
_, err = clusterConfigSvc.UpsertSessionRecordingConfig(ctx, types.DefaultSessionRecordingConfig())
require.NoError(t, err)

localResourceService, err := local.NewKubeWaitingContainerService(backend)
require.NoError(t, err)

client := struct {
*local.AccessService
*local.IdentityService
*local.ClusterConfigurationService
*local.CA
}{
AccessService: roleSvc,
IdentityService: userSvc,
ClusterConfigurationService: clusterSrv,
CA: caSrv,
}

resourceSvc, err := NewService(ServiceConfig{
Authorizer: authorizerFn(t, client),
Backend: localResourceService,
Cache: localResourceService,
})
require.NoError(t, err)
return ctx, resourceSvc

return ctx, client, resourceSvc
}
98 changes: 91 additions & 7 deletions lib/auth/statichostuser/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,21 @@ import (
"fmt"
"testing"

"github.com/google/uuid"
"github.com/gravitational/trace"
"github.com/stretchr/testify/require"

userprovisioningpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/userprovisioning/v1"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/api/types/userprovisioning"
"github.com/gravitational/teleport/api/types/wrappers"
"github.com/gravitational/teleport/lib/auth/test"
"github.com/gravitational/teleport/lib/authz"
"github.com/gravitational/teleport/lib/backend/memory"
"github.com/gravitational/teleport/lib/services/local"
"github.com/gravitational/teleport/lib/tlsca"
)

type authorizerFactory func(t *testing.T, client test.LocalClient) authz.Authorizer
type authorizerFactory func(t *testing.T, client localClient) authz.Authorizer

func staticHostUserName(i int) string {
return fmt.Sprintf("user-%d", i)
Expand All @@ -55,9 +57,9 @@ func makeStaticHostUser(i int) *userprovisioningpb.StaticHostUser {
}

func authorizeWithVerbs(verbs []string, mfaVerified bool) authorizerFactory {
return func(t *testing.T, client test.LocalClient) authz.Authorizer {
return func(t *testing.T, client localClient) authz.Authorizer {
return authz.AuthorizerFunc(func(ctx context.Context) (*authz.Context, error) {
authzContext := test.AuthorizerForDummyUser(t, ctx, client, types.KindStaticHostUser, verbs)
authzContext := authorizerForDummyUser(t, ctx, client, verbs)
if mfaVerified {
authzContext.AdminActionAuthState = authz.AdminActionAuthMFAVerified
} else {
Expand Down Expand Up @@ -255,7 +257,7 @@ func TestStaticHostUserCRUD(t *testing.T) {

func testStaticHostUserAccess(
t *testing.T,
authorizer func(t *testing.T, client test.LocalClient) authz.Authorizer,
authorizer func(t *testing.T, client localClient) authz.Authorizer,
request func(ctx context.Context, svc *Service, localSvc *local.StaticHostUserService) error,
assert require.ErrorAssertionFunc,
) {
Expand All @@ -264,19 +266,101 @@ func testStaticHostUserAccess(
assert(t, err)
}

func initSvc(t *testing.T, authorizerFn authorizerFactory) (context.Context, *Service, *local.StaticHostUserService) {
ctx, client, backend := test.InitRBACServices(t)
func authorizerForDummyUser(t *testing.T, ctx context.Context, localClient localClient, roleVerbs []string) *authz.Context {
const clusterName = "localhost"

// Create role
roleName := "role-" + uuid.NewString()
var allowRules []types.Rule
if len(roleVerbs) != 0 {
allowRules = []types.Rule{
{
Resources: []string{types.KindStaticHostUser},
Verbs: roleVerbs,
},
}
}
role, err := types.NewRole(roleName, types.RoleSpecV6{
Allow: types.RoleConditions{Rules: allowRules},
})
require.NoError(t, err)

role, err = localClient.CreateRole(ctx, role)
require.NoError(t, err)

// Create user
user, err := types.NewUser("user-" + uuid.NewString())
require.NoError(t, err)
user.AddRole(roleName)
user, err = localClient.CreateUser(ctx, user)
require.NoError(t, err)

localUser := authz.LocalUser{
Username: user.GetName(),
Identity: tlsca.Identity{
Username: user.GetName(),
Groups: []string{role.GetName()},
},
}
authCtx, err := authz.ContextForLocalUser(ctx, localUser, localClient, clusterName, true)
require.NoError(t, err)

return authCtx
}

type localClient interface {
authz.AuthorizerAccessPoint

CreateUser(ctx context.Context, user types.User) (types.User, error)
CreateRole(ctx context.Context, role types.Role) (types.Role, error)
}

func initSvc(t *testing.T, authorizerFn func(t *testing.T, client localClient) authz.Authorizer) (context.Context, *Service, *local.StaticHostUserService) {
ctx := context.Background()
backend, err := memory.New(memory.Config{})
require.NoError(t, err)

roleSvc := local.NewAccessService(backend)
userSvc := local.NewTestIdentityService(backend)
clusterSrv, err := local.NewClusterConfigurationService(backend)
require.NoError(t, err)
caSrv := local.NewCAService(backend)

clusterConfigSvc, err := local.NewClusterConfigurationService(backend)
require.NoError(t, err)
_, err = clusterConfigSvc.UpsertAuthPreference(ctx, types.DefaultAuthPreference())
require.NoError(t, err)
_, err = clusterConfigSvc.UpsertClusterAuditConfig(ctx, types.DefaultClusterAuditConfig())
require.NoError(t, err)
_, err = clusterConfigSvc.UpsertClusterNetworkingConfig(ctx, types.DefaultClusterNetworkingConfig())
require.NoError(t, err)
_, err = clusterConfigSvc.UpsertSessionRecordingConfig(ctx, types.DefaultSessionRecordingConfig())
require.NoError(t, err)

localResourceService, err := local.NewStaticHostUserService(backend)
require.NoError(t, err)
for i := 0; i < 10; i++ {
_, err := localResourceService.CreateStaticHostUser(ctx, makeStaticHostUser(i))
require.NoError(t, err)
}

client := struct {
*local.AccessService
*local.IdentityService
*local.ClusterConfigurationService
*local.CA
}{
AccessService: roleSvc,
IdentityService: userSvc,
ClusterConfigurationService: clusterSrv,
CA: caSrv,
}

resourceSvc, err := NewService(ServiceConfig{
Authorizer: authorizerFn(t, client),
Backend: localResourceService,
})
require.NoError(t, err)

return ctx, resourceSvc, localResourceService
}
Loading

0 comments on commit 171ff86

Please sign in to comment.