inital commit
This commit is contained in:
commit
86acca1b8c
7
CHANGELOG.md
Normal file
7
CHANGELOG.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
This project uses Semantic Versioning
|
||||||
|
|
||||||
|
## 0.0.0
|
||||||
|
|
||||||
|
Initial release
|
10
README.md
Normal file
10
README.md
Normal file
@ -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.
|
BIN
__pycache__/setup.cpython-38.pyc
Normal file
BIN
__pycache__/setup.cpython-38.pyc
Normal file
Binary file not shown.
9
kasten/exceptions/__init__.py
Normal file
9
kasten/exceptions/__init__.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
class KastenException(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class InvalidKastenTypeLength(KastenException):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class InvalidEncryptionMode(KastenException):
|
||||||
|
pass
|
BIN
kasten/exceptions/__pycache__/__init__.cpython-38.pyc
Normal file
BIN
kasten/exceptions/__pycache__/__init__.cpython-38.pyc
Normal file
Binary file not shown.
46
kasten/pack/__init__.py
Normal file
46
kasten/pack/__init__.py
Normal file
@ -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
|
BIN
kasten/pack/__pycache__/__init__.cpython-38.pyc
Normal file
BIN
kasten/pack/__pycache__/__init__.cpython-38.pyc
Normal file
Binary file not shown.
2
kasten/types.py
Normal file
2
kasten/types.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
class KastenDataType(str):
|
||||||
|
pass
|
0
requirements.in
Normal file
0
requirements.in
Normal file
6
requirements.txt
Normal file
6
requirements.txt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#
|
||||||
|
# This file is autogenerated by pip-compile
|
||||||
|
# To update, run:
|
||||||
|
#
|
||||||
|
# pip-compile --generate-hashes --output-file=requirements.txt requirements.in
|
||||||
|
#
|
13
run_tests.sh
Executable file
13
run_tests.sh
Executable file
@ -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
|
24
setup.py
Normal file
24
setup.py
Normal file
@ -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"
|
||||||
|
],
|
||||||
|
)
|
32
tests/test_pack.py
Normal file
32
tests/test_pack.py
Normal file
@ -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
Block a user