user_controller.py 25KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598
  1. from pyramid.config import Configurator
  2. from tracim_backend.lib.core.userworkspace import RoleApi
  3. from tracim_backend.lib.utils.utils import password_generator
  4. try: # Python 3.5+
  5. from http import HTTPStatus
  6. except ImportError:
  7. from http import client as HTTPStatus
  8. from tracim_backend import hapic
  9. from tracim_backend.lib.utils.request import TracimRequest
  10. from tracim_backend.models import Group
  11. from tracim_backend.lib.core.group import GroupApi
  12. from tracim_backend.lib.core.user import UserApi
  13. from tracim_backend.lib.core.workspace import WorkspaceApi
  14. from tracim_backend.lib.core.content import ContentApi
  15. from tracim_backend.views.controllers import Controller
  16. from tracim_backend.lib.utils.authorization import require_same_user_or_profile
  17. from tracim_backend.lib.utils.authorization import require_profile
  18. from tracim_backend.exceptions import WrongUserPassword
  19. from tracim_backend.exceptions import EmailAlreadyExistInDb
  20. from tracim_backend.exceptions import PasswordDoNotMatch
  21. from tracim_backend.views.core_api.schemas import UserSchema
  22. from tracim_backend.views.core_api.schemas import AutocompleteQuerySchema
  23. from tracim_backend.views.core_api.schemas import UserDigestSchema
  24. from tracim_backend.views.core_api.schemas import SetEmailSchema
  25. from tracim_backend.views.core_api.schemas import SetPasswordSchema
  26. from tracim_backend.views.core_api.schemas import UserInfosSchema
  27. from tracim_backend.views.core_api.schemas import UserCreationSchema
  28. from tracim_backend.views.core_api.schemas import UserProfileSchema
  29. from tracim_backend.views.core_api.schemas import UserIdPathSchema
  30. from tracim_backend.views.core_api.schemas import ReadStatusSchema
  31. from tracim_backend.views.core_api.schemas import ContentIdsQuerySchema
  32. from tracim_backend.views.core_api.schemas import NoContentSchema
  33. from tracim_backend.views.core_api.schemas import UserWorkspaceIdPathSchema
  34. from tracim_backend.views.core_api.schemas import UserWorkspaceAndContentIdPathSchema
  35. from tracim_backend.views.core_api.schemas import ContentDigestSchema
  36. from tracim_backend.views.core_api.schemas import ActiveContentFilterQuerySchema
  37. from tracim_backend.views.core_api.schemas import WorkspaceDigestSchema
  38. from tracim_backend.app_models.contents import CONTENT_TYPES
  39. SWAGGER_TAG__USER_ENDPOINTS = 'Users'
  40. class UserController(Controller):
  41. @hapic.with_api_doc(tags=[SWAGGER_TAG__USER_ENDPOINTS])
  42. @require_same_user_or_profile(Group.TIM_ADMIN)
  43. @hapic.input_path(UserIdPathSchema())
  44. @hapic.output_body(WorkspaceDigestSchema(many=True),)
  45. def user_workspace(self, context, request: TracimRequest, hapic_data=None):
  46. """
  47. Get list of user workspaces
  48. """
  49. app_config = request.registry.settings['CFG']
  50. wapi = WorkspaceApi(
  51. current_user=request.candidate_user, # User
  52. session=request.dbsession,
  53. config=app_config,
  54. )
  55. workspaces = wapi.get_all_for_user(request.candidate_user)
  56. return [
  57. wapi.get_workspace_with_context(workspace)
  58. for workspace in workspaces
  59. ]
  60. @hapic.with_api_doc(tags=[SWAGGER_TAG__USER_ENDPOINTS])
  61. @require_same_user_or_profile(Group.TIM_ADMIN)
  62. @hapic.input_path(UserIdPathSchema())
  63. @hapic.output_body(UserSchema())
  64. def user(self, context, request: TracimRequest, hapic_data=None):
  65. """
  66. Get user infos.
  67. """
  68. app_config = request.registry.settings['CFG']
  69. uapi = UserApi(
  70. current_user=request.current_user, # User
  71. session=request.dbsession,
  72. config=app_config,
  73. )
  74. return uapi.get_user_with_context(request.candidate_user)
  75. @hapic.with_api_doc(tags=[SWAGGER_TAG__USER_ENDPOINTS])
  76. @require_profile(Group.TIM_ADMIN)
  77. @hapic.output_body(UserDigestSchema(many=True))
  78. def users(self, context, request: TracimRequest, hapic_data=None):
  79. """
  80. Get all users
  81. """
  82. app_config = request.registry.settings['CFG']
  83. uapi = UserApi(
  84. current_user=request.current_user, # User
  85. session=request.dbsession,
  86. config=app_config,
  87. )
  88. users = uapi.get_all()
  89. context_users = [
  90. uapi.get_user_with_context(user) for user in users
  91. ]
  92. return context_users
  93. @hapic.with_api_doc(tags=[SWAGGER_TAG__USER_ENDPOINTS])
  94. @require_same_user_or_profile(Group.TIM_MANAGER)
  95. @hapic.input_path(UserIdPathSchema())
  96. @hapic.input_query(AutocompleteQuerySchema())
  97. @hapic.output_body(UserDigestSchema(many=True))
  98. def known_members(self, context, request: TracimRequest, hapic_data=None):
  99. """
  100. Get known users list
  101. """
  102. app_config = request.registry.settings['CFG']
  103. uapi = UserApi(
  104. current_user=request.candidate_user, # User
  105. session=request.dbsession,
  106. config=app_config,
  107. )
  108. users = uapi.get_known_user(acp=hapic_data.query.acp)
  109. context_users = [
  110. uapi.get_user_with_context(user) for user in users
  111. ]
  112. return context_users
  113. @hapic.with_api_doc(tags=[SWAGGER_TAG__USER_ENDPOINTS])
  114. @hapic.handle_exception(WrongUserPassword, HTTPStatus.FORBIDDEN)
  115. @hapic.handle_exception(EmailAlreadyExistInDb, HTTPStatus.BAD_REQUEST)
  116. @require_same_user_or_profile(Group.TIM_ADMIN)
  117. @hapic.input_body(SetEmailSchema())
  118. @hapic.input_path(UserIdPathSchema())
  119. @hapic.output_body(UserSchema())
  120. def set_user_email(self, context, request: TracimRequest, hapic_data=None):
  121. """
  122. Set user Email
  123. """
  124. app_config = request.registry.settings['CFG']
  125. uapi = UserApi(
  126. current_user=request.current_user, # User
  127. session=request.dbsession,
  128. config=app_config,
  129. )
  130. user = uapi.set_email(
  131. request.candidate_user,
  132. hapic_data.body.loggedin_user_password,
  133. hapic_data.body.email,
  134. do_save=True
  135. )
  136. return uapi.get_user_with_context(user)
  137. @hapic.with_api_doc(tags=[SWAGGER_TAG__USER_ENDPOINTS])
  138. @hapic.handle_exception(WrongUserPassword, HTTPStatus.FORBIDDEN)
  139. @hapic.handle_exception(PasswordDoNotMatch, HTTPStatus.BAD_REQUEST)
  140. @require_same_user_or_profile(Group.TIM_ADMIN)
  141. @hapic.input_body(SetPasswordSchema())
  142. @hapic.input_path(UserIdPathSchema())
  143. @hapic.output_body(NoContentSchema(), default_http_code=HTTPStatus.NO_CONTENT) # nopep8
  144. def set_user_password(self, context, request: TracimRequest, hapic_data=None): # nopep8
  145. """
  146. Set user password
  147. """
  148. app_config = request.registry.settings['CFG']
  149. uapi = UserApi(
  150. current_user=request.current_user, # User
  151. session=request.dbsession,
  152. config=app_config,
  153. )
  154. uapi.set_password(
  155. request.candidate_user,
  156. hapic_data.body.loggedin_user_password,
  157. hapic_data.body.new_password,
  158. hapic_data.body.new_password2,
  159. do_save=True
  160. )
  161. return
  162. @hapic.with_api_doc(tags=[SWAGGER_TAG__USER_ENDPOINTS])
  163. @require_same_user_or_profile(Group.TIM_ADMIN)
  164. @hapic.input_body(UserInfosSchema())
  165. @hapic.input_path(UserIdPathSchema())
  166. @hapic.output_body(UserSchema())
  167. def set_user_infos(self, context, request: TracimRequest, hapic_data=None):
  168. """
  169. Set user info data
  170. """
  171. app_config = request.registry.settings['CFG']
  172. uapi = UserApi(
  173. current_user=request.current_user, # User
  174. session=request.dbsession,
  175. config=app_config,
  176. )
  177. user = uapi.update(
  178. request.candidate_user,
  179. name=hapic_data.body.public_name,
  180. timezone=hapic_data.body.timezone,
  181. lang=hapic_data.body.lang,
  182. do_save=True
  183. )
  184. return uapi.get_user_with_context(user)
  185. @hapic.with_api_doc(tags=[SWAGGER_TAG__USER_ENDPOINTS])
  186. @hapic.handle_exception(EmailAlreadyExistInDb, HTTPStatus.BAD_REQUEST)
  187. @require_profile(Group.TIM_ADMIN)
  188. @hapic.input_body(UserCreationSchema())
  189. @hapic.output_body(UserSchema())
  190. def create_user(self, context, request: TracimRequest, hapic_data=None):
  191. """
  192. Create new user
  193. """
  194. app_config = request.registry.settings['CFG']
  195. uapi = UserApi(
  196. current_user=request.current_user, # User
  197. session=request.dbsession,
  198. config=app_config,
  199. )
  200. gapi = GroupApi(
  201. current_user=request.current_user, # User
  202. session=request.dbsession,
  203. config=app_config,
  204. )
  205. groups = [gapi.get_one_with_name(hapic_data.body.profile)]
  206. user = uapi.create_user(
  207. email=hapic_data.body.email,
  208. password=hapic_data.body.password,
  209. timezone=hapic_data.body.timezone,
  210. lang=hapic_data.body.lang,
  211. name=hapic_data.body.public_name,
  212. do_notify=hapic_data.body.email_notification,
  213. groups=groups,
  214. do_save=True
  215. )
  216. return uapi.get_user_with_context(user)
  217. @hapic.with_api_doc(tags=[SWAGGER_TAG__USER_ENDPOINTS])
  218. @require_profile(Group.TIM_ADMIN)
  219. @hapic.input_path(UserIdPathSchema())
  220. @hapic.output_body(NoContentSchema(), default_http_code=HTTPStatus.NO_CONTENT) # nopep8
  221. def enable_user(self, context, request: TracimRequest, hapic_data=None):
  222. """
  223. enable user
  224. """
  225. app_config = request.registry.settings['CFG']
  226. uapi = UserApi(
  227. current_user=request.current_user, # User
  228. session=request.dbsession,
  229. config=app_config,
  230. )
  231. uapi.enable(user=request.candidate_user, do_save=True)
  232. return
  233. @hapic.with_api_doc(tags=[SWAGGER_TAG__USER_ENDPOINTS])
  234. @require_profile(Group.TIM_ADMIN)
  235. @hapic.input_path(UserIdPathSchema())
  236. @hapic.output_body(NoContentSchema(), default_http_code=HTTPStatus.NO_CONTENT) # nopep8
  237. def delete_user(self, context, request: TracimRequest, hapic_data=None):
  238. """
  239. delete user
  240. """
  241. app_config = request.registry.settings['CFG']
  242. uapi = UserApi(
  243. current_user=request.current_user, # User
  244. session=request.dbsession,
  245. config=app_config,
  246. )
  247. uapi.delete(user=request.candidate_user, do_save=True)
  248. return
  249. @hapic.with_api_doc(tags=[SWAGGER_TAG__USER_ENDPOINTS])
  250. @require_profile(Group.TIM_ADMIN)
  251. @hapic.input_path(UserIdPathSchema())
  252. @hapic.output_body(NoContentSchema(), default_http_code=HTTPStatus.NO_CONTENT) # nopep8
  253. def undelete_user(self, context, request: TracimRequest, hapic_data=None):
  254. """
  255. undelete user
  256. """
  257. app_config = request.registry.settings['CFG']
  258. uapi = UserApi(
  259. current_user=request.current_user, # User
  260. session=request.dbsession,
  261. config=app_config,
  262. show_deleted=True,
  263. )
  264. uapi.undelete(user=request.candidate_user, do_save=True)
  265. return
  266. @hapic.with_api_doc(tags=[SWAGGER_TAG__USER_ENDPOINTS])
  267. @require_profile(Group.TIM_ADMIN)
  268. @hapic.input_path(UserIdPathSchema())
  269. @hapic.output_body(NoContentSchema(), default_http_code=HTTPStatus.NO_CONTENT) # nopep8
  270. def disable_user(self, context, request: TracimRequest, hapic_data=None):
  271. """
  272. disable user
  273. """
  274. app_config = request.registry.settings['CFG']
  275. uapi = UserApi(
  276. current_user=request.current_user, # User
  277. session=request.dbsession,
  278. config=app_config,
  279. )
  280. uapi.disable(user=request.candidate_user, do_save=True)
  281. return
  282. @hapic.with_api_doc(tags=[SWAGGER_TAG__USER_ENDPOINTS])
  283. @require_profile(Group.TIM_ADMIN)
  284. @hapic.input_path(UserIdPathSchema())
  285. @hapic.input_body(UserProfileSchema())
  286. @hapic.output_body(NoContentSchema(), default_http_code=HTTPStatus.NO_CONTENT) # nopep8
  287. def set_profile(self, context, request: TracimRequest, hapic_data=None):
  288. """
  289. set user profile
  290. """
  291. app_config = request.registry.settings['CFG']
  292. uapi = UserApi(
  293. current_user=request.current_user, # User
  294. session=request.dbsession,
  295. config=app_config,
  296. )
  297. gapi = GroupApi(
  298. current_user=request.current_user, # User
  299. session=request.dbsession,
  300. config=app_config,
  301. )
  302. groups = [gapi.get_one_with_name(hapic_data.body.profile)]
  303. uapi.update(
  304. user=request.candidate_user,
  305. groups=groups,
  306. do_save=True,
  307. )
  308. return
  309. @hapic.with_api_doc(tags=[SWAGGER_TAG__USER_ENDPOINTS])
  310. @require_same_user_or_profile(Group.TIM_ADMIN)
  311. @hapic.input_path(UserWorkspaceIdPathSchema())
  312. @hapic.input_query(ActiveContentFilterQuerySchema())
  313. @hapic.output_body(ContentDigestSchema(many=True))
  314. def last_active_content(self, context, request: TracimRequest, hapic_data=None): # nopep8
  315. """
  316. Get last_active_content for user
  317. """
  318. app_config = request.registry.settings['CFG']
  319. content_filter = hapic_data.query
  320. api = ContentApi(
  321. current_user=request.candidate_user, # User
  322. session=request.dbsession,
  323. config=app_config,
  324. )
  325. wapi = WorkspaceApi(
  326. current_user=request.candidate_user, # User
  327. session=request.dbsession,
  328. config=app_config,
  329. )
  330. workspace = None
  331. if hapic_data.path.workspace_id:
  332. workspace = wapi.get_one(hapic_data.path.workspace_id)
  333. before_content = None
  334. if content_filter.before_content_id:
  335. before_content = api.get_one(
  336. content_id=content_filter.before_content_id,
  337. workspace=workspace,
  338. content_type=CONTENT_TYPES.Any_SLUG
  339. )
  340. last_actives = api.get_last_active(
  341. workspace=workspace,
  342. limit=content_filter.limit or None,
  343. before_content=before_content,
  344. )
  345. return [
  346. api.get_content_in_context(content)
  347. for content in last_actives
  348. ]
  349. @hapic.with_api_doc(tags=[SWAGGER_TAG__USER_ENDPOINTS])
  350. @require_same_user_or_profile(Group.TIM_ADMIN)
  351. @hapic.input_path(UserWorkspaceIdPathSchema())
  352. @hapic.input_query(ContentIdsQuerySchema(), as_list=['contents_ids'])
  353. @hapic.output_body(ReadStatusSchema(many=True)) # nopep8
  354. def contents_read_status(self, context, request: TracimRequest, hapic_data=None): # nopep8
  355. """
  356. get user_read status of contents
  357. """
  358. app_config = request.registry.settings['CFG']
  359. content_filter = hapic_data.query
  360. api = ContentApi(
  361. current_user=request.candidate_user, # User
  362. session=request.dbsession,
  363. config=app_config,
  364. )
  365. wapi = WorkspaceApi(
  366. current_user=request.candidate_user, # User
  367. session=request.dbsession,
  368. config=app_config,
  369. )
  370. workspace = None
  371. if hapic_data.path.workspace_id:
  372. workspace = wapi.get_one(hapic_data.path.workspace_id)
  373. last_actives = api.get_last_active(
  374. workspace=workspace,
  375. limit=None,
  376. before_content=None,
  377. content_ids=hapic_data.query.contents_ids or None
  378. )
  379. return [
  380. api.get_content_in_context(content)
  381. for content in last_actives
  382. ]
  383. @hapic.with_api_doc(tags=[SWAGGER_TAG__USER_ENDPOINTS])
  384. @require_same_user_or_profile(Group.TIM_ADMIN)
  385. @hapic.input_path(UserWorkspaceAndContentIdPathSchema())
  386. @hapic.output_body(NoContentSchema(), default_http_code=HTTPStatus.NO_CONTENT) # nopep8
  387. def set_content_as_read(self, context, request: TracimRequest, hapic_data=None): # nopep8
  388. """
  389. set user_read status of content to read
  390. """
  391. app_config = request.registry.settings['CFG']
  392. api = ContentApi(
  393. show_archived=True,
  394. show_deleted=True,
  395. current_user=request.candidate_user,
  396. session=request.dbsession,
  397. config=app_config,
  398. )
  399. api.mark_read(request.current_content, do_flush=True)
  400. return
  401. @hapic.with_api_doc(tags=[SWAGGER_TAG__USER_ENDPOINTS])
  402. @require_same_user_or_profile(Group.TIM_ADMIN)
  403. @hapic.input_path(UserWorkspaceAndContentIdPathSchema())
  404. @hapic.output_body(NoContentSchema(), default_http_code=HTTPStatus.NO_CONTENT) # nopep8
  405. def set_content_as_unread(self, context, request: TracimRequest, hapic_data=None): # nopep8
  406. """
  407. set user_read status of content to unread
  408. """
  409. app_config = request.registry.settings['CFG']
  410. api = ContentApi(
  411. show_archived=True,
  412. show_deleted=True,
  413. current_user=request.candidate_user,
  414. session=request.dbsession,
  415. config=app_config,
  416. )
  417. api.mark_unread(request.current_content, do_flush=True)
  418. return
  419. @hapic.with_api_doc(tags=[SWAGGER_TAG__USER_ENDPOINTS])
  420. @require_same_user_or_profile(Group.TIM_ADMIN)
  421. @hapic.input_path(UserWorkspaceIdPathSchema())
  422. @hapic.output_body(NoContentSchema(), default_http_code=HTTPStatus.NO_CONTENT) # nopep8
  423. def set_workspace_as_read(self, context, request: TracimRequest, hapic_data=None): # nopep8
  424. """
  425. set user_read status of all content of workspace to read
  426. """
  427. app_config = request.registry.settings['CFG']
  428. api = ContentApi(
  429. show_archived=True,
  430. show_deleted=True,
  431. current_user=request.candidate_user,
  432. session=request.dbsession,
  433. config=app_config,
  434. )
  435. api.mark_read__workspace(request.current_workspace)
  436. return
  437. @hapic.with_api_doc(tags=[SWAGGER_TAG__USER_ENDPOINTS])
  438. @require_same_user_or_profile(Group.TIM_ADMIN)
  439. @hapic.input_path(UserWorkspaceIdPathSchema())
  440. @hapic.output_body(NoContentSchema(), default_http_code=HTTPStatus.NO_CONTENT) # nopep8
  441. def enable_workspace_notification(self, context, request: TracimRequest, hapic_data=None): # nopep8
  442. """
  443. enable workspace notification
  444. """
  445. app_config = request.registry.settings['CFG']
  446. api = ContentApi(
  447. current_user=request.candidate_user, # User
  448. session=request.dbsession,
  449. config=app_config,
  450. )
  451. wapi = WorkspaceApi(
  452. current_user=request.candidate_user, # User
  453. session=request.dbsession,
  454. config=app_config,
  455. )
  456. workspace = wapi.get_one(hapic_data.path.workspace_id)
  457. wapi.enable_notifications(request.candidate_user, workspace)
  458. rapi = RoleApi(
  459. current_user=request.candidate_user, # User
  460. session=request.dbsession,
  461. config=app_config,
  462. )
  463. role = rapi.get_one(request.candidate_user.user_id, workspace.workspace_id)
  464. wapi.save(workspace)
  465. return
  466. @hapic.with_api_doc(tags=[SWAGGER_TAG__USER_ENDPOINTS])
  467. @require_same_user_or_profile(Group.TIM_ADMIN)
  468. @hapic.input_path(UserWorkspaceIdPathSchema())
  469. @hapic.output_body(NoContentSchema(), default_http_code=HTTPStatus.NO_CONTENT) # nopep8
  470. def disable_workspace_notification(self, context, request: TracimRequest, hapic_data=None): # nopep8
  471. """
  472. disable workspace notification
  473. """
  474. app_config = request.registry.settings['CFG']
  475. api = ContentApi(
  476. current_user=request.candidate_user, # User
  477. session=request.dbsession,
  478. config=app_config,
  479. )
  480. wapi = WorkspaceApi(
  481. current_user=request.candidate_user, # User
  482. session=request.dbsession,
  483. config=app_config,
  484. )
  485. workspace = wapi.get_one(hapic_data.path.workspace_id)
  486. wapi.disable_notifications(request.candidate_user, workspace)
  487. wapi.save(workspace)
  488. return
  489. def bind(self, configurator: Configurator) -> None:
  490. """
  491. Create all routes and views using pyramid configurator
  492. for this controller
  493. """
  494. # user workspace
  495. configurator.add_route('user_workspace', '/users/{user_id}/workspaces', request_method='GET') # nopep8
  496. configurator.add_view(self.user_workspace, route_name='user_workspace')
  497. # user info
  498. configurator.add_route('user', '/users/{user_id}', request_method='GET') # nopep8
  499. configurator.add_view(self.user, route_name='user')
  500. # users lists
  501. configurator.add_route('users', '/users', request_method='GET') # nopep8
  502. configurator.add_view(self.users, route_name='users')
  503. # known members lists
  504. configurator.add_route('known_members', '/users/{user_id}/known_members', request_method='GET') # nopep8
  505. configurator.add_view(self.known_members, route_name='known_members')
  506. # set user email
  507. configurator.add_route('set_user_email', '/users/{user_id}/email', request_method='PUT') # nopep8
  508. configurator.add_view(self.set_user_email, route_name='set_user_email')
  509. # set user password
  510. configurator.add_route('set_user_password', '/users/{user_id}/password', request_method='PUT') # nopep8
  511. configurator.add_view(self.set_user_password, route_name='set_user_password') # nopep8
  512. # set user_info
  513. configurator.add_route('set_user_info', '/users/{user_id}', request_method='PUT') # nopep8
  514. configurator.add_view(self.set_user_infos, route_name='set_user_info')
  515. # create user
  516. configurator.add_route('create_user', '/users', request_method='POST')
  517. configurator.add_view(self.create_user, route_name='create_user')
  518. # enable user
  519. configurator.add_route('enable_user', '/users/{user_id}/enable', request_method='PUT') # nopep8
  520. configurator.add_view(self.enable_user, route_name='enable_user')
  521. # disable user
  522. configurator.add_route('disable_user', '/users/{user_id}/disable', request_method='PUT') # nopep8
  523. configurator.add_view(self.disable_user, route_name='disable_user')
  524. # delete user
  525. configurator.add_route('delete_user', '/users/{user_id}/delete', request_method='PUT') # nopep8
  526. configurator.add_view(self.delete_user, route_name='delete_user')
  527. # undelete user
  528. configurator.add_route('undelete_user', '/users/{user_id}/undelete', request_method='PUT') # nopep8
  529. configurator.add_view(self.undelete_user, route_name='undelete_user')
  530. # set user profile
  531. configurator.add_route('set_user_profile', '/users/{user_id}/profile', request_method='PUT') # nopep8
  532. configurator.add_view(self.set_profile, route_name='set_user_profile')
  533. # user content
  534. configurator.add_route('contents_read_status', '/users/{user_id}/workspaces/{workspace_id}/contents/read_status', request_method='GET') # nopep8
  535. configurator.add_view(self.contents_read_status, route_name='contents_read_status') # nopep8
  536. # last active content for user
  537. configurator.add_route('last_active_content', '/users/{user_id}/workspaces/{workspace_id}/contents/recently_active', request_method='GET') # nopep8
  538. configurator.add_view(self.last_active_content, route_name='last_active_content') # nopep8
  539. # set content as read/unread
  540. configurator.add_route('read_content', '/users/{user_id}/workspaces/{workspace_id}/contents/{content_id}/read', request_method='PUT') # nopep8
  541. configurator.add_view(self.set_content_as_read, route_name='read_content') # nopep8
  542. configurator.add_route('unread_content', '/users/{user_id}/workspaces/{workspace_id}/contents/{content_id}/unread', request_method='PUT') # nopep8
  543. configurator.add_view(self.set_content_as_unread, route_name='unread_content') # nopep8
  544. # set workspace as read
  545. configurator.add_route('read_workspace', '/users/{user_id}/workspaces/{workspace_id}/read', request_method='PUT') # nopep8
  546. configurator.add_view(self.set_workspace_as_read, route_name='read_workspace') # nopep8
  547. # enable workspace notification
  548. configurator.add_route('enable_workspace_notification', '/users/{user_id}/workspaces/{workspace_id}/notify', request_method='PUT') # nopep8
  549. configurator.add_view(self.enable_workspace_notification, route_name='enable_workspace_notification') # nopep8
  550. # enable workspace notification
  551. configurator.add_route('disable_workspace_notification', '/users/{user_id}/workspaces/{workspace_id}/unnotify', request_method='PUT') # nopep8
  552. configurator.add_view(self.disable_workspace_notification, route_name='disable_workspace_notification') # nopep8