From 6a770dcde96949fc86b8a0f05e02650a63129613 Mon Sep 17 00:00:00 2001 From: Paul Lorenz Date: Thu, 9 Jan 2020 15:16:07 -0500 Subject: [PATCH] Fix edge router roles check. services with role attributes were getting empty edge router lists --- controller/model/edge_router_handlers.go | 2 +- controller/model/edge_router_handlers_test.go | 63 ++++++++++++++++++ controller/model/testing.go | 64 ++++++++++++++++--- 3 files changed, 118 insertions(+), 11 deletions(-) create mode 100644 controller/model/edge_router_handlers_test.go diff --git a/controller/model/edge_router_handlers.go b/controller/model/edge_router_handlers.go index 7ed264f7e..d1a9791b1 100644 --- a/controller/model/edge_router_handlers.go +++ b/controller/model/edge_router_handlers.go @@ -158,7 +158,7 @@ func (handler *EdgeRouterHandler) ListForIdentityAndServiceWithTx(tx *bbolt.Tx, query := fmt.Sprintf(`anyOf(edgeRouterPolicies.identities) = "%v"`, identityId) - if len(service.RoleAttributes) > 0 && !stringz.Contains(service.RoleAttributes, "all") { + if len(service.EdgeRouterRoles) > 0 && !stringz.Contains(service.EdgeRouterRoles, "all") { query += fmt.Sprintf(` and anyOf(services) = "%v"`, service.Id) } diff --git a/controller/model/edge_router_handlers_test.go b/controller/model/edge_router_handlers_test.go new file mode 100644 index 000000000..06148a0fd --- /dev/null +++ b/controller/model/edge_router_handlers_test.go @@ -0,0 +1,63 @@ +package model + +import ( + "github.com/google/uuid" + "go.etcd.io/bbolt" + "testing" +) + +func TestEdgeRouterHandler(t *testing.T) { + ctx := newTestContext(t) + defer ctx.Cleanup() + ctx.Init() + + t.Run("test get edge routers for service and identity", ctx.testGetEdgeRoutersForServiceAndIdentity) +} + +func (ctx *TestContext) testGetEdgeRoutersForServiceAndIdentity(*testing.T) { + edgeRouter := ctx.requireNewEdgeRouter() + edgeRouter2 := ctx.requireNewEdgeRouter() + identity := ctx.requireNewIdentity(false) + service := ctx.requireNewService() + service.RoleAttributes = []string {uuid.New().String()} + ctx.NoError(ctx.handlers.Service.Update(service)) + + ctx.requireNewEdgeRouterPolicy(ss("@all"), ss("@all")) + + // test default case, with no limits on service + ctx.True(ctx.isEdgeRouterAccessible(edgeRouter.Id, identity.Id, service.Id)) + ctx.True(ctx.isEdgeRouterAccessible(edgeRouter2.Id, identity.Id, service.Id)) + + service.EdgeRouterRoles = []string {uuid.New().String()} + ctx.NoError(ctx.handlers.Service.Update(service)) + + // should not be accessible if we limit to a non-existent router + ctx.False(ctx.isEdgeRouterAccessible(edgeRouter.Id, identity.Id, service.Id)) + ctx.False(ctx.isEdgeRouterAccessible(edgeRouter2.Id, identity.Id, service.Id)) + + service.EdgeRouterRoles = []string {edgeRouter.Id} + ctx.NoError(ctx.handlers.Service.Update(service)) + + // should be accessible if we limit to our specific router + ctx.True(ctx.isEdgeRouterAccessible(edgeRouter.Id, identity.Id, service.Id)) + ctx.False(ctx.isEdgeRouterAccessible(edgeRouter2.Id, identity.Id, service.Id)) +} + +func (ctx *TestContext) isEdgeRouterAccessible(edgeRouterId, identityId, serviceId string) bool { + found := false + err := ctx.GetDbProvider().GetDb().View(func(tx *bbolt.Tx) error { + result, err := ctx.handlers.EdgeRouter.ListForIdentityAndServiceWithTx(tx, identityId, serviceId, nil) + if err != nil { + return err + } + for _, er := range result.EdgeRouters { + if er.Id == edgeRouterId { + found = true + break + } + } + return nil + }) + ctx.NoError(err) + return found +} \ No newline at end of file diff --git a/controller/model/testing.go b/controller/model/testing.go index a500cdcca..0156cb063 100644 --- a/controller/model/testing.go +++ b/controller/model/testing.go @@ -17,6 +17,8 @@ package model import ( + jwt2 "github.com/dgrijalva/jwt-go" + "github.com/google/uuid" "github.com/netfoundry/ziti-edge/controller/config" "github.com/netfoundry/ziti-edge/controller/persistence" "github.com/netfoundry/ziti-edge/internal/cert" @@ -27,6 +29,11 @@ import ( type TestContext struct { *persistence.TestContext handlers *Handlers + config *config.Config +} + +func (ctx *TestContext) Generate(string, string, jwt2.MapClaims) (string, error) { + return "I'm a very legitimate", nil } func (ctx *TestContext) GetHandlers() *Handlers { @@ -34,11 +41,11 @@ func (ctx *TestContext) GetHandlers() *Handlers { } func (ctx *TestContext) GetConfig() *config.Config { - panic("implement me") + return ctx.config } func (ctx *TestContext) GetEnrollmentJwtGenerator() jwt.EnrollmentGenerator { - panic("implement me") + return ctx } func (ctx *TestContext) GetDbProvider() persistence.DbProvider { @@ -77,14 +84,23 @@ func (ctx *TestContext) IsEdgeRouterOnline(id string) bool { panic("implement me") } -func NewTestContext(t *testing.T) *TestContext { - return &TestContext{ +func newTestContext(t *testing.T) *TestContext { + context := &TestContext{ TestContext: persistence.NewTestContext(t), } + context.Init() + return context } func (ctx *TestContext) Init() { ctx.TestContext.Init() + ctx.config = &config.Config{ + Enrollment: config.Enrollment{ + EdgeRouter: config.EnrollmentOption{ + DurationMinutes: 60, + }, + }, + } ctx.handlers = InitHandlers(ctx) } @@ -92,23 +108,25 @@ func (ctx *TestContext) Cleanup() { ctx.TestContext.Cleanup() } -func (ctx *TestContext) requireNewIdentity(name string, isAdmin bool) *Identity { +func (ctx *TestContext) requireNewIdentity(isAdmin bool) *Identity { + identityType, err := ctx.handlers.IdentityType.ReadByIdOrName("Service") + ctx.NoError(err) identity := &Identity{ - Name: name, + Name: uuid.New().String(), IsAdmin: isAdmin, + IdentityTypeId: identityType.Id, } - var err error identity.Id, err = ctx.handlers.Identity.Create(identity) ctx.NoError(err) return identity } -func (ctx *TestContext) requireNewService(name string) *Service { +func (ctx *TestContext) requireNewService() *Service { service := &Service{ EndpointAddress: "hosted:unclaimed", EgressRouter: "unclaimed", - Name: name, - DnsHostname: name, + Name: uuid.New().String(), + DnsHostname: uuid.New().String(), DnsPort: 0, } var err error @@ -116,3 +134,29 @@ func (ctx *TestContext) requireNewService(name string) *Service { ctx.NoError(err) return service } + +func (ctx *TestContext) requireNewEdgeRouter() *EdgeRouter { + edgeRouter := &EdgeRouter{ + Name: uuid.New().String(), + } + var err error + edgeRouter.Id, err = ctx.handlers.EdgeRouter.Create(edgeRouter) + ctx.NoError(err) + return edgeRouter +} + +func (ctx *TestContext) requireNewEdgeRouterPolicy(identityRoles, edgeRouterRoles []string) *EdgeRouterPolicy { + edgeRouterPolicy := &EdgeRouterPolicy{ + Name: uuid.New().String(), + IdentityRoles: identityRoles, + EdgeRouterRoles: edgeRouterRoles, + } + var err error + edgeRouterPolicy.Id, err = ctx.handlers.EdgeRouterPolicy.Create(edgeRouterPolicy) + ctx.NoError(err) + return edgeRouterPolicy +} + +func ss(vals...string) []string { + return vals +} \ No newline at end of file