passerelle/passerelle/views.py

177 lines
6.1 KiB
Python

from django.apps import apps
from django.core.exceptions import PermissionDenied
from django.contrib.auth import logout as auth_logout
from django.contrib.auth import views as auth_views
from django.http import HttpResponseBadRequest, HttpResponseRedirect, Http404
from django.views.decorators.csrf import csrf_exempt
from django.views.generic import (RedirectView, View, TemplateView, CreateView,
DeleteView, UpdateView, DetailView)
from django.views.generic.detail import SingleObjectMixin
from django.conf import settings
from django.db import models
from django.shortcuts import resolve_url
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext_lazy as _
from django.forms.models import modelform_factory
try:
from mellon.utils import get_idps
except ImportError:
get_idps = lambda: []
from passerelle.base.models import BaseResource
from .utils import to_json, response_for_json, is_authorized
from .forms import GenericConnectorForm
def get_all_apps():
return [x for x in models.get_models() if issubclass(x, BaseResource) and \
x.is_enabled() ]
def login(request, *args, **kwargs):
if any(get_idps()):
if not 'next' in request.GET:
return HttpResponseRedirect(resolve_url('mellon_login'))
return HttpResponseRedirect(resolve_url('mellon_login') + '?next=' + request.GET.get('next'))
return auth_views.login(request, *args, **kwargs)
def logout(request, next_page=None):
if any(get_idps()):
return HttpResponseRedirect(resolve_url('mellon_logout'))
auth_logout(request)
if next_page is not None:
next_page = resolve_url(next_page)
else:
next_page = '/'
return HttpResponseRedirect(next_page)
class HomePageView(RedirectView):
pattern_name = 'manage-home'
class ManageView(TemplateView):
template_name = 'passerelle/manage.html'
def get_context_data(self, **kwargs):
context = super(ManageView, self).get_context_data(**kwargs)
# get all app instances
context['apps'] = []
for app in get_all_apps():
context['apps'].extend(app.objects.all())
return context
class ManageAddView(TemplateView):
template_name = 'passerelle/manage_add.html'
def get_context_data(self, **kwargs):
context = super(ManageAddView, self).get_context_data(**kwargs)
context['apps'] = get_all_apps()
return context
class GenericConnectorMixin(object):
def get_connector(self, **kwargs):
return kwargs.get('connector')
def dispatch(self, request, *args, **kwargs):
connector = self.get_connector(**kwargs)
try:
app = apps.get_app_config(connector.replace('-', '_'))
except LookupError:
raise Http404()
self.model = app.get_connector_model()
if hasattr(app, 'get_form_class'):
self.form_class = app.get_form_class()
else:
self.form_class = modelform_factory(self.model,
form=GenericConnectorForm, exclude=('slug', 'users'))
return super(GenericConnectorMixin, self).dispatch(
request, *args, **kwargs)
class GenericConnectorView(GenericConnectorMixin, DetailView):
pass
class GenericCreateConnectorView(GenericConnectorMixin, CreateView):
template_name = 'passerelle/manage/service_form.html'
class GenericEditConnectorView(GenericConnectorMixin, UpdateView):
template_name = 'passerelle/manage/service_form.html'
class GenericDeleteConnectorView(GenericConnectorMixin, DeleteView):
template_name = 'passerelle/manage/service_confirm_delete.html'
def get_success_url(self):
return reverse('manage-home')
class GenericEndpointView(GenericConnectorMixin, SingleObjectMixin, View):
def get_params(self, request, *args, **kwargs):
return dict([(x, request.GET[x]) for x in request.GET.keys()])
@csrf_exempt
def dispatch(self, request, *args, **kwargs):
return super(GenericEndpointView, self).dispatch(request, *args, **kwargs)
@property
def endpoint(self):
endpoint = getattr(self.get_object(), self.kwargs.get('endpoint'), None)
endpoint_info = getattr(endpoint, 'endpoint_info', None)
if endpoint_info is None:
raise Http404()
return endpoint
def _allowed_methods(self):
return [x.upper() for x in self.endpoint.endpoint_info.methods]
def check_perms(self, request):
perm = self.endpoint.endpoint_info.perm
if not perm:
return True
return is_authorized(request, self.get_object(), perm)
def perform(self, request, *args, **kwargs):
if request.method.lower() not in self.endpoint.endpoint_info.methods:
return self.http_method_not_allowed(request, *args, **kwargs)
if not self.check_perms(request):
raise PermissionDenied()
return self.endpoint(request, **self.get_params(request, *args, **kwargs))
def get(self, request, *args, **kwargs):
if self.endpoint.endpoint_info.serializer_type == 'json-api':
json_decorator = to_json('api')
else:
json_decorator = to_json('plain')
return json_decorator(self.perform)(request, **self.get_params(request, *args, **kwargs))
def post(self, request, *args, **kwargs):
return self.get(request, *args, **kwargs)
# legacy
LEGACY_APPS_PATTERNS = {
'datasources': {'url': 'data', 'name': 'Data Sources'},
'repost': {'url': 'repost', 'name': 'Re-Post'},
'register': {'url': r'register', 'name': 'Register'},
'queue': {'url': r'queue', 'name': 'Queues'},
}
class LegacyPageView(TemplateView):
template_name = 'passerelle/legacy.html'
def get_context_data(self, **kwargs):
context = super(LegacyPageView, self).get_context_data(**kwargs)
# legacy apps (categories)
context['legacy_apps'] = []
for app in (app for app in settings.INSTALLED_APPS
if app.startswith('passerelle.')
and app.split('.')[1] in LEGACY_APPS_PATTERNS):
context['legacy_apps'].append(LEGACY_APPS_PATTERNS[app.split('.')[1]])
return context