Import notes: sync to ws
This commit is contained in:
parent
6f75e008b8
commit
2a1bca883e
|
@ -2,6 +2,7 @@
|
|||
|
||||
## Next
|
||||
* Collaborative editing in project findings and sections
|
||||
* Collaborative editing: update notes list when import new notes
|
||||
* Fix slot data items `.length` property undefined `<list-of-figures>`, `<list-of-tables>` and `<table-of-contents>` components
|
||||
|
||||
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
from .import_export import (
|
||||
export_notes,
|
||||
export_project_types,
|
||||
export_projects,
|
||||
export_templates,
|
||||
import_notes,
|
||||
import_project_types,
|
||||
import_projects,
|
||||
import_templates,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
'export_project_types', 'export_projects', 'export_templates',
|
||||
'import_project_types', 'import_projects', 'import_templates',
|
||||
'export_project_types', 'export_projects', 'export_templates', 'export_notes',
|
||||
'import_project_types', 'import_projects', 'import_templates', 'import_notes',
|
||||
]
|
||||
|
|
|
@ -19,7 +19,10 @@ from reportcreator_api.archive.import_export.serializers import (
|
|||
PentestProjectExportImportSerializer,
|
||||
ProjectTypeExportImportSerializer,
|
||||
)
|
||||
from reportcreator_api.pentests.consumers import send_collab_event_project, send_collab_event_user
|
||||
from reportcreator_api.pentests.models import (
|
||||
CollabEvent,
|
||||
CollabEventType,
|
||||
FindingTemplate,
|
||||
PentestFinding,
|
||||
PentestProject,
|
||||
|
@ -27,8 +30,14 @@ from reportcreator_api.pentests.models import (
|
|||
ProjectNotebookPage,
|
||||
ProjectType,
|
||||
ReportSection,
|
||||
UserNotebookPage,
|
||||
)
|
||||
from reportcreator_api.pentests.serializers.notes import (
|
||||
ProjectNotebookPageSerializer,
|
||||
ProjectNotebookPageSortListSerializer,
|
||||
UserNotebookPageSerializer,
|
||||
UserNotebookPageSortListSerializer,
|
||||
)
|
||||
from reportcreator_api.pentests.models.notes import UserNotebookPage
|
||||
from reportcreator_api.users.models import PentestUser
|
||||
from reportcreator_api.utils.history import history_context
|
||||
|
||||
|
@ -265,5 +274,41 @@ def import_projects(archive_file):
|
|||
def import_notes(archive_file, context):
|
||||
if not context.get('project') and not context.get('user'):
|
||||
raise ValueError('Either project or user must be provided')
|
||||
return import_archive(archive_file, serializer_classes=[NotesExportImportSerializer], context=context)
|
||||
# Import notes to DB
|
||||
notes = import_archive(archive_file, serializer_classes=[NotesExportImportSerializer], context=context)
|
||||
|
||||
# Send collab events
|
||||
sender_options = {
|
||||
'related_object': context['project'],
|
||||
'serializer': ProjectNotebookPageSerializer,
|
||||
'serializer_sort': ProjectNotebookPageSortListSerializer,
|
||||
'send_collab_event': send_collab_event_project,
|
||||
} if context.get('project') else {
|
||||
'related_object': context['user'],
|
||||
'serializer': UserNotebookPageSerializer,
|
||||
'serializer_sort': UserNotebookPageSortListSerializer,
|
||||
'send_collab_event': send_collab_event_user,
|
||||
}
|
||||
|
||||
# Create events
|
||||
events = CollabEvent.objects.bulk_create(
|
||||
CollabEvent(
|
||||
related_id=sender_options['related_object'].id,
|
||||
path=f'notes.{n.note_id}',
|
||||
type=CollabEventType.CREATE,
|
||||
created=n.created,
|
||||
version=n.created.timestamp(),
|
||||
data={
|
||||
'value': sender_options['serializer'](instance=n).data,
|
||||
},
|
||||
) for n in notes
|
||||
)
|
||||
for e in events:
|
||||
sender_options['send_collab_event'](e)
|
||||
|
||||
# Sort event
|
||||
notes_sorted = sender_options['related_object'].notes.select_related('parent').all()
|
||||
sender_options['serializer_sort'](instance=notes_sorted, context=context).send_collab_event(notes_sorted)
|
||||
|
||||
return notes
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ from reportcreator_api.archive.import_export import (
|
|||
import_templates,
|
||||
)
|
||||
from reportcreator_api.archive.import_export.import_export import export_notes, import_notes
|
||||
from reportcreator_api.pentests.consumers import send_collab_event_project
|
||||
from reportcreator_api.pentests.customfields.predefined_fields import FINDING_FIELDS_PREDEFINED
|
||||
from reportcreator_api.pentests.customfields.types import field_definition_to_dict
|
||||
from reportcreator_api.pentests.models import (
|
||||
|
@ -61,6 +62,7 @@ from reportcreator_api.pentests.models import (
|
|||
UploadedTemplateImage,
|
||||
UserPublicKey,
|
||||
)
|
||||
from reportcreator_api.pentests.models.collab import CollabEvent, CollabEventType
|
||||
from reportcreator_api.pentests.permissions import (
|
||||
ArchivedProjectKeyPartPermissions,
|
||||
IsTemplateEditorOrReadOnly,
|
||||
|
|
|
@ -11,8 +11,12 @@ from django.urls import reverse
|
|||
from django.utils import timezone
|
||||
from rest_framework.test import APIClient
|
||||
|
||||
from reportcreator_api.archive.import_export import export_project_types, export_projects, export_templates
|
||||
from reportcreator_api.archive.import_export.import_export import export_notes
|
||||
from reportcreator_api.archive.import_export import (
|
||||
export_notes,
|
||||
export_project_types,
|
||||
export_projects,
|
||||
export_templates,
|
||||
)
|
||||
from reportcreator_api.notifications.models import NotificationSpec, UserNotification
|
||||
from reportcreator_api.pentests.models import (
|
||||
FindingTemplate,
|
||||
|
|
|
@ -10,10 +10,12 @@ from channels.testing import WebsocketCommunicator
|
|||
from django.conf import settings
|
||||
from django.contrib.auth import BACKEND_SESSION_KEY, HASH_SESSION_KEY, SESSION_KEY
|
||||
from django.contrib.auth.models import AnonymousUser
|
||||
from django.core.files.base import ContentFile
|
||||
from django.core.serializers.json import DjangoJSONEncoder
|
||||
from django.urls import reverse
|
||||
from django.utils.module_loading import import_string
|
||||
|
||||
from reportcreator_api.archive.import_export import export_notes
|
||||
from reportcreator_api.conf.asgi import application
|
||||
from reportcreator_api.pentests.customfields.utils import (
|
||||
ensure_defined_structure,
|
||||
|
@ -451,6 +453,20 @@ class TestProjectNotesDbSync:
|
|||
data=[{'id': self.note.note_id, 'order': 1, 'parent': None}])
|
||||
await self.assert_event({'type': CollabEventType.SORT, 'path': 'notes', 'client_id': None, 'sort': res.data})
|
||||
|
||||
async def test_import_sync(self):
|
||||
def import_notes():
|
||||
res = self.api_client1.post(
|
||||
path=reverse('projectnotebookpage-import', kwargs={'project_pk': self.project.id}),
|
||||
data={'file': ContentFile(content=b''.join(export_notes(self.project)), name='export.tar.gz')},
|
||||
format='multipart',
|
||||
)
|
||||
return res.data
|
||||
notes_imported = await sync_to_async(import_notes)()
|
||||
|
||||
for n in notes_imported:
|
||||
await self.assert_event({'type': CollabEventType.CREATE, 'path': f'notes.{n["id"]}', 'value': n, 'client_id': None})
|
||||
await self.assert_event({'type': CollabEventType.SORT, 'path': 'notes', 'client_id': None})
|
||||
|
||||
async def test_member_removed_write(self):
|
||||
await ProjectMemberInfo.objects.filter(project=self.project, user=self.user1).adelete()
|
||||
|
||||
|
|
Loading…
Reference in New Issue