Skip to content
Merged
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
2 changes: 2 additions & 0 deletions addon_imps/redirect/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
"""addon_imps.redirect: imps that implement a redirect-like interface
"""
9 changes: 9 additions & 0 deletions addon_imps/redirect/redirect_dummy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from addon_toolkit.interfaces._base import BaseAddonInterface
from addon_toolkit.interfaces.redirect import RedirectAddonImp


class DummyRedirectImp(RedirectAddonImp):
"""this is a dummy AddonImp for ALL redirect services.
redirect links will be specified in django admin configuration."""

ADDON_INTERFACE = BaseAddonInterface
16 changes: 16 additions & 0 deletions addon_service/admin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,22 @@ class ExternalComputingServiceAdmin(GravyvaletModelAdmin):
}


@admin.register(models.ExternalRedirectService)
class ExternalRedirectServiceAdmin(GravyvaletModelAdmin):
list_display = ("display_name", "created", "modified")
readonly_fields = (
"id",
"created",
"modified",
)
raw_id_fields = ("oauth2_client_config", "oauth1_client_config")
enum_choice_fields = {
"int_addon_imp": known_imps.RedirectAddonImpNumbers,
"int_credentials_format": CredentialsFormats,
"int_service_type": ServiceTypes,
}


@admin.register(models.OAuth2ClientConfig)
@linked_many_field("external_storage_services")
@linked_many_field("external_citation_services")
Expand Down
9 changes: 9 additions & 0 deletions addon_service/common/known_imps.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
)
from addon_imps.computing import boa
from addon_imps.link import dataverse as link_dataverse
from addon_imps.redirect import redirect_dummy
from addon_imps.storage import (
azure_blob_storage,
bitbucket,
Expand All @@ -30,6 +31,7 @@
from addon_toolkit.interfaces.citation import CitationAddonImp
from addon_toolkit.interfaces.computing import ComputingAddonImp
from addon_toolkit.interfaces.link import LinkAddonImp
from addon_toolkit.interfaces.redirect import RedirectAddonImp
from addon_toolkit.interfaces.storage import StorageAddonImp


Expand Down Expand Up @@ -102,6 +104,9 @@ class KnownAddonImps(enum.Enum):
# Type: Link
LINK_DATAVERSE = link_dataverse.DataverseLinkImp

# Type: Redirect
REDIRECT_DUMMY = redirect_dummy.DummyRedirectImp

if __debug__:
BLARG = my_blarg.MyBlargStorage

Expand Down Expand Up @@ -140,6 +145,9 @@ class AddonImpNumbers(enum.Enum):
# Type: Link
LINK_DATAVERSE = 1030

# Type: Redirect
REDIRECT_DUMMY = 1040

if __debug__:
BLARG = -7

Expand All @@ -158,3 +166,4 @@ def filter_addons_by_type(addon_type):
CitationAddonImpNumbers = filter_addons_by_type(CitationAddonImp)
ComputingAddonImpNumbers = filter_addons_by_type(ComputingAddonImp)
LinkAddonImpNumbers = filter_addons_by_type(LinkAddonImp)
RedirectAddonImpNumbers = filter_addons_by_type(RedirectAddonImp)
2 changes: 2 additions & 0 deletions addon_service/external_service/redirect/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
"""addon_service.external_service.redirect: imps that implement a redirect service
"""
15 changes: 15 additions & 0 deletions addon_service/external_service/redirect/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from django.db import models

from addon_service.external_service.models import ExternalService


class ExternalRedirectService(ExternalService):
redirect_url = models.URLField(blank=True, default="")

class Meta:
verbose_name = "External Redirect Service"
verbose_name_plural = "External Redirect Services"
app_label = "addon_service"

class JSONAPIMeta:
resource_name = "external-redirect-services"
46 changes: 46 additions & 0 deletions addon_service/external_service/redirect/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from rest_framework_json_api import serializers
from rest_framework_json_api.utils import get_resource_type_from_model

from addon_service.addon_imp.models import AddonImpModel
from addon_service.common import view_names
from addon_service.common.serializer_fields import DataclassRelatedDataField
from addon_service.external_service.serializers import ExternalServiceSerializer

from .models import ExternalRedirectService


RESOURCE_TYPE = get_resource_type_from_model(ExternalRedirectService)


class ExternalRedirectServiceSerializer(ExternalServiceSerializer):
"""api serializer for the `ExternalRedirectService` model"""

url = serializers.HyperlinkedIdentityField(
view_name=view_names.detail_view(RESOURCE_TYPE)
)

addon_imp = DataclassRelatedDataField(
dataclass_model=AddonImpModel,
related_link_view_name=view_names.related_view(RESOURCE_TYPE),
)

redirect_url = serializers.CharField(
read_only=True,
)

class Meta:
model = ExternalRedirectService
fields = [
"id",
"addon_imp",
"auth_uri",
"credentials_format",
"display_name",
"url",
"wb_key",
"external_service_name",
"configurable_api_root",
"icon_url",
"api_base_url_options",
"redirect_url",
]
21 changes: 21 additions & 0 deletions addon_service/external_service/redirect/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from drf_spectacular.utils import (
extend_schema,
extend_schema_view,
)
from rest_framework_json_api.views import ReadOnlyModelViewSet

from .models import ExternalRedirectService
from .serializers import ExternalRedirectServiceSerializer


@extend_schema_view(
list=extend_schema(
description="Get the list of all available external redirect services"
),
get=extend_schema(
description="Get particular external redirect service",
),
)
class ExternalRedirectServiceViewSet(ReadOnlyModelViewSet):
queryset = ExternalRedirectService.objects.all()
serializer_class = ExternalRedirectServiceSerializer
39 changes: 39 additions & 0 deletions addon_service/migrations/0017_externalredirectservice.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Generated by Django 4.2.20 on 2025-09-11 18:14

import django.db.models.deletion
from django.db import (
migrations,
models,
)


class Migration(migrations.Migration):

dependencies = [
("addon_service", "0016_externallinkservice_int_supported_features_and_more"),
]

operations = [
migrations.CreateModel(
name="ExternalRedirectService",
fields=[
(
"externalservice_ptr",
models.OneToOneField(
auto_created=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
primary_key=True,
serialize=False,
to="addon_service.externalservice",
),
),
("redirect_url", models.URLField(blank=True, default="")),
],
options={
"verbose_name": "External Redirect Service",
"verbose_name_plural": "External Redirect Services",
},
bases=("addon_service.externalservice",),
),
]
2 changes: 2 additions & 0 deletions addon_service/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from addon_service.external_service.citation.models import ExternalCitationService
from addon_service.external_service.computing.models import ExternalComputingService
from addon_service.external_service.link.models import ExternalLinkService
from addon_service.external_service.redirect.models import ExternalRedirectService
from addon_service.external_service.storage.models import ExternalStorageService
from addon_service.oauth1.models import OAuth1ClientConfig
from addon_service.oauth2.models import (
Expand Down Expand Up @@ -47,4 +48,5 @@
"ExternalLinkService",
"AuthorizedLinkAccount",
"ConfiguredLinkAddon",
"ExternalRedirectService",
)
Binary file added addon_service/static/provider_icons/datapipe.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions addon_service/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ def _register_viewset(viewset):
_register_viewset(views.AddonOperationViewSet)
_register_viewset(views.AddonImpViewSet)
_register_viewset(views.UserReferenceViewSet)
_register_viewset(views.ExternalRedirectServiceViewSet)


###
Expand Down
2 changes: 2 additions & 0 deletions addon_service/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
ExternalComputingServiceViewSet,
)
from addon_service.external_service.link.views import ExternalLinkServiceViewSet
from addon_service.external_service.redirect.views import ExternalRedirectServiceViewSet
from addon_service.external_service.storage.views import ExternalStorageServiceViewSet
from addon_service.oauth1.views import oauth1_callback_view
from addon_service.oauth2.views import oauth2_callback_view
Expand Down Expand Up @@ -70,6 +71,7 @@ async def status(request):
"AuthorizedStorageAccountViewSet",
"ConfiguredStorageAddonViewSet",
"ExternalStorageServiceViewSet",
"ExternalRedirectServiceViewSet",
"ResourceReferenceViewSet",
"UserReferenceViewSet",
"oauth2_callback_view",
Expand Down
12 changes: 12 additions & 0 deletions addon_toolkit/interfaces/redirect.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
"""a static (and still in progress) definition of what composes a redirect addon"""

import dataclasses

from addon_toolkit.imp import AddonImp


@dataclasses.dataclass
class RedirectAddonImp(AddonImp):
"""base class for redirect addon implementations"""

pass