Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ exports[`Authentication Component should allow being disabled: disabled 1`] = `
value={
{
"authorized": {
"inventory": true,
"subscriptions": true,
},
"errorCodes": [],
Expand Down Expand Up @@ -43,6 +44,7 @@ exports[`Authentication Component should render a component authorized: authoriz
value={
{
"authorized": {
"inventory": true,
"subscriptions": true,
},
"errorCodes": [],
Expand Down Expand Up @@ -98,7 +100,10 @@ exports[`Authentication Component should render authorized via kessel when flag
<Context.Provider
value={
{
"authorized": {},
"authorized": {
"inventory": true,
"subscriptions": true,
},
"errorCodes": [],
"errorStatus": undefined,
}
Expand Down Expand Up @@ -218,7 +223,10 @@ exports[`Authentication Component should show optin when kessel authorized and 4
<Context.Provider
value={
{
"authorized": {},
"authorized": {
"inventory": true,
"subscriptions": true,
},
"errorCodes": [],
"errorStatus": 418,
}
Expand All @@ -232,7 +240,10 @@ exports[`Authentication Component should show optin when kessel authorized but o
<Context.Provider
value={
{
"authorized": {},
"authorized": {
"inventory": true,
"subscriptions": true,
},
"errorCodes": [
"SUBSCRIPTIONS1004",
],
Expand All @@ -249,7 +260,8 @@ exports[`Authentication Component should use kessel over legacy rbac when flag i
value={
{
"authorized": {
"subscriptions": false,
"inventory": true,
"subscriptions": true,
},
"errorCodes": [],
"errorStatus": undefined,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,10 @@ describe('Authentication Component', () => {
);

expect(component).toMatchSnapshot('authorized');
expect(component.props.value.authorized).toEqual({
[helpers.UI_NAME]: true,
inventory: true
});
});

const mockUseChromeKesselOn = () => ({ visibilityFunctions: { featureFlag: () => true } });
Expand All @@ -235,6 +239,10 @@ describe('Authentication Component', () => {
);

expect(component).toMatchSnapshot('kessel authorized');
expect(component.props.value.authorized).toEqual({
[helpers.UI_NAME]: true,
inventory: true
});
});

it('should render not authorized via kessel when flag is on', async () => {
Expand Down
14 changes: 14 additions & 0 deletions src/components/authentication/__tests__/useHasRelation.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,18 @@ describe('useHasRelation', () => {
})
);
});

it('should call checkSelf when enabled transitions from false to true', async () => {
mockCheckSelf.mockResolvedValue({ allowed: 'ALLOWED_TRUE' });

const { rerender, act: hookAct } = await renderHook((enabled = false) =>
useHasRelation(Relation.INVENTORY_VIEW, { enabled })
);

expect(mockCheckSelf).not.toHaveBeenCalled();

await hookAct(async () => rerender(true));

expect(mockCheckSelf).toHaveBeenCalledTimes(1);
});
});
32 changes: 30 additions & 2 deletions src/components/authentication/authentication.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useMemo } from 'react';
import { BinocularsIcon } from '@patternfly/react-icons';
import { Maintenance } from '@redhat-cloud-services/frontend-components/Maintenance';
import { NotAuthorized } from '@redhat-cloud-services/frontend-components/NotAuthorized';
Expand Down Expand Up @@ -55,6 +55,34 @@ const Authentication = ({

const isAuthorized = kesselEnabled ? kesselAuthorized : authorized[appName];

/*
* Instance table links read session.authorized.inventory. RBAC v1 inventory is empty in v2 orgs
* (Kessel on or off), so overlay it whenever the user is allowed to see the app.
*/
const sessionData = useMemo(
() => ({
...data,
authorized: {
...authorized,
...(isAuthorized && {
[appName]: true,
inventory: true
})
}
}),
[data, authorized, isAuthorized, appName]
);

helpers.browserExpose({
authDebug: {
kesselEnabled,
kesselAuthorized,
kesselPending,
isAuthorized,
authorized: sessionData.authorized
}
});

const renderContent = () => {
if (isDisabled) {
return (
Expand Down Expand Up @@ -92,7 +120,7 @@ const Authentication = ({
);
};

return <AuthenticationContext.Provider value={data}>{renderContent()}</AuthenticationContext.Provider>;
return <AuthenticationContext.Provider value={sessionData}>{renderContent()}</AuthenticationContext.Provider>;
};

export { Authentication as default, Authentication };
4 changes: 2 additions & 2 deletions src/components/authentication/useHasRelation.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@ const useHasRelation = (relation, { enabled = true } = {}) => {
return () => {
cancelled = true;
};
// intentional: run once on mount, matches React Query one-shot behavior
// re-run if Chrome feature flags arrive after first paint
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
}, [enabled]);

return { has, isLoading };
};
Expand Down
Loading