mirror of
https://github.com/aws-actions/configure-aws-credentials.git
synced 2026-09-02 05:55:10 +09:00
+99
-1
@@ -1,11 +1,16 @@
|
||||
import * as core from '@actions/core';
|
||||
import { fs, vol } from 'memfs';
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import * as helpers from '../src/helpers';
|
||||
|
||||
vi.mock('node:fs');
|
||||
vi.mock('@actions/core');
|
||||
|
||||
describe('Configure AWS Credentials helpers', {}, () => {
|
||||
beforeEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
vi.spyOn(core, 'debug').mockImplementation(() => {});
|
||||
vi.clearAllMocks();
|
||||
vol.reset();
|
||||
});
|
||||
it('removes brackets from GitHub Actor', {}, () => {
|
||||
const actor = 'actor[bot]';
|
||||
@@ -97,4 +102,97 @@ describe('Configure AWS Credentials helpers', {}, () => {
|
||||
helpers.exportCredentials({ AccessKeyId: 'test', SecretAccessKey: 'test' }, false, true);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SESSION_TOKEN', '');
|
||||
});
|
||||
|
||||
describe('filesystem helpers', {}, () => {
|
||||
describe('isSymlink', {}, () => {
|
||||
it('returns true for a symlink', {}, () => {
|
||||
fs.mkdirSync('/dir', { recursive: true });
|
||||
fs.writeFileSync('/dir/target', 'data');
|
||||
fs.symlinkSync('/dir/target', '/dir/link');
|
||||
expect(helpers.isSymlink('/dir/link')).toBe(true);
|
||||
});
|
||||
|
||||
it('returns false for a regular file', {}, () => {
|
||||
fs.mkdirSync('/dir', { recursive: true });
|
||||
fs.writeFileSync('/dir/file', 'data');
|
||||
expect(helpers.isSymlink('/dir/file')).toBe(false);
|
||||
});
|
||||
|
||||
it('returns false for a missing path', {}, () => {
|
||||
expect(helpers.isSymlink('/nonexistent')).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('readFileUtf8', {}, () => {
|
||||
it('returns content for a regular file', {}, () => {
|
||||
fs.mkdirSync('/dir', { recursive: true });
|
||||
fs.writeFileSync('/dir/file', 'hello');
|
||||
expect(helpers.readFileUtf8('/dir/file')).toBe('hello');
|
||||
});
|
||||
|
||||
it('returns null when the file does not exist', {}, () => {
|
||||
fs.mkdirSync('/dir', { recursive: true });
|
||||
expect(helpers.readFileUtf8('/dir/missing')).toBe(null);
|
||||
});
|
||||
|
||||
it('refuses to read through a symlink at the target', {}, () => {
|
||||
fs.mkdirSync('/dir', { recursive: true });
|
||||
fs.writeFileSync('/dir/secret', 'sensitive');
|
||||
fs.symlinkSync('/dir/secret', '/dir/link');
|
||||
expect(() => helpers.readFileUtf8('/dir/link')).toThrow(/Refusing .* \(.* symbolic link\)/);
|
||||
});
|
||||
|
||||
it('refuses to read when the parent directory is a symlink', {}, () => {
|
||||
fs.mkdirSync('/real/.aws', { recursive: true });
|
||||
fs.writeFileSync('/real/.aws/credentials', 'data');
|
||||
fs.mkdirSync('/home', { recursive: true });
|
||||
fs.symlinkSync('/real/.aws', '/home/.aws');
|
||||
expect(() => helpers.readFileUtf8('/home/.aws/credentials')).toThrow(/Refusing .* \(.* symbolic link\)/);
|
||||
});
|
||||
|
||||
it('refuses to read when the path is a directory', {}, () => {
|
||||
fs.mkdirSync('/dir/subdir', { recursive: true });
|
||||
expect(() => helpers.readFileUtf8('/dir/subdir')).toThrow(/not a regular file/);
|
||||
});
|
||||
});
|
||||
|
||||
describe('writeFileUtf8', {}, () => {
|
||||
it('writes content with the specified mode', {}, () => {
|
||||
fs.mkdirSync('/dir', { recursive: true });
|
||||
helpers.writeFileUtf8('/dir/file', 'payload', 0o600);
|
||||
expect(fs.readFileSync('/dir/file', 'utf-8')).toBe('payload');
|
||||
expect(fs.statSync('/dir/file').mode & 0o777).toBe(0o600);
|
||||
});
|
||||
|
||||
it('refuses to follow a symlink at the target and leaves the target file untouched', {}, () => {
|
||||
fs.mkdirSync('/dir', { recursive: true });
|
||||
fs.writeFileSync('/dir/target', 'original');
|
||||
fs.symlinkSync('/dir/target', '/dir/link');
|
||||
expect(() => helpers.writeFileUtf8('/dir/link', 'attacker', 0o600)).toThrow(/Refusing .* \(.* symbolic link\)/);
|
||||
expect(fs.readFileSync('/dir/target', 'utf-8')).toBe('original');
|
||||
});
|
||||
|
||||
it.skipIf(process.platform === 'win32')('tightens mode on existing files', () => {
|
||||
fs.mkdirSync('/dir', { recursive: true });
|
||||
fs.writeFileSync('/dir/file', 'old', { mode: 0o644 });
|
||||
helpers.writeFileUtf8('/dir/file', 'new', 0o600);
|
||||
expect(fs.statSync('/dir/file').mode & 0o777).toBe(0o600);
|
||||
});
|
||||
});
|
||||
|
||||
describe('mkdir', {}, () => {
|
||||
it('is idempotent on a regular directory', {}, () => {
|
||||
helpers.mkdir('/some/nested/dir', 0o700);
|
||||
helpers.mkdir('/some/nested/dir', 0o700);
|
||||
expect(fs.statSync('/some/nested/dir').isDirectory()).toBe(true);
|
||||
});
|
||||
|
||||
it('refuses when the target directory is a symlink', {}, () => {
|
||||
fs.mkdirSync('/real', { recursive: true });
|
||||
fs.mkdirSync('/home', { recursive: true });
|
||||
fs.symlinkSync('/real', '/home/.aws');
|
||||
expect(() => helpers.mkdir('/home/.aws', 0o700)).toThrow(/Refusing .* \(.* symbolic link\)/);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user