Skip to content

Commit 020342a

Browse files
authored
fix: supports roles as json, comma or pipe sepearated values (#4150)
1 parent 3b0b3ed commit 020342a

File tree

2 files changed

+85
-3
lines changed

2 files changed

+85
-3
lines changed

internal/auth/roles.go

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package auth
22

33
import (
4+
"encoding/json"
45
"strings"
56

67
"github.com/rs/zerolog/log"
@@ -18,9 +19,28 @@ const (
1819
const All = Shell | Actions | Download
1920

2021
// ParseRole parses a comma-separated string of roles and returns the corresponding Role.
21-
func ParseRole(commaValues string) Role {
22+
func ParseRole(input string) Role {
2223
var roles Role
23-
for r := range strings.SplitSeq(commaValues, ",") {
24+
var parts []string
25+
26+
// Check if input is valid JSON
27+
trimmed := strings.TrimSpace(input)
28+
if json.Valid([]byte(trimmed)) {
29+
var jsonRoles []string
30+
if err := json.Unmarshal([]byte(trimmed), &jsonRoles); err == nil {
31+
parts = jsonRoles
32+
} else {
33+
log.Warn().Str("input", input).Msg("failed to parse JSON roles")
34+
return None
35+
}
36+
} else {
37+
// Split by both commas and pipes
38+
parts = strings.FieldsFunc(input, func(c rune) bool {
39+
return c == ',' || c == '|'
40+
})
41+
}
42+
43+
for _, r := range parts {
2444
role := strings.TrimSpace(strings.ToLower(r))
2545
switch role {
2646
case "shell":
@@ -34,7 +54,7 @@ func ParseRole(commaValues string) Role {
3454
case "all":
3555
return All
3656
default:
37-
log.Warn().Str("role", role).Msg("invalid role")
57+
log.Debug().Str("role", role).Msg("invalid role")
3858
}
3959
}
4060
return roles

internal/auth/roles_test.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package auth
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestParseRole(t *testing.T) {
8+
testCases := []struct {
9+
name string
10+
input string
11+
expected Role
12+
}{
13+
// Single role tests
14+
{"Single shell role", "shell", Shell},
15+
{"Single actions role", "actions", Actions},
16+
{"Single download role", "download", Download},
17+
{"None role", "none", None},
18+
{"All role", "all", All},
19+
20+
// Case insensitive tests
21+
{"Shell uppercase", "SHELL", Shell},
22+
{"Actions mixed case", "AcTiOnS", Actions},
23+
{"Download with spaces", " download ", Download},
24+
25+
// Multiple roles with comma separator
26+
{"Shell and actions", "shell,actions", Shell | Actions},
27+
{"All three roles", "shell,actions,download", Shell | Actions | Download},
28+
{"Roles with spaces", "shell , actions , download", Shell | Actions | Download},
29+
30+
// Multiple roles with pipe separator
31+
{"Shell and actions with pipe", "shell|actions", Shell | Actions},
32+
{"All three with pipe", "shell|actions|download", Shell | Actions | Download},
33+
{"Mixed separators", "shell,actions|download", Shell | Actions | Download},
34+
35+
// JSON format tests
36+
{"JSON single role", `["shell"]`, Shell},
37+
{"JSON multiple roles", `["shell", "actions"]`, Shell | Actions},
38+
{"JSON all roles", `["shell", "actions", "download"]`, Shell | Actions | Download},
39+
{"JSON with spaces", ` ["shell", "actions"] `, Shell | Actions},
40+
41+
// Edge cases
42+
{"Empty string", "", None},
43+
{"Whitespace only", " ", None},
44+
{"Invalid role", "invalid", None},
45+
{"Mixed valid and invalid", "shell,invalid,actions", Shell | Actions},
46+
{"None overrides others", "shell,none,actions", None},
47+
{"All overrides others", "shell,all,actions", All},
48+
49+
// Invalid JSON
50+
{"Invalid JSON format", `["shell"`, None},
51+
{"Malformed JSON", `{shell: "test"}`, None},
52+
}
53+
54+
for _, tc := range testCases {
55+
t.Run(tc.name, func(t *testing.T) {
56+
result := ParseRole(tc.input)
57+
if result != tc.expected {
58+
t.Errorf("ParseRole(%q) = %d, expected %d", tc.input, int(result), int(tc.expected))
59+
}
60+
})
61+
}
62+
}

0 commit comments

Comments
 (0)