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