bin-tcms-vault-key.t 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. #!/usr/bin/env perl
  2. # bin/tcms-vault-key writes the one secret that cannot be regenerated, so this
  3. # runs it the way a person would and asks Trog::Vault whether it can use the
  4. # result.
  5. use 5.040;
  6. use re '/aasx';
  7. use warnings FATAL => 'all';
  8. use FindBin;
  9. use FindBin::libs;
  10. use Test::More;
  11. use File::Slurper ();
  12. use IPC::Run3();
  13. our ( $REPO, $ROOT, $OLDCWD );
  14. BEGIN {
  15. require Cwd;
  16. require File::Path;
  17. require File::Temp;
  18. $REPO = Cwd::abs_path("$FindBin::Bin/..");
  19. $OLDCWD = Cwd::getcwd();
  20. $ROOT = File::Temp::tempdir( 'tcms-vault-key-XXXXXX', TMPDIR => 1, CLEANUP => 1 );
  21. $ENV{HOME} = $ROOT;
  22. delete $ENV{CREDENTIALS_DIRECTORY};
  23. delete $ENV{TPSGI_VAULT_KEY};
  24. File::Path::make_path("$ROOT/config");
  25. chdir($ROOT) or die "could not chdir to the sandbox: $!";
  26. }
  27. END {
  28. chdir($OLDCWD) if $OLDCWD;
  29. }
  30. # After the sandbox, because it takes the key out of the environment as it loads.
  31. use Trog::Vault ();
  32. my $key_file = $Trog::Vault::key_file;
  33. # Its exit code, and everything it printed.
  34. sub vault_key () {
  35. my $out = q{};
  36. IPC::Run3::run3( [ $^X, "-I$REPO/lib", "$REPO/bin/tcms-vault-key", '--file' ], \undef, \$out, \$out );
  37. return ( $? >> 8, $out );
  38. }
  39. subtest 'a key where there was none' => sub {
  40. # The umask that removes nothing, so the mode is the one the script asked for.
  41. my $umask = umask(0);
  42. my ( $code, $said ) = vault_key();
  43. umask($umask);
  44. is( $code, 0, 'it writes one' ) or diag($said);
  45. is( sprintf( '%04o', ( stat $key_file )[2] & oct('7777') ), '0600', 'that only its owner can read' );
  46. is( length( Trog::Vault::key() // q{} ), $Trog::Vault::key_bytes, 'and that the vault can use' );
  47. };
  48. subtest 'a key that is already there' => sub {
  49. my $before = File::Slurper::read_binary($key_file);
  50. my ( $code, $said ) = vault_key();
  51. is( $code, 2, 'it is refused' );
  52. like( $said, qr/already[ ]a[ ]key/, 'and says so' );
  53. is( File::Slurper::read_binary($key_file), $before, 'and is left alone' );
  54. };
  55. subtest 'a dangling symlink where the key goes' => sub {
  56. unlink($key_file) or die "could not clear the key: $!";
  57. symlink( "$ROOT/elsewhere", $key_file ) or die "could not plant the symlink: $!";
  58. my ( $code, $said ) = vault_key();
  59. is( $code, 2, 'it is refused' ) or diag($said);
  60. ok( !-e "$ROOT/elsewhere", 'and nothing is written where it points' );
  61. };
  62. done_testing();