mirror of
https://github.com/CorentinTh/it-tools.git
synced 2025-05-04 13:29:13 -04:00
parent
ee04bfed87
commit
3d63fde283
5 changed files with 195 additions and 13 deletions
3
components.d.ts
vendored
3
components.d.ts
vendored
|
@ -127,6 +127,7 @@ declare module '@vue/runtime-core' {
|
|||
MetaTagGenerator: typeof import('./src/tools/meta-tag-generator/meta-tag-generator.vue')['default']
|
||||
MimeTypes: typeof import('./src/tools/mime-types/mime-types.vue')['default']
|
||||
NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default']
|
||||
NCheckbox: typeof import('naive-ui')['NCheckbox']
|
||||
NCode: typeof import('naive-ui')['NCode']
|
||||
NCollapseTransition: typeof import('naive-ui')['NCollapseTransition']
|
||||
NConfigProvider: typeof import('naive-ui')['NConfigProvider']
|
||||
|
@ -145,6 +146,7 @@ declare module '@vue/runtime-core' {
|
|||
NMenu: typeof import('naive-ui')['NMenu']
|
||||
NScrollbar: typeof import('naive-ui')['NScrollbar']
|
||||
NSpin: typeof import('naive-ui')['NSpin']
|
||||
NTable: typeof import('naive-ui')['NTable']
|
||||
NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default']
|
||||
OtpCodeGeneratorAndValidator: typeof import('./src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')['default']
|
||||
PasswordStrengthAnalyser: typeof import('./src/tools/password-strength-analyser/password-strength-analyser.vue')['default']
|
||||
|
@ -159,6 +161,7 @@ declare module '@vue/runtime-core' {
|
|||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
RsaKeyPairGenerator: typeof import('./src/tools/rsa-key-pair-generator/rsa-key-pair-generator.vue')['default']
|
||||
SafelinkDecoder: typeof import('./src/tools/safelink-decoder/safelink-decoder.vue')['default']
|
||||
SlugifyString: typeof import('./src/tools/slugify-string/slugify-string.vue')['default']
|
||||
SpanCopyable: typeof import('./src/components/SpanCopyable.vue')['default']
|
||||
SqlPrettify: typeof import('./src/tools/sql-prettify/sql-prettify.vue')['default']
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { describe, expect, it } from 'vitest';
|
||||
import { computeChmodOctalRepresentation, computeChmodSymbolicRepresentation, computePermissionsFromChmodOctalRepresentation } from './chmod-calculator.service';
|
||||
import { computeChmodOctalRepresentation, computeChmodSymbolicRepresentation, computePermissionsFromChmodOctalRepresentation, computePermissionsFromChmodSymbolicRepresentation } from './chmod-calculator.service';
|
||||
|
||||
describe('chmod-calculator', () => {
|
||||
describe('computeChmodOctalRepresentation', () => {
|
||||
|
@ -339,4 +339,119 @@ describe('chmod-calculator', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
describe('computePermissionsFromChmodSymbolicRepresentation', () => {
|
||||
it('throws on invalid symbolic values', () => {
|
||||
expect(() => computePermissionsFromChmodSymbolicRepresentation('rr---')).to.throw();
|
||||
expect(() => computePermissionsFromChmodSymbolicRepresentation('rwxrwx--w')).to.throw();
|
||||
});
|
||||
|
||||
it('get permissions from symbolic representation', () => {
|
||||
expect(
|
||||
computePermissionsFromChmodSymbolicRepresentation('dr-xr-xr-x'),
|
||||
).to.eql({
|
||||
owner: { read: true, write: false, execute: true },
|
||||
group: { read: true, write: false, execute: true },
|
||||
public: { read: true, write: false, execute: true },
|
||||
flags: { setuid: false, setgid: false, stickybit: false },
|
||||
});
|
||||
expect(
|
||||
computePermissionsFromChmodSymbolicRepresentation('-rw-r--r--'),
|
||||
).to.eql({
|
||||
owner: { read: true, write: true, execute: false },
|
||||
group: { read: true, write: false, execute: false },
|
||||
public: { read: true, write: false, execute: false },
|
||||
flags: { setuid: false, setgid: false, stickybit: false },
|
||||
});
|
||||
|
||||
expect(
|
||||
computePermissionsFromChmodSymbolicRepresentation('rwxrwxrwx'),
|
||||
).to.eql({
|
||||
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 },
|
||||
});
|
||||
|
||||
expect(
|
||||
computePermissionsFromChmodSymbolicRepresentation('---------'),
|
||||
).to.eql({
|
||||
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 },
|
||||
});
|
||||
|
||||
expect(
|
||||
computePermissionsFromChmodSymbolicRepresentation('r---wxr-x'),
|
||||
).to.eql({
|
||||
owner: { read: true, write: false, execute: false },
|
||||
group: { read: false, write: true, execute: true },
|
||||
public: { read: true, write: false, execute: true },
|
||||
flags: { setuid: false, setgid: false, stickybit: false },
|
||||
});
|
||||
|
||||
expect(
|
||||
computePermissionsFromChmodSymbolicRepresentation('r---w---x'),
|
||||
).to.eql({
|
||||
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 },
|
||||
});
|
||||
|
||||
expect(
|
||||
computePermissionsFromChmodSymbolicRepresentation('--x-w-r--'),
|
||||
).to.eql({
|
||||
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 },
|
||||
});
|
||||
|
||||
expect(
|
||||
computePermissionsFromChmodSymbolicRepresentation('-w--w--w-'),
|
||||
).to.eql({
|
||||
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 },
|
||||
});
|
||||
|
||||
expect(
|
||||
computePermissionsFromChmodSymbolicRepresentation('-ws-ws-wt'),
|
||||
).to.eql({
|
||||
owner: { read: false, write: true, execute: true },
|
||||
group: { read: false, write: true, execute: true },
|
||||
public: { read: false, write: true, execute: true },
|
||||
flags: { setuid: true, setgid: true, stickybit: true },
|
||||
});
|
||||
|
||||
expect(
|
||||
computePermissionsFromChmodSymbolicRepresentation('-ws-w--w-'),
|
||||
).to.eql({
|
||||
owner: { read: false, write: true, execute: true },
|
||||
group: { read: false, write: true, execute: false },
|
||||
public: { read: false, write: true, execute: false },
|
||||
flags: { setuid: true, setgid: false, stickybit: false },
|
||||
});
|
||||
|
||||
expect(
|
||||
computePermissionsFromChmodSymbolicRepresentation('-w--ws-w-'),
|
||||
).to.eql({
|
||||
owner: { read: false, write: true, execute: false },
|
||||
group: { read: false, write: true, execute: true },
|
||||
public: { read: false, write: true, execute: false },
|
||||
flags: { setuid: false, setgid: true, stickybit: false },
|
||||
});
|
||||
|
||||
expect(
|
||||
computePermissionsFromChmodSymbolicRepresentation('-w--w--wt'),
|
||||
).to.eql({
|
||||
owner: { read: false, write: true, execute: false },
|
||||
group: { read: false, write: true, execute: false },
|
||||
public: { read: false, write: true, execute: true },
|
||||
flags: { setuid: false, setgid: false, stickybit: true },
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import _ from 'lodash';
|
||||
import type { GroupPermissions, Permissions, SpecialPermissions } from './chmod-calculator.types';
|
||||
|
||||
export { computeChmodOctalRepresentation, computeChmodSymbolicRepresentation, computePermissionsFromChmodOctalRepresentation };
|
||||
export { computeChmodOctalRepresentation, computeChmodSymbolicRepresentation, computePermissionsFromChmodOctalRepresentation, computePermissionsFromChmodSymbolicRepresentation };
|
||||
|
||||
function computeChmodOctalRepresentation({ permissions }: { permissions: Permissions }): string {
|
||||
const permissionValue = { read: 4, write: 2, execute: 1 };
|
||||
|
@ -61,3 +61,28 @@ function computePermissionsFromChmodOctalRepresentation(octalPermissions: string
|
|||
flags: computePermissionObject(specialPermissionValue, flagsPosition),
|
||||
};
|
||||
}
|
||||
|
||||
function computePermissionsFromChmodSymbolicRepresentation(symbolicPermissions: string): Permissions {
|
||||
const formatRegex = /^[-dlbcsp]?([r-])([w-])([xs-])([r-])([w-])([xs-])([r-])([w-])([xt-])$/;
|
||||
if (!symbolicPermissions || !symbolicPermissions.match(formatRegex)) {
|
||||
throw new Error(`Invalid string permissions (must be in form 'rwxrwxrwx'): ${symbolicPermissions}`);
|
||||
}
|
||||
|
||||
const [_, rOwner, wOwner, xOwner, rGroup, wGroup, xGroup, rAll, wAll, xAll] = formatRegex.exec(symbolicPermissions) || [];
|
||||
const getOctal = (flag: string, flagLetter: string, flagValue: number) => flag === flagLetter ? flagValue : 0;
|
||||
const owner = getOctal(rOwner, 'r', 4)
|
||||
+ getOctal(wOwner, 'w', 2)
|
||||
+ getOctal(xOwner, 'x', 1) + getOctal(xOwner, 's', 1);
|
||||
const groups = getOctal(rGroup, 'r', 4)
|
||||
+ getOctal(wGroup, 'w', 2)
|
||||
+ getOctal(xGroup, 'x', 1) + getOctal(xGroup, 's', 1);
|
||||
const all = getOctal(rAll, 'r', 4)
|
||||
+ getOctal(wAll, 'w', 2)
|
||||
+ getOctal(xAll, 'x', 1) + getOctal(xAll, 't', 1);
|
||||
const flags = getOctal(xOwner, 's', 4)
|
||||
+ getOctal(xGroup, 's', 2)
|
||||
+ getOctal(xAll, 't', 1);
|
||||
const octalString = `${(flags > 0 ? flags : '')}${owner}${groups}${all}`;
|
||||
|
||||
return computePermissionsFromChmodOctalRepresentation(octalString);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import { useThemeVars } from 'naive-ui';
|
||||
|
||||
import InputCopyable from '../../components/InputCopyable.vue';
|
||||
import { computeChmodOctalRepresentation, computeChmodSymbolicRepresentation, computePermissionsFromChmodOctalRepresentation } from './chmod-calculator.service';
|
||||
import { computeChmodOctalRepresentation, computeChmodSymbolicRepresentation, computePermissionsFromChmodOctalRepresentation, computePermissionsFromChmodSymbolicRepresentation } from './chmod-calculator.service';
|
||||
|
||||
import type { Group, Scope } from './chmod-calculator.types';
|
||||
import { useValidation } from '@/composable/validation';
|
||||
|
@ -23,9 +23,9 @@ const permissions = ref({
|
|||
flags: { setuid: false, setgid: false, stickybit: false },
|
||||
});
|
||||
|
||||
const permissionsInput = ref('000');
|
||||
const permissionsInputValidation = useValidation({
|
||||
source: permissionsInput,
|
||||
const octalPermissionsInput = ref('000');
|
||||
const octalPermissionsInputValidation = useValidation({
|
||||
source: octalPermissionsInput,
|
||||
rules: [
|
||||
{
|
||||
message: 'Invalid octal permission string',
|
||||
|
@ -42,15 +42,43 @@ const permissionsInputValidation = useValidation({
|
|||
],
|
||||
});
|
||||
watch(
|
||||
permissionsInput,
|
||||
octalPermissionsInput,
|
||||
(newPermissions) => {
|
||||
if (!permissionsInputValidation.isValid) {
|
||||
if (!octalPermissionsInputValidation.isValid) {
|
||||
return;
|
||||
}
|
||||
permissions.value = computePermissionsFromChmodOctalRepresentation(newPermissions.trim());
|
||||
},
|
||||
);
|
||||
|
||||
const symbolicPermissionsInput = ref('---------');
|
||||
const symbolicPermissionsInputValidation = useValidation({
|
||||
source: symbolicPermissionsInput,
|
||||
rules: [
|
||||
{
|
||||
message: 'Invalid symbolic permission string',
|
||||
validator: (value) => {
|
||||
try {
|
||||
computePermissionsFromChmodSymbolicRepresentation(value.trim());
|
||||
return true;
|
||||
}
|
||||
catch {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
watch(
|
||||
symbolicPermissionsInput,
|
||||
(newPermissions) => {
|
||||
if (!symbolicPermissionsInputValidation.isValid) {
|
||||
return;
|
||||
}
|
||||
permissions.value = computePermissionsFromChmodSymbolicRepresentation(newPermissions.trim());
|
||||
},
|
||||
);
|
||||
|
||||
const octal = computed(() => computeChmodOctalRepresentation({ permissions: permissions.value }));
|
||||
const symbolic = computed(() => computeChmodSymbolicRepresentation({ permissions: permissions.value }));
|
||||
</script>
|
||||
|
@ -58,13 +86,25 @@ const symbolic = computed(() => computeChmodSymbolicRepresentation({ permissions
|
|||
<template>
|
||||
<div>
|
||||
<c-input-text
|
||||
v-model:value="permissionsInput"
|
||||
v-model:value="octalPermissionsInput"
|
||||
placeholder="Put your octal permissions here..."
|
||||
label="Copy your octal permissions"
|
||||
:validation="permissionsInputValidation"
|
||||
:validation="octalPermissionsInputValidation"
|
||||
mb-2
|
||||
/>
|
||||
|
||||
<n-divider />
|
||||
|
||||
<c-input-text
|
||||
v-model:value="symbolicPermissionsInput"
|
||||
placeholder="Put your symbolic permissions here..."
|
||||
label="Copy your symbolic permissions"
|
||||
:validation="symbolicPermissionsInputValidation"
|
||||
mb-2
|
||||
/>
|
||||
|
||||
<n-divider />
|
||||
|
||||
<n-table :bordered="false" :bottom-bordered="false" single-column class="permission-table">
|
||||
<thead>
|
||||
<tr>
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
import { FileInvoice } from '@vicons/tabler';
|
||||
import { defineTool } from '../tool';
|
||||
import { translate } from '@/plugins/i18n.plugin';
|
||||
|
||||
export const tool = defineTool({
|
||||
name: translate('tools.chmod-calculator.title'),
|
||||
name: 'Chmod calculator',
|
||||
path: '/chmod-calculator',
|
||||
description: translate('tools.chmod-calculator.description'),
|
||||
description: 'Compute your chmod permissions and commands with this online chmod calculator.',
|
||||
keywords: [
|
||||
'chmod',
|
||||
'calculator',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue