PageRenderTime 2ms CodeModel.GetById 102ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 0ms

/openstack_dashboard/dashboards/admin/users/forms.py

https://bitbucket.org/xtchenhui/horizon-zte
Python | 196 lines | 168 code | 9 blank | 19 comment | 2 complexity | bdc8509c2867b8a2186922bce64c981d MD5 | raw file
Possible License(s): Apache-2.0
  1# vim: tabstop=4 shiftwidth=4 softtabstop=4
  2
  3# Copyright 2012 United States Government as represented by the
  4# Administrator of the National Aeronautics and Space Administration.
  5# All Rights Reserved.
  6#
  7# Copyright 2012 Nebula, Inc.
  8#
  9#    Licensed under the Apache License, Version 2.0 (the "License"); you may
 10#    not use this file except in compliance with the License. You may obtain
 11#    a copy of the License at
 12#
 13#         http://www.apache.org/licenses/LICENSE-2.0
 14#
 15#    Unless required by applicable law or agreed to in writing, software
 16#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 17#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 18#    License for the specific language governing permissions and limitations
 19#    under the License.
 20
 21import logging
 22
 23from django.forms import ValidationError
 24from django.utils.translation import force_unicode, ugettext_lazy as _
 25from django.views.decorators.debug import sensitive_variables
 26
 27from horizon import exceptions
 28from horizon import forms
 29from horizon import messages
 30from horizon.utils import validators
 31
 32from openstack_dashboard import api
 33
 34
 35LOG = logging.getLogger(__name__)
 36
 37
 38class BaseUserForm(forms.SelfHandlingForm):
 39    def __init__(self, request, *args, **kwargs):
 40        super(BaseUserForm, self).__init__(request, *args, **kwargs)
 41        # Populate tenant choices
 42        tenant_choices = [('', _("Select a project"))]
 43
 44        for tenant in api.keystone.tenant_list(request, admin=True):
 45            if tenant.enabled:
 46                tenant_choices.append((tenant.id, tenant.name))
 47        self.fields['tenant_id'].choices = tenant_choices
 48
 49    def clean(self):
 50        '''Check to make sure password fields match.'''
 51        data = super(forms.Form, self).clean()
 52        if 'password' in data:
 53            if data['password'] != data.get('confirm_password', None):
 54                raise ValidationError(_('Passwords do not match.'))
 55        return data
 56
 57
 58ADD_PROJECT_URL = "horizon:admin:projects:create"
 59
 60
 61class CreateUserForm(BaseUserForm):
 62    name = forms.CharField(label=_("User Name"))
 63    email = forms.EmailField(label=_("Email"))
 64    password = forms.RegexField(
 65            label=_("Password"),
 66            widget=forms.PasswordInput(render_value=False),
 67            regex=validators.password_validator(),
 68            error_messages={'invalid': validators.password_validator_msg()})
 69    confirm_password = forms.CharField(
 70            label=_("Confirm Password"),
 71            required=False,
 72            widget=forms.PasswordInput(render_value=False))
 73    tenant_id = forms.DynamicChoiceField(label=_("Primary Project"),
 74                                         add_item_link=ADD_PROJECT_URL)
 75    role_id = forms.ChoiceField(label=_("Role"))
 76
 77    def __init__(self, *args, **kwargs):
 78        roles = kwargs.pop('roles')
 79        super(CreateUserForm, self).__init__(*args, **kwargs)
 80        role_choices = [(role.id, role.name) for role in roles]
 81        self.fields['role_id'].choices = role_choices
 82
 83    # We have to protect the entire "data" dict because it contains the
 84    # password and confirm_password strings.
 85    @sensitive_variables('data')
 86    def handle(self, request, data):
 87        try:
 88            LOG.info('Creating user with name "%s"' % data['name'])
 89            new_user = api.keystone.user_create(request,
 90                                                data['name'],
 91                                                data['email'],
 92                                                data['password'],
 93                                                data['tenant_id'],
 94                                                True)
 95            messages.success(request,
 96                             _('User "%s" was successfully created.')
 97                             % data['name'])
 98            if data['role_id']:
 99                try:
100                    api.keystone.add_tenant_user_role(request,
101                                             data['tenant_id'],
102                                             new_user.id,
103                                             data['role_id'])
104                except:
105                    exceptions.handle(request,
106                                      _('Unable to add user'
107                                        'to primary project.'))
108            return new_user
109        except:
110            exceptions.handle(request, _('Unable to create user.'))
111
112
113class UpdateUserForm(BaseUserForm):
114    id = forms.CharField(label=_("ID"), widget=forms.HiddenInput)
115    name = forms.CharField(label=_("User Name"))
116    email = forms.EmailField(label=_("Email"))
117    password = forms.RegexField(label=_("Password"),
118            widget=forms.PasswordInput(render_value=False),
119            regex=validators.password_validator(),
120            required=False,
121            error_messages={'invalid':
122                    validators.password_validator_msg()})
123    confirm_password = forms.CharField(
124            label=_("Confirm Password"),
125            widget=forms.PasswordInput(render_value=False),
126            required=False)
127    tenant_id = forms.ChoiceField(label=_("Primary Project"))
128
129    def __init__(self, request, *args, **kwargs):
130        super(UpdateUserForm, self).__init__(request, *args, **kwargs)
131
132        if api.keystone.keystone_can_edit_user() is False:
133            for field in ('name', 'email', 'password', 'confirm_password'):
134                self.fields.pop(field)
135
136    # We have to protect the entire "data" dict because it contains the
137    # password and confirm_password strings.
138    @sensitive_variables('data', 'password')
139    def handle(self, request, data):
140        failed, succeeded = [], []
141        user_is_editable = api.keystone.keystone_can_edit_user()
142        user = data.pop('id')
143        tenant = data.pop('tenant_id')
144
145        if user_is_editable:
146            password = data.pop('password')
147            data.pop('confirm_password', None)
148
149        if user_is_editable:
150            # Update user details
151            msg_bits = (_('name'), _('email'))
152            try:
153                api.keystone.user_update(request, user, **data)
154                succeeded.extend(msg_bits)
155            except:
156                failed.extend(msg_bits)
157                exceptions.handle(request, ignore=True)
158
159        # Update default tenant
160        msg_bits = (_('primary project'),)
161        try:
162            api.keystone.user_update_tenant(request, user, tenant)
163            succeeded.extend(msg_bits)
164        except:
165            failed.append(msg_bits)
166            exceptions.handle(request, ignore=True)
167
168        # Check for existing roles
169        # Show a warning if no role exists for the tenant
170        user_roles = api.keystone.roles_for_user(request, user, tenant)
171        if not user_roles:
172            messages.warning(request,
173                             _('The user %s has no role defined for' +
174                             ' that project.')
175                             % data.get('name', None))
176
177        if user_is_editable:
178            # If present, update password
179            # FIXME(gabriel): password change should be its own form and view
180            if password:
181                msg_bits = (_('password'),)
182                try:
183                    api.keystone.user_update_password(request, user, password)
184                    succeeded.extend(msg_bits)
185                except:
186                    failed.extend(msg_bits)
187                    exceptions.handle(request, ignore=True)
188
189        if succeeded:
190            messages.success(request, _('User has been updated successfully.'))
191        if failed:
192            failed = map(force_unicode, failed)
193            messages.error(request,
194                           _('Unable to update %(attributes)s for the user.')
195                             % {"attributes": ", ".join(failed)})
196        return True