Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
b3feaff
feat(provider): add s3compatsigv4 provider for S3 signature V4
tishin-endou Feb 7, 2026
3bc9092
Merge branch 'RCOSDP:develop' into feature/s3compatsigv4
tishin-endou Feb 20, 2026
bf3bef4
fix(migration): add merge migration for s3compatsigv4
tishin-endou Feb 20, 2026
4d9d450
fix(s3compatsigv4): rename duplicate HTML id to avoid conflict with s…
tishin-endou Feb 20, 2026
c45d120
Revert - fix(s3compatsigv4): rename duplicate HTML id to avoid confli…
anqiuy Mar 1, 2026
287d6ee
Merge pull request #1 from anqiuy/patch-1
tishin-endou Mar 1, 2026
8dff693
fix(migration): revert changes to existing migrations 0121 and 0237
tishin-endou Mar 1, 2026
6369e33
fix(migration): 既存マイグレーションにクロスアプリ依存関係を追加
tishin-endou Mar 2, 2026
b1824d8
Merge branch 'RCOSDP:develop' into feature/s3compatsigv4
tishin-endou Mar 2, 2026
8fec4f3
fix(migration): 0264 の重複リーフノードを統合するマージマイグレーション追加
tishin-endou Mar 2, 2026
3d759b6
Fix to use osfHelpers
fujimotodaisuke Mar 6, 2026
ac5bfb6
fix(s3compatsigv4): セキュリティと例外処理の改善
tishin-endou Mar 12, 2026
23ad303
fix(s3compatsigv4): テストを固定エラーメッセージに合わせて更新
tishin-endou Mar 12, 2026
d5f93bf
Merge pull request #705 from tishin-endou/feature/s3compatsigv4
hide24 Mar 12, 2026
0a17506
Merge pull request #704 from RCOSDP/hotfix/57633
hide24 Mar 12, 2026
6e5e43e
Update text
fujimotodaisuke Mar 13, 2026
d0dcc3a
Remove unnecessary text
fujimotodaisuke Mar 6, 2026
8f7af13
Enable to hide Export Account Function
fujimotodaisuke Mar 6, 2026
44116cb
Enable to hide Deactivate Account Function
fujimotodaisuke Mar 6, 2026
5cb4876
Merge pull request #709 from RCOSDP/hotfix/54036
hide24 Mar 16, 2026
4831b62
Merge pull request #708 from RCOSDP/hotfix/58117
hide24 Mar 16, 2026
4842f7a
wiki: Fix list rendering with heading syntax
hide24 Mar 16, 2026
aee8c4c
Merge pull request #710 from RCOSDP/feature/DispTitle
hide24 Mar 16, 2026
9e286e5
s3compatsigv4 setting injection
hide24 Mar 25, 2026
1c01da2
Merge pull request #711 from RCOSDP/feature/s3sigv4-settings
hide24 Mar 25, 2026
f4c01a5
Modified method of creating ro-crate.
kahokago Apr 3, 2026
6e9399b
Added test code for creating ro-crate with Mebyo schema.
kahokago Apr 3, 2026
e320f0f
feat(s3compatsigv4): WaterButler設定にregionパラメータを追加
tishin-endou Apr 3, 2026
8782375
Merge pull request #715 from RCOSDP/feature/fix-subitem-filename-in-r…
hide24 Apr 6, 2026
a98b47e
Merge pull request #716 from tishin-endou/feature/s3compatsigv4
hide24 Apr 8, 2026
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
2 changes: 2 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ COPY ./addons/swift/requirements.txt ./addons/swift/
COPY ./addons/azureblobstorage/requirements.txt ./addons/azureblobstorage/
COPY ./addons/weko/requirements.txt ./addons/weko/
COPY ./addons/s3compat/requirements.txt ./addons/s3compat/
COPY ./addons/s3compatsigv4/requirements.txt ./addons/s3compatsigv4/
COPY ./addons/s3compatinstitutions/requirements.txt ./addons/s3compatinstitutions/
COPY ./addons/s3compatb3/requirements.txt ./addons/s3compatb3/
COPY ./addons/ociinstitutions/requirements.txt ./addons/ociinstitutions/
Expand Down Expand Up @@ -167,6 +168,7 @@ COPY ./addons/azureblobstorage/static/ ./addons/azureblobstorage/static/
COPY ./addons/weko/static/ ./addons/weko/static/
COPY ./addons/jupyterhub/static/ ./addons/jupyterhub/static/
COPY ./addons/s3compat/static/ ./addons/s3compat/static/
COPY ./addons/s3compatsigv4/static/ ./addons/s3compatsigv4/static/
COPY ./addons/s3compatinstitutions/static/ ./addons/s3compatinstitutions/static/
COPY ./addons/s3compatb3/static/ ./addons/s3compatb3/static/
COPY ./addons/ociinstitutions/requirements.txt ./addons/ociinstitutions/
Expand Down
8 changes: 8 additions & 0 deletions addons.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"weko",
"jupyterhub",
"s3compat",
"s3compatsigv4",
"s3compatinstitutions",
"s3compatb3",
"ociinstitutions",
Expand Down Expand Up @@ -62,6 +63,7 @@
"azureblobstorage": "partial",
"weko": "partial",
"s3compat": "partial",
"s3compatsigv4": "partial",
"s3compatinstitutions": "partial",
"s3compatb3": "partial",
"ociinstitutions": "partial",
Expand Down Expand Up @@ -89,6 +91,7 @@
"azureblobstorage",
"weko",
"s3compat",
"s3compatsigv4",
"s3compatinstitutions",
"s3compatb3",
"ociinstitutions",
Expand Down Expand Up @@ -129,6 +132,7 @@
"weko": "JAIRO Cloud is an application server to share, archive data.",
"jupyterhub": "Jupyter is a web-based interactive computational environment. Files on a GakuNin RDM project can be imported to/exported from Jupyter",
"s3compat": "S3 Compatible Storage is a file storage add-on. Connect your S3 Compatible Storage account to a GakuNin RDM project to interact with files hosted on S3 Compatible Storage via the GakuNin RDM.",
"s3compatsigv4": "S3 Compatible Storage (SigV4) is a file storage add-on. Connect your S3 Compatible Storage (SigV4) account to a GakuNin RDM project to interact with files hosted on S3 Compatible Storage (SigV4) via the GakuNin RDM.",
"s3compatinstitutions": "S3 Compatible Storage for Institutions is a file storage add-on. Connect your S3 Compatible Storage account to a GakuNin RDM project to interact with files hosted on S3 Compatible Storage via the GakuNin RDM.",
"s3compatb3": "S3 Compatible Storage is a file storage add-on. Connect your S3 Compatible Storage account to a GakuNin RDM project to interact with files hosted on S3 Compatible Storage via the GakuNin RDM.",
"ociinstitutions": "Oracle Cloud Infrastructure for Institutions is a file storage add-on. Connect your Oracle Cloud Infrastructure Object Storage account to a GakuNin RDM project to interact with files hosted on Oracle Cloud Infrastructure Object Storage via the GakuNin RDM.",
Expand Down Expand Up @@ -161,6 +165,7 @@
"weko": "https://weko.at.nii.ac.jp/",
"jupyterhub": "https://jupyterhub.readthedocs.io/",
"s3compat": "https://aws.amazon.com/s3/",
"s3compatsigv4": "https://aws.amazon.com/s3/",
"s3compatb3": "https://aws.amazon.com/s3/",
"nextcloud": "https://nextcloud.com/",
"iqbrims": "https://drive.google.com",
Expand All @@ -187,18 +192,21 @@
"onedrive",
"s3",
"s3compat",
"s3compatsigv4",
"owncloud"
],
"addons_has_max_keys": [
"s3",
"s3compat",
"s3compatsigv4",
"s3compatinstitutions",
"s3compatb3",
"ociinstitutions"
],
"addons_folder_field": {
"s3": "folder_name",
"s3compat": "folder_name",
"s3compatsigv4": "folder_name",
"s3compatb3": "folder_name",
"azureblobstorage": "folder_name",
"box": "folder_name",
Expand Down
33 changes: 33 additions & 0 deletions addons/s3compatsigv4/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# RDM S3 Compatible Storage (SigV4) Addon

S3 Compatible Storage (SigV4) Addon enables to mount Cloud Storage which supports Amazon S3-like API on the project.

## Configuring the addon

Users can select storage from the S3 Compatible Storage (SigV4) List,
which is defined in `addons/s3compatsigv4/static/settings.json`.

```
{
"availableServices": [{"name": "Wasabi",
"host": "s3.wasabisys.com",
"bucketLocations": {
"us-east": {"name": "us-east", "host": "s3.wasabisys.com"},
"us-west-1": {"name": "us-west-1", "host": "s3.us-west-1.wasabisys.com"},
"eu-central": {"name": "eu-central", "host": "s3.eu-central-1.wasabisys.com"},
"": {"name": "Virginia"}}},
{"name": "My Private Storage",
"host": "my-private-storage-address:80"}
],
"encryptUploads": true
}
```

## Enabling the addon

### Enable on RDM
1. On RDM, enable S3 Compatible Storage (SigV4) as a provider
2. Scroll down to Configure Add-ons
3. Choose desired storage service
4. Connect your account and enter your ID and secret
5. Select a bucket to work from, or create a new one.
1 change: 1 addition & 0 deletions addons/s3compatsigv4/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
default_app_config = 'addons.s3compatsigv4.apps.S3CompatSigV4AddonAppConfig'
68 changes: 68 additions & 0 deletions addons/s3compatsigv4/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import os
from addons.base.apps import BaseAddonAppConfig, generic_root_folder
from addons.s3compatsigv4.settings import MAX_UPLOAD_SIZE

s3compatsigv4_root_folder = generic_root_folder('s3compatsigv4')

HERE = os.path.dirname(os.path.abspath(__file__))
TEMPLATE_PATH = os.path.join(
HERE,
'templates'
)

class S3CompatSigV4AddonAppConfig(BaseAddonAppConfig):

name = 'addons.s3compatsigv4'
label = 'addons_s3compatsigv4'
owners = ['user', 'node']
configs = ['accounts', 'node']
categories = ['storage']
has_hgrid_files = True
max_file_size = MAX_UPLOAD_SIZE
node_settings_template = os.path.join(TEMPLATE_PATH, 's3compatsigv4_node_settings.mako')
user_settings_template = os.path.join(TEMPLATE_PATH, 's3compatsigv4_user_settings.mako')

@property
def full_name(self):
return 'S3 Compatible Storage (SigV4)'

@property
def short_name(self):
return 's3compatsigv4'

@property
def get_hgrid_data(self):
return s3compatsigv4_root_folder

BUCKET_LINKED = 's3compatsigv4_bucket_linked'
BUCKET_UNLINKED = 's3compatsigv4_bucket_unlinked'
FILE_ADDED = 's3compatsigv4_file_added'
FILE_REMOVED = 's3compatsigv4_file_removed'
FILE_UPDATED = 's3compatsigv4_file_updated'
FOLDER_CREATED = 's3compatsigv4_folder_created'
NODE_AUTHORIZED = 's3compatsigv4_node_authorized'
NODE_DEAUTHORIZED = 's3compatsigv4_node_deauthorized'
NODE_DEAUTHORIZED_NO_USER = 's3compatsigv4_node_deauthorized_no_user'

actions = (BUCKET_LINKED,
BUCKET_UNLINKED,
FILE_ADDED,
FILE_REMOVED,
FILE_UPDATED,
FOLDER_CREATED,
NODE_AUTHORIZED,
NODE_DEAUTHORIZED,
NODE_DEAUTHORIZED_NO_USER)

@property
def routes(self):
from . import routes
return [routes.api_routes]

@property
def user_settings(self):
return self.get_model('UserSettings')

@property
def node_settings(self):
return self.get_model('NodeSettings')
68 changes: 68 additions & 0 deletions addons/s3compatsigv4/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.28 on 2026-01-12 14:02
from __future__ import unicode_literals

import addons.base.models
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django_extensions.db.fields
import osf.models.base
import osf.utils.datetime_aware_jsonfield
import osf.utils.fields


class Migration(migrations.Migration):

initial = True

dependencies = [
('osf', '0261_auto_20260112_1402'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]

operations = [
migrations.CreateModel(
name='NodeSettings',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', django_extensions.db.fields.CreationDateTimeField(auto_now_add=True, verbose_name='created')),
('modified', django_extensions.db.fields.ModificationDateTimeField(auto_now=True, verbose_name='modified')),
('_id', models.CharField(db_index=True, default=osf.models.base.generate_object_id, max_length=24, unique=True)),
('is_deleted', models.BooleanField(default=False)),
('deleted', osf.utils.fields.NonNaiveDateTimeField(blank=True, null=True)),
('folder_id', models.TextField(blank=True, null=True)),
('folder_name', models.TextField(blank=True, null=True)),
('folder_location', models.TextField(blank=True, null=True)),
('encrypt_uploads', models.BooleanField(default=True)),
('external_account', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='addons_s3compatsigv4_node_settings', to='osf.ExternalAccount')),
('owner', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='addons_s3compatsigv4_node_settings', to='osf.AbstractNode')),
],
options={
'abstract': False,
},
bases=(models.Model, osf.models.base.QuerySetExplainMixin, addons.base.models.BaseStorageAddon),
),
migrations.CreateModel(
name='UserSettings',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', django_extensions.db.fields.CreationDateTimeField(auto_now_add=True, verbose_name='created')),
('modified', django_extensions.db.fields.ModificationDateTimeField(auto_now=True, verbose_name='modified')),
('_id', models.CharField(db_index=True, default=osf.models.base.generate_object_id, max_length=24, unique=True)),
('is_deleted', models.BooleanField(default=False)),
('deleted', osf.utils.fields.NonNaiveDateTimeField(blank=True, null=True)),
('oauth_grants', osf.utils.datetime_aware_jsonfield.DateTimeAwareJSONField(blank=True, default=dict, encoder=osf.utils.datetime_aware_jsonfield.DateTimeAwareJSONEncoder)),
('owner', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='addons_s3compatsigv4_user_settings', to=settings.AUTH_USER_MODEL)),
],
options={
'abstract': False,
},
bases=(models.Model, osf.models.base.QuerySetExplainMixin),
),
migrations.AddField(
model_name='nodesettings',
name='user_settings',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='addons_s3compatsigv4.UserSettings'),
),
]
Empty file.
Loading
Loading