Skip to content

Commit

Permalink
Make session edge-router check more efficient. Fixes openziti#1418
Browse files Browse the repository at this point in the history
  • Loading branch information
plorenz committed Apr 12, 2023
1 parent 70a3610 commit d8e50ba
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 44 deletions.
11 changes: 2 additions & 9 deletions controller/handler_edge_ctrl/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,8 @@ func (self *baseSessionRequestContext) checkSessionFingerprints(fingerprints []s
func (self *baseSessionRequestContext) verifyEdgeRouterAccess() {
if self.err == nil {
// validate edge router
result, err := self.handler.getAppEnv().Managers.EdgeRouter.ListForSession(self.session.Id)
erMgr := self.handler.getAppEnv().Managers.EdgeRouter
edgeRouterAllowed, err := erMgr.IsAccessToEdgeRouterAllowed(self.session.IdentityId, self.session.ServiceId, self.sourceRouter.Id)
if err != nil {
self.err = internalError(err)
logrus.
Expand All @@ -239,14 +240,6 @@ func (self *baseSessionRequestContext) verifyEdgeRouterAccess() {
return
}

edgeRouterAllowed := false
for _, er := range result.EdgeRouters {
if er.Id == self.sourceRouter.Id {
edgeRouterAllowed = true
break
}
}

if !edgeRouterAllowed {
self.err = InvalidEdgeRouterForSessionError{}
}
Expand Down
2 changes: 1 addition & 1 deletion controller/internal/routes/session_api_model.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ func MapSessionsToRestEntities(ae *env.AppEnv, rc *response.RequestContext, sess
func getSessionEdgeRouters(ae *env.AppEnv, ns *model.Session) ([]*rest_model.SessionEdgeRouter, error) {
var edgeRouters []*rest_model.SessionEdgeRouter

edgeRoutersForSession, err := ae.Managers.EdgeRouter.ListForSession(ns.Id)
edgeRoutersForSession, err := ae.Managers.EdgeRouter.ListForIdentityAndService(ns.IdentityId, ns.ServiceId, nil)
if err != nil {
return nil, err
}
Expand Down
72 changes: 41 additions & 31 deletions controller/model/edge_router_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,27 +188,6 @@ func (self *EdgeRouterManager) Query(query string) (*EdgeRouterListResult, error
return result, nil
}

func (self *EdgeRouterManager) ListForSession(sessionId string) (*EdgeRouterListResult, error) {
var result *EdgeRouterListResult

err := self.env.GetDbProvider().GetDb().View(func(tx *bbolt.Tx) error {
session, err := self.env.GetStores().Session.LoadOneById(tx, sessionId)
if err != nil {
return err
}
apiSession, err := self.env.GetStores().ApiSession.LoadOneById(tx, session.ApiSessionId)
if err != nil {
return err
}

limit := -1

result, err = self.ListForIdentityAndServiceWithTx(tx, apiSession.IdentityId, session.ServiceId, &limit)
return err
})
return result, err
}

func (self *EdgeRouterManager) ListForIdentityAndService(identityId, serviceId string, limit *int) (*EdgeRouterListResult, error) {
var list *EdgeRouterListResult
var err error
Expand All @@ -223,27 +202,58 @@ func (self *EdgeRouterManager) ListForIdentityAndService(identityId, serviceId s
}

func (self *EdgeRouterManager) ListForIdentityAndServiceWithTx(tx *bbolt.Tx, identityId, serviceId string, limit *int) (*EdgeRouterListResult, error) {
service, err := self.env.GetStores().EdgeService.LoadOneById(tx, serviceId)
if err != nil {
return nil, err
}
if service == nil {
return nil, errors.Errorf("no service with id %v found", serviceId)
}

query := fmt.Sprintf(`anyOf(identities) = "%v" and anyOf(services) = "%v"`, identityId, service.Id)
query := fmt.Sprintf(`anyOf(identities) = "%v" and anyOf(services) = "%v"`, identityId, serviceId)

if limit != nil {
query += " limit " + strconv.Itoa(*limit)
}

result := &EdgeRouterListResult{manager: self}
if err = self.ListWithTx(tx, query, result.collect); err != nil {
if err := self.ListWithTx(tx, query, result.collect); err != nil {
return nil, err
}
return result, nil
}

func (self *EdgeRouterManager) IsAccessToEdgeRouterAllowed(identityId, serviceId, edgeRouterId string) (bool, error) {
var result bool
err := self.GetDb().View(func(tx *bbolt.Tx) error {
identityEdgeRouters := self.env.GetStores().Identity.GetRefCountedLinkCollection(db.EntityTypeRouters)
serviceEdgeRouters := self.env.GetStores().EdgeService.GetRefCountedLinkCollection(persistence.FieldEdgeRouters)

identityCount := identityEdgeRouters.GetLinkCount(tx, []byte(identityId), []byte(edgeRouterId))
serviceCount := serviceEdgeRouters.GetLinkCount(tx, []byte(serviceId), []byte(edgeRouterId))
result = identityCount != nil && *identityCount > 0 && serviceCount != nil && *serviceCount > 0
return nil
})
if err != nil {
return false, nil
}
return result, nil
}

func (self *EdgeRouterManager) IsSharedEdgeRouterPresent(identityId, serviceId string) (bool, error) {
var result bool
err := self.GetDb().View(func(tx *bbolt.Tx) error {
identityEdgeRouters := self.env.GetStores().Identity.GetRefCountedLinkCollection(db.EntityTypeRouters)
serviceEdgeRouters := self.env.GetStores().EdgeService.GetRefCountedLinkCollection(persistence.FieldEdgeRouters)

cursor := identityEdgeRouters.IterateLinks(tx, []byte(identityId), true)
for cursor.IsValid() {
serviceCount := serviceEdgeRouters.GetLinkCount(tx, []byte(serviceId), cursor.Current())
if result = serviceCount != nil && *serviceCount > 0; result {
return nil
}
cursor.Next()
}
return nil
})
if err != nil {
return false, nil
}
return result, nil
}

func (self *EdgeRouterManager) QueryRoleAttributes(queryString string) ([]string, *models.QueryMetaData, error) {
index := self.env.GetStores().EdgeRouter.GetRoleAttributesIndex()
return self.queryRoleAttributes(index, queryString)
Expand Down
9 changes: 9 additions & 0 deletions controller/model/edge_router_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,23 @@ func (ctx *TestContext) testGetEdgeRoutersForServiceAndIdentity(*testing.T) {
// test default case, with no limits on service
ctx.False(ctx.isEdgeRouterAccessible(edgeRouter.Id, identity.Id, service.Id))
ctx.False(ctx.isEdgeRouterAccessible(edgeRouter2.Id, identity.Id, service.Id))
ctx.False(ctx.managers.EdgeRouter.IsSharedEdgeRouterPresent(identity.Id, service.Id))

serp := ctx.requireNewServiceNewEdgeRouterPolicy(ss("@"+service.Id), ss("#"+eid.New()))

// should not be accessible if we limit to a role no one has
ctx.False(ctx.isEdgeRouterAccessible(edgeRouter.Id, identity.Id, service.Id))
ctx.False(ctx.isEdgeRouterAccessible(edgeRouter2.Id, identity.Id, service.Id))
ctx.False(ctx.managers.EdgeRouter.IsSharedEdgeRouterPresent(identity.Id, service.Id))

serp.EdgeRouterRoles = []string{"@" + edgeRouter.Id}
ctx.NoError(ctx.managers.ServiceEdgeRouterPolicy.Update(serp, nil))

// 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))
ctx.True(ctx.managers.EdgeRouter.IsSharedEdgeRouterPresent(identity.Id, service.Id))

}

func (ctx *TestContext) isEdgeRouterAccessible(edgeRouterId, identityId, serviceId string) bool {
Expand All @@ -58,5 +62,10 @@ func (ctx *TestContext) isEdgeRouterAccessible(edgeRouterId, identityId, service
return nil
})
ctx.NoError(err)

accessAllowed, err := ctx.managers.EdgeRouter.IsAccessToEdgeRouterAllowed(identityId, serviceId, edgeRouterId)
ctx.NoError(err)
ctx.Equal(found, accessAllowed)

return found
}
5 changes: 2 additions & 3 deletions controller/model/session_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,12 +189,11 @@ func (self *SessionManager) Create(entity *Session) (string, error) {
return "", apierror.NewInvalidPosture(policyResult.Cause)
}

maxRows := 1
result, err := self.GetEnv().GetManagers().EdgeRouter.ListForIdentityAndService(apiSession.IdentityId, entity.ServiceId, &maxRows)
edgeRouterAvailable, err := self.GetEnv().GetManagers().EdgeRouter.IsSharedEdgeRouterPresent(apiSession.IdentityId, entity.ServiceId)
if err != nil {
return "", err
}
if result.Count < 1 {
if !edgeRouterAvailable {
return "", apierror.NewNoEdgeRoutersAvailable()
}

Expand Down

0 comments on commit d8e50ba

Please sign in to comment.