Add support for user.spec in moderated sessions filters (#18402)

As pointed out in #15898, our moderated session filters use user.roles instead of user.spec.roles as the rest of Teleport.
This change adds support for both formats, so we don't break the existing filters and support the desired one.
This commit is contained in:
Jakub Nyckowski 2022-11-14 14:44:29 -05:00 committed by GitHub
parent e773e9c442
commit 71a1bcc81d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 1 deletions

View file

@ -98,7 +98,15 @@ type SessionAccessContext struct {
func (ctx *SessionAccessContext) GetIdentifier(fields []string) (interface{}, error) {
if fields[0] == "user" {
if len(fields) == 2 || len(fields) == 3 {
switch fields[1] {
checkedFieldIdx := 1
// Unify the format. Moderated session originally skipped the spec field (user.roles was used instead of
// user.spec.roles) which was not aligned with how our roles filtering works.
// Here we try support both cases. We don't want to modify the original fields slice,
// as that would change the reported error message (see return below).
if len(fields) == 3 && fields[1] == "spec" {
checkedFieldIdx = 2
}
switch fields[checkedFieldIdx] {
case "name":
return ctx.Username, nil
case "roles":

View file

@ -73,6 +73,46 @@ func successStartTestCase(t *testing.T) startTestCase {
}
}
func successStartTestCaseSpec(t *testing.T) startTestCase {
hostRole, err := types.NewRole("host", types.RoleSpecV5{})
require.NoError(t, err)
participantRole, err := types.NewRole("participant", types.RoleSpecV5{})
require.NoError(t, err)
hostRole.SetSessionRequirePolicies([]*types.SessionRequirePolicy{{
Filter: "contains(user.spec.roles, \"participant\")",
Kinds: []string{string(types.SSHSessionKind), string(types.KubernetesSessionKind)},
Count: 2,
OnLeave: types.OnSessionLeaveTerminate,
Modes: []string{"peer"},
}})
participantRole.SetSessionJoinPolicies([]*types.SessionJoinPolicy{{
Roles: []string{hostRole.GetName()},
Kinds: []string{string(types.SSHSessionKind), string(types.KubernetesSessionKind)},
Modes: []string{"*"},
}})
return startTestCase{
name: "success with spec",
host: []types.Role{hostRole},
sessionKinds: []types.SessionKind{types.SSHSessionKind, types.KubernetesSessionKind},
participants: []SessionAccessContext{
{
Username: "participant",
Roles: []types.Role{participantRole},
Mode: "peer",
},
{
Username: "participant2",
Roles: []types.Role{participantRole},
Mode: "peer",
},
},
expected: []bool{true, true},
}
}
func failCountStartTestCase(t *testing.T) startTestCase {
hostRole, err := types.NewRole("host", types.RoleSpecV5{})
require.NoError(t, err)
@ -173,6 +213,7 @@ func failFilterStartTestCase(t *testing.T) startTestCase {
func TestSessionAccessStart(t *testing.T) {
testCases := []startTestCase{
successStartTestCase(t),
successStartTestCaseSpec(t),
failCountStartTestCase(t),
failFilterStartTestCase(t),
succeedDiscardPolicySetStartTestCase(t),