Skip to content

Commit

Permalink
tsh UI: Squash Okta roles in tsh login output (#45581)
Browse files Browse the repository at this point in the history
  • Loading branch information
smallinsky authored Aug 22, 2024
1 parent 76f2a52 commit d528b7d
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 1 deletion.
7 changes: 7 additions & 0 deletions constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -939,3 +939,10 @@ const (
// debug service.
DebugServiceSocketName = "debug.sock"
)

const (
// OktaAccessRoleContext is the context used to name Okta Access role created by Okta access list sync
OktaAccessRoleContext = "access-okta-acl-role"
// OktaReviewerRoleContext is the context used to name Okta Reviewer role created by Okta Access List sync
OktaReviewerRoleContext = "reviewer-okta-acl-role"
)
31 changes: 30 additions & 1 deletion tool/tsh/common/tsh.go
Original file line number Diff line number Diff line change
Expand Up @@ -4477,7 +4477,7 @@ func printStatus(debug bool, p *profileInfo, env map[string]string, isActive boo
if cluster != "" {
fmt.Printf(" Cluster: %v\n", cluster)
}
fmt.Printf(" Roles: %v\n", strings.Join(p.Roles, ", "))
fmt.Printf(" Roles: %v\n", rolesToString(debug, p.Roles))
if debug {
var count int
for k, v := range p.Traits {
Expand Down Expand Up @@ -4535,6 +4535,35 @@ func printStatus(debug bool, p *profileInfo, env map[string]string, isActive boo
fmt.Printf("\n")
}

func isOktaRole(role string) bool {
return strings.Contains(role, teleport.OktaReviewerRoleContext) || strings.Contains(role, teleport.OktaAccessRoleContext)
}

func rolesToString(debug bool, roles []string) string {
sort.Strings(roles)
var nonOktaRoles, oktaRoles []string
for _, role := range roles {
if isOktaRole(role) {
oktaRoles = append(oktaRoles, role)
} else {
nonOktaRoles = append(nonOktaRoles, role)
}
}
if len(oktaRoles) == 0 {
return strings.Join(nonOktaRoles, ", ")
}

squashRolesThreshold := 9

if !debug && len(nonOktaRoles)+len(oktaRoles) > squashRolesThreshold {
oktaRolesText := fmt.Sprintf("and %v more Okta access list roles ...", len(oktaRoles))
return strings.Join(append(nonOktaRoles, oktaRolesText), ", ")
}
// Keep okta roles at the end of list.
out := append(nonOktaRoles, oktaRoles...)
return strings.Join(out, ", ")
}

// printLoginInformation displays the provided profile information to the user.
func printLoginInformation(cf *CLIConf, profile *client.ProfileStatus, profiles []*client.ProfileStatus, accessListsToReview []*accesslist.AccessList) error {
env := getTshEnv()
Expand Down
32 changes: 32 additions & 0 deletions tool/tsh/common/tsh_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6133,3 +6133,35 @@ func TestProxyTemplatesMakeClient(t *testing.T) {
})
}
}

func TestRolesToString(t *testing.T) {
tests := []struct {
name string
roles []string
expected string
debug bool
}{
{
name: "empty",
roles: []string{},
expected: "",
},
{
name: "exceed threshold okta roles should be squashed",
roles: append([]string{"app-figma-reviewer-okta-acl-role", "app-figma-access-okta-acl-role"}, []string{"r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10"}...),
expected: "r1, r10, r2, r3, r4, r5, r6, r7, r8, r9, and 2 more Okta access list roles ...",
},
{
name: "debug flag",
roles: append([]string{"app-figma-reviewer-okta-acl-role", "app-figma-access-okta-acl-role"}, []string{"r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10"}...),
debug: true,
expected: "r1, r10, r2, r3, r4, r5, r6, r7, r8, r9, app-figma-access-okta-acl-role, app-figma-reviewer-okta-acl-role",
},
}

for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
require.Equal(t, tc.expected, rolesToString(tc.debug, tc.roles))
})
}
}

0 comments on commit d528b7d

Please sign in to comment.