diff options
author | CoprDistGit <infra@openeuler.org> | 2023-04-11 18:58:01 +0000 |
---|---|---|
committer | CoprDistGit <infra@openeuler.org> | 2023-04-11 18:58:01 +0000 |
commit | eae9590c0cd3a1be94f1d919076a3086190e54b0 (patch) | |
tree | 17a4fbe1fda565395abc11a570478f0e9a91ff77 | |
parent | 25778ad6b452fadb8ed9f1a430962bf9d2a9021e (diff) |
automatic import of python-django-searchable-encrypted-fields
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | python-django-searchable-encrypted-fields.spec | 597 | ||||
-rw-r--r-- | sources | 1 |
3 files changed, 599 insertions, 0 deletions
@@ -0,0 +1 @@ +/django-searchable-encrypted-fields-0.2.1.tar.gz diff --git a/python-django-searchable-encrypted-fields.spec b/python-django-searchable-encrypted-fields.spec new file mode 100644 index 0000000..cc7a8b0 --- /dev/null +++ b/python-django-searchable-encrypted-fields.spec @@ -0,0 +1,597 @@ +%global _empty_manifest_terminate_build 0 +Name: python-django-searchable-encrypted-fields +Version: 0.2.1 +Release: 1 +Summary: Django model fields encrypted using Pycryptodome AES-256 GCM. +License: MIT +URL: https://gitlab.com/guywillett/django-searchable-encrypted-fields +Source0: https://mirrors.nju.edu.cn/pypi/web/packages/6c/39/77c7635e27a3a54c2cb034530d62da9cd1a191470877ed80123538816440/django-searchable-encrypted-fields-0.2.1.tar.gz +BuildArch: noarch + + +%description +# Django Searchable Encrypted Fields +This package is for you if you would like to encrypt model field data "in app" - ie before it is sent to the database. + +**Why another encrypted field package?** + +1. We use AES-256 encryption with GCM mode (via the Pycryptodome library). +2. Encryption keys never leave the app. +3. It is easy to generate appropriate encryption keys with `secrets.token_hex(32)` from the standard library. +4. You can make 'exact' search lookups when also using the SearchField. + +## Install & Setup +```shell +$ pip install django-searchable-encrypted-fields +``` +```python +# in settings.py +INSTALLED_APPS += ["encrypted_fields"] + +# A list of hex-encoded 32 byte keys +# You only need one unless/until rotating keys +FIELD_ENCRYPTION_KEYS = [ + "f164ec6bd6fbc4aef5647abc15199da0f9badcc1d2127bde2087ae0d794a9a0b" +] +``` + +## Intro +This package provides two types of model field for Django. +1. A series of **EncryptedField** classes which can be used by themselves and work just like their regular Django counterparts. Contents are transparently encrypted/decrypted. +2. A **SearchField** which can be used in conjunction with any EncryptedField. Values are concatentaed with a `hash_key` and then hashed with SHA256 before storing in a separate field. This means 'exact' searches can be performed. + +This is probably best demonstrated by example: + +## Using a stand-alone EncryptedField +```python +from encrypted_fields import fields + +class Person(models.Model): + favorite_number = fields.EncryptedIntegerField(help_text="Your favorite number.") +``` +You can use all the usual field arguments and add validators as normal. +Note, however, that primary_key, unique and db_index are not supported because they do not make sense for encrypted data. +### Migrations +Always add a new EncryptedField and do a data-migration, rather than alter an existing regular Django model field. +See the `encrypted_fields_test` app for an example. +### Included EncryptedField classes +The following are included: +```python +"EncryptedFieldMixin", +"EncryptedTextField", +"EncryptedCharField", +"EncryptedEmailField", +"EncryptedIntegerField", +"EncryptedDateField", +"EncryptedDateTimeField", +"EncryptedBigIntegerField", +"EncryptedPositiveIntegerField", +"EncryptedPositiveSmallIntegerField", +"EncryptedSmallIntegerField", +``` +Note that, although untested, you should be able to extend other regular Django model field classes like this: +```python +class EncryptedIPAddressField(EncryptedFieldMixin, models.GenericIPAddressField): + pass +``` + +## Using a SearchField along with an EncryptedField +### Philosophy +The SearchField is responsible for: +1. Providing the input for its EncryptedField +2. Displaying (returning) the EncryptedField's value +3. Storing the searchable hashed version of the input + +The EncryptedField is the "real" field and so should be the appropriate field type for the expected input. It does all the under-the-hood things you would expect, eg: +* Providing validation/validators for the input +* Converting the input and database values to the appropriate python object +* Encryption/decryption + +### Example usage +```python +def get_hash_key(): + # This must return a suitable string, eg from secrets.token_hex(32) + return "f414ed6bd6fbc4aef5647abc15199da0f9badcc1d2127bde2087ae0d794a8a0a" + +class Person(models.Model): + _name_data = fields.EncryptedCharField(max_length=50, default="", null=True/False) + name = fields.SearchField(hash_key=get_hash_key, encrypted_field_name="_name_data") + favorite_number = fields.EncryptedIntegerField() + city = models.CharField(max_length=255) # regular Django model field +``` +You can then use it like: +```python +# "Jo" is hashed and stored in 'name' as well as symmetrically encrypted and stored in '_name_data' +Person.objects.create(name="Jo", favorite_number=7, city="London") +person = Person.objects.get(name="Jo") +assert person.name == "Jo" +assert person.favorite_number == 7 + +person = Person.objects.get(city="London") +assert person.name == "Jo" . # the data is taken from '_name_data', which decrypts it first. +``` +You can safely update like this: +```python +person.name = "Simon" +person.save() +``` +But when using `update()` you need to provide the value to both fields: +```python +Person.objects.filter(name="Jo").update(name="Bob", _name_data="Bob") +``` +### Please note: +A SearchField inherits the validators, default value and default formfield (widget) from its associated EncryptedField. So: + +1. Do not add validators (they will be ignored), add them to the associated EncryptedField instead. +2. Use `null=`, `blank=` and `default=` on the EncryptedField, not the SearchField. +3. Do not include the EncryptedField in forms, only include the SearchField. +4. Typically you should avoid `editable=False` in the EncryptedField - it prevents validation. +5. You can override the SearchField widget in a `ModelForm` as usual (see the `encrypted_fields_test` app). +6. By convention, declare the EncryptedField *before* the SearchField in your Model. + +**Note** Although unique validation (and unique constraints at the database level) for an EncryptedField makes little sense, it is possible to add `unique=True` to a SearchField. + +An example of when this makes sense is in a custom user model, where the `username` field is replaced with an `EncryptedCharField` and `SearchField`. Please see the custom user model in `encrypted_fields_test.models` and its tests for an example. + +Please let us know if you have problems when doing this. +## Migrations: Add Search/EncryptedFields to your model, don't alter existing fields +You are encouraged to look at the demo migrations in the `encrypted_fields_test` app. + +**Stand alone EncryptedFields:** + +Be careful not to change/alter a pre-existing regular django field to be an +EncryptedField. The data for existing rows will be unencrypted in the database and +appear 'corrupted' when trying to decrypt/fetch it. +Instead, add the new EncryptedField to the model and do a data-migration +to transfer data from the old field. + +**SearchField with EncryptedField:** + +The same goes for SearchFields: add the new SearchField and new Encrypted field to the model. Then do a data-migration to transfer data from the old field to the SearchField (the SearchField will populate the new EncryptedField automatically). + +**IMPORTANT!** Never add a SearchField and point it to an **existing** EncryptedField, or your SearchField will have the wrong value, and you might lose all your data! How? Why? When adding a new field to a model, Django will update each existing row's new field to have the default value. Note that the default value might be `None` or `""` even if `default=` is not defined in your field. If the new field is a SearchField then it will be saved with the EncryptedField's default value. This is almost certainly not what you want, even if you did define a default for it. +## Generating Encryption Keys +You can use `secrets` from the standard library. It will print appropriate hex-encoded keys to the terminal, ready to be used in `settings.FIELD_ENCRYPTION_KEYS` or as a hash_key for a SearchField: +```shell +$ python manage.py shell +>>> import secrets +>>> secrets.token_hex(32) +``` +Note: Thanks to Andrew Mendoza for the suggestion. + +Note: encryption keys **must** be hex encoded and 32 bytes + +**Important**: use different hash_key values for each SearchField and make sure they are different from any keys in `settings.FIELD_ENCRYPTION_KEYS`. +## Rotating Encryption Keys +If you want to rotate the encryption key just prepend `settings.FIELD_ENCRYPTION_KEYS` with a new key. This new key (the first in the list) will be used for encrypting/decrypting all data. If decrypting data fails (because it was encrypted with an older key), each key in the list is tried. +A model instance will start using the new encryption key the next time they are accessed. + +You can do a data-migration, simply fetching and saving all objects, to force a complete rotation to the new encryption key. +See the `encrypted_fields_test` app for an example. + +Be sure to keep all old encryption keys in the list until you are certain all objects have rotated to the new key. +## Compatability +`django-searchable-encrypted-fields` is tested with Django(3.2, 4.0, 4.1) on Python(3.8, 3.9) using SQLite and PostgreSQL (11 and 12). + +Test coverage is at 96%. + +## More on testing +Please see the `encrypted_fields_test` app (in the gitlab repo) for some example admin site and model form implementations. Just run `pip install -r requirements.txt`, `python manage.py migrate` and `python manage.py runserver` to get started using SQLite. + +There is also a basic DjangoRestFramework implementation with a `ModelSerializer` and `ModelViewSet`. + +In our test app, the `User` model uses a SearchField for the username. This means that when creating a superuser you must provide the `--username` argument: `python manage.py createsuperuser --username bob` to avoid an error. + +Final note of interest: the tox test suite runs `python manage.py makemigrations` for every environment with an empty initial migration directory. This helps ensure the test app will work as expected in all tested environments. + + + + +%package -n python3-django-searchable-encrypted-fields +Summary: Django model fields encrypted using Pycryptodome AES-256 GCM. +Provides: python-django-searchable-encrypted-fields +BuildRequires: python3-devel +BuildRequires: python3-setuptools +BuildRequires: python3-pip +%description -n python3-django-searchable-encrypted-fields +# Django Searchable Encrypted Fields +This package is for you if you would like to encrypt model field data "in app" - ie before it is sent to the database. + +**Why another encrypted field package?** + +1. We use AES-256 encryption with GCM mode (via the Pycryptodome library). +2. Encryption keys never leave the app. +3. It is easy to generate appropriate encryption keys with `secrets.token_hex(32)` from the standard library. +4. You can make 'exact' search lookups when also using the SearchField. + +## Install & Setup +```shell +$ pip install django-searchable-encrypted-fields +``` +```python +# in settings.py +INSTALLED_APPS += ["encrypted_fields"] + +# A list of hex-encoded 32 byte keys +# You only need one unless/until rotating keys +FIELD_ENCRYPTION_KEYS = [ + "f164ec6bd6fbc4aef5647abc15199da0f9badcc1d2127bde2087ae0d794a9a0b" +] +``` + +## Intro +This package provides two types of model field for Django. +1. A series of **EncryptedField** classes which can be used by themselves and work just like their regular Django counterparts. Contents are transparently encrypted/decrypted. +2. A **SearchField** which can be used in conjunction with any EncryptedField. Values are concatentaed with a `hash_key` and then hashed with SHA256 before storing in a separate field. This means 'exact' searches can be performed. + +This is probably best demonstrated by example: + +## Using a stand-alone EncryptedField +```python +from encrypted_fields import fields + +class Person(models.Model): + favorite_number = fields.EncryptedIntegerField(help_text="Your favorite number.") +``` +You can use all the usual field arguments and add validators as normal. +Note, however, that primary_key, unique and db_index are not supported because they do not make sense for encrypted data. +### Migrations +Always add a new EncryptedField and do a data-migration, rather than alter an existing regular Django model field. +See the `encrypted_fields_test` app for an example. +### Included EncryptedField classes +The following are included: +```python +"EncryptedFieldMixin", +"EncryptedTextField", +"EncryptedCharField", +"EncryptedEmailField", +"EncryptedIntegerField", +"EncryptedDateField", +"EncryptedDateTimeField", +"EncryptedBigIntegerField", +"EncryptedPositiveIntegerField", +"EncryptedPositiveSmallIntegerField", +"EncryptedSmallIntegerField", +``` +Note that, although untested, you should be able to extend other regular Django model field classes like this: +```python +class EncryptedIPAddressField(EncryptedFieldMixin, models.GenericIPAddressField): + pass +``` + +## Using a SearchField along with an EncryptedField +### Philosophy +The SearchField is responsible for: +1. Providing the input for its EncryptedField +2. Displaying (returning) the EncryptedField's value +3. Storing the searchable hashed version of the input + +The EncryptedField is the "real" field and so should be the appropriate field type for the expected input. It does all the under-the-hood things you would expect, eg: +* Providing validation/validators for the input +* Converting the input and database values to the appropriate python object +* Encryption/decryption + +### Example usage +```python +def get_hash_key(): + # This must return a suitable string, eg from secrets.token_hex(32) + return "f414ed6bd6fbc4aef5647abc15199da0f9badcc1d2127bde2087ae0d794a8a0a" + +class Person(models.Model): + _name_data = fields.EncryptedCharField(max_length=50, default="", null=True/False) + name = fields.SearchField(hash_key=get_hash_key, encrypted_field_name="_name_data") + favorite_number = fields.EncryptedIntegerField() + city = models.CharField(max_length=255) # regular Django model field +``` +You can then use it like: +```python +# "Jo" is hashed and stored in 'name' as well as symmetrically encrypted and stored in '_name_data' +Person.objects.create(name="Jo", favorite_number=7, city="London") +person = Person.objects.get(name="Jo") +assert person.name == "Jo" +assert person.favorite_number == 7 + +person = Person.objects.get(city="London") +assert person.name == "Jo" . # the data is taken from '_name_data', which decrypts it first. +``` +You can safely update like this: +```python +person.name = "Simon" +person.save() +``` +But when using `update()` you need to provide the value to both fields: +```python +Person.objects.filter(name="Jo").update(name="Bob", _name_data="Bob") +``` +### Please note: +A SearchField inherits the validators, default value and default formfield (widget) from its associated EncryptedField. So: + +1. Do not add validators (they will be ignored), add them to the associated EncryptedField instead. +2. Use `null=`, `blank=` and `default=` on the EncryptedField, not the SearchField. +3. Do not include the EncryptedField in forms, only include the SearchField. +4. Typically you should avoid `editable=False` in the EncryptedField - it prevents validation. +5. You can override the SearchField widget in a `ModelForm` as usual (see the `encrypted_fields_test` app). +6. By convention, declare the EncryptedField *before* the SearchField in your Model. + +**Note** Although unique validation (and unique constraints at the database level) for an EncryptedField makes little sense, it is possible to add `unique=True` to a SearchField. + +An example of when this makes sense is in a custom user model, where the `username` field is replaced with an `EncryptedCharField` and `SearchField`. Please see the custom user model in `encrypted_fields_test.models` and its tests for an example. + +Please let us know if you have problems when doing this. +## Migrations: Add Search/EncryptedFields to your model, don't alter existing fields +You are encouraged to look at the demo migrations in the `encrypted_fields_test` app. + +**Stand alone EncryptedFields:** + +Be careful not to change/alter a pre-existing regular django field to be an +EncryptedField. The data for existing rows will be unencrypted in the database and +appear 'corrupted' when trying to decrypt/fetch it. +Instead, add the new EncryptedField to the model and do a data-migration +to transfer data from the old field. + +**SearchField with EncryptedField:** + +The same goes for SearchFields: add the new SearchField and new Encrypted field to the model. Then do a data-migration to transfer data from the old field to the SearchField (the SearchField will populate the new EncryptedField automatically). + +**IMPORTANT!** Never add a SearchField and point it to an **existing** EncryptedField, or your SearchField will have the wrong value, and you might lose all your data! How? Why? When adding a new field to a model, Django will update each existing row's new field to have the default value. Note that the default value might be `None` or `""` even if `default=` is not defined in your field. If the new field is a SearchField then it will be saved with the EncryptedField's default value. This is almost certainly not what you want, even if you did define a default for it. +## Generating Encryption Keys +You can use `secrets` from the standard library. It will print appropriate hex-encoded keys to the terminal, ready to be used in `settings.FIELD_ENCRYPTION_KEYS` or as a hash_key for a SearchField: +```shell +$ python manage.py shell +>>> import secrets +>>> secrets.token_hex(32) +``` +Note: Thanks to Andrew Mendoza for the suggestion. + +Note: encryption keys **must** be hex encoded and 32 bytes + +**Important**: use different hash_key values for each SearchField and make sure they are different from any keys in `settings.FIELD_ENCRYPTION_KEYS`. +## Rotating Encryption Keys +If you want to rotate the encryption key just prepend `settings.FIELD_ENCRYPTION_KEYS` with a new key. This new key (the first in the list) will be used for encrypting/decrypting all data. If decrypting data fails (because it was encrypted with an older key), each key in the list is tried. +A model instance will start using the new encryption key the next time they are accessed. + +You can do a data-migration, simply fetching and saving all objects, to force a complete rotation to the new encryption key. +See the `encrypted_fields_test` app for an example. + +Be sure to keep all old encryption keys in the list until you are certain all objects have rotated to the new key. +## Compatability +`django-searchable-encrypted-fields` is tested with Django(3.2, 4.0, 4.1) on Python(3.8, 3.9) using SQLite and PostgreSQL (11 and 12). + +Test coverage is at 96%. + +## More on testing +Please see the `encrypted_fields_test` app (in the gitlab repo) for some example admin site and model form implementations. Just run `pip install -r requirements.txt`, `python manage.py migrate` and `python manage.py runserver` to get started using SQLite. + +There is also a basic DjangoRestFramework implementation with a `ModelSerializer` and `ModelViewSet`. + +In our test app, the `User` model uses a SearchField for the username. This means that when creating a superuser you must provide the `--username` argument: `python manage.py createsuperuser --username bob` to avoid an error. + +Final note of interest: the tox test suite runs `python manage.py makemigrations` for every environment with an empty initial migration directory. This helps ensure the test app will work as expected in all tested environments. + + + + +%package help +Summary: Development documents and examples for django-searchable-encrypted-fields +Provides: python3-django-searchable-encrypted-fields-doc +%description help +# Django Searchable Encrypted Fields +This package is for you if you would like to encrypt model field data "in app" - ie before it is sent to the database. + +**Why another encrypted field package?** + +1. We use AES-256 encryption with GCM mode (via the Pycryptodome library). +2. Encryption keys never leave the app. +3. It is easy to generate appropriate encryption keys with `secrets.token_hex(32)` from the standard library. +4. You can make 'exact' search lookups when also using the SearchField. + +## Install & Setup +```shell +$ pip install django-searchable-encrypted-fields +``` +```python +# in settings.py +INSTALLED_APPS += ["encrypted_fields"] + +# A list of hex-encoded 32 byte keys +# You only need one unless/until rotating keys +FIELD_ENCRYPTION_KEYS = [ + "f164ec6bd6fbc4aef5647abc15199da0f9badcc1d2127bde2087ae0d794a9a0b" +] +``` + +## Intro +This package provides two types of model field for Django. +1. A series of **EncryptedField** classes which can be used by themselves and work just like their regular Django counterparts. Contents are transparently encrypted/decrypted. +2. A **SearchField** which can be used in conjunction with any EncryptedField. Values are concatentaed with a `hash_key` and then hashed with SHA256 before storing in a separate field. This means 'exact' searches can be performed. + +This is probably best demonstrated by example: + +## Using a stand-alone EncryptedField +```python +from encrypted_fields import fields + +class Person(models.Model): + favorite_number = fields.EncryptedIntegerField(help_text="Your favorite number.") +``` +You can use all the usual field arguments and add validators as normal. +Note, however, that primary_key, unique and db_index are not supported because they do not make sense for encrypted data. +### Migrations +Always add a new EncryptedField and do a data-migration, rather than alter an existing regular Django model field. +See the `encrypted_fields_test` app for an example. +### Included EncryptedField classes +The following are included: +```python +"EncryptedFieldMixin", +"EncryptedTextField", +"EncryptedCharField", +"EncryptedEmailField", +"EncryptedIntegerField", +"EncryptedDateField", +"EncryptedDateTimeField", +"EncryptedBigIntegerField", +"EncryptedPositiveIntegerField", +"EncryptedPositiveSmallIntegerField", +"EncryptedSmallIntegerField", +``` +Note that, although untested, you should be able to extend other regular Django model field classes like this: +```python +class EncryptedIPAddressField(EncryptedFieldMixin, models.GenericIPAddressField): + pass +``` + +## Using a SearchField along with an EncryptedField +### Philosophy +The SearchField is responsible for: +1. Providing the input for its EncryptedField +2. Displaying (returning) the EncryptedField's value +3. Storing the searchable hashed version of the input + +The EncryptedField is the "real" field and so should be the appropriate field type for the expected input. It does all the under-the-hood things you would expect, eg: +* Providing validation/validators for the input +* Converting the input and database values to the appropriate python object +* Encryption/decryption + +### Example usage +```python +def get_hash_key(): + # This must return a suitable string, eg from secrets.token_hex(32) + return "f414ed6bd6fbc4aef5647abc15199da0f9badcc1d2127bde2087ae0d794a8a0a" + +class Person(models.Model): + _name_data = fields.EncryptedCharField(max_length=50, default="", null=True/False) + name = fields.SearchField(hash_key=get_hash_key, encrypted_field_name="_name_data") + favorite_number = fields.EncryptedIntegerField() + city = models.CharField(max_length=255) # regular Django model field +``` +You can then use it like: +```python +# "Jo" is hashed and stored in 'name' as well as symmetrically encrypted and stored in '_name_data' +Person.objects.create(name="Jo", favorite_number=7, city="London") +person = Person.objects.get(name="Jo") +assert person.name == "Jo" +assert person.favorite_number == 7 + +person = Person.objects.get(city="London") +assert person.name == "Jo" . # the data is taken from '_name_data', which decrypts it first. +``` +You can safely update like this: +```python +person.name = "Simon" +person.save() +``` +But when using `update()` you need to provide the value to both fields: +```python +Person.objects.filter(name="Jo").update(name="Bob", _name_data="Bob") +``` +### Please note: +A SearchField inherits the validators, default value and default formfield (widget) from its associated EncryptedField. So: + +1. Do not add validators (they will be ignored), add them to the associated EncryptedField instead. +2. Use `null=`, `blank=` and `default=` on the EncryptedField, not the SearchField. +3. Do not include the EncryptedField in forms, only include the SearchField. +4. Typically you should avoid `editable=False` in the EncryptedField - it prevents validation. +5. You can override the SearchField widget in a `ModelForm` as usual (see the `encrypted_fields_test` app). +6. By convention, declare the EncryptedField *before* the SearchField in your Model. + +**Note** Although unique validation (and unique constraints at the database level) for an EncryptedField makes little sense, it is possible to add `unique=True` to a SearchField. + +An example of when this makes sense is in a custom user model, where the `username` field is replaced with an `EncryptedCharField` and `SearchField`. Please see the custom user model in `encrypted_fields_test.models` and its tests for an example. + +Please let us know if you have problems when doing this. +## Migrations: Add Search/EncryptedFields to your model, don't alter existing fields +You are encouraged to look at the demo migrations in the `encrypted_fields_test` app. + +**Stand alone EncryptedFields:** + +Be careful not to change/alter a pre-existing regular django field to be an +EncryptedField. The data for existing rows will be unencrypted in the database and +appear 'corrupted' when trying to decrypt/fetch it. +Instead, add the new EncryptedField to the model and do a data-migration +to transfer data from the old field. + +**SearchField with EncryptedField:** + +The same goes for SearchFields: add the new SearchField and new Encrypted field to the model. Then do a data-migration to transfer data from the old field to the SearchField (the SearchField will populate the new EncryptedField automatically). + +**IMPORTANT!** Never add a SearchField and point it to an **existing** EncryptedField, or your SearchField will have the wrong value, and you might lose all your data! How? Why? When adding a new field to a model, Django will update each existing row's new field to have the default value. Note that the default value might be `None` or `""` even if `default=` is not defined in your field. If the new field is a SearchField then it will be saved with the EncryptedField's default value. This is almost certainly not what you want, even if you did define a default for it. +## Generating Encryption Keys +You can use `secrets` from the standard library. It will print appropriate hex-encoded keys to the terminal, ready to be used in `settings.FIELD_ENCRYPTION_KEYS` or as a hash_key for a SearchField: +```shell +$ python manage.py shell +>>> import secrets +>>> secrets.token_hex(32) +``` +Note: Thanks to Andrew Mendoza for the suggestion. + +Note: encryption keys **must** be hex encoded and 32 bytes + +**Important**: use different hash_key values for each SearchField and make sure they are different from any keys in `settings.FIELD_ENCRYPTION_KEYS`. +## Rotating Encryption Keys +If you want to rotate the encryption key just prepend `settings.FIELD_ENCRYPTION_KEYS` with a new key. This new key (the first in the list) will be used for encrypting/decrypting all data. If decrypting data fails (because it was encrypted with an older key), each key in the list is tried. +A model instance will start using the new encryption key the next time they are accessed. + +You can do a data-migration, simply fetching and saving all objects, to force a complete rotation to the new encryption key. +See the `encrypted_fields_test` app for an example. + +Be sure to keep all old encryption keys in the list until you are certain all objects have rotated to the new key. +## Compatability +`django-searchable-encrypted-fields` is tested with Django(3.2, 4.0, 4.1) on Python(3.8, 3.9) using SQLite and PostgreSQL (11 and 12). + +Test coverage is at 96%. + +## More on testing +Please see the `encrypted_fields_test` app (in the gitlab repo) for some example admin site and model form implementations. Just run `pip install -r requirements.txt`, `python manage.py migrate` and `python manage.py runserver` to get started using SQLite. + +There is also a basic DjangoRestFramework implementation with a `ModelSerializer` and `ModelViewSet`. + +In our test app, the `User` model uses a SearchField for the username. This means that when creating a superuser you must provide the `--username` argument: `python manage.py createsuperuser --username bob` to avoid an error. + +Final note of interest: the tox test suite runs `python manage.py makemigrations` for every environment with an empty initial migration directory. This helps ensure the test app will work as expected in all tested environments. + + + + +%prep +%autosetup -n django-searchable-encrypted-fields-0.2.1 + +%build +%py3_build + +%install +%py3_install +install -d -m755 %{buildroot}/%{_pkgdocdir} +if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi +if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi +if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi +if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi +pushd %{buildroot} +if [ -d usr/lib ]; then + find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/lib64 ]; then + find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/bin ]; then + find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/sbin ]; then + find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst +fi +touch doclist.lst +if [ -d usr/share/man ]; then + find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst +fi +popd +mv %{buildroot}/filelist.lst . +mv %{buildroot}/doclist.lst . + +%files -n python3-django-searchable-encrypted-fields -f filelist.lst +%dir %{python3_sitelib}/* + +%files help -f doclist.lst +%{_docdir}/* + +%changelog +* Tue Apr 11 2023 Python_Bot <Python_Bot@openeuler.org> - 0.2.1-1 +- Package Spec generated @@ -0,0 +1 @@ +43ecc67610d98a915b3c83f9d330de07 django-searchable-encrypted-fields-0.2.1.tar.gz |