Skip to content

Commit

Permalink
ANXOS-390: Initial implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
beachmachine committed Oct 25, 2024
1 parent ef8158e commit 40231da
Show file tree
Hide file tree
Showing 31 changed files with 853 additions and 3 deletions.
41 changes: 41 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Publish package
on:
release:
types: [created]

jobs:
deploy:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.10'
architecture: 'x64'

- name: Install dependencies and package
run: |
pip install -U pip
pip install -r requirements.txt
- name: Build source and binary distribution package
run: |
python setup.py sdist bdist_wheel
env:
PACKAGE_VERSION: ${{ github.ref }}

- name: Check distribution package
run: |
twine check dist/*
- name: Publish distribution package
run: |
twine upload dist/*
env:
TWINE_REPOSITORY: ${{ secrets.PYPI_REPOSITORY }}
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
TWINE_NON_INTERACTIVE: yes
56 changes: 56 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: Run linter and tests
on: [push, pull_request]

jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version:
- '3.10'
- '3.11'
- '3.12'
- '3.13'
- 'pypy3.10'
django-version:
- '4.2'
- '5.0'
- '5.1'

steps:
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies and package
run: |
pip install -U pip
pip install -r requirements.txt
pip install django~=${{ matrix.django-version }}
- name: Lint
run: |
pre-commit run --all-files
- name: Run tests with coverage
run: |
# prepare Django project: link all necessary data from the test project into the root directory
# Hint: Simply changing the directory does not work (leads to missing files in coverage report)
ln -s ./tests/testapp testapp
ln -s ./tests/manage.py manage.py
ln -s ./tests/pytest.ini pytest.ini
# run tests with coverage
pytest --cov=django_fernet --cov-report=xml testapp/tests/
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
fail_ci_if_error: true
files: ./coverage.xml
token: ${{ secrets.CODECOV_TOKEN }}
verbose: false
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.idea
.vscode
.env
.DS_Store
.pytest_cache
.coverage
coverage.xml
*.egg-info
*.pyc
*.pyo
db.sqlite3
27 changes: 27 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: check-merge-conflict
- id: end-of-file-fixer
- id: requirements-txt-fixer
- id: trailing-whitespace
args: ["--markdown-linebreak-ext=md"]

- repo: https://github.com/asottile/pyupgrade
rev: v3.17.0
hooks:
- id: pyupgrade
args: ["--py310-plus"]

- repo: https://github.com/asottile/add-trailing-comma
rev: v3.1.0
hooks:
- id: add-trailing-comma

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.6.2
hooks:
- id: ruff
args: [ --fix ]
- id: ruff-format
34 changes: 34 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Guidance on how to contribute

> By submitting a pull request or filing a bug, issue, or feature request,
> you are agreeing to comply with this waiver of copyright interest.
> Details can be found in our [LICENSE](LICENSE).

There are two primary ways to help:
- Using the issue tracker, and
- Changing the code-base.


## Using the issue tracker

Use the issue tracker to suggest feature requests, report bugs, and ask questions.
This is also a great way to connect with the developers of the project as well
as others who are interested in this solution.

Use the issue tracker to find ways to contribute. Find a bug or a feature, mention in
the issue that you will take on that effort, then follow the _Changing the code-base_
guidance below.


## Changing the code-base

Generally speaking, you should fork this repository, make changes in your
own fork, and then submit a pull request. All new code should have associated
unit tests that validate implemented features and the presence or lack of defects.
Additionally, the code should follow any stylistic and architectural guidelines
prescribed by the project. In the absence of such guidelines, mimic the styles
and patterns in the existing code-base.

### Contribution guidelines
- Your code should follow PEP 8 -- Style Guide for Python Code
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2024 Anexia
Copyright (c) 2024 ANEXIA Internetdienstleisungs GmbH

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
141 changes: 139 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,139 @@
# django-fernet
Django Model Fields that store the value encrypted with Fernet.
# Django Fernet

[![PyPI](https://badge.fury.io/py/django-fernet.svg)](https://pypi.org/project/django-fernet/)
[![Test Status](https://github.com/anexia/django-fernet/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/anexia/django-fernet/actions/workflows/test.yml)
[![Codecov](https://codecov.io/gh/anexia/django-fernet/branch/main/graph/badge.svg)](https://codecov.io/gh/anexia/django-fernet)

A library that provides Django model fields to store value encrypted using Fernet.

## Installation

With a [correctly configured](https://pipenv.pypa.io/en/latest/basics/#basic-usage-of-pipenv) `pipenv` toolchain:

```bash
pipenv install django-fernet
```

You may also use classic `pip` to install the package:

```bash
pip install django-fernet
```

### Auto-formatter setup
We use ruff (https://github.com/astral-sh/ruff) for local auto-formatting and for linting in the CI pipeline.
The pre-commit framework (https://pre-commit.com) provides Git hooks for these tools, so they are automatically applied
before every commit.

Steps to activate:
* Install the pre-commit framework: `pip install pre-commit` (for alternative installation options
see https://pre-commit.com/#install)
* Activate the framework (from the root directory of the repository): `pre-commit install`

Hint: You can also run the formatters manually at any time with the following command: `pre-commit run --all-files`


## Getting started

### Example model that defines fernet text fields

```python
from django.db import models
from django_fernet.fields import *


class ExampleTextModel(models.Model):
example_field = FernetTextField(
verbose_name="Example field",
)
```

### Example model that defines fernet binary fields

```python
from django.db import models
from django_fernet.fields import *


class ExampleBinaryModel(models.Model):
example_field = FernetBinaryField(
verbose_name="Example field",
)
```


## How to use

### Save encrypted text to the database

```python
from django_fernet.fernet import *

field_data = FernetTextFieldData()
field_data.encrypt("foo", "--secret--")

instance = ExampleTextModel()
instance.example_field = field_data
instance.save()
```

### Save encrypted binary data to the database

```python
from django_fernet.fernet import *

field_data = FernetTextFieldData()
field_data.encrypt(b"foo", "--secret--")

instance = ExampleBinaryModel()
instance.example_field = field_data
instance.save()
```

### Load encrypted text from the database

```python
instance = ExampleTextModel.objects.get(pk=...)
decrypted_str = instance.example_field.decrypt("--secret--")
```

### Load encrypted binary data from the database

```python
instance = ExampleBinaryModel.objects.get(pk=...)
decrypted_bytes = instance.example_field.decrypt("--secret--")
```


## Supported versions

| | Django 4.2 | Django 5.0 | Django 5.1 |
|-------------|------------|------------|------------|
| Python 3.10 ||||
| Python 3.11 ||||
| Python 3.12 ||||
| Python 3.13 ||||
| PyPy 3.10 ||||


## Tests

An example Django app that makes use of `django-fernet` can be found in the [tests/](tests/) folder. This example
Django app also contains the unit tests.

Follow below instructions to run the tests. You may exchange the installed Django version according to your
requirements.

```bash
# install dependencies
python -m pip install --upgrade pip
pip install -r requirements.txt

# run tests
cd tests && pytest
```


## List of developers

* Andreas Stocker <AStocker@anexia-it.com>
7 changes: 7 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Reporting Security Issues

Please report any security issues you discovered to opensource[at]anexia-it[dot]com

We will assess the risk, plus make a fix available before we create a GitHub issue.

Thank you for your contribution.
Empty file added django_fernet/__init__.py
Empty file.
9 changes: 9 additions & 0 deletions django_fernet/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from django.apps import AppConfig

__all__ = [
"Config",
]


class Config(AppConfig):
name = "django_fernet"
Loading

0 comments on commit 40231da

Please sign in to comment.