html_document_controller.py 8.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. # coding=utf-8
  2. import typing
  3. import transaction
  4. from pyramid.config import Configurator
  5. from tracim.models.data import UserRoleInWorkspace
  6. try: # Python 3.5+
  7. from http import HTTPStatus
  8. except ImportError:
  9. from http import client as HTTPStatus
  10. from tracim import TracimRequest
  11. from tracim.extensions import hapic
  12. from tracim.lib.core.content import ContentApi
  13. from tracim.views.controllers import Controller
  14. from tracim.views.core_api.schemas import HtmlDocumentContentSchema
  15. from tracim.views.core_api.schemas import HtmlDocumentRevisionSchema
  16. from tracim.views.core_api.schemas import SetContentStatusSchema
  17. from tracim.views.core_api.schemas import HtmlDocumentModifySchema
  18. from tracim.views.core_api.schemas import WorkspaceAndContentIdPathSchema
  19. from tracim.views.core_api.schemas import NoContentSchema
  20. from tracim.lib.utils.authorization import require_content_types
  21. from tracim.lib.utils.authorization import require_workspace_role
  22. from tracim.exceptions import WorkspaceNotFound
  23. from tracim.exceptions import ContentTypeNotAllowed
  24. from tracim.exceptions import InsufficientUserWorkspaceRole
  25. from tracim.exceptions import NotAuthenticated
  26. from tracim.exceptions import AuthenticationFailed
  27. from tracim.models.context_models import ContentInContext
  28. from tracim.models.context_models import RevisionInContext
  29. from tracim.models.contents import ContentTypeLegacy as ContentType
  30. from tracim.models.contents import html_documents_type
  31. from tracim.models.revision_protection import new_revision
  32. HTML_DOCUMENT_ENDPOINTS_TAG = 'HTML documents'
  33. class HTMLDocumentController(Controller):
  34. @hapic.with_api_doc(tags=[HTML_DOCUMENT_ENDPOINTS_TAG])
  35. @hapic.handle_exception(NotAuthenticated, HTTPStatus.UNAUTHORIZED)
  36. @hapic.handle_exception(InsufficientUserWorkspaceRole, HTTPStatus.FORBIDDEN)
  37. @hapic.handle_exception(WorkspaceNotFound, HTTPStatus.FORBIDDEN)
  38. @hapic.handle_exception(AuthenticationFailed, HTTPStatus.FORBIDDEN)
  39. @hapic.handle_exception(ContentTypeNotAllowed, HTTPStatus.BAD_REQUEST)
  40. @require_workspace_role(UserRoleInWorkspace.READER)
  41. @require_content_types([html_documents_type])
  42. @hapic.input_path(WorkspaceAndContentIdPathSchema())
  43. @hapic.output_body(HtmlDocumentContentSchema())
  44. def get_html_document(self, context, request: TracimRequest, hapic_data=None) -> ContentInContext: # nopep8
  45. """
  46. Get html document content
  47. """
  48. app_config = request.registry.settings['CFG']
  49. api = ContentApi(
  50. current_user=request.current_user,
  51. session=request.dbsession,
  52. config=app_config,
  53. )
  54. content = api.get_one(
  55. hapic_data.path.content_id,
  56. content_type=ContentType.Any
  57. )
  58. return api.get_content_in_context(content)
  59. @hapic.with_api_doc(tags=[HTML_DOCUMENT_ENDPOINTS_TAG])
  60. @hapic.handle_exception(NotAuthenticated, HTTPStatus.UNAUTHORIZED)
  61. @hapic.handle_exception(InsufficientUserWorkspaceRole, HTTPStatus.FORBIDDEN)
  62. @hapic.handle_exception(WorkspaceNotFound, HTTPStatus.FORBIDDEN)
  63. @hapic.handle_exception(AuthenticationFailed, HTTPStatus.FORBIDDEN)
  64. @require_workspace_role(UserRoleInWorkspace.CONTRIBUTOR)
  65. @require_content_types([html_documents_type])
  66. @hapic.input_path(WorkspaceAndContentIdPathSchema())
  67. @hapic.input_body(HtmlDocumentModifySchema())
  68. @hapic.output_body(HtmlDocumentContentSchema())
  69. def update_html_document(self, context, request: TracimRequest, hapic_data=None) -> ContentInContext: # nopep8
  70. """
  71. update_html_document
  72. """
  73. app_config = request.registry.settings['CFG']
  74. api = ContentApi(
  75. current_user=request.current_user,
  76. session=request.dbsession,
  77. config=app_config,
  78. )
  79. content = api.get_one(
  80. hapic_data.path.content_id,
  81. content_type=ContentType.Any
  82. )
  83. with new_revision(
  84. session=request.dbsession,
  85. tm=transaction.manager,
  86. content=content
  87. ):
  88. api.update_content(
  89. item=content,
  90. new_label=hapic_data.body.label,
  91. new_content=hapic_data.body.raw_content,
  92. )
  93. api.save(content)
  94. return api.get_content_in_context(content)
  95. @hapic.with_api_doc(tags=[HTML_DOCUMENT_ENDPOINTS_TAG])
  96. @hapic.handle_exception(NotAuthenticated, HTTPStatus.UNAUTHORIZED)
  97. @hapic.handle_exception(InsufficientUserWorkspaceRole, HTTPStatus.FORBIDDEN)
  98. @hapic.handle_exception(WorkspaceNotFound, HTTPStatus.FORBIDDEN)
  99. @hapic.handle_exception(AuthenticationFailed, HTTPStatus.FORBIDDEN)
  100. @require_workspace_role(UserRoleInWorkspace.READER)
  101. @require_content_types([html_documents_type])
  102. @hapic.input_path(WorkspaceAndContentIdPathSchema())
  103. @hapic.output_body(HtmlDocumentRevisionSchema(many=True))
  104. def get_html_document_revisions(
  105. self,
  106. context,
  107. request: TracimRequest,
  108. hapic_data=None
  109. ) -> typing.List[RevisionInContext]:
  110. """
  111. get html_document revisions
  112. """
  113. app_config = request.registry.settings['CFG']
  114. api = ContentApi(
  115. current_user=request.current_user,
  116. session=request.dbsession,
  117. config=app_config,
  118. )
  119. content = api.get_one(
  120. hapic_data.path.content_id,
  121. content_type=ContentType.Any
  122. )
  123. revisions = content.revisions
  124. return [
  125. api.get_revision_in_context(revision)
  126. for revision in revisions
  127. ]
  128. @hapic.with_api_doc(tags=[HTML_DOCUMENT_ENDPOINTS_TAG])
  129. @hapic.handle_exception(NotAuthenticated, HTTPStatus.UNAUTHORIZED)
  130. @hapic.handle_exception(InsufficientUserWorkspaceRole, HTTPStatus.FORBIDDEN)
  131. @hapic.handle_exception(WorkspaceNotFound, HTTPStatus.FORBIDDEN)
  132. @hapic.handle_exception(AuthenticationFailed, HTTPStatus.FORBIDDEN)
  133. @require_workspace_role(UserRoleInWorkspace.CONTRIBUTOR)
  134. @require_content_types([html_documents_type])
  135. @hapic.input_path(WorkspaceAndContentIdPathSchema())
  136. @hapic.input_body(SetContentStatusSchema())
  137. @hapic.output_body(NoContentSchema(), default_http_code=HTTPStatus.NO_CONTENT) # nopep8
  138. def set_html_document_status(
  139. self,
  140. context,
  141. request: TracimRequest,
  142. hapic_data=None
  143. ) -> None:
  144. """
  145. set html_document status
  146. """
  147. app_config = request.registry.settings['CFG']
  148. api = ContentApi(
  149. current_user=request.current_user,
  150. session=request.dbsession,
  151. config=app_config,
  152. )
  153. content = api.get_one(
  154. hapic_data.path.content_id,
  155. content_type=ContentType.Any
  156. )
  157. with new_revision(
  158. session=request.dbsession,
  159. tm=transaction.manager,
  160. content=content
  161. ):
  162. api.set_status(
  163. content,
  164. hapic_data.body.status,
  165. )
  166. api.save(content)
  167. return
  168. def bind(self, configurator: Configurator) -> None:
  169. # Get html-document
  170. configurator.add_route(
  171. 'html_document',
  172. '/workspaces/{workspace_id}/html-documents/{content_id}',
  173. request_method='GET'
  174. )
  175. configurator.add_view(self.get_html_document, route_name='html_document') # nopep8
  176. # update html-document
  177. configurator.add_route(
  178. 'update_html_document',
  179. '/workspaces/{workspace_id}/html-documents/{content_id}',
  180. request_method='PUT'
  181. ) # nopep8
  182. configurator.add_view(self.update_html_document, route_name='update_html_document') # nopep8
  183. # get html document revisions
  184. configurator.add_route(
  185. 'html_document_revisions',
  186. '/workspaces/{workspace_id}/html-documents/{content_id}/revisions', # nopep8
  187. request_method='GET'
  188. )
  189. configurator.add_view(self.get_html_document_revisions, route_name='html_document_revisions') # nopep8
  190. # get html document revisions
  191. configurator.add_route(
  192. 'set_html_document_status',
  193. '/workspaces/{workspace_id}/html-documents/{content_id}/status', # nopep8
  194. request_method='PUT'
  195. )
  196. configurator.add_view(self.set_html_document_status, route_name='set_html_document_status') # nopep8