Skip to content

Commit

Permalink
Add decrypt command
Browse files Browse the repository at this point in the history
decrypt accepts the output from tar.

For #21
  • Loading branch information
peterstory committed Jul 22, 2024
1 parent 388cf9d commit baaa1e5
Show file tree
Hide file tree
Showing 9 changed files with 195 additions and 5 deletions.
6 changes: 4 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ ADD README.md /root/pydiode/README.md
# Install Python dependencies
RUN pip install pyinstaller

# Install fpm, for generating .deb packages
RUN apt update && apt install -y ruby && gem install fpm
# Install:
# - fpm, for generating .deb packages
# - gpg, for decrypting files
RUN apt update && apt install -y ruby && gem install fpm && apt install -y gpg

# Increase the default height of the file dialogue
RUN sed -i 's/-height 120/-height 500/' /usr/share/tcltk/tk8.6/iconlist.tcl
Expand Down
39 changes: 39 additions & 0 deletions src/pydiode/decrypt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
"""
decrypt.py
Reads filenames from STDIN, and uses gpg to decrypt files ending in .gpg
Usage:
> ls
1.txt.gpg
> echo "1.txt.gpg" | python -m pydiode.decrypt
> ls
1.txt
1.txt.gpg
"""

from pathlib import Path
import subprocess
import sys


def main():
for line in sys.stdin:
path = Path(line.strip())
if path.exists() and path.suffix == ".gpg":
subprocess.run(
[
"gpg",
"--batch",
"--yes",
"--quiet",
"--output",
path.with_suffix(""),
"--decrypt",
path,
]
)


if __name__ == "__main__":
main()
5 changes: 3 additions & 2 deletions src/pydiode/tar.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ def main():
try:
with tarfile.open(fileobj=sys.stdin.buffer, mode="r|") as tar:
tar.extractall(args.path)
# Print the name of each file extracted
tar.list(verbose=False)
# Print the path of each file extracted
for name in tar.getnames():
print(os.path.join(args.path, name))
# Don't print the full stack trace for known error types
except tarfile.ReadError as e:
if str(e) == "empty file":
Expand Down
Binary file added tests/1.txt.gpg
Binary file not shown.
Binary file added tests/2.txt.gpg
Binary file not shown.
Binary file added tests/3.txt.gpg
Binary file not shown.
106 changes: 106 additions & 0 deletions tests/PRIVATE.asc
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
-----BEGIN PGP PRIVATE KEY BLOCK-----

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
WCM=
=Zub4
-----END PGP PRIVATE KEY BLOCK-----
41 changes: 41 additions & 0 deletions tests/test_decrypt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from pathlib import Path
import shutil
import subprocess
import sys
import tempfile
import unittest

PARENT_DIR = Path(__file__).parent


class TestDecrypt(unittest.TestCase):
def setUp(self):
subprocess.run(
["gpg", "--import", PARENT_DIR / "PRIVATE.asc"],
capture_output=True,
check=True,
)

def test_decrypt(self):
files = {
Path("1.txt.gpg"): "ABC",
Path("2.txt.gpg"): "DEF",
Path("3.txt.gpg"): "GHI",
}

with tempfile.TemporaryDirectory() as tmpdir:
# Copy the encrypted files
for file in files:
shutil.copy(PARENT_DIR / file, tmpdir)

# Decrypt the files
decrypt = subprocess.run(
[sys.executable, "-m", "pydiode.decrypt"],
input="\n".join([str(tmpdir / file) for file in files.keys()]),
text=True,
)

# Check the files were decrypted
for file, data in files.items():
with open(tmpdir / file.with_suffix(""), "r") as f:
self.assertEqual(data, f.read().strip())
3 changes: 2 additions & 1 deletion tests/test_tar.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ def test_tar_untar(self):

# Ensure the printed filenames match the sent files
self.assertEqual(
list(files.keys()), receiver_stdout.decode("utf-8").split()
[os.path.join(dest, file) for file in files.keys()],
receiver_stdout.decode("utf-8").split(),
)

# Ensure the extracted files match the sent files
Expand Down

0 comments on commit baaa1e5

Please sign in to comment.