Browse Source

HUE-950 [core] New Permissions API

Romain Rigaux 12 years ago
parent
commit
890514372d

+ 1 - 5
apps/oozie/src/oozie/tests.py

@@ -16,10 +16,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-try:
-  import json
-except ImportError:
-  import simplejson as json
+import json
 import logging
 import re
 import os
@@ -40,7 +37,6 @@ from liboozie.types import WorkflowList, Workflow as OozieWorkflow, Coordinator
 
 from oozie.models import Workflow, Node, Kill, Link, Job, Coordinator, History,\
   find_parameters, NODE_TYPES, Bundle
-from oozie.conf import SHARE_JOBS
 from oozie.utils import workflow_to_dict, model_to_dict, smart_path
 from oozie.import_workflow import import_workflow
 from oozie.import_jobsub import convert_jobsub_design

+ 57 - 19
desktop/core/src/desktop/models.py

@@ -332,18 +332,26 @@ class Document(models.Model):
       LOG.warn(force_unicode(e))
       return '/static/art/favicon.png'
 
+  def share(self, users, groups, name='read'):
+    DocumentPermission.objects.update(document=self, name=name, users=users, groups=groups, add=True)
 
-class DocumentPermission(models.Model):
-  READ_PERM = 'read'
+  def unshare(self, users, groups, name='read'):
+    DocumentPermission.objects.update(document=self, name=name, users=users, groups=groups, add=False)
 
-  doc = models.ForeignKey(Document)
+  def sync_permissions(self, perms_dict):
+    """
+    Example of input: {'read': {'user_ids': [1, 2, 3], 'group_ids': [1, 2, 3]}}
+    """
+    for name, perm in perms_dict.iteritems():
+      users = groups = None
 
-  users = models.ManyToManyField(auth_models.User, db_index=True)
-  groups = models.ManyToManyField(auth_models.Group, db_index=True)
-  perms = models.TextField(
-      default='read', choices=((READ_PERM, 'read'),),)
+      if perm.get('user_ids'):
+        users = auth_models.User.objects.in_bulk(perm.get('user_ids'))
 
-  #unique_together = ('doc', 'perms')
+      if perm.get('group_ids'):
+        groups = auth_models.Group.objects.in_bulk(perm.get('group_ids'))
+
+      DocumentPermission.objects.sync(document=self, name=name, users=users, groups=groups)
 
 
 class DocumentPermissionManager(models.Manager):
@@ -351,32 +359,62 @@ class DocumentPermissionManager(models.Manager):
   def share_to_default(self, document):
     perm, created = DocumentPermission.objects.get_or_create(doc=document)
     default_group = get_default_user_group()
+
     if default_group:
       perm.groups.add(default_group)
 
+  def update(self, document, name='read', users=None, groups=None, add=True):
+    if name != DocumentPermission.READ_PERM:
+      raise PopupException(_('Only %s permissions is supported, not %s.') % (DocumentPermission.READ_PERM, name))
+
+    perm, created = DocumentPermission.objects.get_or_create(doc=document, perms=name)
+
+    if users is not None:
+      if add:
+        perm.users.add(*users)
+      else:
+        perm.users.remove(*users)
 
-  def update(self, perm=None, perm_id=None, document=None, name=DocumentPermission.READ_PERM, user_ids=None, groups_ids=None):
-    if perm_id is not None:
-      perm = DocumentPermission.objects.get(id=perm_id)
+    if groups is not None:
+      if add:
+        perm.groups.add(*groups)
+      else:
+        perm.groups.remove(*groups)
 
-    if document is not None:
-      perm, created = DocumentPermission.objects.get_or_create(doc=document, perms=name)
+    if not perm.users and not perm.groups:
+      perm.delete()
 
-    if user_ids is not None:
-      users = auth_models.User.objects.in_bulk(user_ids)
+  def sync(self, document, name='read', users=None, groups=None):
+    if name != DocumentPermission.READ_PERM:
+      raise PopupException(_('Only %s permissions is supported, not %s.') % (DocumentPermission.READ_PERM, name))
+
+    perm, created = DocumentPermission.objects.get_or_create(doc=document, perms=name)
+
+    if users is not None:
       perm.users = []
       perm.users = users
 
-    if groups_ids is not None:
-      groups = auth_models.Group.objects.in_bulk(groups_ids)
+    if groups is not None:
       perm.groups = []
       perm.groups = groups
 
     if not perm.users and not perm.groups:
       perm.delete()
 
