Browse Source

HUE-12. Drop down box to select user for chown

bc Wong 15 năm trước cách đây
mục cha
commit
86c623dc9a

+ 9 - 0
apps/filebrowser/src/filebrowser/forms.py

@@ -20,6 +20,7 @@ from django.forms import FileField, CharField, BooleanField, Textarea
 
 from filebrowser.lib import rwx
 from hadoop.fs import normpath
+from django.contrib.auth.models import User, Group
 
 import logging
 logger = logging.getLogger(__name__)
@@ -70,7 +71,15 @@ class ChownForm(forms.Form):
   # These could be "ChoiceFields", listing only users and groups
   # that the current user has permissions for.
   user = CharField(label="User", min_length=1)
+  user_other = CharField(label="OtherUser", min_length=1, required=False)
   group = CharField(label="Group", min_length=1)
+  group_other = CharField(label="OtherGroup", min_length=1, required=False)
+
+  def __init__(self, *args, **kwargs):
+    super(ChownForm, self).__init__(*args, **kwargs)
+
+    self.all_groups = [ group.name for group in Group.objects.all() ]
+    self.all_users = [ user.username for user in User.objects.all() ]
 
 class ChmodForm(forms.Form):
   op = "chmod"

+ 37 - 2
apps/filebrowser/src/filebrowser/templates/chown.mako

@@ -16,14 +16,49 @@
 <%namespace name="edit" file="editor_components.mako" />
 <%namespace name="comps" file="fb_components.mako" />
 ${comps.header('Change Owner / Group: ' + path.split('/')[-1])}
+<%! from desktop.lib.django_util import extract_field_data %>
+
+## Puts together a selection list with an "other" field as well.
+<%def name="selection(name, choices, current_value, other_key)">
+    <% seen = False %>
+    % if len(choices) == 0:
+      <select name="${name}" class="ccs-hidden">
+    % else:
+      <select name="${name}">
+    % endif
+    % for choice in choices:
+      % if choice == current_value:
+        <% seen = True %>
+        <option selected>${choice}</option>
+      % else:
+        <option>${choice}</option>
+      % endif
+    % endfor
+    % if seen or not current_value:
+      <option value="__other__">Other</option>
+    % else:
+      <option value="__other__" selected="true">Other</option>
+    % endif
+
+    </select>
+    % if seen or not current_value:
+      <input name="${other_key}" class="ccs-hidden">
+    % else:
+      <input name="${other_key}" value="${current_value}">
+    % endif
+</%def>
+
 
 <div class="prompt_popup">
 <form action="/filebrowser/chown?next=${next|u}" method="POST" enctype="multipart/form-data">
   <h4 class="ccs-hidden">Change Owner / Group: ${path}</h4>
   <dl class="fb-side-by-side">
     ${edit.render_field(form["path"], hidden=True)}
-    ${edit.render_field(form["user"])}
-    ${edit.render_field(form["group"])}
+
+    <dt><label>User</label></dt>
+    <dd class="ccs-select-with-other">${ selection("user", form.all_users, extract_field_data(form["user"]), "user_other") }</dd>
+    <dt><label>Group</label></dt>
+    <dd class="ccs-select-with-other">${ selection("group", form.all_groups, extract_field_data(form["group"]), "group_other") }</dd>
   </dl>
   <input class="ccs-hidden" type="submit" value="Submit" />
 </form>

+ 10 - 1
apps/filebrowser/src/filebrowser/views.py

@@ -591,7 +591,16 @@ def chmod(request):
   return generic_op(ChmodForm, request, request.fs.chmod, ["path", "mode"], "path", template="chmod.mako")
 
 def chown(request):
-  return generic_op(ChownForm, request, request.fs.chown, ["path", "user", "group"], "path", template="chown.mako")
+  # This is a bit clever: generic_op takes an argument (here, args), indicating
+  # which POST parameters to pick out and pass to the given function.
+  # We update that mapping based on whether or not the user selected "other".
+  args = [ "path", "user", "group" ]
+  if request.POST.get("user") == "__other__":
+    args[1] = "user_other"
+  if request.POST.get("group") == "__other__":
+    args[2] = "group_other"
+
+  return generic_op(ChownForm, request, request.fs.chown, args, "path", template="chown.mako")
 
 def upload_flash(request):
   """

+ 19 - 0
apps/filebrowser/src/filebrowser/views_test.py

@@ -25,6 +25,25 @@ import logging
 
 LOG = logging.getLogger(__name__)
 
+@attr('requires_hadoop')
+def test_chown():
+  cluster = mini_cluster.shared_cluster(conf=True)
+  try:
+    # Only the Hadoop superuser really has carte blanche here
+    c = make_logged_in_client(cluster.superuser)
+    cluster.fs.setuser(cluster.superuser)
+
+    PATH = "/test-chown"
+    cluster.fs.mkdir(PATH)
+    c.post("/filebrowser/chown", dict(path=PATH, user="x", group="y"))
+    assert_equal("x", cluster.fs.stats(PATH)["user"])
+    assert_equal("y", cluster.fs.stats(PATH)["group"])
+    c.post("/filebrowser/chown", dict(path=PATH, user="__other__", user_other="z", group="y"))
+    assert_equal("z", cluster.fs.stats(PATH)["user"])
+
+  finally:
+    cluster.shutdown()
+
 @attr('requires_hadoop')
 def test_listdir():
   cluster = mini_cluster.shared_cluster(conf=True)