Sfoglia il codice sorgente

HUE-8530 [organization] Support creating a new user

Romain 6 anni fa
parent
commit
71647438c1

+ 83 - 51
apps/useradmin/src/useradmin/forms.py

@@ -34,7 +34,7 @@ from useradmin.hue_password_policy import hue_get_password_validators
 from useradmin.models import GroupPermission, HuePermission, get_default_user_group
 
 if ENABLE_ORGANIZATIONS.get():
-  from useradmin.models2 import OrganizationUser as User, OrganizationGroup as Group
+  from useradmin.models2 import OrganizationUser as User, OrganizationGroup as Group, default_organization, Organization
 else:
   from django.contrib.auth.models import User, Group
 
@@ -96,27 +96,37 @@ class UserChangeForm(django.contrib.auth.forms.UserChangeForm):
       help_text = _t("Required. 30 characters or fewer. No whitespaces or colons."),
       error_messages = {'invalid': _t("Whitespaces and ':' not allowed") })
 
-  password1 = forms.CharField(label=_t("New Password"),
-                              widget=forms.
-                              PasswordInput,
-                              required=False,
-                              validators=hue_get_password_validators())
-  password2 = forms.CharField(label=_t("Password confirmation"),
-                              widget=forms.PasswordInput,
-                              required=False,
-                              validators=hue_get_password_validators())
+  password1 = forms.CharField(
+      label=_t("New Password"),
+      widget=forms.
+      PasswordInput,
+      required=False,
+      validators=hue_get_password_validators()
+  )
+  password2 = forms.CharField(
+      label=_t("Password confirmation"),
+      widget=forms.PasswordInput,
+      required=False,
+      validators=hue_get_password_validators()
+  )
   password_old = forms.CharField(label=_t("Current password"), widget=forms.PasswordInput, required=False)
-  ensure_home_directory = forms.BooleanField(label=_t("Create home directory"),
-                                            help_text=_t("Create home directory if one doesn't already exist."),
-                                            initial=True,
-                                            required=False)
-  language = forms.ChoiceField(label=_t("Language Preference"),
-                               choices=LANGUAGES,
-                               required=False)
-  unlock_account = forms.BooleanField(label=_t("Unlock Account"),
-                                      help_text=_t("Unlock user's account for login."),
-                                      initial=False,
-                                      required=False)
+  ensure_home_directory = forms.BooleanField(
+      label=_t("Create home directory"),
+      help_text=_t("Create home directory if one doesn't already exist."),
+      initial=True,
+      required=False
+  )
+  language = forms.ChoiceField(
+      label=_t("Language Preference"),
+      choices=LANGUAGES,
+      required=False
+  )
+  unlock_account = forms.BooleanField(
+      label=_t("Unlock Account"),
+      help_text=_t("Unlock user's account for login."),
+      initial=False,
+      required=False
+  )
 
   class Meta(django.contrib.auth.forms.UserChangeForm.Meta):
     model =  User
@@ -209,6 +219,15 @@ class OrganizationUserChangeForm(UserChangeForm):
     if self.instance.id:
       self.fields['email'].widget.attrs['readonly'] = True
 
