Files
Reskreen/venv/Lib/site-packages/baton/views.py
Ambulance Clerc c990f87413 avancé de dev
2022-02-15 14:48:18 +01:00

255 lines
8.8 KiB
Python

# -*- coding: utf-8 -*-
import hashlib
from django.http import JsonResponse
from django.contrib.admin import site
from django.contrib.admin.views.decorators import staff_member_required
from django.utils.decorators import method_decorator
from django.core.exceptions import ImproperlyConfigured
from django.views import View
from .config import get_config
class GetAppListJsonView(View):
@method_decorator(staff_member_required)
def dispatch(self, *args, **kwargs):
""" Only staff members can access this view """
return super(GetAppListJsonView, self).dispatch(*args, **kwargs)
def get(self, request):
""" Returns a json representing the menu voices
in a format eaten by the js menu.
Raised ImproperlyConfigured exceptions can be viewed
in the browser console
"""
self.app_list = site.get_app_list(request)
self.apps_dict = self.create_app_list_dict()
# no menu provided
items = self.get_menu(request)
if not items:
voices = self.get_default_voices()
else:
voices = []
for item in items:
self.add_voice(voices, item)
return JsonResponse(voices, safe=False)
def get_menu(self, request):
return get_config('MENU')
def add_voice(self, voices, item):
""" Adds a voice to the list
"""
voice = None
if item.get('type') == 'title':
voice = self.get_title_voice(item)
elif item.get('type') == 'app':
voice = self.get_app_voice(item)
elif item.get('type') == 'model':
voice = self.get_app_model_voice(item)
elif item.get('type') == 'free':
voice = self.get_free_voice(item)
if voice:
voices.append(voice)
def get_title_voice(self, item):
""" Title voice
Returns the js menu compatible voice dict if the user
can see it, None otherwise
"""
view = True
if item.get('perms', None):
view = self.check_user_permission(item.get('perms', []))
elif item.get('apps', None):
view = self.check_apps_permission(item.get('apps', []))
if view:
children_items = item.get('children', [])
children = []
if len(children_items):
for citem in children_items:
self.add_voice(children, citem)
return {
'type': 'title',
'label': item.get('label', ''),
'icon': item.get('icon', None),
'defaultOpen': item.get('default_open', False),
'children': children,
}
return None
def get_free_voice(self, item):
""" Free voice
Returns the js menu compatible voice dict if the user
can see it, None otherwise
"""
view = True
if item.get('perms', None):
view = self.check_user_permission(item.get('perms', []))
elif item.get('apps', None):
view = self.check_apps_permission(item.get('apps', []))
if view:
children_items = item.get('children', [])
children = []
if len(children_items):
for citem in children_items:
self.add_voice(children, citem)
return {
'type': 'free',
'label': item.get('label', ''),
'icon': item.get('icon', None),
'url': item.get('url', None),
're': item.get('re', None),
'defaultOpen': item.get('default_open', False),
'children': children,
}
return None
def get_app_voice(self, item):
""" App voice
Returns the js menu compatible voice dict if the user
can see it, None otherwise
"""
if item.get('name', None) is None:
raise ImproperlyConfigured('App menu voices must have a name key')
if self.check_apps_permission([item.get('name', None)]):
children = []
if item.get('models', None) is None:
for name, model in self.apps_dict[item.get('name')]['models'].items(): # noqa
children.append({
'type': 'model',
'label': model.get('name', ''),
'url': model.get('admin_url', '')
})
else:
for model_item in item.get('models', []):
voice = self.get_model_voice(item.get('name'), model_item)
if voice:
children.append(voice)
return {
'type': 'app',
'label': item.get('label', ''),
'icon': item.get('icon', None),
'defaultOpen': item.get('default_open', False),
'children': children
}
return None
def get_app_model_voice(self, app_model_item):
""" App Model voice
Returns the js menu compatible voice dict if the user
can see it, None otherwise
"""
if app_model_item.get('name', None) is None:
raise ImproperlyConfigured('Model menu voices must have a name key') # noqa
if app_model_item.get('app', None) is None:
raise ImproperlyConfigured('Model menu voices must have an app key') # noqa
return self.get_model_voice(app_model_item.get('app'), app_model_item)
def get_model_voice(self, app, model_item):
""" Model voice
Returns the js menu compatible voice dict if the user
can see it, None otherwise
"""
if model_item.get('name', None) is None:
raise ImproperlyConfigured('Model menu voices must have a name key') # noqa
if self.check_model_permission(app, model_item.get('name', None)):
return {
'type': 'model',
'label': model_item.get('label', ''),
'icon': model_item.get('icon', None),
'url': self.apps_dict[app]['models'][model_item.get('name')]['admin_url'], # noqa
}
return None
def create_app_list_dict(self):
""" Creates a more efficient to check dictionary from
the app_list list obtained from django admin
"""
d = {}
for app in self.app_list:
models = {}
for model in app.get('models', []):
models[model.get('object_name').lower()] = model
d[app.get('app_label').lower()] = {
'app_url': app.get('app_url', ''),
'app_label': app.get('app_label'),
'models': models
}
return d
def check_user_permission(self, perms):
for perm in perms:
if self.request.user.has_perm(perm):
return True
return False
def check_apps_permission(self, apps):
""" Checks if one of apps is listed in apps_dict
Since apps_dict is derived from the app_list
given by django admin, it lists only the apps
the user can view
"""
for app in apps:
if app in self.apps_dict:
return True
return False
def check_model_permission(self, app, model):
""" Checks if model is listed in apps_dict
Since apps_dict is derived from the app_list
given by django admin, it lists only the apps
and models the user can view
"""
if self.apps_dict.get(app, False) and model in self.apps_dict[app]['models']:
return True
return False
def get_default_voices(self):
""" When no custom menu is defined in settings
Retrieves a js menu ready dict from the django admin app list
"""
voices = []
for app in self.app_list:
children = []
for model in app.get('models', []):
child = {
'type': 'model',
'label': model.get('name', ''),
'url': model.get('admin_url', '')
}
children.append(child)
voice = {
'type': 'app',
'label': app.get('name', ''),
'url': app.get('app_url', ''),
'children': children
}
voices.append(voice)
return voices
class GetGravatartUrlJsonView(View):
def get(self, request):
if not request.user.is_authenticated:
return JsonResponse({})
try:
email = request.user.email.lower().strip()
hash = hashlib.md5(email.encode())
return JsonResponse({"hash": hash.hexdigest()})
except Exception:
return JsonResponse({})