no_deprecated_authz_config eslint rule fixes (#194807)

## Summary

ESLint was not correctly migrating tags that involved tags with multiple
prefixes or helper functions. Specifically, it was failing to handle:
- Tags using helper functions, such as: `['access:securitySolution',
routeTagHelper('someTag')]`.
- Nested prefixes like: `['access:ml:some-tag']`.

This resulted in incomplete tag migrations.

Also added `MIGRATE_DISABLED_AUTHZ` flag which allows to skip migration
for routes opted out from authorization with
`MIGRATE_DISABLED_AUTHZ=false`


### Checklist

- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios


__Closes: https://github.com/elastic/kibana/issues/194798__
This commit is contained in:
Elena Shostak 2024-10-04 11:42:58 +02:00 committed by GitHub
parent a91d00731a
commit 3e3b8ddde6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 54 additions and 6 deletions

View file

@ -20,5 +20,6 @@ module.exports = {
no_this_in_property_initializers: require('./rules/no_this_in_property_initializers'),
no_unsafe_console: require('./rules/no_unsafe_console'),
no_unsafe_hash: require('./rules/no_unsafe_hash'),
no_deprecated_authz_config: require('./rules/no_deprecated_authz_config'),
},
};

View file

@ -12,15 +12,16 @@ const ACCESS_TAG_PREFIX = 'access:';
const isStringLiteral = (el) => el.type === 'Literal' && typeof el.value === 'string';
const isLiteralAccessTag = (el) => isStringLiteral(el) && el.value.startsWith(ACCESS_TAG_PREFIX);
const isLiteralNonAccessTag = (el) =>
isStringLiteral(el) && !el.value.startsWith(ACCESS_TAG_PREFIX);
const isTemplateLiteralAccessTag = (el) =>
el.type === 'TemplateLiteral' && el.quasis[0].value.raw.startsWith(ACCESS_TAG_PREFIX);
const isTemplateLiteralNonAccessTag = (el) =>
el.type === 'TemplateLiteral' && !el.quasis[0].value.raw.startsWith(ACCESS_TAG_PREFIX);
const maybeReportDisabledSecurityConfig = (node, context, isVersionedRoute = false) => {
// Allow disabling migration for routes that are opted out from authorization
if (process.env.MIGRATE_DISABLED_AUTHZ === 'false') {
return;
}
const callee = node.callee;
const isAddVersionCall =
callee.type === 'MemberExpression' && callee.property.name === 'addVersion';
@ -166,11 +167,11 @@ const handleRouteConfig = (node, context, isVersionedRoute = false) => {
const accessTagsFilter = (el) => isLiteralAccessTag(el) || isTemplateLiteralAccessTag(el);
const nonAccessTagsFilter = (el) =>
isLiteralNonAccessTag(el) || isTemplateLiteralNonAccessTag(el);
!isLiteralAccessTag(el) && !isTemplateLiteralAccessTag(el);
const getAccessPrivilege = (el) => {
if (el.type === 'Literal') {
return `'${el.value.split(':')[1]}'`;
return `'${el.value.split(ACCESS_TAG_PREFIX)[1]}'`;
}
if (el.type === 'TemplateLiteral') {

View file

@ -158,6 +158,28 @@ ruleTester.run('no_deprecated_authz_config', rule, {
`,
name: 'invalid: access tags are string literals, move to security.authz.requiredPrivileges',
},
{
code: `
router.get({
path: '/some/path',
options: {
tags: ['access:ml:someTag', 'access:prefix:someTag'],
},
});
`,
errors: [{ message: "Move 'access' tags to security.authz.requiredPrivileges." }],
output: `
router.get({
path: '/some/path',
security: {
authz: {
requiredPrivileges: ['ml:someTag', 'prefix:someTag'],
},
},
});
`,
name: 'invalid: access tags have multiple prefixes, move to security.authz.requiredPrivileges',
},
{
code: `
router.get({
@ -180,6 +202,30 @@ ruleTester.run('no_deprecated_authz_config', rule, {
`,
name: 'invalid: access tags are template literals, move to security.authz.requiredPrivileges',
},
{
code: `
router.get({
path: '/some/path',
options: {
tags: ['access:securitySolution', routeTagHelper('someTag')],
},
});
`,
errors: [{ message: "Move 'access' tags to security.authz.requiredPrivileges." }],
output: `
router.get({
path: '/some/path',
security: {
authz: {
requiredPrivileges: ['securitySolution'],
},
},options: {
tags: [routeTagHelper('someTag')],
},
});
`,
name: 'invalid: access tags and tags made with helper function, only access tags are moved to security.authz.requiredPrivileges',
},
{
code: `
router.get({