Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename access rules to admin rules #52577

Open
wants to merge 1 commit into
base: bl-nero/role-editor-buttons
Choose a base branch
from
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 @@ -90,7 +90,7 @@ test('rendering and switching tabs for new role', async () => {
expect(screen.getByLabelText('Role Name *')).toHaveValue('new_role_name');
expect(screen.getByLabelText('Description')).toHaveValue('');
await forwardToTab('Resources');
await forwardToTab('Access Rules');
await forwardToTab('Admin Rules');
await forwardToTab('Options');
expect(screen.getByRole('button', { name: 'Create Role' })).toBeEnabled();

Expand All @@ -117,7 +117,7 @@ test('rendering and switching tabs for new role', async () => {
screen.queryByRole('button', { name: /Reset to Standard Settings/i })
).not.toBeInTheDocument();
await forwardToTab('Resources');
await forwardToTab('Access Rules');
await forwardToTab('Admin Rules');
await forwardToTab('Options');
expect(screen.getByRole('button', { name: 'Create Role' })).toBeEnabled();
});
Expand Down Expand Up @@ -326,7 +326,7 @@ test('saving a new role', async () => {
'That is not dead which can eternal lie.'
);
await forwardToTab('Resources');
await forwardToTab('Access Rules');
await forwardToTab('Admin Rules');
await forwardToTab('Options');
await user.click(screen.getByRole('button', { name: 'Create Role' }));

Expand Down Expand Up @@ -407,7 +407,7 @@ test('error while saving', async () => {
const onSave = jest.fn().mockRejectedValue(new Error('oh noes'));
render(<TestRoleEditor onSave={onSave} />);
await forwardToTab('Resources');
await forwardToTab('Access Rules');
await forwardToTab('Admin Rules');
await forwardToTab('Options');
await user.click(screen.getByRole('button', { name: 'Create Role' }));
expect(screen.getByText('oh noes')).toBeVisible();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export function RoleEditorAdapter({
borderLeft={1}
borderColor={theme.colors.interactive.tonal.neutral[0]}
backgroundColor={theme.colors.levels.surface}
width="700px"
width="550px"
>
{convertAttempt.status === 'processing' && (
<Flex
Expand Down Expand Up @@ -113,7 +113,7 @@ export function RoleEditorAdapter({
)}
</Flex>
{roleDiffProps ? (
roleDiffProps.roleDiffElement
<Flex flex="1">{roleDiffProps.roleDiffElement}</Flex>
) : (
<Flex flex="1" alignItems="center" justifyContent="center" m={3}>
<PolicyPlaceholder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,20 @@ import { Validator } from 'shared/components/Validation';

import { ResourceKind } from 'teleport/services/resources';

import { AccessRules } from './AccessRules';
import { AdminRules } from './AdminRules';
import { RuleModel } from './standardmodel';
import { StatefulSectionWithDispatch } from './StatefulSection';
import { AccessRuleValidationResult } from './validation';
import { AdminRuleValidationResult } from './validation';

describe('AccessRules', () => {
describe('AdminRules', () => {
const setup = () => {
const modelRef = jest.fn();
let validator: Validator;
render(
<StatefulSectionWithDispatch<RuleModel[], AccessRuleValidationResult[]>
<StatefulSectionWithDispatch<RuleModel[], AdminRuleValidationResult[]>
selector={m => m.roleModel.rules}
validationSelector={m => m.validationResult.rules}
component={AccessRules}
component={AdminRules}
validatorRef={v => {
validator = v;
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,25 +40,25 @@ import {
RuleModel,
verbOptions,
} from './standardmodel';
import { AccessRuleValidationResult } from './validation';
import { AdminRuleValidationResult } from './validation';

/**
* Access rules tab. This component is memoized to optimize performance; make
* Admin rules tab. This component is memoized to optimize performance; make
* sure that the properties don't change unless necessary.
*/
export const AccessRules = memo(function AccessRules({
export const AdminRules = memo(function AdminRules({
value,
isProcessing,
validation,
dispatch,
}: SectionPropsWithDispatch<RuleModel[], AccessRuleValidationResult[]>) {
}: SectionPropsWithDispatch<RuleModel[], AdminRuleValidationResult[]>) {
function addRule() {
dispatch({ type: 'add-access-rule' });
}
return (
<Flex flexDirection="column" gap={3}>
{value.map((rule, i) => (
<AccessRule
<AdminRule
key={rule.id}
isProcessing={isProcessing}
value={rule}
Expand All @@ -74,12 +74,12 @@ export const AccessRules = memo(function AccessRules({
);
});

const AccessRule = memo(function AccessRule({
const AdminRule = memo(function AdminRule({
value,
isProcessing,
validation,
dispatch,
}: SectionPropsWithDispatch<RuleModel, AccessRuleValidationResult>) {
}: SectionPropsWithDispatch<RuleModel, AdminRuleValidationResult>) {
const { id, resources, verbs, where } = value;
const theme = useTheme();
function setRule(rule: RuleModel) {
Expand All @@ -90,7 +90,7 @@ const AccessRule = memo(function AccessRule({
}
return (
<SectionBox
title="Access Rule"
title="Admin Rule"
tooltip="A rule that gives users access to certain kinds of resources"
removable
isProcessing={isProcessing}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,14 +240,14 @@ test('creating a new role', async () => {
render(<TestStandardEditor onSave={onSave} />);
await user.type(screen.getByLabelText('Description'), 'foo');
await forwardToTab('Resources');
await forwardToTab('Access Rules');
await forwardToTab('Admin Rules');
await forwardToTab('Options');
expect(onSave).not.toHaveBeenCalled();

// By now, all the tabs should be enabled.
expect(getTabByName('Overview')).toBeEnabled();
expect(getTabByName('Resources')).toBeEnabled();
expect(getTabByName('Access Rules')).toBeEnabled();
expect(getTabByName('Admin Rules')).toBeEnabled();
expect(getTabByName('Options')).toBeEnabled();

// Allow free navigation.
Expand Down Expand Up @@ -288,16 +288,13 @@ test('tab-level validation when creating a new role', async () => {
expect(screen.getByPlaceholderText('label key')).toHaveAccessibleDescription(
''
);
await user.click(screen.getByRole('button', { name: 'Next: Access Rules' }));
expect(getTabByName('Access Rules')).toHaveAttribute(
'aria-selected',
'false'
);
await user.click(screen.getByRole('button', { name: 'Next: Admin Rules' }));
expect(getTabByName('Admin Rules')).toHaveAttribute('aria-selected', 'false');
// Fix the field value and retry.
await user.type(screen.getByPlaceholderText('label key'), 'foo');
await user.type(screen.getByPlaceholderText('label value'), 'bar');
await user.click(screen.getByRole('button', { name: 'Next: Access Rules' }));
expect(getTabByName('Access Rules')).toHaveAttribute('aria-selected', 'true');
await user.click(screen.getByRole('button', { name: 'Next: Admin Rules' }));
expect(getTabByName('Admin Rules')).toHaveAttribute('aria-selected', 'true');
});

const getAllMenuItemNames = () =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { useValidation } from 'shared/components/Validation';
import { Role, RoleWithYaml } from 'teleport/services/resources';

import { ActionButtonsContainer, SaveButton } from '../Shared';
import { AccessRules } from './AccessRules';
import { AdminRules } from './AdminRules';
import { MetadataSection } from './MetadataSection';
import { Options } from './Options';
import { RequiresResetToStandard } from './RequiresResetToStandard';
Expand Down Expand Up @@ -65,7 +65,7 @@ export const StandardEditor = ({
enum StandardEditorTab {
Overview,
Resources,
AccessRules,
AdminRules,
Options,
}

Expand Down Expand Up @@ -114,7 +114,7 @@ export const StandardEditor = ({
[setCurrentTab, currentTab]
);

const tabTitles = ['Overview', 'Resources', 'Access Rules', 'Options'];
const tabTitles = ['Overview', 'Resources', 'Admin Rules', 'Options'];
const tabElementIDs = [
`${idPrefix}-overview`,
`${idPrefix}-resources`,
Expand Down Expand Up @@ -161,7 +161,7 @@ export const StandardEditor = ({
validationResult.resources.some(s => !s.valid)
),
tabSpec(
StandardEditorTab.AccessRules,
StandardEditorTab.AdminRules,
validator.state.validating &&
validationResult.rules.some(s => !s.valid)
),
Expand Down Expand Up @@ -209,13 +209,13 @@ export const StandardEditor = ({
/>
</Box>
<Box
id={tabElementIDs[StandardEditorTab.AccessRules]}
id={tabElementIDs[StandardEditorTab.AdminRules]}
style={{
display:
currentTab === StandardEditorTab.AccessRules ? '' : 'none',
currentTab === StandardEditorTab.AdminRules ? '' : 'none',
}}
>
<AccessRules
<AdminRules
isProcessing={isProcessing}
value={roleModel.rules}
dispatch={dispatch}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,7 @@ function roleConditionsToModel(
// GitHub organization access
github_permissions,

// Access rules
// Admin rules
rules,

...unsupported
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,9 @@ type StandardModelAction =
| AddResourceAccessAction
| SetResourceAccessAction
| RemoveResourceAccessAction
| AddAccessRuleAction
| SetAccessRuleAction
| RemoveAccessRuleAction
| AddAdminRuleAction
| SetAdminRuleAction
| RemoveAdminRuleAction
| SetOptionsAction;

/** Sets the entire model. */
Expand All @@ -108,9 +108,9 @@ type RemoveResourceAccessAction = {
type: 'remove-resource-access';
payload: { kind: ResourceAccessKind };
};
type AddAccessRuleAction = { type: 'add-access-rule'; payload?: never };
type SetAccessRuleAction = { type: 'set-access-rule'; payload: RuleModel };
type RemoveAccessRuleAction = {
type AddAdminRuleAction = { type: 'add-access-rule'; payload?: never };
type SetAdminRuleAction = { type: 'set-access-rule'; payload: RuleModel };
type RemoveAdminRuleAction = {
type: 'remove-access-rule';
payload: { id: string };
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import {
} from './standardmodel';
import {
KubernetesAccessValidationResult,
validateAccessRule,
validateAdminRule,
validateResourceAccess,
validateRoleEditorModel,
} from './validation';
Expand Down Expand Up @@ -212,7 +212,7 @@ describe('validateRoleEditorModel', () => {
}
);

test('invalid access rule', () => {
test('invalid Admin Rule', () => {
const model = minimalRoleModel();
model.rules = [
{
Expand Down Expand Up @@ -247,16 +247,16 @@ describe('validateResourceAccess', () => {
});
});

describe('validateAccessRule', () => {
describe('validateAdminRule', () => {
it('reuses previously computed results', () => {
const rule: RuleModel = {
id: 'some-id',
resources: [],
verbs: [],
where: '',
};
const result1 = validateAccessRule(rule, undefined, undefined);
const result2 = validateAccessRule(rule, rule, result1);
const result1 = validateAdminRule(rule, undefined, undefined);
const result2 = validateAdminRule(rule, rule, result1);
expect(result2).toBe(result1);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export const kubernetesClusterWideResourceKinds: KubernetesResourceKind[] = [
export type RoleEditorModelValidationResult = {
metadata: MetadataValidationResult;
resources: ResourceAccessValidationResult[];
rules: AccessRuleValidationResult[];
rules: AdminRuleValidationResult[];
/**
* isValid is true if all the fields in the validation result are valid.
*/
Expand Down Expand Up @@ -92,7 +92,7 @@ export function validateRoleEditorModel(
previousResult?.resources
);

const rulesResult = validateAccessRuleList(
const rulesResult = validateAdminRuleList(
model.rules,
previousModel?.rules,
previousResult?.rules
Expand Down Expand Up @@ -305,34 +305,34 @@ export type WindowsDesktopAccessValidationResult = RuleSetValidationResult<

export type GitHubOrganizationAccessValidationResult = ValidationResult;

export function validateAccessRuleList(
export function validateAdminRuleList(
rules: RuleModel[],
previousRules: RuleModel[],
previousResults: AccessRuleValidationResult[]
): AccessRuleValidationResult[] {
previousResults: AdminRuleValidationResult[]
): AdminRuleValidationResult[] {
if (previousRules === rules) {
return previousResults;
}
return rules.map((rule, i) =>
validateAccessRule(rule, previousRules?.[i], previousResults?.[i])
validateAdminRule(rule, previousRules?.[i], previousResults?.[i])
);
}

export const validateAccessRule = (
export const validateAdminRule = (
rule: RuleModel,
previousRule: RuleModel,
previousResult: AccessRuleValidationResult
): AccessRuleValidationResult => {
previousResult: AdminRuleValidationResult
): AdminRuleValidationResult => {
if (previousRule === rule) {
return previousResult;
}
return runRules(rule, accessRuleValidationRules);
return runRules(rule, adminRuleValidationRules);
};

const accessRuleValidationRules = {
const adminRuleValidationRules = {
resources: requiredField('At least one resource kind is required'),
verbs: requiredField('At least one permission is required'),
};
export type AccessRuleValidationResult = RuleSetValidationResult<
typeof accessRuleValidationRules
export type AdminRuleValidationResult = RuleSetValidationResult<
typeof adminRuleValidationRules
>;
Loading