Skip to content

Commit bae84f4

Browse files
committed
[backend] allow to set multiple backends encrypted or not
1 parent 11723db commit bae84f4

File tree

5 files changed

+33
-35
lines changed

5 files changed

+33
-35
lines changed

flask_fs/__init__.py

-2
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@ def init_app(app, *storages):
3636
app.config.setdefault("FS_PREFIX", None)
3737
app.config.setdefault("FS_URL", None)
3838
app.config.setdefault("FS_BACKEND", DEFAULT_BACKEND)
39-
app.config.setdefault("FS_AES256_ENCRYPTED", False)
40-
app.config.setdefault("FS_AES256_KEY", None)
4139
app.config.setdefault("FS_IMAGES_OPTIMIZE", False)
4240
app.config.setdefault("FS_CREATE_STORAGE", False)
4341

flask_fs/backends/__init__.py

+6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from flask_fs import files
2+
from flask_fs.crypto import AES256FileEncryptor
23

34
__all__ = ["BaseBackend", "DEFAULT_BACKEND"]
45

@@ -18,6 +19,11 @@ def __init__(self, name, config):
1819
self.name = name
1920
self.config = config
2021

22+
if getattr(config, "aes256_encrypted", False):
23+
self.encryptor = AES256FileEncryptor(config.aes256_key)
24+
else:
25+
self.encryptor = None
26+
2127
def exists(self, filename):
2228
"""Test wether a file exists or not given its filename in the storage"""
2329
raise NotImplementedError("Existance checking is not implemented")

flask_fs/storage.py

+12-15
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
from werkzeug.utils import secure_filename, cached_property
77
from werkzeug.datastructures import FileStorage
88

9-
from .crypto import AES256FileEncryptor
109
from .errors import (
1110
UnauthorizedFileType,
1211
FileExists,
@@ -116,10 +115,6 @@ def configure(self, app):
116115
backend_key, app.config["FS_BACKEND"]
117116
)
118117
self.backend_prefix = BACKEND_PREFIX.format(self.backend_name.upper())
119-
if app.config.get("FS_AES256_ENCRYPTED", False):
120-
self.encryptor = AES256FileEncryptor(app.config["FS_AES256_KEY"])
121-
else:
122-
self.encryptor = None
123118
backend_excluded_keys = [
124119
"".join((self.backend_prefix, k)) for k in BACKEND_EXCLUDED_CONFIG
125120
]
@@ -267,8 +262,8 @@ def read(self, filename):
267262

268263
readed_content = self.backend.read(filename)
269264

270-
if self.encryptor is not None:
271-
return self.encryptor.decrypt_entire_file(readed_content)
265+
if self.backend.encryptor is not None:
266+
return self.backend.encryptor.decrypt_entire_file(readed_content)
272267
else:
273268
return readed_content
274269

@@ -283,8 +278,10 @@ def read_chunks(self, filename, chunk_size=1024 * 1024):
283278
raise FileNotFound(filename)
284279

285280
generator = self.backend.read_chunks(filename, chunk_size)
286-
if self.encryptor is not None:
287-
return self.encryptor.decrypt_file_from_generator(generator)
281+
if self.backend.encryptor is not None:
282+
return self.backend.encryptor.decrypt_file_from_generator(
283+
generator
284+
)
288285
else:
289286
return generator
290287

@@ -316,20 +313,20 @@ def write(self, filename, content, overwrite=False):
316313
):
317314
raise FileExists()
318315

319-
if self.encryptor is not None:
316+
if self.backend.encryptor is not None:
320317
if hasattr(content, "read") or os.path.isfile(content):
321-
encrypted_content_path = self.encryptor.encrypt_file(content)
318+
encrypted_content_path = self.backend.encryptor.encrypt_file(
319+
content
320+
)
322321
try:
323322
read_stream = open(encrypted_content_path, "rb")
324-
return self.backend.write(
325-
filename, read_stream
326-
)
323+
return self.backend.write(filename, read_stream)
327324
finally:
328325
read_stream.close()
329326
os.remove(encrypted_content_path)
330327
else:
331328
return self.backend.write(
332-
filename, self.encryptor.encrypt_content(content)
329+
filename, self.backend.encryptor.encrypt_content(content)
333330
)
334331
else:
335332
return self.backend.write(filename, content)

