mirror of
https://github.com/CorentinTh/it-tools.git
synced 2025-05-04 13:29:13 -04:00
Merge 4f5a09ed89
into 318fb6efb9
This commit is contained in:
commit
93e3d32a2c
6 changed files with 635 additions and 13 deletions
3
components.d.ts
vendored
3
components.d.ts
vendored
|
@ -129,6 +129,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']
|
||||
|
@ -143,6 +144,8 @@ declare module '@vue/runtime-core' {
|
|||
NLayoutSider: typeof import('naive-ui')['NLayoutSider']
|
||||
NMenu: typeof import('naive-ui')['NMenu']
|
||||
NScrollbar: typeof import('naive-ui')['NScrollbar']
|
||||
NSpin: typeof import('naive-ui')['NSpin']
|
||||
NTable: typeof import('naive-ui')['NTable']
|
||||
NSlider: typeof import('naive-ui')['NSlider']
|
||||
NSwitch: typeof import('naive-ui')['NSwitch']
|
||||
NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default']
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { describe, expect, it } from 'vitest';
|
||||
import { computeChmodOctalRepresentation, computeChmodSymbolicRepresentation } from './chmod-calculator.service';
|
||||
import { computeChmodOctalRepresentation, computeChmodSymbolicRepresentation, computePermissionsFromChmodOctalRepresentation, computePermissionsFromChmodSymbolicRepresentation, computeUmaskRepresentation } from './chmod-calculator.service';
|
||||
|
||||
describe('chmod-calculator', () => {
|
||||
describe('computeChmodOctalRepresentation', () => {
|
||||
|
@ -10,6 +10,7 @@ describe('chmod-calculator', () => {
|
|||
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.eql('777');
|
||||
|
@ -20,6 +21,7 @@ describe('chmod-calculator', () => {
|
|||
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.eql('000');
|
||||
|
@ -30,6 +32,7 @@ describe('chmod-calculator', () => {
|
|||
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.eql('235');
|
||||
|
@ -40,6 +43,7 @@ describe('chmod-calculator', () => {
|
|||
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.eql('421');
|
||||
|
@ -50,6 +54,7 @@ describe('chmod-calculator', () => {
|
|||
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.eql('124');
|
||||
|
@ -60,11 +65,57 @@ describe('chmod-calculator', () => {
|
|||
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.eql('222');
|
||||
});
|
||||
|
||||
expect(
|
||||
computeChmodOctalRepresentation({
|
||||
permissions: {
|
||||
owner: { read: false, write: true, execute: false },
|
||||
group: { read: false, write: true, execute: false },
|
||||
public: { read: false, write: true, execute: false },
|
||||
flags: { setuid: true, setgid: true, stickybit: true },
|
||||
},
|
||||
}),
|
||||
).to.eql('7222');
|
||||
|
||||
expect(
|
||||
computeChmodOctalRepresentation({
|
||||
permissions: {
|
||||
owner: { read: false, write: true, execute: false },
|
||||
group: { read: false, write: true, execute: false },
|
||||
public: { read: false, write: true, execute: false },
|
||||
flags: { setuid: true, setgid: false, stickybit: false },
|
||||
},
|
||||
}),
|
||||
).to.eql('4222');
|
||||
|
||||
expect(
|
||||
computeChmodOctalRepresentation({
|
||||
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: true, stickybit: false },
|
||||
},
|
||||
}),
|
||||
).to.eql('2222');
|
||||
|
||||
expect(
|
||||
computeChmodOctalRepresentation({
|
||||
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: true },
|
||||
},
|
||||
}),
|
||||
).to.eql('1222');
|
||||
});
|
||||
});
|
||||
describe('computeChmodSymbolicRepresentation', () => {
|
||||
it('get the symbolic representation from permissions', () => {
|
||||
expect(
|
||||
computeChmodSymbolicRepresentation({
|
||||
|
@ -72,6 +123,7 @@ describe('chmod-calculator', () => {
|
|||
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.eql('rwxrwxrwx');
|
||||
|
@ -82,6 +134,7 @@ describe('chmod-calculator', () => {
|
|||
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.eql('---------');
|
||||
|
@ -92,6 +145,7 @@ describe('chmod-calculator', () => {
|
|||
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.eql('-w--wxr-x');
|
||||
|
@ -102,6 +156,7 @@ describe('chmod-calculator', () => {
|
|||
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.eql('r---w---x');
|
||||
|
@ -112,6 +167,7 @@ describe('chmod-calculator', () => {
|
|||
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.eql('--x-w-r--');
|
||||
|
@ -122,9 +178,382 @@ describe('chmod-calculator', () => {
|
|||
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.eql('-w--w--w-');
|
||||
|
||||
expect(
|
||||
computeChmodSymbolicRepresentation({
|
||||
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: true },
|
||||
},
|
||||
}),
|
||||
).to.eql('--x-w-r-t');
|
||||
|
||||
expect(
|
||||
computeChmodSymbolicRepresentation({
|
||||
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: true, stickybit: true },
|
||||
},
|
||||
}),
|
||||
).to.eql('--x-wsr-t');
|
||||
|
||||
expect(
|
||||
computeChmodSymbolicRepresentation({
|
||||
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.eql('--s-wsr-t');
|
||||
|
||||
expect(
|
||||
computeChmodSymbolicRepresentation({
|
||||
permissions: {
|
||||
owner: { read: true, write: false, execute: true },
|
||||
group: { read: true, write: true, execute: false },
|
||||
public: { read: true, write: false, execute: false },
|
||||
flags: { setuid: false, setgid: false, stickybit: false },
|
||||
},
|
||||
}),
|
||||
).to.eql('r-xrw-r--');
|
||||
|
||||
expect(
|
||||
computeChmodSymbolicRepresentation({
|
||||
permissions: {
|
||||
owner: { read: true, write: true, execute: true },
|
||||
group: { read: true, write: true, execute: true },
|
||||
public: { read: true, write: true, execute: true },
|
||||
flags: { setuid: true, setgid: true, stickybit: true },
|
||||
},
|
||||
}),
|
||||
).to.eql('rwsrwsrwt');
|
||||
});
|
||||
});
|
||||
describe('computePermissionsFromChmodOctalRepresentation', () => {
|
||||
it('throws on invalid octal values', () => {
|
||||
expect(() => computePermissionsFromChmodOctalRepresentation('12')).to.throw();
|
||||
expect(() => computePermissionsFromChmodOctalRepresentation('12345')).to.throw();
|
||||
expect(() => computePermissionsFromChmodOctalRepresentation('999')).to.throw();
|
||||
expect(() => computePermissionsFromChmodOctalRepresentation('9999')).to.throw();
|
||||
});
|
||||
|
||||
it('get permissions from octal representation', () => {
|
||||
expect(
|
||||
computePermissionsFromChmodOctalRepresentation('777'),
|
||||
).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(
|
||||
computePermissionsFromChmodOctalRepresentation('000'),
|
||||
).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(
|
||||
computePermissionsFromChmodOctalRepresentation('235'),
|
||||
).to.eql({
|
||||
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 },
|
||||
});
|
||||
|
||||
expect(
|
||||
computePermissionsFromChmodOctalRepresentation('421'),
|
||||
).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(
|
||||
computePermissionsFromChmodOctalRepresentation('124'),
|
||||
).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(
|
||||
computePermissionsFromChmodOctalRepresentation('222'),
|
||||
).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(
|
||||
computePermissionsFromChmodOctalRepresentation('7222'),
|
||||
).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: true, setgid: true, stickybit: true },
|
||||
});
|
||||
|
||||
expect(
|
||||
computePermissionsFromChmodOctalRepresentation('4222'),
|
||||
).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: true, setgid: false, stickybit: false },
|
||||
});
|
||||
|
||||
expect(
|
||||
computePermissionsFromChmodOctalRepresentation('2222'),
|
||||
).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: true, stickybit: false },
|
||||
});
|
||||
|
||||
expect(
|
||||
computePermissionsFromChmodOctalRepresentation('1222'),
|
||||
).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: true },
|
||||
});
|
||||
});
|
||||
});
|
||||
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 },
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
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',
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,15 +1,21 @@
|
|||
import _ from 'lodash';
|
||||
import type { GroupPermissions, Permissions } from './chmod-calculator.types';
|
||||
import type { GroupPermissions, Permissions, SpecialPermissions } from './chmod-calculator.types';
|
||||
|
||||
export { computeChmodOctalRepresentation, computeChmodSymbolicRepresentation };
|
||||
export { computeUmaskRepresentation, computeChmodOctalRepresentation, computeChmodSymbolicRepresentation, computePermissionsFromChmodOctalRepresentation, computePermissionsFromChmodSymbolicRepresentation };
|
||||
|
||||
function computeChmodOctalRepresentation({ permissions }: { permissions: Permissions }): string {
|
||||
const permissionValue = { read: 4, write: 2, execute: 1 };
|
||||
const specialPermissionValue = { setuid: 4, setgid: 2, stickybit: 1 };
|
||||
|
||||
const getGroupPermissionValue = (permission: GroupPermissions) =>
|
||||
_.reduce(permission, (acc, isPermSet, key) => acc + (isPermSet ? _.get(permissionValue, key, 0) : 0), 0);
|
||||
const getSpecialPermissionValue = (permission: SpecialPermissions) => {
|
||||
const octalValue = _.reduce(permission, (acc, isPermSet, key) => acc + (isPermSet ? _.get(specialPermissionValue, key, 0) : 0), 0);
|
||||
return octalValue > 0 ? octalValue.toString() : '';
|
||||
};
|
||||
|
||||
return [
|
||||
getSpecialPermissionValue(permissions.flags || { setuid: false, setgid: false, stickybit: false }),
|
||||
getGroupPermissionValue(permissions.owner),
|
||||
getGroupPermissionValue(permissions.group),
|
||||
getGroupPermissionValue(permissions.public),
|
||||
|
@ -18,13 +24,92 @@ function computeChmodOctalRepresentation({ permissions }: { permissions: Permiss
|
|||
|
||||
function computeChmodSymbolicRepresentation({ permissions }: { permissions: Permissions }): string {
|
||||
const permissionValue = { read: 'r', write: 'w', execute: 'x' };
|
||||
const specialFlagPermission = 'execute';
|
||||
|
||||
const getGroupPermissionValue = (permission: GroupPermissions) =>
|
||||
_.reduce(permission, (acc, isPermSet, key) => acc + (isPermSet ? _.get(permissionValue, key, '') : '-'), '');
|
||||
const getGroupPermissionValue = (permission: GroupPermissions, specialFlag: null | 's' | 't') =>
|
||||
_.reduce(permission, (acc, isPermSet, key) => acc + ((key === specialFlagPermission ? specialFlag : undefined)
|
||||
|| (isPermSet ? _.get(permissionValue, key, '') : '-')), '');
|
||||
|
||||
return [
|
||||
getGroupPermissionValue(permissions.owner),
|
||||
getGroupPermissionValue(permissions.group),
|
||||
getGroupPermissionValue(permissions.public),
|
||||
getGroupPermissionValue(permissions.owner, permissions.flags?.setuid ? 's' : null),
|
||||
getGroupPermissionValue(permissions.group, permissions.flags?.setgid ? 's' : null),
|
||||
getGroupPermissionValue(permissions.public, permissions.flags?.stickybit ? 't' : null),
|
||||
].join('');
|
||||
}
|
||||
|
||||
function computePermissionsFromChmodOctalRepresentation(octalPermissions: string): Permissions {
|
||||
const permissionValue = { read: 4, write: 2, execute: 1 };
|
||||
const specialPermissionValue = { setuid: 4, setgid: 2, stickybit: 1 };
|
||||
|
||||
if (!octalPermissions || !octalPermissions.match(/^[0-7]{3,4}$/)) {
|
||||
throw new Error(`Invalid octal permissions (must be 3 or 4 octal digits): ${octalPermissions}`);
|
||||
}
|
||||
const fullOctalPermissions = octalPermissions.length === 3 ? `0${octalPermissions}` : octalPermissions;
|
||||
|
||||
const hasSet = (position: number, flagValue: number) => (Number(fullOctalPermissions[position]) & flagValue) === flagValue;
|
||||
function computePermissionObject<T>(permissionSet: object, position: number): T {
|
||||
return _.reduce(permissionSet, (acc, flag, key) => ({ ...acc, [key]: hasSet(position, flag) }), {}) as T;
|
||||
}
|
||||
const flagsPosition = 0;
|
||||
const ownerPosition = 1;
|
||||
const groupPosition = 2;
|
||||
const publicPosition = 3;
|
||||
return {
|
||||
owner: computePermissionObject(permissionValue, ownerPosition),
|
||||
group: computePermissionObject(permissionValue, groupPosition),
|
||||
public: computePermissionObject(permissionValue, publicPosition),
|
||||
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);
|
||||
}
|
||||
|
||||
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,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,10 +1,17 @@
|
|||
export type Scope = 'read' | 'write' | 'execute';
|
||||
export type Group = 'owner' | 'group' | 'public';
|
||||
export type SpecialFlags = 'setuid' | 'setgid' | 'stickybit';
|
||||
|
||||
export type GroupPermissions = {
|
||||
[k in Scope]: boolean;
|
||||
};
|
||||
|
||||
export type SpecialPermissions = {
|
||||
[k in SpecialFlags]: boolean;
|
||||
};
|
||||
|
||||
export type Permissions = {
|
||||
[k in Group]: GroupPermissions;
|
||||
} & {
|
||||
flags: SpecialPermissions
|
||||
};
|
||||
|
|
|
@ -2,9 +2,10 @@
|
|||
import { useThemeVars } from 'naive-ui';
|
||||
|
||||
import InputCopyable from '../../components/InputCopyable.vue';
|
||||
import { computeChmodOctalRepresentation, computeChmodSymbolicRepresentation } from './chmod-calculator.service';
|
||||
import { computeChmodOctalRepresentation, computeChmodSymbolicRepresentation, computePermissionsFromChmodOctalRepresentation, computePermissionsFromChmodSymbolicRepresentation, computeUmaskRepresentation } from './chmod-calculator.service';
|
||||
|
||||
import type { Group, Scope } from './chmod-calculator.types';
|
||||
import { useValidation } from '@/composable/validation';
|
||||
|
||||
const themeVars = useThemeVars();
|
||||
|
||||
|
@ -19,14 +20,92 @@ const permissions = ref({
|
|||
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 },
|
||||
});
|
||||
|
||||
const octalPermissionsInput = ref('000');
|
||||
const octalPermissionsInputValidation = useValidation({
|
||||
source: octalPermissionsInput,
|
||||
rules: [
|
||||
{
|
||||
message: 'Invalid octal permission string',
|
||||
validator: (value) => {
|
||||
try {
|
||||
computePermissionsFromChmodOctalRepresentation(value.trim());
|
||||
return true;
|
||||
}
|
||||
catch {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
watch(
|
||||
octalPermissionsInput,
|
||||
(newPermissions) => {
|
||||
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 }));
|
||||
const umask = computed(() => computeUmaskRepresentation({ permissions: permissions.value }));
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<c-input-text
|
||||
v-model:value="octalPermissionsInput"
|
||||
placeholder="Put your octal permissions here..."
|
||||
label="Copy your octal permissions"
|
||||
: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>
|
||||
|
@ -52,6 +131,20 @@ const symbolic = computed(() => computeChmodSymbolicRepresentation({ permissions
|
|||
<n-checkbox v-model:checked="permissions[group][scope]" size="large" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="line-header">
|
||||
Flags
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<n-checkbox v-model:checked="permissions.flags.setuid" size="large" />
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<n-checkbox v-model:checked="permissions.flags.setgid" size="large" />
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<n-checkbox v-model:checked="permissions.flags.stickybit" size="large" />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</n-table>
|
||||
|
||||
|
@ -63,6 +156,11 @@ const symbolic = computed(() => computeChmodSymbolicRepresentation({ permissions
|
|||
</div>
|
||||
|
||||
<InputCopyable :value="`chmod ${octal} path`" readonly />
|
||||
|
||||
<c-card title="Umask">
|
||||
<InputCopyable :value="umask.octal" readonly />
|
||||
<InputCopyable :value="umask.symbolic" readonly />
|
||||
</c-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -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',
|
||||
|
@ -17,6 +16,7 @@ export const tool = defineTool({
|
|||
'recursive',
|
||||
'generator',
|
||||
'octal',
|
||||
'umask',
|
||||
],
|
||||
component: () => import('./chmod-calculator.vue'),
|
||||
icon: FileInvoice,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue