Эх сурвалжийг харах

HUE-8530 [organization] Support for Edit user page

Romain 6 жил өмнө
parent
commit
d334cc2af8

+ 36 - 2
apps/useradmin/src/useradmin/forms.py

@@ -125,7 +125,7 @@ class UserChangeForm(django.contrib.auth.forms.UserChangeForm):
   def __init__(self, *args, **kwargs):
   def __init__(self, *args, **kwargs):
     super(UserChangeForm, self).__init__(*args, **kwargs)
     super(UserChangeForm, self).__init__(*args, **kwargs)
 
 
-    if self.instance.id:
+    if self.instance.id and 'username' in self.fields:
       self.fields['username'].widget.attrs['readonly'] = True
       self.fields['username'].widget.attrs['readonly'] = True
 
 
     if 'desktop.auth.backend.LdapBackend' in desktop_conf.AUTH.BACKEND.get():
     if 'desktop.auth.backend.LdapBackend' in desktop_conf.AUTH.BACKEND.get():
@@ -148,7 +148,6 @@ class UserChangeForm(django.contrib.auth.forms.UserChangeForm):
     username = self.cleaned_data["username"]
     username = self.cleaned_data["username"]
     if self.instance.username == username:
     if self.instance.username == username:
       return username
       return username
-
     try:
     try:
       User._default_manager.get(username=username)
       User._default_manager.get(username=username)
     except User.DoesNotExist:
     except User.DoesNotExist:
@@ -193,6 +192,24 @@ class UserChangeForm(django.contrib.auth.forms.UserChangeForm):
     return user
     return user
 
 
 
 
+class OrganizationUserChangeForm(UserChangeForm):
+  username = None
+  email = forms.CharField(
+      label=_t("Email"),
+      widget=forms.TextInput(attrs={'maxlength': 150, 'placeholder': _t("Email"), 'autocomplete': 'off', 'autofocus': 'autofocus'})
+  )
+
+  class Meta(django.contrib.auth.forms.UserChangeForm.Meta):
+    model =  User
+    fields = ["first_name", "last_name", "email", "ensure_home_directory"]
+
+  def __init__(self, *args, **kwargs):
+    super(OrganizationUserChangeForm, self).__init__(*args, **kwargs)
+
+    if self.instance.id:
+      self.fields['email'].widget.attrs['readonly'] = True
+
+
 class PasswordChangeForm(UserChangeForm):
 class PasswordChangeForm(UserChangeForm):
   """
   """
   This inherits from UserChangeForm to allow for forced password change on first login
   This inherits from UserChangeForm to allow for forced password change on first login
@@ -222,6 +239,23 @@ class SuperUserChangeForm(UserChangeForm):
       else:
       else:
         self.initial['groups'] = []
         self.initial['groups'] = []
 
 
+class OrganizationSuperUserChangeForm(OrganizationUserChangeForm):
+  class Meta(UserChangeForm.Meta):
+    fields = ["email", "is_active"] + OrganizationUserChangeForm.Meta.fields + ["is_superuser", "unlock_account", "groups"]
+
+  def __init__(self, *args, **kwargs):
+    super(OrganizationSuperUserChangeForm, self).__init__(*args, **kwargs)
+    if self.instance.id:
+      # If the user exists already, we'll use its current group memberships
+      self.initial['groups'] = set(self.instance.groups.all())
+    else:
+      # If his is a new user, suggest the default group
+      default_group = get_default_user_group()
+      if default_group is not None:
+        self.initial['groups'] = set([default_group])
+      else:
+        self.initial['groups'] = []
+
 
 
 class AddLdapUsersForm(forms.Form):
 class AddLdapUsersForm(forms.Form):
   username_pattern = forms.CharField(
   username_pattern = forms.CharField(

+ 17 - 9
apps/useradmin/src/useradmin/templates/edit_user.mako

@@ -16,18 +16,19 @@
 <%!
 <%!
 from django.utils.translation import ugettext as _
 from django.utils.translation import ugettext as _
 
 
+from desktop.auth.backend import is_admin
+from desktop.conf import ENABLE_ORGANIZATIONS
 from desktop.views import commonheader, commonfooter
 from desktop.views import commonheader, commonfooter
 
 
 from useradmin.hue_password_policy import is_password_policy_enabled, get_password_hint
 from useradmin.hue_password_policy import is_password_policy_enabled, get_password_hint
 from useradmin.views import is_user_locked_out
 from useradmin.views import is_user_locked_out
-from desktop.auth.backend import is_admin
 %>
 %>
 
 
 <%namespace name="layout" file="layout.mako" />
 <%namespace name="layout" file="layout.mako" />
 
 
-%if not is_embeddable:
+% if not is_embeddable:
 ${ commonheader(_('Hue Users'), "useradmin", user, request) | n,unicode }
 ${ commonheader(_('Hue Users'), "useradmin", user, request) | n,unicode }
-%endif
+% endif
 
 
 ${ layout.menubar(section='users') }
 ${ layout.menubar(section='users') }
 
 
@@ -56,21 +57,26 @@ ${ layout.menubar(section='users') }
         <li><a href="javascript:void(0)" class="step" data-step="step2">${ is_admin(user) and _('Step 2: Profile and Groups') or _('Step 2: Profile') }</a>
         <li><a href="javascript:void(0)" class="step" data-step="step2">${ is_admin(user) and _('Step 2: Profile and Groups') or _('Step 2: Profile') }</a>
         </li>
         </li>
         % if is_admin(user):
         % if is_admin(user):
-            <li><a href="javascript:void(0)" class="step" data-step="step3">${ _('Step 3: Advanced') }</a></li>
+          <li><a href="javascript:void(0)" class="step" data-step="step3">${ _('Step 3: Advanced') }</a></li>
         % endif
         % endif
       </ul>
       </ul>
 
 
     <div class="steps">
     <div class="steps">
       <div id="step1" class="stepDetails">
       <div id="step1" class="stepDetails">
-        ${layout.render_field(form["username"], extra_attrs={'validate':'true'})}
+        % if ENABLE_ORGANIZATIONS.get():
+          ${ layout.render_field(form["email"], extra_attrs={'validate':'true'}) }
+        % else:
+          ${ layout.render_field(form["username"], extra_attrs={'validate':'true'}) }
+        % endif
+
         % if "password1" in form.fields:
         % if "password1" in form.fields:
           % if username and "password_old" in form.fields:
           % if username and "password_old" in form.fields:
-            ${layout.render_field(form["password_old"], extra_attrs=username is None and {'validate':'true'} or {})}
+            ${ layout.render_field(form["password_old"], extra_attrs=username is None and {'validate':'true'} or {}) }
           % endif
           % endif
-          ${layout.render_field(form["password1"], extra_attrs=username is None and {'validate':'true'} or {})}
+          ${ layout.render_field(form["password1"], extra_attrs=username is None and {'validate':'true'} or {}) }
           % if is_password_policy_enabled():
           % if is_password_policy_enabled():
             <div class="password_rule" style="margin-left:180px; width:500px;">
             <div class="password_rule" style="margin-left:180px; width:500px;">
-              <p>${get_password_hint()}</p>
+              <p>${ get_password_hint() }</p>
             </div>
             </div>
           % endif
           % endif
           ${layout.render_field(form["password2"], extra_attrs=username is None and {'validate':'true'} or {})}
           ${layout.render_field(form["password2"], extra_attrs=username is None and {'validate':'true'} or {})}
@@ -83,7 +89,9 @@ ${ layout.menubar(section='users') }
             ${layout.render_field(form["last_name"])}
             ${layout.render_field(form["last_name"])}
           % endif
           % endif
 
 
-          ${layout.render_field(form["email"])}
+          % if not ENABLE_ORGANIZATIONS.get():
+            ${layout.render_field(form["email"])}
+          % endif
 
 
           %if request.user.username == username:
           %if request.user.username == username:
             ${layout.render_field(form["language"])}
             ${layout.render_field(form["language"])}

+ 17 - 13
apps/useradmin/src/useradmin/views.py

@@ -25,7 +25,6 @@ import subprocess
 import sys
 import sys
 import json
 import json
 
 
-
 from axes.decorators import FAILURE_LIMIT, LOCK_OUT_AT_FAILURE
 from axes.decorators import FAILURE_LIMIT, LOCK_OUT_AT_FAILURE
 from axes.models import AccessAttempt
 from axes.models import AccessAttempt
 from axes.utils import reset
 from axes.utils import reset
@@ -49,12 +48,12 @@ from desktop.views import antixss
 from hadoop.fs.exceptions import WebHdfsException
 from hadoop.fs.exceptions import WebHdfsException
 
 
 from useradmin import ldap_access
 from useradmin import ldap_access
+from useradmin.forms import SyncLdapUsersGroupsForm, AddLdapGroupsForm, AddLdapUsersForm,\
+  PermissionsEditForm, GroupEditForm, SuperUserChangeForm, UserChangeForm, validate_username, validate_first_name, \
+  validate_last_name, PasswordChangeForm, OrganizationUserChangeForm, OrganizationSuperUserChangeForm
 from useradmin.ldap_access import LdapBindException, LdapSearchException
 from useradmin.ldap_access import LdapBindException, LdapSearchException
 from useradmin.models import HuePermission, UserProfile, LdapGroup
 from useradmin.models import HuePermission, UserProfile, LdapGroup
 from useradmin.models import get_profile, get_default_user_group
 from useradmin.models import get_profile, get_default_user_group
-from useradmin.forms import SyncLdapUsersGroupsForm, AddLdapGroupsForm, AddLdapUsersForm,\
-  PermissionsEditForm, GroupEditForm, SuperUserChangeForm, UserChangeForm, validate_username, validate_first_name, \
-  validate_last_name, PasswordChangeForm
 
 
 if sys.version_info[0] > 2:
 if sys.version_info[0] > 2:
   unicode = str
   unicode = str
@@ -74,8 +73,8 @@ __groups_lock = threading.Lock()
 def is_ldap_setup():
 def is_ldap_setup():
   return bool(LDAP.LDAP_SERVERS.get()) or LDAP.LDAP_URL.get() is not None
   return bool(LDAP.LDAP_SERVERS.get()) or LDAP.LDAP_URL.get() is not None
 
 
-def list_users(request):
 
 
+def list_users(request):
   return render("list_users.mako", request, {
   return render("list_users.mako", request, {
       'users': User.objects.all(),
       'users': User.objects.all(),
       'users_json': json.dumps(list(User.objects.values_list('id', flat=True))),
       'users_json': json.dumps(list(User.objects.values_list('id', flat=True))),
@@ -86,7 +85,6 @@ def list_users(request):
 
 
 
 
 def list_groups(request):
 def list_groups(request):
-
   return render("list_groups.mako", request, {
   return render("list_groups.mako", request, {
       'groups': Group.objects.all(),
       'groups': Group.objects.all(),
       'groups_json': json.dumps(list(Group.objects.values_list('name', flat=True))),
       'groups_json': json.dumps(list(Group.objects.values_list('name', flat=True))),
@@ -139,6 +137,7 @@ def list_for_autocomplete(request):
   }
   }
   return JsonResponse(response)
   return JsonResponse(response)
 
 
+
 def get_users_by_id(request):
 def get_users_by_id(request):
   userids = json.loads(request.GET.get('userids', "[]"))
   userids = json.loads(request.GET.get('userids', "[]"))
   userids = userids[:100]
   userids = userids[:100]
@@ -148,6 +147,7 @@ def get_users_by_id(request):
   }
   }
   return JsonResponse(response)
   return JsonResponse(response)
 
 
+
 def massage_users_for_json(users, extended=False):
 def massage_users_for_json(users, extended=False):
   simple_users = []
   simple_users = []
   for user in users:
   for user in users:
@@ -220,7 +220,6 @@ def delete_user(request):
     return redirect(reverse(list_users))
     return redirect(reverse(list_users))
 
 
 
 
-
 def delete_group(request):
 def delete_group(request):
   if not is_admin(request.user):
   if not is_admin(request.user):
     request.audit = {
     request.audit = {
@@ -288,16 +287,17 @@ def edit_user(request, username=None):
   is_embeddable = request.GET.get('is_embeddable', request.POST.get('is_embeddable', False))
   is_embeddable = request.GET.get('is_embeddable', request.POST.get('is_embeddable', False))
 
 
   if username is not None:
   if username is not None:
-    instance = User.objects.get(username=username)
+    lookup = {'email': username} if ENABLE_ORGANIZATIONS.get() else {'username': username}
+    instance = User.objects.get(**lookup)
   else:
   else:
     instance = None
     instance = None
 
 
   if require_change_password(userprofile):
   if require_change_password(userprofile):
     form_class = PasswordChangeForm
     form_class = PasswordChangeForm
   elif is_admin(request.user):
   elif is_admin(request.user):
-    form_class = SuperUserChangeForm
+    form_class = OrganizationSuperUserChangeForm if ENABLE_ORGANIZATIONS.get() else SuperUserChangeForm
   else:
   else:
-    form_class = UserChangeForm
+    form_class = OrganizationUserChangeForm if ENABLE_ORGANIZATIONS.get() else UserChangeForm
 
 
   if request.method == 'POST':
   if request.method == 'POST':
     form = form_class(request.POST, instance=instance)
     form = form_class(request.POST, instance=instance)
@@ -313,14 +313,18 @@ def edit_user(request, username=None):
         if request.user.username == username and not form.instance.is_active:
         if request.user.username == username and not form.instance.is_active:
           raise PopupException(_("You cannot make yourself inactive."), error_code=401)
           raise PopupException(_("You cannot make yourself inactive."), error_code=401)
 
 
-        # user changing his own information, form.changed_data=['ensure_home_directory', 'language'] or changing information about another user, form.changed_data=['ensure_home_directory']
-        updated = (request.user.username == username and len(form.changed_data) > 2) or (request.user.username != username and len(form.changed_data) > 1)
+        # user changing his own information, form.changed_data=['ensure_home_directory', 'language']
+        # or changing information about another user, form.changed_data=['ensure_home_directory']
+        updated = (
+          request.user.username == username and len(form.changed_data) > 2) or (
+          request.user.username != username and len(form.changed_data) > 1
+        )
 
 
         global __users_lock
         global __users_lock
         __users_lock.acquire()
         __users_lock.acquire()
         try:
         try:
           # form.instance (and instance) now carry the new data
           # form.instance (and instance) now carry the new data
-          orig = User.objects.get(username=username)
+          orig = User.objects.get(**lookup)
           if orig.is_superuser:
           if orig.is_superuser:
             if not form.instance.is_superuser or not form.instance.is_active:
             if not form.instance.is_superuser or not form.instance.is_active:
               _check_remove_last_super(orig)
               _check_remove_last_super(orig)