Parcourir la source

Disable ability to create empty revision from webdav and webui

Guénaël Muller il y a 6 ans
Parent
révision
20d598ea5e

+ 39 - 35
tracim/tracim/controllers/content.py Voir le fichier

@@ -174,7 +174,7 @@ class UserWorkspaceFolderFileRestController(TIMWorkspaceContentRestController):
174 174
 
175 175
     @property
176 176
     def _err_url(self):
177
-        return tg.url('/dashboard/workspaces/{}/folders/{}/file/{}')
177
+        return tg.url('/workspaces/{}/folders/{}/files/{}')
178 178
 
179 179
     @property
180 180
     def _item_type(self):
@@ -376,19 +376,13 @@ class UserWorkspaceFolderFileRestController(TIMWorkspaceContentRestController):
376 376
         try:
377 377
             api = ContentApi(tmpl_context.current_user)
378 378
             item = api.get_one(int(item_id), self._item_type, workspace)
379
-            label_changed = False
380
-            if label is not None and label != item.label:
381
-                label_changed = True
382
-
383
-            if label is None:
384
-                label = ''
385
-
386
-            # TODO - D.A. - 2015-03-19
387
-            # refactor this method in order to make code easier to understand
388 379
 
389 380
             with new_revision(item):
381
+                if label:
382
+                    # This case is the default "file title and description
383
+                    # update" In this case the file itself is not revisionned
390 384
 
391
-                if (comment and label) or (not comment and label_changed):
385
+                    # Update description and label
392 386
                     updated_item = api.update_content(
393 387
                         item, label if label else item.label,
394 388
                         comment if comment else ''
@@ -401,31 +395,21 @@ class UserWorkspaceFolderFileRestController(TIMWorkspaceContentRestController):
401 395
                         return render_invalid_integrity_chosen_path(
402 396
                             updated_item.get_label_as_file(),
403 397
                         )
404
-
405 398
                     api.save(updated_item, ActionDescription.EDITION)
406
-
407
-                    # This case is the default "file title and description
408
-                    # update" In this case the file itself is not revisionned
409
-
410 399
                 else:
411 400
                     # So, now we may have a comment and/or a file revision
412
-                    if comment and '' == label:
413
-                        comment_item = api.create_comment(workspace,
414
-                                                          item, comment,
415
-                                                          do_save=False)
416
-
417
-                        if not isinstance(file_data, FieldStorage):
418
-                            api.save(comment_item, ActionDescription.COMMENT)
419
-                        else:
420
-                            # The notification is only sent
421
-                            # if the file is NOT updated
422
-                            #
423
-                            # If the file is also updated,
424
-                            # then a 'file revision' notification will be sent.
425
-                            api.save(comment_item,
426
-                                     ActionDescription.COMMENT,
427
-                                     do_notify=False)
401
+                    comment_item = None
402
+                    file_revision = None
428 403
 
404
+                    # INFO - G.M - 20/03/2018 - Add new comment
405
+                    if comment:
406
+                        comment_item = api.create_comment(
407
+                            workspace,
408
+                            item,
409
+                            comment,
410
+                            do_save=False
411
+                        )
412
+                    # INFO - G.M - 20/03/2018 - Add new file-revision
429 413
                     if isinstance(file_data, FieldStorage):
430 414
                         api.update_file_data(item,
431 415
                                              file_data.filename,
@@ -440,8 +424,20 @@ class UserWorkspaceFolderFileRestController(TIMWorkspaceContentRestController):
440 424
                             return render_invalid_integrity_chosen_path(
441 425
                                 item.get_label_as_file(),
442 426
                             )
443
-
427
+                        file_revision = True
428
+
429
+                    # INFO - G.M - 20/03/2018 - Save revision/comment
430
+                    if comment_item and file_revision:
431
+                        api.save(
432
+                            comment_item,
433
+                            ActionDescription.COMMENT,
434
+                            do_notify= False
435
+                        )
436
+                        api.save(item, ActionDescription.REVISION)
437
+                    elif file_revision:
444 438
                         api.save(item, ActionDescription.REVISION)
439
+                    elif comment_item:
440
+                        api.save(comment_item, ActionDescription.COMMENT)
445 441
 
446 442
             msg = _('{} updated').format(self._item_type_label)
447 443
             tg.flash(msg, CST.STATUS_OK)
@@ -449,6 +445,14 @@ class UserWorkspaceFolderFileRestController(TIMWorkspaceContentRestController):
449 445
                                              tmpl_context.folder_id,
450 446
                                              item.content_id))
451 447
 
448
+        except SameValueError:
449
+            not_updated = '{} not updated: the content did not change'
450
+            msg = _(not_updated).format(self._item_type_label)
451
+            tg.flash(msg, CST.STATUS_WARNING)
452
+            tg.redirect(self._err_url.format(tmpl_context.workspace_id,
453
+                                             tmpl_context.folder_id,
454
+                                             item_id))
455
+
452 456
         except ValueError as e:
453 457
             error = '{} not updated - error: {}'
454 458
             msg = _(error).format(self._item_type_label,
@@ -459,6 +463,7 @@ class UserWorkspaceFolderFileRestController(TIMWorkspaceContentRestController):
459 463
                                              item_id))
460 464
 
461 465
 
