1# -*- coding: utf-8 -*- 2""" 3Edit Toolbar middleware 4""" 5from django import forms 6from django.contrib.admin.models import LogEntry, ADDITION, CHANGE 7from django.core.exceptions import ValidationError 8from django.urls import resolve 9 10from cms.toolbar.toolbar import CMSToolbar 11from cms.toolbar.utils import get_toolbar_from_request 12from cms.utils.conf import get_cms_setting 13from cms.utils.compat.dj import MiddlewareMixin 14from cms.utils.request_ip_resolvers import get_request_ip_resolver 15 16 17get_request_ip = get_request_ip_resolver() 18 19 20class ToolbarMiddleware(MiddlewareMixin): 21 """ 22 Middleware to set up CMS Toolbar. 23 """ 24 25 def is_cms_request(self, request): 26 toolbar_hide = get_cms_setting('TOOLBAR_HIDE') 27 internal_ips = get_cms_setting('INTERNAL_IPS') 28 29 if internal_ips: 30 client_ip = get_request_ip(request) 31 try: 32 client_ip = forms.GenericIPAddressField().clean(client_ip) 33 except ValidationError: 34 return False 35 else: 36 if client_ip not in internal_ips: 37 return False 38 39 if not toolbar_hide: 40 return True 41 42 try: 43 match = resolve(request.path_info) 44 except: 45 return False 46 47 return match.url_name in ('pages-root', 'pages-details-by-slug') 48 49 def process_request(self, request): 50 """ 51 If we should show the toolbar for this request, put it on 52 request.toolbar. 53 """ 54 55 if not self.is_cms_request(request): 56 return 57 58 edit_on = get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON') 59 edit_off = get_cms_setting('CMS_TOOLBAR_URL__EDIT_OFF') 60 disable = get_cms_setting('CMS_TOOLBAR_URL__DISABLE') 61 anonymous_on = get_cms_setting('TOOLBAR_ANONYMOUS_ON') 62 edit_enabled = edit_on in request.GET and 'preview' not in request.GET 63 edit_disabled = edit_off in request.GET or 'preview' in request.GET 64 65 if disable in request.GET: 66 request.session['cms_toolbar_disabled'] = True 67 68 if edit_enabled: 69 # If we actively enter edit mode, we should show the toolbar in any case 70 request.session['cms_toolbar_disabled'] = False 71 72 toolbar_enabled = not request.session.get('cms_toolbar_disabled', False) 73 can_see_toolbar = request.user.is_staff or (anonymous_on and request.user.is_anonymous) 74 show_toolbar = (toolbar_enabled and can_see_toolbar) 75 76 if edit_enabled and show_toolbar and not request.session.get('cms_edit'): 77 # User has explicitly enabled mode 78 # AND can see the toolbar 79 request.session['cms_edit'] = True 80 request.session['cms_preview'] = False 81 82 if edit_disabled or not show_toolbar and request.session.get('cms_edit'): 83 # User has explicitly disabled the toolbar 84 # OR user has explicitly turned off edit mode 85 # OR user can't see toolbar 86 request.session['cms_edit'] = False 87 88 if 'preview' in request.GET and not request.session.get('cms_preview'): 89 # User has explicitly requested a preview of the live page. 90 request.session['cms_preview'] = True 91 92 if request.user.is_staff: 93 try: 94 request.cms_latest_entry = LogEntry.objects.filter( 95 user=request.user, 96 action_flag__in=(ADDITION, CHANGE) 97 ).only('pk').order_by('-pk')[0].pk 98 except IndexError: 99 request.cms_latest_entry = -1 100 request.toolbar = CMSToolbar(request) 101 102 def process_response(self, request, response): 103 if not self.is_cms_request(request): 104 return response 105 106 from django.utils.cache import add_never_cache_headers 107 108 toolbar = get_toolbar_from_request(request) 109 110 if toolbar._cache_disabled: 111 add_never_cache_headers(response) 112 113 if hasattr(request, 'user') and request.user.is_staff and response.status_code != 500: 114 try: 115 if hasattr(request, 'cms_latest_entry'): 116 pk = LogEntry.objects.filter( 117 user=request.user, 118 action_flag__in=(ADDITION, CHANGE) 119 ).only('pk').order_by('-pk')[0].pk 120 121 if request.cms_latest_entry != pk: 122 request.session['cms_log_latest'] = pk 123 # If there were no LogEntries, just don't touch the session. 124 # Note that in the case of a user logging-in as another user, 125 # request may have a cms_latest_entry attribute, but there are no 126 # LogEntries for request.user. 127 except IndexError: 128 pass 129 return response 130