-# TODO: I think it is fine to load all the users and groups in the form
-# layout like gdoc?
+
+class DocumentPermission(models.Model):
+  READ_PERM = 'read'
+
+  doc = models.ForeignKey(Document)
+
+  users = models.ManyToManyField(auth_models.User, db_index=True)
+  groups = models.ManyToManyField(auth_models.Group, db_index=True)
+  perms = models.TextField(
+      default='read', choices=((READ_PERM, 'read'),),)
+
+
+  objects = DocumentPermissionManager()
+  #unique_together = ('doc', 'perms')
 
 
 # HistoryTable

+ 14 - 6
desktop/core/src/desktop/tests.py

@@ -570,6 +570,7 @@ class TestDocModelTags():
 
 
 class TestDocModelPermissions():
+  
   def setUp(self):
     self.client = make_logged_in_client(username="perm_user")
     self.client_not_me = make_logged_in_client(username="not_perm_user")
@@ -580,10 +581,17 @@ class TestDocModelPermissions():
     grant_access(self.user.username, self.user.username, "desktop")
     grant_access(self.user_not_me.username, self.user_not_me.username, "desktop")        
 
-  def test_add_or_update_permission(self):
-    response = self.client.get("/doc/add_or_update_permission")    
-    assert_equal(-1, json.loads(response.content).status)
+  def add_doc(self, name):
+    script = PigScript.objects.create(owner=self.user)
+    doc = Document.objects.link(script, owner=script.owner, name=name)
+    return script, doc
 
-  def test_remove_permission(self):
-    response = self.client.get("/doc/remove_permission")    
-    assert_equal(-1, json.loads(response.content).status)
+  def test_update_permissions(self):
+    script, doc = self.add_doc('test_update_permissions')
+    
+    response = self.client.post("/doc/update_permissions", {
+        'doc_id': doc.id,
+        'data': json.dumps({'read': {'user_ids': [1, 2], 'group_ids': [1]}})
+    })
+        
+    assert_equal(0, json.loads(response.content)['status'], response.content)

+ 0 - 2
desktop/core/src/desktop/urls.py

@@ -77,8 +77,6 @@ dynamic_patterns += patterns('desktop.views',
   (r'^doc/update_tags$', 'update_tags'),
 
   # Permissions
-  #(r'^doc/add_or_update_permission$', 'add_or_update_permission'),
-  #(r'^doc/remove_permission$', 'remove_permission'),
   (r'^doc/update_permissions', 'update_permissions'),
 
   # Jasmine

+ 22 - 10
desktop/core/src/desktop/views.py

@@ -51,11 +51,11 @@ LOG = logging.getLogger(__name__)
 def home(request):
   docs = Document.objects.get_docs(request.user).order_by('-last_modified')[:100]
   tags = DocumentTag.objects.filter(owner=request.user)
-  
+
   apps = appmanager.get_apps_dict(request.user)
-  
+
   return render('home.mako', request, {
-    'apps': apps,                                       
+    'apps': apps,
     'documents': docs,
     'json_documents': json.dumps(massaged_documents_for_json(docs)),
     'tags': tags,
@@ -125,7 +125,7 @@ def add_tag(request):
 
 def tag(request):
   response = {'status': -1, 'message': ''}
-  
+
   if request.method == 'POST':
     request_json = json.loads(request.POST['data'])
     try:
@@ -136,7 +136,7 @@ def tag(request):
       response['message'] = force_unicode(e)
   else:
     response['message'] = _('POST request only')
-  
+
   return HttpResponse(json.dumps(response), mimetype="application/json")
 
 
@@ -176,11 +176,23 @@ def remove_tags(request):
 
 
 def update_permissions(request):
-  # doc_id or None if no perms yet for this doc
-  # some users [id1, id2...]
-  # some groups [id1, id2...]
-  # type: 'read' for now
-  pass
+  response = {'status': -1, 'message': _('Error')}
+
+  if request.method == 'POST':
+    data = json.loads(request.POST['data'])
+    doc_id = json.loads(request.POST['doc_id'])
+    try:
+      doc = Document.objects.get_doc(doc_id, request.user)
+      # doc.sync_permissions({'read': {'user_ids': [1, 2, 3], 'group_ids': [1, 2, 3]}})
+      doc.sync_permissions(data)
+      response['message'] = _('Permissions updated!')
+      response['status'] = 0
+    except Exception, e:
+      response['message'] = force_unicode(e)
+  else:
+    response['message'] = _('POST request only')
+
+  return HttpResponse(json.dumps(response), mimetype="application/json")
 
 
 @access_log_level(logging.WARN)