diff --git a/admin/nodes/urls.py b/admin/nodes/urls.py index c2704ee95b2..cb8942ebb85 100644 --- a/admin/nodes/urls.py +++ b/admin/nodes/urls.py @@ -19,6 +19,7 @@ re_path(r'^(?P[a-z0-9]+)/schema_responses/$', views.AdminNodeSchemaResponseView.as_view(), name='schema-responses'), re_path(r'^(?P[a-z0-9]+)/update_embargo/$', views.RegistrationUpdateEmbargoView.as_view(), name='update-embargo'), + re_path(r'^(?P[a-z0-9]+)/change_provider/$', views.RegistrationChangeProviderView.as_view(), name='change-provider'), re_path(r'^(?P[a-z0-9]+)/remove/$', views.NodeDeleteView.as_view(), name='remove'), re_path(r'^(?P[a-z0-9]+)/restore/$', views.NodeDeleteView.as_view(), name='restore'), re_path(r'^(?P[a-z0-9]+)/confirm_spam/$', views.NodeConfirmSpamView.as_view(), name='confirm-spam'), diff --git a/admin/nodes/views.py b/admin/nodes/views.py index 2d4f0c1194f..40cf261945d 100644 --- a/admin/nodes/views.py +++ b/admin/nodes/views.py @@ -16,7 +16,7 @@ ListView, TemplateView, ) -from django.shortcuts import redirect, reverse +from django.shortcuts import redirect, reverse, get_object_or_404 from django.urls import reverse_lazy from admin.base.utils import change_embargo_date @@ -33,6 +33,7 @@ NodeLog, AbstractNode, Registration, + RegistrationProvider, RegistrationApproval, SpamStatus ) @@ -398,6 +399,28 @@ def post(self, request, *args, **kwargs): return redirect(self.get_success_url()) +class RegistrationChangeProviderView(NodeMixin, View): + """ Allows authorized users to update provider of a registration. + """ + permission_required = ('osf.change_node') + + def post(self, request, *args, **kwargs): + provider_id = int(request.POST.get('provider_id')) + provider = get_object_or_404(RegistrationProvider, pk=provider_id) + registration = self.get_object() + + try: + provider.validate_schema(registration.registration_schema) + registration.provider = provider + registration.save() + except ValidationError as exc: + messages.error(request, str(exc)) + else: + messages.success(request, 'Provider successfully changed.') + + return redirect(self.get_success_url()) + + class NodeSpamList(PermissionRequiredMixin, ListView): """ Allows authorized users to view a list of nodes that have a particular spam status. """ diff --git a/admin/templates/nodes/node.html b/admin/templates/nodes/node.html index c178709534f..33b5731e32c 100644 --- a/admin/templates/nodes/node.html +++ b/admin/templates/nodes/node.html @@ -78,11 +78,9 @@

{{ node.type|cut:'osf.'|title }}: {{ node.title }} {{ node.provider.name }} - {% else %} - None - {% endif %} + + {% include "nodes/registration_provider.html" with node=node %} + Parent diff --git a/admin/templates/nodes/registration_provider.html b/admin/templates/nodes/registration_provider.html new file mode 100644 index 00000000000..ba03d2244c3 --- /dev/null +++ b/admin/templates/nodes/registration_provider.html @@ -0,0 +1,17 @@ +{% load node_extras %} + +{% if node.provider %} +
+ {% csrf_token %} + +
+{% else %} +

None

+{% endif %} \ No newline at end of file diff --git a/osf/models/registrations.py b/osf/models/registrations.py index b92aed1e8e2..2a7d5f501e2 100644 --- a/osf/models/registrations.py +++ b/osf/models/registrations.py @@ -368,6 +368,14 @@ def date_withdrawn(self): def withdrawal_justification(self): return getattr(self.root.retraction, 'justification', None) + @property + def available_providers(self): + """Return all providers that support current registration schema.""" + schema = self.registration_schema + if not schema: + return RegistrationProvider.objects.none() + return RegistrationProvider.objects.filter(schemas=schema) + @property def provider_specific_metadata(self): """Surfaces the additional_metadata fields supported by the provider.