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