commit
86acca1b8c
@ -0,0 +1,7 @@ |
||||
# Changelog |
||||
|
||||
This project uses Semantic Versioning |
||||
|
||||
## 0.0.0 |
||||
|
||||
Initial release |
@ -0,0 +1,10 @@ |
||||
# Python Template |
||||
|
||||
This is a template repository for Python projects. I dedicate this template to the public domain using the creative commons zero license: https://creativecommons.org/publicdomain/zero/1.0/legalcode |
||||
|
||||
Recommended tools: |
||||
|
||||
* virtualenv: https://virtualenv.pypa.io/en/latest/ |
||||
* pip-tools: https://github.com/jazzband/pip-tools |
||||
|
||||
This includes a setup for running tests including travis-ci. The Makefile contains a test command which will execute all test scripts in tests/ and exit with an error code if any of the tests fail. |
Binary file not shown.
@ -0,0 +1,9 @@ |
||||
class KastenException(Exception): |
||||
pass |
||||
|
||||
|
||||
class InvalidKastenTypeLength(KastenException): |
||||
pass |
||||
|
||||
class InvalidEncryptionMode(KastenException): |
||||
pass |
Binary file not shown.
@ -0,0 +1,46 @@ |
||||
""" |
||||
0: type: str: 4bytesmax |
||||
1: enc-mode: int: 0, 1, 2 (0=plaintext, 1=asymmetic, 2=symmetric). |
||||
2. Timestamp: int |
||||
encrypted with specified mode: |
||||
3. signer: bytes (max 256bits) |
||||
4. signature: bytes (max 256bits) |
||||
5. app_metadata: JSON |
||||
\n |
||||
data: bytes |
||||
|
||||
""" |
||||
from msgpack import packb |
||||
|
||||
from .. import exceptions |
||||
|
||||
|
||||
def pack(data: bytes, data_type: 'KastenDataType', |
||||
enc_mode: 'KastenEncryptionModeID', |
||||
signer: bytes = None, signature: bytes = None, |
||||
app_metadata: 'KastenSerializeableDict' = None) -> 'PreparedKasten': |
||||
|
||||
# Ensure data type does not exceed 4 characters |
||||
if not data_type or len(data_type) > 4: |
||||
raise exceptions.InvalidKastenTypeLength |
||||
|
||||
# Ensure encryption mode is valid (asymmetric, symmetric, plaintext) |
||||
enc_mode = int(enc_mode) |
||||
if enc_mode not in range(3): |
||||
raise |
||||
try: |
||||
data = data.encode('utf8') |
||||
except AttributeError: |
||||
pass |
||||
|
||||
kasten_header = [data_type, enc_mode] |
||||
if signer: |
||||
if signature is None: |
||||
raise ValueError("Signer specified without signature") |
||||
kasten_header.extend((signer, signature)) |
||||
if app_metadata is not None: |
||||
kasten_header.append(app_metadata) |
||||
|
||||
kasten_header = packb(kasten_header) + packb(b'\n') |
||||
|
||||
return kasten_header + data |
Binary file not shown.
@ -0,0 +1,2 @@ |
||||
class KastenDataType(str): |
||||
pass |
@ -0,0 +1,6 @@ |
||||
# |
||||
# This file is autogenerated by pip-compile |
||||
# To update, run: |
||||
# |
||||
# pip-compile --generate-hashes --output-file=requirements.txt requirements.in |
||||
# |
@ -0,0 +1,13 @@ |
||||
#!/bin/bash |
||||
ran=0 |
||||
SECONDS=0 ; |
||||
close () { |
||||
exit 10; |
||||
} |
||||
|
||||
for f in tests/*.py; do |
||||
python3 "$f" || close # if needed |
||||
let "ran++" |
||||
done |
||||
echo "ran $ran test files successfully in $SECONDS seconds" |
||||
rm -f *.dat |
@ -0,0 +1,24 @@ |
||||
from setuptools import setup, find_packages |
||||
|
||||
from os import path |
||||
this_directory = path.abspath(path.dirname(__file__)) |
||||
with open(path.join(this_directory, 'README.md'), encoding='utf-8') as f: |
||||
long_description = f.read() |
||||
|
||||
setup(name='kasten', |
||||
version='0.0.5', |
||||
description='Library desc', |
||||
author='Author Name', |
||||
author_email='beardog@mailbox.org', |
||||
url='https://chaoswebs.net', |
||||
packages=find_packages(exclude=['contrib', 'docs', 'tests']), |
||||
install_requires=['mimcvdf', 'msgpack'], |
||||
long_description=long_description, |
||||
long_description_content_type='text/markdown', |
||||
classifiers=[ |
||||
"Programming Language :: Python :: 3", |
||||
"License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", |
||||
"Operating System :: OS Independent", |
||||
"Intended Audience :: Developers" |
||||
], |
||||
) |
@ -0,0 +1,32 @@ |
||||
import unittest |
||||
import os |
||||
|
||||
from kasten import pack |
||||
from kasten import exceptions |
||||
|
||||
|
||||
class TestPack(unittest.TestCase): |
||||
|
||||
def test_unsigned_pack(self): |
||||
data = os.urandom(10) |
||||
packed = pack.pack(data, 'bin', 0) |
||||
parts = packed.split(b'\n', 1) |
||||
self.assertEqual(parts[0], b'\x92\xa3bin\x00\xc4\x01') |
||||
self.assertEqual(parts[1], data) |
||||
|
||||
def test_linebreak_data(self): |
||||
data = os.urandom(9) + b'\n' + b"okay" |
||||
packed = pack.pack(data, 'bin', 0) |
||||
parts = packed.split(b'\n', 1) |
||||
self.assertEqual(parts[0], b'\x92\xa3bin\x00\xc4\x01') |
||||
self.assertEqual(parts[1], data) |
||||
|
||||
def test_invalid_data_type(self): |
||||
data = os.urandom(10) |
||||
self.assertRaises(exceptions.InvalidKastenTypeLength, pack.pack, data, '', 1) |
||||
data = os.urandom(10) |
||||
self.assertRaises(exceptions.InvalidKastenTypeLength, pack.pack, data, 'aaaaa', 1) |
||||
|
||||
|
||||
|
||||
unittest.main() |
Loading…
Reference in new issue