workspace.py 9.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. # -*- coding: utf-8 -*-
  2. import tg
  3. from tg import tmpl_context
  4. from tg.i18n import ugettext as _
  5. from tracim.controllers import TIMRestController
  6. from tracim.controllers import TIMRestPathContextSetup
  7. from tracim.lib import CST
  8. from tracim.lib.base import BaseController
  9. from tracim.lib.user import UserApi
  10. from tracim.lib.userworkspace import RoleApi
  11. from tracim.lib.content import ContentApi
  12. from tracim.lib.workspace import WorkspaceApi
  13. from tracim.model.auth import Group
  14. from tracim.model.data import NodeTreeItem
  15. from tracim.model.data import Content
  16. from tracim.model.data import ContentType
  17. from tracim.model.data import Workspace
  18. from tracim.model.data import UserRoleInWorkspace
  19. from tracim.model.serializers import Context, CTX, DictLikeClass
  20. from tracim.controllers.content import UserWorkspaceFolderRestController
  21. class RoleInWorkspaceRestController(TIMRestController, BaseController):
  22. def _before(self, *args, **kw):
  23. """
  24. Instantiate the current workspace in tg.tmpl_context
  25. :param args:
  26. :param kw:
  27. :return:
  28. """
  29. super(self.__class__, self)._before(args, kw)
  30. workspace_api = WorkspaceApi(tg.tmpl_context.current_user)
  31. workspace_id = tg.request.controller_state.routing_args.get('workspace_id')
  32. workspace = workspace_api.get_one(workspace_id)
  33. tg.tmpl_context.workspace_id = workspace_id
  34. tg.tmpl_context.workspace = workspace
  35. @property
  36. def _base_url(self):
  37. return '/admin/workspaces/{}/roles'.format(tg.tmpl_context.workspace_id)
  38. @tg.expose()
  39. def get_one(self, user_id):
  40. pass
  41. def put(self, *args, **kw):
  42. pass
  43. @tg.expose()
  44. def get_delete(self, user_id):
  45. """
  46. Shortcut to post_delete for convenience only.
  47. This allow to put a link that allow to delete a user
  48. (instead of generating a POST or DELETE http query
  49. """
  50. return self.post_delete(user_id)
  51. @tg.expose()
  52. def post_delete(self, user_id):
  53. user_id = int(user_id)
  54. role_api = RoleApi(tg.tmpl_context.current_user)
  55. role = role_api.get_one(user_id, tg.tmpl_context.workspace_id)
  56. username = role.user.get_display_name()
  57. undo_url = self.url(user_id, 'undelete', dict(old_role=role.role))
  58. if tmpl_context.current_user.profile.id<Group.TIM_ADMIN and tmpl_context.current_user.user_id==user_id:
  59. tg.flash(_('You can\'t remove yourself from this workgroup'), CST.STATUS_ERROR)
  60. tg.redirect(self.parent_controller.url(tg.tmpl_context.workspace_id))
  61. role_api.delete_one(user_id, tg.tmpl_context.workspace_id, True)
  62. tg.flash(_('User {} removed. You can <a class="alert-link" href="{}">restore it</a>').format(username, undo_url), CST.STATUS_OK, no_escape=True)
  63. tg.redirect(self.parent_controller.url(tg.tmpl_context.workspace_id))
  64. @tg.expose()
  65. def undelete(self, user_id, old_role):
  66. user_id = int(user_id)
  67. role_id = int(old_role)
  68. self._add_user_with_role(user_id, role_id, None, _('User {} restored in workspace {} as {}'))
  69. tg.redirect(self.parent_controller.url(tg.tmpl_context.workspace_id))
  70. @tg.expose()
  71. def post(self, user_id, role_id, with_notif=False):
  72. user_id = int(user_id)
  73. role_id = int(role_id)
  74. self._add_user_with_role(user_id, role_id, with_notif, _('User {} added to workspace {} as {}'))
  75. tg.redirect(self.parent_controller.url(tg.tmpl_context.workspace_id))
  76. def _add_user_with_role(self, user_id: int, role_id: int, with_notif: bool, flash_msg_template)-> UserRoleInWorkspace:
  77. user_api = UserApi(tg.tmpl_context.current_user)
  78. user = user_api.get_one(user_id)
  79. role_api = RoleApi(tg.tmpl_context.current_user)
  80. role = role_api.create_one(user, tg.tmpl_context.workspace, role_id, with_notif)
  81. tg.flash(flash_msg_template.format(
  82. role.user.get_display_name(),
  83. tg.tmpl_context.workspace.label,
  84. role.role_as_label()), CST.STATUS_OK)
  85. tg.redirect(self.parent_controller.url(tg.tmpl_context.workspace_id))
  86. @tg.expose()
  87. def change(self, user_id, new_role):
  88. # FIXME CHECK RIGHTS
  89. user_id = int(user_id)
  90. new_role_id = int(new_role)
  91. role_api = RoleApi(tg.tmpl_context.current_user)
  92. role = role_api.get_one(user_id, tg.tmpl_context.workspace_id)
  93. if tmpl_context.current_user.profile.id<Group.TIM_ADMIN and tmpl_context.current_user.user_id==user_id:
  94. tg.flash(_('You can\'t change your own role'), CST.STATUS_ERROR)
  95. tg.redirect(self.parent_controller.url(tg.tmpl_context.workspace_id))
  96. if new_role_id not in role_api.ALL_ROLE_VALUES:
  97. tg.flash(_('Unknown role'), CST.STATUS_ERROR)
  98. tg.redirect(self.parent_controller.url(tg.tmpl_context.workspace_id))
  99. return
  100. if new_role_id==role.role:
  101. tg.flash(_('No change found.'), CST.STATUS_ERROR)
  102. tg.redirect(self.parent_controller.url(tg.tmpl_context.workspace_id))
  103. return
  104. role.role = new_role_id
  105. role_api.save(role)
  106. tg.redirect(self.parent_controller.url(tg.tmpl_context.workspace_id))
  107. class WorkspaceRestController(TIMRestController, BaseController):
  108. """
  109. CRUD Controller allowing to manage Workspaces
  110. Reminder: a workspace is a group of users with associated rights
  111. responsible / advanced contributor. / contributor / reader
  112. """
  113. @property
  114. def _base_url(self):
  115. return '/admin/workspaces'
  116. @classmethod
  117. def current_item_id_key_in_context(cls):
  118. return 'workspace_id'
  119. @tg.expose('tracim.templates.admin.workspace_getall')
  120. def get_all(self, *args, **kw):
  121. user = tmpl_context.current_user
  122. workspace_api_controller = WorkspaceApi(user)
  123. workspaces = workspace_api_controller.get_all()
  124. current_user_content = Context(CTX.CURRENT_USER).toDict(user)
  125. fake_api = Context(CTX.ADMIN_WORKSPACE).toDict({'current_user': current_user_content})
  126. dictified_workspaces = Context(CTX.ADMIN_WORKSPACES).toDict(workspaces, 'workspaces', 'workspace_nb')
  127. return DictLikeClass(result = dictified_workspaces, fake_api=fake_api)
  128. @tg.expose('tracim.templates.admin.workspace_getone')
  129. def get_one(self, workspace_id):
  130. user = tmpl_context.current_user
  131. workspace_api_controller = WorkspaceApi(user)
  132. role_api = RoleApi(tg.tmpl_context.current_user)
  133. user_api = UserApi(tg.tmpl_context.current_user)
  134. workspace = workspace_api_controller.get_one(workspace_id)
  135. role_list = role_api.get_roles_for_select_field()
  136. user_list = user_api.get_all()
  137. current_user_content = Context(CTX.CURRENT_USER).toDict(user)
  138. dictified_workspace = Context(CTX.ADMIN_WORKSPACE).toDict(workspace, 'workspace')
  139. fake_api_content = DictLikeClass(role_types=role_list, users=user_list, current_user=current_user_content)
  140. fake_api = Context(CTX.ADMIN_WORKSPACE).toDict(fake_api_content)
  141. return dict(result = dictified_workspace, fake_api = fake_api)
  142. @tg.expose()
  143. def post(self, name, description):
  144. # FIXME - Check user profile
  145. user = tmpl_context.current_user
  146. workspace_api_controller = WorkspaceApi(user)
  147. workspace = workspace_api_controller.create_workspace(name, description)
  148. tg.flash(_('{} workspace created.').format(workspace.label), CST.STATUS_OK)
  149. tg.redirect(self.url())
  150. return
  151. @tg.expose('tracim.templates.workspace.edit')
  152. def edit(self, id):
  153. user = tmpl_context.current_user
  154. workspace_api_controller = WorkspaceApi(user)
  155. workspace = workspace_api_controller.get_one(id)
  156. dictified_workspace = Context(CTX.ADMIN_WORKSPACE).toDict(workspace, 'workspace')
  157. return DictLikeClass(result = dictified_workspace)
  158. @tg.expose('tracim.templates.workspace.edit')
  159. def put(self, id, name, description):
  160. user = tmpl_context.current_user
  161. workspace_api_controller = WorkspaceApi(user)
  162. workspace = workspace_api_controller.get_one(id)
  163. workspace.label = name
  164. workspace.description = description
  165. workspace_api_controller.save(workspace)
  166. tg.flash(_('{} workspace updated.').format(workspace.label), CST.STATUS_OK)
  167. tg.redirect(self.url(workspace.workspace_id))
  168. return
  169. @tg.expose()
  170. def get_delete(self, workspace_id):
  171. """
  172. Shortcut to post_delete for convenience only.
  173. This allow to put a link that allow to delete a user
  174. (instead of generating a POST or DELETE http query
  175. """
  176. return self.post_delete(workspace_id)
  177. @tg.expose()
  178. def post_delete(self, workspace_id):
  179. workspace_id = int(workspace_id)
  180. api = WorkspaceApi(tg.tmpl_context.current_user)
  181. workspace = api.get_one(workspace_id)
  182. api.delete_one(workspace_id)
  183. workspace_label = workspace.label
  184. undo_url = self.url(workspace_id, self.restore.__name__)
  185. tg.flash(_('{} workspace deleted. In case of error, you can <a class="alert-link" href="{}">restore it</a>.').format(workspace_label, undo_url), CST.STATUS_OK, no_escape=True)
  186. tg.redirect(self.url())
  187. @tg.expose()
  188. def restore(self, workspace_id):
  189. workspace_id = int(workspace_id)
  190. api = WorkspaceApi(tg.tmpl_context.current_user)
  191. workspace = api.restore_one(workspace_id, True)
  192. workspace_label = workspace.label
  193. undo_url = self.url(workspace_id, 'delete')
  194. tg.flash(_('{} workspace restored.').format(workspace_label), CST.STATUS_OK)
  195. tg.redirect(self.url())
  196. roles = RoleInWorkspaceRestController()