Gabriel Hurley f986a631a2 Make sure Horizon is treating passwords securely.
* Applies the sensitive_post_parameters and sensitive_variables
  decorators to functions that handle sensitive data.
* Defines a custom Exception Filter class to provide some added
  security.
* Adds notes on logging to the docs.

Fixes bug 1004114 for Horizon.

Change-Id: I13ac91d91e0ed2322cc61633b02455cfed39fdcd
2012-05-24 15:28:01 -07:00

109 lines
3.9 KiB
Python

# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2012 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
# Copyright 2012 Nebula, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import logging
from django import shortcuts
from django.conf import settings
from django.contrib.auth import REDIRECT_FIELD_NAME
from django.utils.decorators import method_decorator
from django.utils.translation import ugettext as _
from django.views.decorators.debug import sensitive_post_parameters
import horizon
from horizon import api
from horizon import exceptions
from horizon import forms
from horizon import users
from horizon.base import Horizon
from horizon.views.auth_forms import Login, LoginWithTenant, _set_session_data
LOG = logging.getLogger(__name__)
def user_home(request):
""" Reversible named view to direct a user to the appropriate homepage. """
return shortcuts.redirect(horizon.get_user_home(request.user))
class LoginView(forms.ModalFormView):
"""
Logs in a user and redirects them to the URL specified by
:func:`horizon.get_user_home`.
"""
form_class = Login
template_name = "horizon/auth/login.html"
@method_decorator(sensitive_post_parameters('password'))
def dispatch(self, *args, **kwargs):
return super(LoginView, self).dispatch(*args, **kwargs)
def get_context_data(self, **kwargs):
context = super(LoginView, self).get_context_data(**kwargs)
redirect_to = self.request.REQUEST.get(REDIRECT_FIELD_NAME, "")
context["redirect_field_name"] = REDIRECT_FIELD_NAME
context["next"] = redirect_to
return context
def get_initial(self):
initial = super(LoginView, self).get_initial()
current_region = self.request.session.get('region_endpoint', None)
requested_region = self.request.GET.get('region', None)
regions = dict(getattr(settings, "AVAILABLE_REGIONS", []))
if requested_region in regions and requested_region != current_region:
initial.update({'region': requested_region})
return initial
@sensitive_post_parameters("password")
def switch_tenants(request, tenant_id):
"""
Swaps a user from one tenant to another using the unscoped token from
Keystone to exchange scoped tokens for the new tenant.
"""
form, handled = LoginWithTenant.maybe_handle(
request, initial={'tenant': tenant_id,
'username': request.user.username})
if handled:
return handled
unscoped_token = request.session.get('unscoped_token', None)
if unscoped_token:
try:
token = api.token_create_scoped(request,
tenant_id,
unscoped_token)
_set_session_data(request, token)
user = users.User(users.get_user_from_request(request))
return shortcuts.redirect(Horizon.get_user_home(user))
except:
exceptions.handle(request,
_("You are not authorized for that tenant."))
return shortcuts.redirect("horizon:auth_login")
def logout(request):
""" Clears the session and logs the current user out. """
request.user_logout()
# FIXME(gabriel): we don't ship a view named splash
return shortcuts.redirect('splash')