Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion registrar/apps/core/filestore.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,31 @@
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.core.files.base import ContentFile
from django.core.files.storage import default_storage, get_storage_class
from django.core.files.storage import default_storage
from django.utils.module_loading import import_string

from registrar.apps.api.utils import to_absolute_api_url


logger = logging.getLogger(__name__)


def get_storage_class():
# Prefer new-style Django 4.2+ STORAGES
storages_config = getattr(settings, 'STORAGES', {})

if storages_config.get('default') and storages_config['default'].get('BACKEND'):
return import_string(storages_config['default'].get('BACKEND'))

# Legacy fallback: DEFAULT_FILE_STORAGE
storage_class_path = getattr(settings, 'DEFAULT_FILE_STORAGE', {})

if storage_class_path:
return import_string(storage_class_path)

return default_storage.__class__


class FilestoreBase:
"""
Abstract base class for file stores.
Expand Down
22 changes: 22 additions & 0 deletions registrar/apps/core/tests/test_filestore.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@
import moto
import requests
from botocore.exceptions import ClientError
from django.conf import settings
from django.test import TestCase
from django.test.utils import override_settings
from storages.backends.s3boto3 import S3Boto3Storage

from ..filestore import (
FilestoreBase,
Expand All @@ -19,6 +22,7 @@
get_filestore,
get_job_results_filestore,
get_program_reports_filestore,
get_storage_class,
)
from ..filestore import logger as filestore_logger
from .mixins import S3MockEnvVarsMixin
Expand Down Expand Up @@ -140,3 +144,21 @@ def test_filestore_error_logging(self):
assert path_prefix in log_message
assert filepath in log_message
assert contents not in log_message


class GetStorageClassTests(TestCase):
@override_settings(
STORAGES={"default": {"BACKEND": "storages.backends.s3boto3.S3Boto3Storage"}}
)
def test_get_storage_class_with_storages(self):
storage_class = get_storage_class()
self.assertIs(storage_class, S3Boto3Storage)

@override_settings(
DEFAULT_FILE_STORAGE="storages.backends.s3boto3.S3Boto3Storage",
STORAGES={}
)
def test_get_storage_class_with_default_file_storage(self):
del settings.STORAGES
storage_class = get_storage_class()
self.assertIs(storage_class, S3Boto3Storage)
11 changes: 9 additions & 2 deletions registrar/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,10 +189,18 @@
root('conf', 'locale'),
)

STORAGES = {
"default": {
"BACKEND": "django.core.files.storage.FileSystemStorage",
},
"staticfiles": {
"BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage",
},
}

# MEDIA CONFIGURATION
MEDIA_ROOT = root('media')
MEDIA_URL = '/api/media/'
DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage'
REGISTRAR_BUCKET = 'change-me-to-registrar-bucket'
PROGRAM_REPORTS_BUCKET = 'change-me-to-program-reports-bucket'
PROGRAM_REPORTS_FOLDER = 'reports_v2'
Expand Down Expand Up @@ -325,7 +333,6 @@
EXTRA_APPS = []
SERVICE_USER = 'registrar_service_user'
SESSION_EXPIRE_AT_BROWSER_CLOSE = False
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.StaticFilesStorage'
CSRF_TRUSTED_ORIGINS = []
CACHES = {
'default': {
Expand Down
6 changes: 5 additions & 1 deletion registrar/settings/devstack.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@
}
}

STATICFILES_STORAGE = os.environ.get('STATICFILES_STORAGE', 'django.contrib.staticfiles.storage.StaticFilesStorage')
staticfiles_storage = os.environ.get('STATICFILES_STORAGE')

if staticfiles_storage:
STORAGES["staticfiles"]["BACKEND"] = staticfiles_storage

STATIC_URL = os.environ.get('STATIC_URL', '/static/')

LMS_BASE_URL = 'http://edx.devstack.lms:18000'
Expand Down
9 changes: 9 additions & 0 deletions registrar/settings/production.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@
vars()[key].update(value)

vars().update(config_from_yaml)

default_file_storage = MEDIA_STORAGE_BACKEND.pop('DEFAULT_FILE_STORAGE', None)
staticfiles_storage = MEDIA_STORAGE_BACKEND.pop('STATICFILES_STORAGE', None)

if default_file_storage:
STORAGES["default"]["BACKEND"] = default_file_storage
if staticfiles_storage:
STORAGES["staticfiles"]["BACKEND"] = staticfiles_storage

vars().update(MEDIA_STORAGE_BACKEND)

DB_OVERRIDES = dict(
Expand Down
2 changes: 1 addition & 1 deletion registrar/settings/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
# END CELERY

# Media
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
STORAGES["default"]["BACKEND"] = 'storages.backends.s3boto3.S3Boto3Storage'
AWS_LOCATION = ''
AWS_QUERYSTRING_AUTH = True
AWS_QUERYSTRING_EXPIRE = 3600
Expand Down