+    self.fields['organization'] = forms.ChoiceField(choices=((default_organization().id, default_organization()),), initial=default_organization())
+
+  def clean_organization(self):
+    try:
+      return Organization.objects.get(id=int(self.cleaned_data.get('organization')))
+    except:
+      LOG.exception('The organization does not exist.')
+      return None
+
 
 class PasswordChangeForm(UserChangeForm):
   """
@@ -239,6 +258,7 @@ class SuperUserChangeForm(UserChangeForm):
       else:
         self.initial['groups'] = []
 
+# Mixin __init__ method?
 class OrganizationSuperUserChangeForm(OrganizationUserChangeForm):
   class Meta(UserChangeForm.Meta):
     fields = ["email", "is_active"] + OrganizationUserChangeForm.Meta.fields + ["is_superuser", "unlock_account", "groups"]
@@ -261,16 +281,20 @@ class AddLdapUsersForm(forms.Form):
   username_pattern = forms.CharField(
       label=_t("Username"),
       help_text=_t("Required. 30 characters or fewer with username. 64 characters or fewer with DN. No whitespaces or colons."),
-      error_messages={'invalid': _t("Whitespaces and ':' not allowed")})
-  dn = forms.BooleanField(label=_t("Distinguished name"),
-                          help_text=_t("Whether or not the user should be imported by "
-                                    "distinguished name."),
-                          initial=False,
-                          required=False)
-  ensure_home_directory = forms.BooleanField(label=_t("Create home directory"),
-                                            help_text=_t("Create home directory for user if one doesn't already exist."),
-                                            initial=True,
-                                            required=False)
+      error_messages={'invalid': _t("Whitespaces and ':' not allowed")}
+  )
+  dn = forms.BooleanField(
+      label=_t("Distinguished name"),
+      help_text=_t("Whether or not the user should be imported by distinguished name."),
+      initial=False,
+      required=False
+  )
+  ensure_home_directory = forms.BooleanField(
+      label=_t("Create home directory"),
+      help_text=_t("Create home directory for user if one doesn't already exist."),
+      initial=True,
+      required=False
+  )
 
   def __init__(self, *args, **kwargs):
     super(AddLdapUsersForm, self).__init__(*args, **kwargs)
@@ -300,24 +324,33 @@ class AddLdapGroupsForm(forms.Form):
       label=_t("Name"),
       max_length=256,
       help_text=_t("Required. 256 characters or fewer."),
-      error_messages={'invalid': _t("256 characters or fewer.") })
-  dn = forms.BooleanField(label=_t("Distinguished name"),
-                          help_text=_t("Whether or not the group should be imported by "
-                                    "distinguished name."),
-                          initial=False,
-                          required=False)
-  import_members = forms.BooleanField(label=_t('Import new members'),
-                                      help_text=_t('Import unimported or new users from the group.'),
-                                      initial=False,
-                                      required=False)
-  ensure_home_directories = forms.BooleanField(label=_t('Create home directories'),
-                                                help_text=_t('Create home directories for every member imported, if members are being imported.'),
-                                                initial=True,
-                                                required=False)
-  import_members_recursive = forms.BooleanField(label=_t('Import new members from all subgroups'),
-                                                help_text=_t('Import unimported or new users from the all subgroups.'),
-                                                initial=False,
-                                                required=False)
+      error_messages={'invalid': _t("256 characters or fewer.")}
+  )
+  dn = forms.BooleanField(
+      label=_t("Distinguished name"),
+      help_text=_t("Whether or not the group should be imported by "
+                "distinguished name."),
+      initial=False,
+      required=False
+  )
+  import_members = forms.BooleanField(
+      label=_t('Import new members'),
+      help_text=_t('Import unimported or new users from the group.'),
+      initial=False,
+      required=False
+  )
+  ensure_home_directories = forms.BooleanField(
+      label=_t('Create home directories'),
+      help_text=_t('Create home directories for every member imported, if members are being imported.'),
+      initial=True,
+      required=False
+  )
+  import_members_recursive = forms.BooleanField(
+      label=_t('Import new members from all subgroups'),
+      help_text=_t('Import unimported or new users from the all subgroups.'),
+      initial=False,
+      required=False
+  )
 
   def __init__(self, *args, **kwargs):
     super(AddLdapGroupsForm, self).__init__(*args, **kwargs)
@@ -356,8 +389,7 @@ class GroupEditForm(forms.ModelForm):
     # Note that the superclass doesn't have a clean_name method.
     data = self.cleaned_data["name"]
     if not self.GROUPNAME.match(data):
-      raise forms.ValidationError(_("Group name may only contain letters, " +
-                                  "numbers, hyphens or underscores."))
+      raise forms.ValidationError(_("Group name may only contain letters, numbers, hyphens or underscores."))
     return data
 
   def __init__(self, *args, **kwargs):

+ 3 - 0
apps/useradmin/src/useradmin/models2.py

@@ -40,6 +40,9 @@ class Organization(models.Model):
 
   objects = OrganizationManager()
 
+  def __str__(self):
+    return self.name
+
 
 class OrganizationGroupManager(models.Manager):
 

+ 6 - 4
apps/useradmin/src/useradmin/templates/edit_user.mako

@@ -89,11 +89,13 @@ ${ layout.menubar(section='users') }
             ${layout.render_field(form["last_name"])}
           % endif
 
-          % if not ENABLE_ORGANIZATIONS.get():
+          % if ENABLE_ORGANIZATIONS.get():
+            ${layout.render_field(form["organization"])}
+          % else:
             ${layout.render_field(form["email"])}
           % endif
 
-          %if request.user.username == username:
+          % if request.user.username == username:
             ${layout.render_field(form["language"])}
           % endif
 
@@ -103,10 +105,10 @@ ${ layout.menubar(section='users') }
         </div>
       % if is_admin(user):
         <div id="step3" class="stepDetails hide">
-          ${layout.render_field(form["is_active"])}
+          ${ layout.render_field(form["is_active"]) }
           ${'is_superuser' in form.fields and layout.render_field(form["is_superuser"])}
           % if is_user_locked_out(username):
-            ${layout.render_field(form["unlock_account"])}
+            ${ layout.render_field(form["unlock_account"]) }
           % endif
         </div>
       % endif

+ 67 - 62
apps/useradmin/src/useradmin/tests.py

@@ -171,63 +171,65 @@ class LdapTestConnection(object):
 
   class Data(object):
     def __init__(self):
-      self.users = {'moe': {'dn': 'uid=moe,ou=People,dc=example,dc=com', 'username':'moe', 'first':'Moe', 'email':'moe@stooges.com', 'groups': ['cn=TestUsers,ou=Groups,dc=example,dc=com']},
-                    'lårry': {'dn': 'uid=lårry,ou=People,dc=example,dc=com', 'username':'lårry', 'first':'Larry', 'last':'Stooge', 'email':'larry@stooges.com', 'groups': ['cn=TestUsers,ou=Groups,dc=example,dc=com', 'cn=Test Administrators,cn=TestUsers,ou=Groups,dc=example,dc=com']},
-                    'curly': {'dn': 'uid=curly,ou=People,dc=example,dc=com', 'username':'curly', 'first':'Curly', 'last':'Stooge', 'email':'curly@stooges.com', 'groups': ['cn=TestUsers,ou=Groups,dc=example,dc=com', 'cn=Test Administrators,cn=TestUsers,ou=Groups,dc=example,dc=com']},
-                    'Rock': {'dn': 'uid=Rock,ou=People,dc=example,dc=com', 'username':'Rock', 'first':'rock', 'last':'man', 'email':'rockman@stooges.com', 'groups': ['cn=Test Administrators,cn=TestUsers,ou=Groups,dc=example,dc=com']},
-                    'nestedguy': {'dn': 'uid=nestedguy,ou=People,dc=example,dc=com', 'username':'nestedguy', 'first':'nested', 'last':'guy', 'email':'nestedguy@stooges.com', 'groups': ['cn=NestedGroup,ou=Groups,dc=example,dc=com']},
-                    'otherguy': {'dn': 'uid=otherguy,ou=People,dc=example,dc=com', 'username':'otherguy', 'first':'Other', 'last':'Guy', 'email':'other@guy.com'},
-                    'posix_person': {'dn': 'uid=posix_person,ou=People,dc=example,dc=com', 'username': 'posix_person', 'first': 'pos', 'last': 'ix', 'email': 'pos@ix.com'},
-                    'posix_person2': {'dn': 'uid=posix_person2,ou=People,dc=example,dc=com', 'username': 'posix_person2', 'first': 'pos', 'last': 'ix', 'email': 'pos@ix.com'},
-                    'user with space': {'dn': 'uid=user with space,ou=People,dc=example,dc=com', 'username': 'user with space', 'first': 'user', 'last': 'space', 'email': 'user@space.com'},
-                    'spaceless': {'dn': 'uid=user without space,ou=People,dc=example,dc=com', 'username': 'spaceless', 'first': 'user', 'last': 'space', 'email': 'user@space.com'},
-                    'test_toolongusernametoolongusername': {'dn': 'uid=test_toolongusernametoolongusername,ou=People,dc=example,dc=com', 'username': 'test_toolongusernametoolongusername', 'first': 'toolong', 'last': 'username', 'email': 'toolong@username.com'},
-                    'test_longfirstname': {'dn': 'uid=test_longfirstname,ou=People,dc=example,dc=com', 'username': 'test_longfirstname', 'first': 'test_longfirstname_test_longfirstname', 'last': 'username', 'email': 'toolong@username.com'},}
-
-      self.groups = {'TestUsers': {
-                        'dn': 'cn=TestUsers,ou=Groups,dc=example,dc=com',
-                        'name':'TestUsers',
-                        'members':['uid=moe,ou=People,dc=example,dc=com','uid=lårry,ou=People,dc=example,dc=com','uid=curly,ou=People,dc=example,dc=com','uid=test_toolongusernametoolongusername,ou=People,dc=example,dc=com'],
-                        'posix_members':[]},
-                      'Test Administrators': {
-                        'dn': 'cn=Test Administrators,cn=TestUsers,ou=Groups,dc=example,dc=com',
-                        'name':'Test Administrators',
-                        'members':['uid=Rock,ou=People,dc=example,dc=com','uid=lårry,ou=People,dc=example,dc=com','uid=curly,ou=People,dc=example,dc=com','uid=test_toolongusernametoolongusername,ou=People,dc=example,dc=com'],
-                        'posix_members':[]},
-                      'OtherGroup': {
-                        'dn': 'cn=OtherGroup,cn=TestUsers,ou=Groups,dc=example,dc=com',
-                        'name':'OtherGroup',
-                        'members':[],
-                        'posix_members':[]},
-                      'NestedGroups': {
-                        'dn': 'cn=NestedGroups,ou=Groups,dc=example,dc=com',
-                        'name':'NestedGroups',
-                        'members':['cn=NestedGroup,ou=Groups,dc=example,dc=com'],
-                        'posix_members':[]
-                      },
-                      'NestedGroup': {
-                        'dn': 'cn=NestedGroup,ou=Groups,dc=example,dc=com',
-                        'name':'NestedGroup',
-                        'members':['uid=nestedguy,ou=People,dc=example,dc=com'],
-                        'posix_members':[]
-                      },
-                      'NestedPosixGroups': {
-                        'dn': 'cn=NestedPosixGroups,ou=Groups,dc=example,dc=com',
-                        'name':'NestedPosixGroups',
-                        'members':['cn=PosixGroup,ou=Groups,dc=example,dc=com'],
-                        'posix_members':[]
-                      },
-                      'PosixGroup': {
-                        'dn': 'cn=PosixGroup,ou=Groups,dc=example,dc=com',
-                        'name':'PosixGroup',
-                        'members':[],
-                        'posix_members':['posix_person','lårry']},
-                      'PosixGroup1': {
-                        'dn': 'cn=PosixGroup1,cn=PosixGroup,ou=Groups,dc=example,dc=com',
-                        'name':'PosixGroup1',
-                        'members':[],
-                        'posix_members':['posix_person2']},
-                     }
+      self.users = {
+        'moe': {'dn': 'uid=moe,ou=People,dc=example,dc=com', 'username':'moe', 'first':'Moe', 'email':'moe@stooges.com', 'groups': ['cn=TestUsers,ou=Groups,dc=example,dc=com']},
+        'lårry': {'dn': 'uid=lårry,ou=People,dc=example,dc=com', 'username':'lårry', 'first':'Larry', 'last':'Stooge', 'email':'larry@stooges.com', 'groups': ['cn=TestUsers,ou=Groups,dc=example,dc=com', 'cn=Test Administrators,cn=TestUsers,ou=Groups,dc=example,dc=com']},
+        'curly': {'dn': 'uid=curly,ou=People,dc=example,dc=com', 'username':'curly', 'first':'Curly', 'last':'Stooge', 'email':'curly@stooges.com', 'groups': ['cn=TestUsers,ou=Groups,dc=example,dc=com', 'cn=Test Administrators,cn=TestUsers,ou=Groups,dc=example,dc=com']},
+        'Rock': {'dn': 'uid=Rock,ou=People,dc=example,dc=com', 'username':'Rock', 'first':'rock', 'last':'man', 'email':'rockman@stooges.com', 'groups': ['cn=Test Administrators,cn=TestUsers,ou=Groups,dc=example,dc=com']},
+        'nestedguy': {'dn': 'uid=nestedguy,ou=People,dc=example,dc=com', 'username':'nestedguy', 'first':'nested', 'last':'guy', 'email':'nestedguy@stooges.com', 'groups': ['cn=NestedGroup,ou=Groups,dc=example,dc=com']},
+        'otherguy': {'dn': 'uid=otherguy,ou=People,dc=example,dc=com', 'username':'otherguy', 'first':'Other', 'last':'Guy', 'email':'other@guy.com'},
+        'posix_person': {'dn': 'uid=posix_person,ou=People,dc=example,dc=com', 'username': 'posix_person', 'first': 'pos', 'last': 'ix', 'email': 'pos@ix.com'},
+        'posix_person2': {'dn': 'uid=posix_person2,ou=People,dc=example,dc=com', 'username': 'posix_person2', 'first': 'pos', 'last': 'ix', 'email': 'pos@ix.com'},
+        'user with space': {'dn': 'uid=user with space,ou=People,dc=example,dc=com', 'username': 'user with space', 'first': 'user', 'last': 'space', 'email': 'user@space.com'},
+        'spaceless': {'dn': 'uid=user without space,ou=People,dc=example,dc=com', 'username': 'spaceless', 'first': 'user', 'last': 'space', 'email': 'user@space.com'},
+        'test_toolongusernametoolongusername': {'dn': 'uid=test_toolongusernametoolongusername,ou=People,dc=example,dc=com', 'username': 'test_toolongusernametoolongusername', 'first': 'toolong', 'last': 'username', 'email': 'toolong@username.com'},
+        'test_longfirstname': {'dn': 'uid=test_longfirstname,ou=People,dc=example,dc=com', 'username': 'test_longfirstname', 'first': 'test_longfirstname_test_longfirstname', 'last': 'username', 'email': 'toolong@username.com'},}
+
+      self.groups = {
+        'TestUsers': {
+          'dn': 'cn=TestUsers,ou=Groups,dc=example,dc=com',
+          'name':'TestUsers',
+          'members':['uid=moe,ou=People,dc=example,dc=com','uid=lårry,ou=People,dc=example,dc=com','uid=curly,ou=People,dc=example,dc=com','uid=test_toolongusernametoolongusername,ou=People,dc=example,dc=com'],
+          'posix_members':[]},
+        'Test Administrators': {
+          'dn': 'cn=Test Administrators,cn=TestUsers,ou=Groups,dc=example,dc=com',
+          'name':'Test Administrators',
+          'members':['uid=Rock,ou=People,dc=example,dc=com','uid=lårry,ou=People,dc=example,dc=com','uid=curly,ou=People,dc=example,dc=com','uid=test_toolongusernametoolongusername,ou=People,dc=example,dc=com'],
+          'posix_members':[]},
+        'OtherGroup': {
+          'dn': 'cn=OtherGroup,cn=TestUsers,ou=Groups,dc=example,dc=com',
+          'name':'OtherGroup',
+          'members':[],
+          'posix_members':[]},
+        'NestedGroups': {
+          'dn': 'cn=NestedGroups,ou=Groups,dc=example,dc=com',
+          'name':'NestedGroups',
+          'members':['cn=NestedGroup,ou=Groups,dc=example,dc=com'],
+          'posix_members':[]
+        },
+        'NestedGroup': {
+          'dn': 'cn=NestedGroup,ou=Groups,dc=example,dc=com',
+          'name':'NestedGroup',
+          'members':['uid=nestedguy,ou=People,dc=example,dc=com'],
+          'posix_members':[]
+        },
+        'NestedPosixGroups': {
+          'dn': 'cn=NestedPosixGroups,ou=Groups,dc=example,dc=com',
+          'name':'NestedPosixGroups',
+          'members':['cn=PosixGroup,ou=Groups,dc=example,dc=com'],
+          'posix_members':[]
+        },
+        'PosixGroup': {
+          'dn': 'cn=PosixGroup,ou=Groups,dc=example,dc=com',
+          'name':'PosixGroup',
+          'members':[],
+          'posix_members':['posix_person','lårry']},
+        'PosixGroup1': {
+          'dn': 'cn=PosixGroup1,cn=PosixGroup,ou=Groups,dc=example,dc=com',
+          'name':'PosixGroup1',
+          'members':[],
+          'posix_members':['posix_person2']},
+        }
 
 
 def test_invalid_username():
@@ -287,11 +289,14 @@ class TestUserAdmin(BaseUserAdminTests):
     # Get ourselves set up with a user and a group with superuser group priv
     cadmin = make_logged_in_client(username="supertest", is_superuser=True)
     Group.objects.create(name="super-test-group")
-    cadmin.post('/useradmin/groups/edit/super-test-group',
-                dict(name="super-test-group",
-                     members=[User.objects.get(username="supertest").pk],
-                     permissions=[HuePermission.objects.get(app='useradmin', action='superuser').pk],
-                     save="Save"), follow=True)
+    cadmin.post('/useradmin/groups/edit/super-test-group', {
+        'name': "super-test-group",
+        'members': [User.objects.get(username="supertest").pk],
+        'permissions': [HuePermission.objects.get(app='useradmin', action='superuser').pk],
+        "save": "Save"
+      },
+      follow=True
+    )
     assert_equal(len(GroupPermission.objects.all()), 2)
 
     supertest = User.objects.get(username="supertest")

+ 4 - 5
apps/useradmin/src/useradmin/views.py

@@ -299,7 +299,8 @@ def edit_user(request, username=None):
     form = form_class(request.POST, instance=instance)
     if is_admin(request.user) and request.user.username != username:
       form.fields.pop("password_old")
-    if form.is_valid(): # All validation rules pass
+
+    if form.is_valid():
       if instance is None:
         instance = form.save()
         get_profile(instance)
@@ -328,10 +329,8 @@ def edit_user(request, username=None):
             if form.instance.is_superuser and not is_admin(request.user):
               raise PopupException(_("You cannot make yourself a superuser."), error_code=401)
 
-          # All ok
           form.save()
 
-          # Unlock account if selected
           if form.cleaned_data.get('unlock_account'):
             if not is_admin(request.user):
               raise PopupException(_('You must be a superuser to reset users.'), error_code=401)
@@ -900,9 +899,9 @@ def _check_remove_last_super(user_obj):
     return
 
   # Is there any other active superuser left?
-  all_active_su = User.objects.filter(is_superuser__exact = True,
-                                      is_active__exact = True)
+  all_active_su = User.objects.filter(is_superuser__exact = True, is_active__exact = True)
   num_active_su = all_active_su.count()
+
   if num_active_su < 1:
     raise PopupException(_("No active superuser configured."))
   if num_active_su == 1:

+ 3 - 6
desktop/core/src/desktop/auth/forms.py

@@ -44,8 +44,9 @@ def get_backend_names():
   return get_backends and [backend.__class__.__name__ for backend in get_backends()]
 
 def is_active_directory():
-  return 'LdapBackend' in get_backend_names() and \
-                          (bool(conf.LDAP.NT_DOMAIN.get()) or bool(conf.LDAP.LDAP_SERVERS.get()) or conf.LDAP.LDAP_URL.get() is not None)
+  return 'LdapBackend' in get_backend_names() and (
+    bool(conf.LDAP.NT_DOMAIN.get()) or bool(conf.LDAP.LDAP_SERVERS.get()) or conf.LDAP.LDAP_URL.get() is not None
+  )
 
 def get_ldap_server_keys():
   return [(ldap_server_record_key) for ldap_server_record_key in conf.LDAP.LDAP_SERVERS.get()]
@@ -143,9 +144,6 @@ class OrganizationAuthenticationForm(Form):
 
     return self.cleaned_data
 
-  # def authenticate(self):
-  #   return super(OrganizationAuthenticationForm, self).clean()
-
   def confirm_login_allowed(self, user):
         """
         Controls whether the given User may log in. This is a policy setting,
@@ -173,7 +171,6 @@ class OrganizationAuthenticationForm(Form):
           params={'email': 'Email'},
       )
 
-
   # def clean(self):
   #   # TODO: checks for inactivity
   #   return self.authenticate()