add settings.PASSERELLE_APPS (#6900)

This commit is contained in:
Thomas NOËL 2015-04-03 14:57:30 +02:00
parent 0a2b1ea6a9
commit f38a0cb6af
5 changed files with 169 additions and 32 deletions

View File

@ -1,3 +1,4 @@
from django.conf import settings
from django.core.exceptions import ValidationError, ObjectDoesNotExist
from django.db import models
from django.db.models import Q
@ -85,6 +86,14 @@ class BaseResource(models.Model):
restricted = self.users.all()
return not restricted or request.apiuser in restricted
@classmethod
def is_enabled(cls):
# TODO: once the legacy connectors are ported, the test on
# get_icon_class won't be necessary anymore.
if not hasattr(cls, 'get_icon_class'):
return False
return cls._meta.app_label in settings.PASSERELLE_APPS
class AccessRight(models.Model):
codename = models.CharField(max_length=100, verbose_name='codename')

View File

@ -115,6 +115,9 @@ INSTALLED_APPS = (
)
INSTALLED_APPS = register_plugins_installed_apps(INSTALLED_APPS)
# active applications
PASSERELLE_APPS = INSTALLED_APPS
# Authentication settings
try:
import mellon

View File

@ -8,7 +8,7 @@ from django.views.static import serve as static_serve
from .views import (HomePageView, ManageView, ManageAddView,
LEGACY_APPS_PATTERNS, LegacyPageView, login, logout)
from .urls_utils import decorated_includes
from .urls_utils import decorated_includes, required, app_enabled
from .base.urls import access_urlpatterns
from .plugins import register_plugins_urls
@ -38,43 +38,87 @@ urlpatterns = patterns('',
url(r'^manage/access/',
decorated_includes(login_required, include(access_urlpatterns))),
)
url(r'^choosit/', include(choosit.urls.urlpatterns)),
url(r'^manage/choosit/',
decorated_includes(login_required, include(choosit.urls.management_urlpatterns))),
urlpatterns += required(
app_enabled('choosit'),
patterns('',
url(r'^choosit/', include(choosit.urls.urlpatterns)),
url(r'^manage/choosit/',
decorated_includes(login_required, include(choosit.urls.management_urlpatterns))),
)
)
url(r'^clicrdv/', include(clicrdv.urls.urlpatterns)),
url(r'^manage/clicrdv/',
decorated_includes(login_required, include(clicrdv.urls.management_urlpatterns))),
urlpatterns += required(
app_enabled('clicrdv'),
patterns('',
url(r'^clicrdv/', include(clicrdv.urls.urlpatterns)),
url(r'^manage/clicrdv/',
decorated_includes(login_required, include(clicrdv.urls.management_urlpatterns))),
)
)
url(r'^gdc/', include(gdc.urls.urlpatterns)),
url(r'^manage/gdc/',
decorated_includes(login_required, include(gdc.urls.management_urlpatterns))),
urlpatterns += required(
app_enabled('gdc'),
patterns('',
url(r'^gdc/', include(gdc.urls.urlpatterns)),
url(r'^manage/gdc/',
decorated_includes(login_required, include(gdc.urls.management_urlpatterns))),
)
)
url(r'^mobyt/', include(mobyt.urls.urlpatterns)),
url(r'^manage/mobyt/',
decorated_includes(login_required, include(mobyt.urls.management_urlpatterns))),
urlpatterns += required(
app_enabled('mobyt'),
patterns('',
url(r'^mobyt/', include(mobyt.urls.urlpatterns)),
url(r'^manage/mobyt/',
decorated_includes(login_required, include(mobyt.urls.management_urlpatterns))),
)
)
url(r'^ovh/', include(ovh.urls.urlpatterns)),
url(r'^manage/ovh/',
decorated_includes(login_required, include(ovh.urls.management_urlpatterns))),
urlpatterns += required(
app_enabled('ovh'),
patterns('',
url(r'^ovh/', include(ovh.urls.urlpatterns)),
url(r'^manage/ovh/',
decorated_includes(login_required, include(ovh.urls.management_urlpatterns))),
)
)
url(r'^oxyd/', include(oxyd.urls.urlpatterns)),
url(r'^manage/oxyd/',
decorated_includes(login_required, include(oxyd.urls.management_urlpatterns))),
urlpatterns += required(
app_enabled('oxyd'),
patterns('',
url(r'^oxyd/', include(oxyd.urls.urlpatterns)),
url(r'^manage/oxyd/',
decorated_includes(login_required, include(oxyd.urls.management_urlpatterns))),
)
)
url(r'^pastell/', include(pastell.urls.urlpatterns)),
url(r'^manage/pastell/',
decorated_includes(login_required, include(pastell.urls.management_urlpatterns))),
urlpatterns += required(
app_enabled('pastell'),
patterns('',
url(r'^pastell/', include(pastell.urls.urlpatterns)),
url(r'^manage/pastell/',
decorated_includes(login_required, include(pastell.urls.management_urlpatterns))),
)
)
url(r'^concerto/', include(concerto.urls.urlpatterns)),
url(r'^manage/concerto/',
decorated_includes(login_required, include(concerto.urls.management_urlpatterns))),
url(r'^bdp/', include(bdp.urls.urlpatterns)),
url(r'^manage/bdp/',
decorated_includes(login_required, include(bdp.urls.management_urlpatterns))),
urlpatterns += required(
app_enabled('concerto'),
patterns('',
url(r'^concerto/', include(concerto.urls.urlpatterns)),
url(r'^manage/concerto/',
decorated_includes(login_required, include(concerto.urls.management_urlpatterns))),
)
)
urlpatterns += required(
app_enabled('bdp'),
patterns('',
url(r'^bdp/', include(bdp.urls.urlpatterns)),
url(r'^manage/bdp/',
decorated_includes(login_required, include(bdp.urls.management_urlpatterns))),
)
)
# add patterns from plugins

View File

@ -1,6 +1,11 @@
# Decorating URL includes, <https://djangosnippets.org/snippets/2532/>
from functools import wraps
from django.conf import settings
from django.core.urlresolvers import RegexURLPattern, RegexURLResolver
from django.views.debug import technical_404_response
from django.http import Http404
class DecoratedURLPattern(RegexURLPattern):
def resolve(self, *args, **kwargs):
@ -29,3 +34,81 @@ def decorated_includes(func, includes, *args, **kwargs):
item._decorate_with = func
return urlconf_module, app_name, namespace
# below, a set of decorators to generate urls.py like this:
# urlpatterns = required(
# app_enabled('applabel'),
# patterns( ... urls for applabel ... )
# )
def unless(test, message):
'''Decorator returning a 404 status code if some condition is not met'''
def decorator(func):
@wraps(func)
def f(request, *args, **kwargs):
if not test():
return technical_404_response(request, Http404(message))
return func(request, *args, **kwargs)
return f
return decorator
def app_enabled(app_label):
'''for enabling a view based on its status in PASSERELLE_APPS'''
def test():
return app_label in settings.PASSERELLE_APPS
return unless(test, 'please enable %s' % app_label)
def setting_enabled(name):
'''for enabling a view based on a setting'''
def test():
return getattr(settings, name, False)
return unless(test, 'please enable %s' % name)
# code bellow is borrowed from https://djangosnippets.org/snippets/2607/
# or https://gist.github.com/sjzabel/1378003
def required(wrapping_functions,patterns_rslt):
'''
Used to require 1..n decorators in any view returned by a url tree
Usage:
urlpatterns = required(func,patterns(...))
urlpatterns = required((func,func,func),patterns(...))
Note:
Use functools.partial to pass keyword params to the required
decorators. If you need to pass args you will have to write a
wrapper function.
Example:
from functools import partial
urlpatterns = required(
partial(login_required,login_url='/accounts/login/'),
patterns(...)
)
'''
if not hasattr(wrapping_functions, '__iter__'):
wrapping_functions = (wrapping_functions, )
return [
_wrap_instance__resolve(wrapping_functions, instance)
for instance in patterns_rslt
]
def _wrap_instance__resolve(wrapping_functions, instance):
def _wrap_func_in_returned_resolver_match(*args, **kwargs):
rslt = resolve(*args, **kwargs)
if not hasattr(rslt, 'func'):
return rslt
f = getattr(rslt, 'func')
for _f in reversed(wrapping_functions):
# @decorate the function from inner to outter
f = _f(f)
setattr(rslt, 'func', f)
return rslt
if not hasattr(instance, 'resolve'):
return instance
resolve = getattr(instance, 'resolve')
setattr(instance, 'resolve', _wrap_func_in_returned_resolver_match)
return instance

View File

@ -15,10 +15,8 @@ from passerelle.base.models import BaseResource
def get_all_apps():
# TODO: once the legacy connectors are ported, the test on get_icon_class
# won't be necessary anymore.
return [x for x in models.get_models() if issubclass(x, BaseResource) and \
hasattr(x, 'get_icon_class')]
x.is_enabled() ]
def login(request, *args, **kwargs):
if any(get_idps()):