Skip to content

Commit a2342e2

Browse files
committed
Add get_encrypted_fields_map management command
Create a `schema_map` for all encrypted models that can be passed to `AutoEncryptionOpts` for production use. Usage may involve something like: - Configure QE site for development - Develop encrypted models and fields - Run `python manage.py get_encrypted_fields_map` - Reconfigure QE site for production by adding `schema_map` to AutoEncryptionOpts
1 parent be3dd16 commit a2342e2

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import json
2+
3+
from django.apps import apps
4+
from django.core.management.base import BaseCommand
5+
from django.db import DEFAULT_DB_ALIAS, connections
6+
7+
8+
class Command(BaseCommand):
9+
help = "Generate an encryptedFieldsMap for MongoDB automatic encryption"
10+
11+
def handle(self, *args, **options):
12+
connection = connections[DEFAULT_DB_ALIAS]
13+
14+
schema_map = self.generate_encrypted_fields_schema_map(connection)
15+
16+
self.stdout.write(json.dumps(schema_map, indent=2))
17+
18+
def generate_encrypted_fields_schema_map(self, conn):
19+
schema_map = {}
20+
21+
for model in apps.get_models():
22+
encrypted_fields = self.get_encrypted_fields(model, conn)
23+
if encrypted_fields:
24+
collection = model._meta.db_table
25+
schema_map[collection] = {"fields": encrypted_fields}
26+
27+
return schema_map
28+
29+
def get_encrypted_fields(self, model, conn):
30+
fields = model._meta.fields
31+
encrypted_fields = []
32+
33+
for field in fields:
34+
if getattr(field, "encrypted", False):
35+
field_map = {
36+
"path": field.column,
37+
"bsonType": field.db_type(conn),
38+
}
39+
40+
if getattr(field, "queries", None):
41+
field_map["queries"] = field.queries[0].to_dict()
42+
43+
encrypted_fields.append(field_map)
44+
45+
return encrypted_fields

tests/encryption_/tests.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
from django.core import management
12
from django.db import connection
2-
from django.test import TestCase
3+
from django.test import TestCase, modify_settings
34

45
from .models import Person
56

@@ -24,3 +25,13 @@ def test_encrypted_fields_map(self):
2425
}
2526
with connection.schema_editor() as editor:
2627
self.assertEqual(editor._get_encrypted_fields_map(self.person), expected)
28+
29+
30+
@modify_settings(
31+
INSTALLED_APPS={"prepend": "django_mongodb_backend"},
32+
)
33+
class AutoEncryptionOptsTests(TestCase):
34+
databases = {"default", "encrypted"}
35+
36+
def test_auto_encryption_opts(self):
37+
management.call_command("get_encrypted_fields_map", verbosity=0)

0 commit comments

Comments
 (0)