Skip to content

Commit 0426766

Browse files
committed
OCPBUGS-72526: Enhance GraphQL client and UI actions for impersonation handling
Made-with: Cursor
1 parent 759d8cc commit 0426766

4 files changed

Lines changed: 27 additions & 8 deletions

File tree

frontend/public/actions/features.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,9 @@ const ssarCheckActions = ssarChecks.map(({ flag, resourceAttributes, after }) =>
122122
after(dispatch, allowed);
123123
}
124124
},
125-
(err) => handleError({ response: err.graphQLErrors[0]?.extensions }, flag, dispatch, fn),
125+
(err) => {
126+
handleError({ response: err.graphQLErrors[0]?.extensions }, flag, dispatch, fn);
127+
},
126128
);
127129
return fn;
128130
});

frontend/public/actions/ui.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { detectFeatures } from './features';
1515
import { clearSSARFlags } from './flags';
1616
import { OverviewSpecialGroup } from '../components/overview/constants';
1717
import { setClusterID, setCreateProjectMessage, ActionType } from './common';
18-
import { subsClient } from '../graphql/client';
18+
import { subsClient, setForceHTTP } from '../graphql/client';
1919
import {
2020
beginImpersonate,
2121
endImpersonate,
@@ -241,15 +241,14 @@ export const startImpersonate = (kind: string, name: string, groups?: string[])
241241
// This ensures flags refresh happens in sync with React's render cycle
242242
};
243243

244-
// Action to refresh features after impersonation change
245-
// Don't clear flags - just re-detect them. Old values remain until new ones are fetched.
246-
// This prevents components from seeing PENDING state and showing loading spinners.
247244
export const refreshFeaturesAfterImpersonation = () => (dispatch) => {
245+
setForceHTTP(true);
248246
dispatch(detectFeatures());
249247
};
250248
export const stopImpersonate = () => (dispatch) => {
251249
dispatch(endImpersonate());
252250
subsClient.close(false, true);
251+
setForceHTTP(false);
253252
dispatch(clearSSARFlags());
254253
dispatch(detectFeatures());
255254
};

frontend/public/graphql/client.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ import { URLQueryType, URLQueryVariables } from '../../@types/console/generated/
1212
import { getConsoleRequestHeaders, coFetch } from '../co-fetch';
1313

1414
let wssErrors = 0;
15+
// @ts-ignore TS6133 - forceHTTP is read inside the split() closure below
16+
let forceHTTP = false;
17+
18+
export const setForceHTTP = (force: boolean) => {
19+
forceHTTP = force;
20+
};
1521

1622
class GraphQLReady {
1723
private callback: VoidFunction;
@@ -68,7 +74,7 @@ const wsLink = new WebSocketLink(subsClient);
6874

6975
// fallback to http connection if websocket connection was not successful
7076
// iOS does not allow wss with self signed certificate
71-
const link = split(() => wssErrors > 4, httpLink, wsLink);
77+
const link = split(() => wssErrors > 4 || forceHTTP, httpLink, wsLink);
7278

7379
const client = new ApolloClient({
7480
link,

pkg/server/server.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -381,9 +381,21 @@ func (s *Server) HTTPHandler() (http.Handler, error) {
381381
handler.InitPayload = resolver.InitPayload
382382
graphQLHandler := handler.NewHandlerFunc(schema, gql.NewHttpHandler(schema))
383383
handle("/api/graphql", authHandlerWithUser(func(user *auth.User, w http.ResponseWriter, r *http.Request) {
384-
ctx := context.WithValue(context.Background(), resolver.HeadersKey, map[string]interface{}{
384+
headers := map[string]interface{}{
385385
"Authorization": fmt.Sprintf("Bearer %s", user.Token),
386-
})
386+
}
387+
if impUser := r.Header.Get("Impersonate-User"); impUser != "" {
388+
headers["Impersonate-User"] = impUser
389+
}
390+
if consoleGroups := r.Header.Get("X-Console-Impersonate-Groups"); consoleGroups != "" {
391+
groups := strings.Split(consoleGroups, ",")
392+
groups = append(groups, "system:authenticated")
393+
headers["Impersonate-Group"] = groups
394+
} else if impGroups := r.Header.Values("Impersonate-Group"); len(impGroups) > 0 {
395+
impGroups = append(impGroups, "system:authenticated")
396+
headers["Impersonate-Group"] = impGroups
397+
}
398+
ctx := context.WithValue(context.Background(), resolver.HeadersKey, headers)
387399
graphQLHandler(w, r.WithContext(ctx))
388400
}))
389401

0 commit comments

Comments
 (0)