1# Copyright 2012 Nebula, Inc. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); you may 4# not use this file except in compliance with the License. You may obtain 5# a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12# License for the specific language governing permissions and limitations 13# under the License. 14 15from importlib import import_module 16import logging 17import urllib 18 19from django.conf import settings 20from django import http 21from django import shortcuts 22from django import urls 23from django.utils.encoding import smart_text 24import django.views.decorators.vary 25from django.views.generic import TemplateView 26 27import horizon 28from horizon import exceptions 29from horizon import notifications 30 31LOG = logging.getLogger(__name__) 32 33 34MESSAGES_PATH = settings.MESSAGES_PATH 35 36 37def get_user_home(user): 38 dashboard = horizon.get_default_dashboard() 39 return dashboard.get_absolute_url() 40 41 42# TODO(stephenfin): Migrate to CBV 43@django.views.decorators.vary.vary_on_cookie 44def splash(request): 45 if not request.user.is_authenticated: 46 raise exceptions.NotAuthenticated() 47 48 response = shortcuts.redirect(horizon.get_user_home(request.user)) 49 if 'logout_reason' in request.COOKIES: 50 response.delete_cookie('logout_reason') 51 if 'logout_status' in request.COOKIES: 52 response.delete_cookie('logout_status') 53 # Display Message of the Day message from the message files 54 # located in MESSAGES_PATH 55 if MESSAGES_PATH: 56 notifications.process_message_notification(request, MESSAGES_PATH) 57 return response 58 59 60def get_url_with_pagination(request, marker_name, prev_marker_name, url_string, 61 object_id=None): 62 if object_id: 63 url = urls.reverse(url_string, args=(object_id,)) 64 else: 65 url = urls.reverse(url_string) 66 marker = request.GET.get(marker_name, None) 67 if marker: 68 return "{}?{}".format(url, 69 urllib.parse.urlencode({marker_name: marker})) 70 71 prev_marker = request.GET.get(prev_marker_name, None) 72 if prev_marker: 73 return "{}?{}".format(url, 74 urllib.parse.urlencode({prev_marker_name: 75 prev_marker})) 76 return url 77 78 79class ExtensibleHeaderView(TemplateView): 80 template_name = 'header/_header_sections.html' 81 82 def get_context_data(self, **kwargs): 83 context = super().get_context_data(**kwargs) 84 header_sections = [] 85 config = getattr(settings, 'HORIZON_CONFIG', {}) 86 for view_path in config.get("header_sections", []): 87 mod_path, view_cls = view_path.rsplit(".", 1) 88 try: 89 mod = import_module(mod_path) 90 except ImportError: 91 LOG.warning("Could not load header view: %s", mod_path) 92 continue 93 94 try: 95 view = getattr(mod, view_cls)(request=self.request) 96 response = view.get(self.request) 97 rendered_response = response.render() 98 packed_response = [view_path.replace('.', '-'), 99 smart_text(rendered_response.content)] 100 header_sections.append(packed_response) 101 102 except Exception as e: 103 LOG.warning("Could not render header %(path)s, exception: " 104 "%(exc)s", {'path': view_path, 'exc': e}) 105 continue 106 107 context['header_sections'] = header_sections 108 return context 109 110 111def csrf_failure(request, reason=""): 112 url = settings.LOGIN_URL + "?csrf_failure=%s" % urllib.parse.quote(reason) 113 response = http.HttpResponseRedirect(url) 114 return response 115