From 1fc69b5b568716017e62497475a03adc62875bda Mon Sep 17 00:00:00 2001 From: Joey Wilhelm Date: Fri, 4 Mar 2022 17:23:02 -0700 Subject: [PATCH 1/2] Set up tox, stub tests, and satisfy linters --- asherah/__init__.py | 2 ++ asherah/asherah.py | 11 ++++++++++- asherah/exceptions.py | 3 +++ asherah/types.py | 25 +++++++++++++++++------- tests/__init__.py | 0 tests/test_asherah.py | 8 ++++++++ tox.ini | 44 +++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 85 insertions(+), 8 deletions(-) create mode 100644 tests/__init__.py create mode 100644 tests/test_asherah.py create mode 100644 tox.ini diff --git a/asherah/__init__.py b/asherah/__init__.py index 1d65753..d50ab36 100644 --- a/asherah/__init__.py +++ b/asherah/__init__.py @@ -1,3 +1,5 @@ +"""Asherah application encryption library""" + from .asherah import Asherah from .types import AsherahConfig diff --git a/asherah/asherah.py b/asherah/asherah.py index a0edadf..da2497f 100644 --- a/asherah/asherah.py +++ b/asherah/asherah.py @@ -1,12 +1,18 @@ +"""Main Asherah class, for encrypting and decrypting of data""" +# pylint: disable=line-too-long, too-many-locals + import os -from cobhan import Cobhan from datetime import datetime, timezone from typing import ByteString, Union +from cobhan import Cobhan + from . import exceptions, types class Asherah: + """The main class for providing encryption and decryption functionality""" + KEY_SIZE = 64 def __init__(self): @@ -22,6 +28,7 @@ def __init__(self): ) def setup(self, config: types.AsherahConfig) -> None: + """Set up/initialize the underlying encryption library.""" kms_type_buf = self.__cobhan.str_to_buf(config.kms_type) metastore_buf = self.__cobhan.str_to_buf(config.metastore) service_name_buf = self.__cobhan.str_to_buf(config.service_name) @@ -61,6 +68,7 @@ def setup(self, config: types.AsherahConfig) -> None: ) def encrypt(self, partition_id: str, data: Union[ByteString, str]): + """Encrypt a chunk of data""" if isinstance(data, str): data = data.encode("utf-8") # Inputs @@ -108,6 +116,7 @@ def encrypt(self, partition_id: str, data: Union[ByteString, str]): def decrypt( self, partition_id: str, data_row_record: types.DataRowRecord ) -> bytearray: + """Decrypt data that was previously encrypted by Asherah""" # Inputs partition_id_buf = self.__cobhan.str_to_buf(partition_id) encrypted_data_buf = self.__cobhan.bytearray_to_buf(data_row_record.data) diff --git a/asherah/exceptions.py b/asherah/exceptions.py index e1da3f2..f8a2bd2 100644 --- a/asherah/exceptions.py +++ b/asherah/exceptions.py @@ -1,2 +1,5 @@ +"""Custom exceptions for Asherah""" + + class AsherahException(Exception): """Base exception class for any problems encountered in Asherah""" diff --git a/asherah/types.py b/asherah/types.py index 03ee46a..b788450 100644 --- a/asherah/types.py +++ b/asherah/types.py @@ -1,21 +1,26 @@ +"""Type definitions for the Asherah library""" +# pylint: disable=too-many-instance-attributes,invalid-name + from dataclasses import dataclass from datetime import datetime -from typing import ByteString +from typing import ByteString, Optional @dataclass class AsherahConfig: + """Configuration options for Asherah setup""" + kms_type: str metastore: str service_name: str product_id: str - rdbms_connection_string: str = None - dynamo_db_endpoint: str = None - dynamo_db_region: str = None - dynamo_db_table_name: str = None + rdbms_connection_string: Optional[str] = None + dynamo_db_endpoint: Optional[str] = None + dynamo_db_region: Optional[str] = None + dynamo_db_table_name: Optional[str] = None enable_region_suffix: bool = False - preferred_region: str = None - region_map: str = None + preferred_region: Optional[str] = None + region_map: Optional[str] = None verbose: bool = False session_cache: bool = False debug_output: bool = False @@ -23,12 +28,16 @@ class AsherahConfig: @dataclass class KeyMeta: + """Metadata about an encryption key""" + id: str created: datetime @dataclass class EnvelopeKeyRecord: + """Information about an encryption envelope""" + encrypted_key: ByteString created: datetime parent_key_meta: KeyMeta @@ -36,5 +45,7 @@ class EnvelopeKeyRecord: @dataclass class DataRowRecord: + """Encrypted data and its related information""" + data: ByteString key: EnvelopeKeyRecord diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_asherah.py b/tests/test_asherah.py new file mode 100644 index 0000000..911f76b --- /dev/null +++ b/tests/test_asherah.py @@ -0,0 +1,8 @@ +# pylint: disable=missing-function-docstring,missing-class-docstring,missing-module-docstring + +from unittest import TestCase + + +class AsherahTest(TestCase): + def test_fake(self): + self.assertEqual(True, True) diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..7e267a8 --- /dev/null +++ b/tox.ini @@ -0,0 +1,44 @@ +[tox] +minversion = 3.7.0 +toxworkdir = {env:TOX_WORK_DIR:.tox} +skip_missing_interpreters = True +envlist = py{37,38,39,310},black,mypy,pylint +parallel_show_output = True +isolated_build = True + +[gh-actions] +python = + 3.7: py37 + 3.8: py38 + 3.9: py39 + 3.10: py310 + +[testenv] +whitelist_externals = + poetry + pytest +setenv = + PYTHONDONTWRITEBYTECODE=1 + PYTHONHASHSEED=0 + PYTHONWARNINGS=ignore +commands = + poetry install --no-root -v + poetry run pytest {posargs} + +[testenv:black] +basepython = python3.7 +commands = + poetry install --no-root -v + poetry run black --check . + +[testenv:mypy] +basepython = python3.7 +commands = + poetry install --no-root -v + poetry run mypy . + +[testenv:pylint] +basepython = python3.7 +commands = + poetry install --no-root -v + poetry run pylint asherah/ tests/ From acf3dac035d67a0dd63c609b26e84b1781459dd1 Mon Sep 17 00:00:00 2001 From: Joey Wilhelm Date: Fri, 4 Mar 2022 17:23:19 -0700 Subject: [PATCH 2/2] Set up workflows for CodeQL and publishing to PyPI --- .github/workflows/codeql-analysis.yml | 70 +++++++++++++++++++++++++++ .github/workflows/publish.yml | 28 +++++++++++ 2 files changed, 98 insertions(+) create mode 100644 .github/workflows/codeql-analysis.yml create mode 100644 .github/workflows/publish.yml diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 0000000..72d7914 --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,70 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ main ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ main ] + schedule: + - cron: '17 21 * * 6' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'python' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] + # Learn more about CodeQL language support at https://git.io/codeql-language-support + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v1 + + # ℹī¸ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # ✏ī¸ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..a1e5447 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,28 @@ +name: publish + +on: + release: + types: [published] # Trigger when release is created + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f + - name: Set up Python 3.7 + uses: actions/setup-python@3105fb18c05ddd93efea5f9e0bef7a03a6e9e7df + with: + python-version: 3.7 + - name: Install dependencies + run: | + pip install --upgrade pip + pip install --upgrade poetry + - name: Download Asherah binaries + run: | + ./download-libasherah.sh + - name: Package and publish with Poetry + run: | + poetry config pypi-token.pypi $PYPI_TOKEN + poetry publish --build + env: + PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}