Files
horizon/openstack_dashboard/dashboards/identity/users/tables.py
David Lyle 18e8ea810d Separating Identity Dashboard and using RBAC
Moving identity panels to their own dashboard.

RBAC is now used to determine the data to load in the identity
dashboard. Using the default policy file, a user with role member
will now be able to see their project list.

Also, adding a policy check mechanism at the panel and dashboard
level to determine which panels and dashboards the user can access.

Implements blueprint separate-identity-dash

Change-Id: I7ebfec2bf6e44899bec79d3b23c90d56a976200f
2014-08-18 16:40:56 -06:00

153 lines
5.1 KiB
Python

# 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.
from django.template import defaultfilters
from django.utils.translation import ugettext_lazy as _
from horizon import messages
from horizon import tables
from openstack_dashboard import api
ENABLE = 0
DISABLE = 1
class CreateUserLink(tables.LinkAction):
name = "create"
verbose_name = _("Create User")
url = "horizon:identity:users:create"
classes = ("ajax-modal",)
icon = "plus"
policy_rules = (('identity', 'identity:create_grant'),
("identity", "identity:create_user"),
("identity", "identity:list_roles"),
("identity", "identity:list_projects"),)
def allowed(self, request, user):
return api.keystone.keystone_can_edit_user()
class EditUserLink(tables.LinkAction):
name = "edit"
verbose_name = _("Edit")
url = "horizon:identity:users:update"
classes = ("ajax-modal",)
icon = "pencil"
policy_rules = (("identity", "identity:update_user"),
("identity", "identity:list_projects"),)
def get_policy_target(self, request, user):
return {"user_id": user.id}
def allowed(self, request, user):
return api.keystone.keystone_can_edit_user()
class ToggleEnabled(tables.BatchAction):
name = "toggle"
action_present = (_("Enable"), _("Disable"))
action_past = (_("Enabled"), _("Disabled"))
data_type_singular = _("User")
data_type_plural = _("Users")
classes = ("btn-toggle",)
policy_rules = (("identity", "identity:update_user"),)
def get_policy_target(self, request, user=None):
if user:
return {"user_id": user.id}
return {}
def allowed(self, request, user=None):
if not api.keystone.keystone_can_edit_user():
return False
self.enabled = True
if not user:
return self.enabled
self.enabled = user.enabled
if self.enabled:
self.current_present_action = DISABLE
else:
self.current_present_action = ENABLE
return True
def update(self, request, user=None):
super(ToggleEnabled, self).update(request, user)
if user and user.id == request.user.id:
self.attrs["disabled"] = "disabled"
def action(self, request, obj_id):
if obj_id == request.user.id:
messages.info(request, _('You cannot disable the user you are '
'currently logged in as.'))
return
if self.enabled:
api.keystone.user_update_enabled(request, obj_id, False)
self.current_past_action = DISABLE
else:
api.keystone.user_update_enabled(request, obj_id, True)
self.current_past_action = ENABLE
class DeleteUsersAction(tables.DeleteAction):
data_type_singular = _("User")
data_type_plural = _("Users")
policy_rules = (("identity", "identity:delete_user"),)
def allowed(self, request, datum):
if not api.keystone.keystone_can_edit_user() or \
(datum and datum.id == request.user.id):
return False
return True
def delete(self, request, obj_id):
api.keystone.user_delete(request, obj_id)
class UserFilterAction(tables.FilterAction):
def filter(self, table, users, filter_string):
"""Naive case-insensitive search."""
q = filter_string.lower()
return [user for user in users
if q in user.name.lower()
or q in getattr(user, 'email', '').lower()]
class UsersTable(tables.DataTable):
STATUS_CHOICES = (
("true", True),
("false", False)
)
name = tables.Column('name', verbose_name=_('User Name'))
email = tables.Column('email', verbose_name=_('Email'),
filters=(lambda v: defaultfilters
.default_if_none(v, ""),
defaultfilters.escape,
defaultfilters.urlize)
)
# Default tenant is not returned from Keystone currently.
# default_tenant = tables.Column('default_tenant',
# verbose_name=_('Default Project'))
id = tables.Column('id', verbose_name=_('User ID'))
enabled = tables.Column('enabled', verbose_name=_('Enabled'),
status=True,
status_choices=STATUS_CHOICES,
empty_value="False")
class Meta:
name = "users"
verbose_name = _("Users")
row_actions = (EditUserLink, ToggleEnabled, DeleteUsersAction)
table_actions = (UserFilterAction, CreateUserLink, DeleteUsersAction)