feat: add umask computation

Fix #719
This commit is contained in:
ShareVB 2024-08-25 22:19:33 +02:00
parent 3d63fde283
commit 703988880e
4 changed files with 139 additions and 3 deletions

View file

@ -1,5 +1,5 @@
import { describe, expect, it } from 'vitest'; import { describe, expect, it } from 'vitest';
import { computeChmodOctalRepresentation, computeChmodSymbolicRepresentation, computePermissionsFromChmodOctalRepresentation, computePermissionsFromChmodSymbolicRepresentation } from './chmod-calculator.service'; import { computeChmodOctalRepresentation, computeChmodSymbolicRepresentation, computePermissionsFromChmodOctalRepresentation, computePermissionsFromChmodSymbolicRepresentation, computeUmaskRepresentation } from './chmod-calculator.service';
describe('chmod-calculator', () => { describe('chmod-calculator', () => {
describe('computeChmodOctalRepresentation', () => { describe('computeChmodOctalRepresentation', () => {
@ -454,4 +454,106 @@ describe('chmod-calculator', () => {
}); });
}); });
}); });
describe('computeUmaskRepresentation', () => {
it('get the umask from permissions', () => {
expect(
computeUmaskRepresentation({
permissions: {
owner: { read: true, write: true, execute: true },
group: { read: true, write: true, execute: true },
public: { read: true, write: true, execute: true },
flags: { setuid: false, setgid: false, stickybit: false },
},
}),
).to.deep.eq({
octal: '000',
symbolic: 'umask u=rwx,g=rwx,o=rwx',
});
expect(
computeUmaskRepresentation({
permissions: {
owner: { read: false, write: false, execute: false },
group: { read: false, write: false, execute: false },
public: { read: false, write: false, execute: false },
flags: { setuid: false, setgid: false, stickybit: false },
},
}),
).to.deep.eq({
octal: '777',
symbolic: 'umask u=,g=,o=',
});
expect(
computeUmaskRepresentation({
permissions: {
owner: { read: false, write: true, execute: false },
group: { read: false, write: true, execute: true },
public: { read: true, write: false, execute: true },
flags: { setuid: false, setgid: false, stickybit: false },
},
}),
).to.deep.eq({
octal: '542',
symbolic: 'umask u=w,g=wx,o=rx',
});
expect(
computeUmaskRepresentation({
permissions: {
owner: { read: true, write: false, execute: false },
group: { read: false, write: true, execute: false },
public: { read: false, write: false, execute: true },
flags: { setuid: false, setgid: false, stickybit: false },
},
}),
).to.deep.eq({
octal: '356',
symbolic: 'umask u=r,g=w,o=x',
});
expect(
computeUmaskRepresentation({
permissions: {
owner: { read: false, write: false, execute: true },
group: { read: false, write: true, execute: false },
public: { read: true, write: false, execute: false },
flags: { setuid: false, setgid: false, stickybit: false },
},
}),
).to.deep.eq({
octal: '653',
symbolic: 'umask u=x,g=w,o=r',
});
expect(
computeUmaskRepresentation({
permissions: {
owner: { read: false, write: true, execute: false },
group: { read: false, write: true, execute: false },
public: { read: false, write: true, execute: false },
flags: { setuid: false, setgid: false, stickybit: false },
},
}),
).to.deep.eq({
octal: '555',
symbolic: 'umask u=w,g=w,o=w',
});
expect(
computeUmaskRepresentation({
permissions: {
owner: { read: false, write: false, execute: true },
group: { read: false, write: true, execute: false },
public: { read: true, write: false, execute: false },
flags: { setuid: true, setgid: true, stickybit: true },
},
}),
).to.deep.eq({
octal: '653',
symbolic: 'umask u=x,g=w,o=r',
});
});
});
}); });

View file