466
+
462 467
 class UserWorkspaceFolderPageRestController(TIMWorkspaceContentRestController):
463 468
     """
464 469
     manage a path like this: /workspaces/1/folders/XXX/pages/4
@@ -606,7 +611,7 @@ class UserWorkspaceFolderPageRestController(TIMWorkspaceContentRestController):
606 611
             tg.redirect(self._std_url.format(tmpl_context.workspace_id,
607 612
                                              tmpl_context.folder_id,
608 613
                                              item.content_id))
609
-        except SameValueError as e:
614
+        except SameValueError:
610 615
             not_updated = '{} not updated: the content did not change'
611 616
             msg = _(not_updated).format(self._item_type_label)
612 617
             tg.flash(msg, CST.STATUS_WARNING)
@@ -621,7 +626,6 @@ class UserWorkspaceFolderPageRestController(TIMWorkspaceContentRestController):
621 626
                                              tmpl_context.folder_id,
622 627
                                              item_id))
623 628
 
624
-
625 629
 class UserWorkspaceFolderThreadRestController(TIMWorkspaceContentRestController):
626 630
     """
627 631
     manage a path like this: /workspaces/1/folders/XXX/pages/4

+ 6 - 1
tracim/tracim/lib/content.py Voir le fichier

@@ -920,7 +920,9 @@ class ContentApi(object):
920 920
 
921 921
     def update_content(self, item: Content, new_label: str, new_content: str=None) -> Content:
922 922
         if item.label==new_label and item.description==new_content:
923
-            raise SameValueError(_('The content did not changed'))
923
+            # TODO - G.M - 20-03-2018 - Fix internatization for webdav access.
924
+            # Internatization disabled in libcontent for now.
925
+            raise SameValueError('The content did not changed')
924 926
         item.owner = self._user
925 927
         item.label = new_label
926 928
         item.description = new_content if new_content else item.description # TODO: convert urls into links
@@ -928,6 +930,9 @@ class ContentApi(object):
928 930
         return item
929 931
 
930 932
     def update_file_data(self, item: Content, new_filename: str, new_mimetype: str, new_content: bytes) -> Content:
933
+        if new_mimetype == item.file_mimetype and \
934
+                new_content == item.depot_file.file.read():
935
+            raise SameValueError('The content did not changed')
931 936
         item.owner = self._user
932 937
         item.file_name = new_filename
933 938
         item.file_mimetype = new_mimetype

+ 16 - 7
tracim/tracim/lib/webdav/__init__.py Voir le fichier

@@ -5,11 +5,13 @@ from wsgidav import util
5 5
 from wsgidav import compat
6 6
 
7 7
 from tracim.lib.content import ContentApi
8
+from tracim.lib.utils import SameValueError
8 9
 from tracim.model import new_revision
9 10
 from tracim.model.data import ActionDescription
10 11
 from tracim.model.data import ContentType
11 12
 from tracim.model.data import Content
12 13
 from tracim.model.data import Workspace
14
+from wsgidav.dav_error import DAVError, HTTP_FORBIDDEN, HTTP_NOT_MODIFIED
13 15
 
14 16
 
15 17
 class HistoryType(object):
@@ -96,12 +98,20 @@ class FakeFileStream(object):
96 98
 
97 99
         self._file_stream.seek(0)
98 100
 
99
-        if self._content is None:
100
-            self.create_file()
101
-        else:
102
-            self.update_file()
103
-
104
-        transaction.commit()
101
+        try:
102
+            if self._content is None:
103
+                self.create_file()
104
+            else:
105
+                self.update_file()
106
+            transaction.commit()
107
+        except SameValueError:
108
+            transaction.abort()
109
+            transaction.begin()
110
+            raise DAVError(HTTP_NOT_MODIFIED)
111
+        except ValueError:
112
+            transaction.abort()
113
+            transaction.begin()
114
+            raise DAVError(HTTP_FORBIDDEN)
105 115
 
106 116
     def create_file(self):
107 117
         """
@@ -138,5 +148,4 @@ class FakeFileStream(object):
138 148
                 util.guessMimeType(self._content.file_name),
139 149
                 self._file_stream.read()
140 150
             )
141
-
142 151
             self._api.save(self._content, ActionDescription.REVISION)

+ 9 - 1
tracim/tracim/model/__init__.py Voir le fichier

@@ -8,7 +8,8 @@ from sqlalchemy.orm.unitofwork import UOWTransaction
8 8
 from zope.sqlalchemy import ZopeTransactionExtension
9 9
 
10 10
 from tracim.lib.exception import ContentRevisionUpdateError, ContentRevisionDeleteError
11
-
11
+from tracim.lib.utils import SameValueError
12
+import transaction
12 13
 
13 14
 class RevisionsIntegrity(object):
14 15
     """
@@ -136,5 +137,12 @@ def new_revision(
136 137
                 content.new_revision()
137 138
             RevisionsIntegrity.add_to_updatable(content.revision)
138 139
             yield content
140
+        except SameValueError or ValueError as e:
141
+            # INFO - 20-03-2018 - renew transaction when error happened
142
+            # This avoid bad session data like new "temporary" revision
143
+            # to be add when problem happen.
144
+            transaction.abort()
145
+            transaction.begin()
146
+            raise e
139 147
         finally:
140 148
             RevisionsIntegrity.remove_from_updatable(content.revision)