Skip to content

Commit a1dd871

Browse files
committed
CONSOLE-4785: GraphQL Context Updates for multi-group impersonation
Update GraphQL context to support array-valued headers for multi-group impersonation. Change headers type from map[string]string to map[string]interface{} to support both single string values and []string arrays.
1 parent d62c016 commit a1dd871

File tree

2 files changed

+29
-9
lines changed

2 files changed

+29
-9
lines changed

pkg/graphql/resolver/utils.go

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,31 @@ const HeadersKey string = "headers"
1111

1212
func contextToHeaders(ctx context.Context, request *http.Request) {
1313
if ctx.Value(HeadersKey) != nil {
14-
headers, ok := ctx.Value(HeadersKey).(map[string]string)
14+
headers, ok := ctx.Value(HeadersKey).(map[string]interface{})
1515
if ok {
1616
for key, value := range headers {
17-
if value != "" {
18-
request.Header.Add(key, value)
17+
switch v := value.(type) {
18+
case string:
19+
if v != "" {
20+
request.Header.Add(key, v)
21+
}
22+
case []string:
23+
// Handle multiple values for the same header (e.g., Impersonate-Group)
24+
for _, val := range v {
25+
if val != "" {
26+
request.Header.Add(key, val)
27+
}
28+
}
1929
}
2030
}
2131
}
2232
}
2333
}
2434

2535
type initPayload struct {
26-
ImpersonateUser string `json:"Impersonate-User"`
27-
ImpersonateGroup string `json:"Impersonate-Group"`
36+
ImpersonateUser string `json:"Impersonate-User"`
37+
ImpersonateGroup string `json:"Impersonate-Group"`
38+
ImpersonateGroups []string `json:"Impersonate-Groups"`
2839
}
2940

3041
func InitPayload(ctx context.Context, payload json.RawMessage) context.Context {
@@ -33,10 +44,19 @@ func InitPayload(ctx context.Context, payload json.RawMessage) context.Context {
3344
if err != nil {
3445
return ctx
3546
}
36-
headers, ok := ctx.Value(HeadersKey).(map[string]string)
47+
headers, ok := ctx.Value(HeadersKey).(map[string]interface{})
3748
if ok {
38-
headers["Impersonate-User"] = initPayload.ImpersonateUser
39-
headers["Impersonate-Group"] = initPayload.ImpersonateGroup
49+
if initPayload.ImpersonateUser != "" {
50+
headers["Impersonate-User"] = initPayload.ImpersonateUser
51+
}
52+
// Support both single group (backward compatibility) and multiple groups
53+
if len(initPayload.ImpersonateGroups) > 0 {
54+
groups := initPayload.ImpersonateGroups
55+
groups = append(groups, "system:authenticated")
56+
headers["Impersonate-Group"] = groups
57+
} else if initPayload.ImpersonateGroup != "" {
58+
headers["Impersonate-Group"] = []string{initPayload.ImpersonateGroup, "system:authenticated"}
59+
}
4060
ctx = context.WithValue(ctx, HeadersKey, headers)
4161
}
4262
return ctx

pkg/server/server.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ func (s *Server) HTTPHandler() (http.Handler, error) {
365365
handler.InitPayload = resolver.InitPayload
366366
graphQLHandler := handler.NewHandlerFunc(schema, gql.NewHttpHandler(schema))
367367
handle("/api/graphql", authHandlerWithUser(func(user *auth.User, w http.ResponseWriter, r *http.Request) {
368-
ctx := context.WithValue(context.Background(), resolver.HeadersKey, map[string]string{
368+
ctx := context.WithValue(context.Background(), resolver.HeadersKey, map[string]interface{}{
369369
"Authorization": fmt.Sprintf("Bearer %s", user.Token),
370370
})
371371
graphQLHandler(w, r.WithContext(ctx))

0 commit comments

Comments
 (0)