@ -1,7 +1,7 @@
import _ from 'lodash'; import _ from 'lodash';
import type { GroupPermissions, Permissions, SpecialPermissions } from './chmod-calculator.types'; import type { GroupPermissions, Permissions, SpecialPermissions } from './chmod-calculator.types';
export { computeChmodOctalRepresentation, computeChmodSymbolicRepresentation, computePermissionsFromChmodOctalRepresentation, computePermissionsFromChmodSymbolicRepresentation }; export { computeUmaskRepresentation, computeChmodOctalRepresentation, computeChmodSymbolicRepresentation, computePermissionsFromChmodOctalRepresentation, computePermissionsFromChmodSymbolicRepresentation };
function computeChmodOctalRepresentation({ permissions }: { permissions: Permissions }): string { function computeChmodOctalRepresentation({ permissions }: { permissions: Permissions }): string {
const permissionValue = { read: 4, write: 2, execute: 1 }; const permissionValue = { read: 4, write: 2, execute: 1 };
@ -86,3 +86,30 @@ function computePermissionsFromChmodSymbolicRepresentation(symbolicPermissions:
return computePermissionsFromChmodOctalRepresentation(octalString); return computePermissionsFromChmodOctalRepresentation(octalString);
} }
function computeUmaskRepresentation({ permissions }: { permissions: Permissions }): {
octal: string
symbolic: string
} {
const permissionValue = { read: 'r', write: 'w', execute: 'x' };
const getGroupPermissionValue = (permission: GroupPermissions) =>
_.reduce(permission, (acc, isPermSet, key) => acc + ((isPermSet ? _.get(permissionValue, key, '') : '')), '');
const symbolic = `umask u=${getGroupPermissionValue(permissions.owner)},g=${getGroupPermissionValue(permissions.group)},o=${getGroupPermissionValue(permissions.public)}`;
const octal = (0o777 - Number.parseInt(
computeChmodOctalRepresentation({
permissions:
{
owner: permissions.owner,
group: permissions.group,
public: permissions.public,
flags: { setuid: false, setgid: false, stickybit: false },
},
}), 8))
.toString(8)
.padStart(3, '0');
return {
symbolic, octal,
};
}

View file

@ -2,7 +2,7 @@
import { useThemeVars } from 'naive-ui'; import { useThemeVars } from 'naive-ui';
import InputCopyable from '../../components/InputCopyable.vue'; import InputCopyable from '../../components/InputCopyable.vue';
import { computeChmodOctalRepresentation, computeChmodSymbolicRepresentation, computePermissionsFromChmodOctalRepresentation, computePermissionsFromChmodSymbolicRepresentation } from './chmod-calculator.service'; import { computeChmodOctalRepresentation, computeChmodSymbolicRepresentation, computePermissionsFromChmodOctalRepresentation, computePermissionsFromChmodSymbolicRepresentation, computeUmaskRepresentation } from './chmod-calculator.service';
import type { Group, Scope } from './chmod-calculator.types'; import type { Group, Scope } from './chmod-calculator.types';
import { useValidation } from '@/composable/validation'; import { useValidation } from '@/composable/validation';
@ -81,6 +81,7 @@ watch(
const octal = computed(() => computeChmodOctalRepresentation({ permissions: permissions.value })); const octal = computed(() => computeChmodOctalRepresentation({ permissions: permissions.value }));
const symbolic = computed(() => computeChmodSymbolicRepresentation({ permissions: permissions.value })); const symbolic = computed(() => computeChmodSymbolicRepresentation({ permissions: permissions.value }));
const umask = computed(() => computeUmaskRepresentation({ permissions: permissions.value }));
</script> </script>
<template> <template>
@ -155,6 +156,11 @@ const symbolic = computed(() => computeChmodSymbolicRepresentation({ permissions
</div> </div>
<InputCopyable :value="`chmod ${octal} path`" readonly /> <InputCopyable :value="`chmod ${octal} path`" readonly />
<c-card title="Umask">
<InputCopyable :value="umask.octal" readonly />
<InputCopyable :value="umask.symbolic" readonly />
</c-card>
</div> </div>
</template> </template>

View file

@ -16,6 +16,7 @@ export const tool = defineTool({
'recursive', 'recursive',
'generator', 'generator',
'octal', 'octal',
'umask',
], ],
component: () => import('./chmod-calculator.vue'), component: () => import('./chmod-calculator.vue'),
icon: FileInvoice, icon: FileInvoice,