tests/conftest.py

+8-11
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
from flask import Flask
55
from werkzeug.datastructures import FileStorage
6+
from flask_fs.crypto import AES256FileEncryptor
7+
68

79
import pytest
810

@@ -23,8 +25,6 @@ class TestConfigEncrypted:
2325
MONGODB_DB = "flask-fs-test"
2426
MONGODB_HOST = "localhost"
2527
MONGODB_PORT = 27017
26-
FS_AES256_ENCRYPTED = True
27-
FS_AES256_KEY = "jHEyo0GjTZDCUEnCkMcaF-LIxmnOix8b3JH633I7dls="
2828

2929

3030
class TestFlask(Flask):
@@ -43,13 +43,6 @@ def app():
4343
yield app
4444

4545

46-
@pytest.fixture
47-
def app_encrypted():
48-
app_encrypted = TestFlask("flaskfs-tests")
49-
app_encrypted.config.from_object(TestConfigEncrypted)
50-
yield app_encrypted
51-
52-
5346
@pytest.fixture
5447
def binfile():
5548
return PNG_FILE
@@ -89,11 +82,15 @@ def utils(faker):
8982
def mock_backend(app, mocker):
9083
app.config["FS_BACKEND"] = "mock"
9184
mock = mocker.patch("flask_fs.backends.mock.MockBackend")
85+
mock.return_value.encryptor = None
9286
yield mock
9387

9488

9589
@pytest.fixture
96-
def mock_encrypted_backend(app_encrypted, mocker):
97-
app_encrypted.config["FS_BACKEND"] = "mock"
90+
def mock_encrypted_backend(app, mocker):
91+
app.config["FS_BACKEND"] = "mock"
9892
mock = mocker.patch("flask_fs.backends.mock.MockBackend")
93+
mock.return_value.encryptor = AES256FileEncryptor(
94+
"jHEyo0GjTZDCUEnCkMcaF-LIxmnOix8b3JH633I7dls="
95+
)
9996
yield mock

tests/test_storage.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,9 @@ def test_read(app, mock_backend):
9696
assert storage.read("file.test") == "content"
9797

9898

99-
def test_read_encrypted(app_encrypted, mock_encrypted_backend):
99+
def test_read_encrypted(app, mock_encrypted_backend):
100100
storage = fs.Storage("test")
101-
app_encrypted.configure(storage)
101+
app.configure(storage)
102102

103103
backend = mock_encrypted_backend.return_value
104104
backend.read.return_value = (
@@ -124,9 +124,9 @@ def test_read_chunks(app, mock_backend):
124124
assert data == "content"
125125

126126

127-
def test_read_chunks_encrypted(app_encrypted, mock_encrypted_backend):
127+
def test_read_chunks_encrypted(app, mock_encrypted_backend):
128128
storage = fs.Storage("test")
129-
app_encrypted.configure(storage)
129+
app.configure(storage)
130130

131131
backend = mock_encrypted_backend.return_value
132132
backend.read_chunks.return_value = iter(
@@ -171,9 +171,9 @@ def test_write(app, mock_backend):
171171
backend.write.assert_called_with("file.test", "content")
172172

173173

174-
def test_write_encrypted(app_encrypted, mock_encrypted_backend):
174+
def test_write_encrypted(app, mock_encrypted_backend):
175175
storage = fs.Storage("test")
176-
app_encrypted.configure(storage)
176+
app.configure(storage)
177177

178178
backend = mock_encrypted_backend.return_value
179179
backend.exists.return_value = False
@@ -183,7 +183,7 @@ def test_write_encrypted(app_encrypted, mock_encrypted_backend):
183183
args = backend.write.call_args.args
184184
assert args[0] == "file.test"
185185
assert (
186-
storage.encryptor.decrypt_entire_file(args[1])
186+
storage.backend.encryptor.decrypt_entire_file(args[1])
187187
== b"It's an encrypted file."
188188
)
189189

0 commit comments

Comments
 (0)