Skip to content
14 changes: 12 additions & 2 deletions addons/base/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from flask import redirect
from flask import request
import furl
import json
import jwe
import jwt
import waffle
Expand Down Expand Up @@ -969,9 +970,17 @@ def addon_view_or_download_file(auth, path, provider, **kwargs):

# TODO clean up these urls and unify what is used as a version identifier
if request.method == 'HEAD':
return make_response(('', http_status.HTTP_302_FOUND, {
headers = {
'Location': file_node.generate_waterbutler_url(**dict(extras, direct=None, version=version.identifier, _internal=extras.get('mode') == 'render'))
}))
}
if hasattr(version, 'metadata') and version.metadata:
try:
# Convert metadata to JSON string and add to header
metadata_json = json.dumps(version.metadata, default=str)
headers['X-File-Metadata'] = metadata_json
except (TypeError, ValueError) as e:
logger.warning(f'Failed to serialize metadata to JSON: {e}')
return make_response(('', http_status.HTTP_302_FOUND, headers))

if action == 'download':
format = extras.get('format')
Expand Down Expand Up @@ -1088,6 +1097,7 @@ def addon_view_file(auth, node, file_node, version):
'mode': 'render',
'action': 'download',
'public_file': node.is_public,
'version': 'Latest',
})
)

Expand Down
20 changes: 20 additions & 0 deletions addons/s3/migrations/0005_nodesettings_region.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.28 on 2025-06-10 13:14
from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('addons_s3', '0004_rename_deleted_field'),
]

operations = [
migrations.AddField(
model_name='nodesettings',
name='region',
field=models.CharField(blank=True, max_length=50, null=True),
),
]
46 changes: 46 additions & 0 deletions addons/s3/migrations/0006_auto_20250610_1315.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.28 on 2025-06-10 13:15
from __future__ import unicode_literals

from django.db import migrations
from addons.s3.utils import get_bucket_location_or_error
from addons.s3.settings import BUCKET_LOCATIONS


def populate_region_field(apps, schema_editor):
NodeSettings = apps.get_model('addons_s3', 'NodeSettings')

for node_setting in NodeSettings.objects.filter(folder_id__isnull=False):
try:
if node_setting.external_account:
bucket_location = get_bucket_location_or_error(
node_setting.external_account.oauth_key,
node_setting.external_account.oauth_secret,
node_setting.folder_id
)

node_setting.region = bucket_location
node_setting.save()

except Exception as e:
print(f'Failed to get region for bucket {node_setting.folder_id}: {e}')
node_setting.region = 'us-east-1' # aws default region
node_setting.save()


def reverse_populate_region_field(apps, schema_editor):
NodeSettings = apps.get_model('addons_s3', 'NodeSettings')
NodeSettings.objects.update(region=None)

class Migration(migrations.Migration):

dependencies = [
('addons_s3', '0005_nodesettings_region'),
]

operations = [
migrations.RunPython(
populate_region_field,
reverse_populate_region_field
),
]
5 changes: 4 additions & 1 deletion addons/s3/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class NodeSettings(BaseOAuthNodeSettings, BaseStorageAddon):
folder_name = models.TextField(blank=True, null=True)
encrypt_uploads = models.BooleanField(default=ENCRYPT_UPLOADS_DEFAULT)
user_settings = models.ForeignKey(UserSettings, null=True, blank=True, on_delete=models.CASCADE)
region = models.CharField(max_length=50, blank=True, null=True)

@property
def folder_path(self):
Expand All @@ -68,6 +69,7 @@ def set_folder(self, folder_id, auth):
self.external_account.oauth_secret,
folder_id
)
self.region = bucket_location
try:
bucket_location = BUCKET_LOCATIONS[bucket_location]
except KeyError:
Expand Down Expand Up @@ -139,7 +141,8 @@ def serialize_waterbutler_settings(self):
raise exceptions.AddonError('Cannot serialize settings for S3 addon')
return {
'bucket': self.folder_id,
'encrypt_uploads': self.encrypt_uploads
'encrypt_uploads': self.encrypt_uploads,
'region': self.region
}

def create_waterbutler_log(self, auth, action, metadata):
Expand Down
Loading