A multipurpose python flask API server and administration SPA
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

133 lines
3.8 KiB

  1. """User API blueprint and endpoint definitions."""
  2. from flask import Blueprint, abort, request, g
  3. from server.api.decorators import return_json
  4. from server.api.model import APIResponse, APIMessage, APIPage
  5. from server.middleware import authentication_middleware
  6. from server.middleware.authentication_middleware import Auth
  7. from server.model import User
  8. from server.service import (
  9. patch_service,
  10. transformation_service,
  11. user_service
  12. )
  13. from server.service.patch_service import get_patch_fields
  14. from server.service.role_service import Role
  15. from server.utility.pagination_utility import get_pagination_params
  16. from server.service.role_service import ROLE_LIST
  17. USER_BLUEPRINT = Blueprint(
  18. name='user', import_name=__name__, url_prefix='/user')
  19. @USER_BLUEPRINT.route('', methods=['GET'])
  20. @return_json
  21. @authentication_middleware.require(
  22. required_auth=Auth.TOKEN, required_role=Role.USER)
  23. def get_users() -> APIResponse:
  24. """
  25. Get a list of users.
  26. :return: a paginated list of users
  27. """
  28. page, per_page = get_pagination_params(request.args)
  29. user_page = user_service.get_users(page, per_page)
  30. if user_page is not None:
  31. return APIResponse(APIPage.from_page(user_page), 200)
  32. return abort(404)
  33. @USER_BLUEPRINT.route('/<name>', methods=['GET'])
  34. @return_json
  35. @authentication_middleware.require(
  36. required_auth=Auth.TOKEN, required_role=Role.USER)
  37. def get_user(name: str) -> APIResponse:
  38. """
  39. Get a user.
  40. :return: user if exists, else 404
  41. """
  42. user = user_service.find_by_name(name)
  43. if user is not None:
  44. return APIResponse(user, 200)
  45. return abort(404)
  46. @USER_BLUEPRINT.route('/<name>', methods=['PATCH'])
  47. @return_json
  48. @authentication_middleware.require(
  49. required_auth=Auth.TOKEN, required_role=Role.USER)
  50. def patch_user(name: str) -> APIResponse:
  51. """
  52. Patch a user.
  53. :return: user if patched, 4xx error on patching issue, 404 on nonexistent
  54. """
  55. user = user_service.find_by_name(name)
  56. if user is not None:
  57. user_patch: User = transformation_service.deserialize_model(
  58. User, request.json)
  59. patched_user = patch_service.patch(
  60. g.user, user, user_patch, get_patch_fields(request.json))
  61. return APIResponse(patched_user, 200)
  62. return abort(404)
  63. @USER_BLUEPRINT.route('', methods=['POST'])
  64. @return_json
  65. @authentication_middleware.require(
  66. required_auth=Auth.TOKEN, required_role=Role.ADMIN)
  67. def register_user() -> APIResponse:
  68. """
  69. Register a user with the service.
  70. :return: The newly registered User
  71. """
  72. new_user: User = transformation_service.deserialize_model(
  73. User, request.json)
  74. requested_password = None
  75. if 'password' in request.json:
  76. requested_password = request.json['password'].strip()
  77. registered_user = user_service.register(
  78. name=new_user.name,
  79. password=requested_password,
  80. role=new_user.role
  81. )
  82. return APIResponse(payload=registered_user, status=200)
  83. @USER_BLUEPRINT.route('/<name>', methods=['DELETE'])
  84. @return_json
  85. @authentication_middleware.require(
  86. required_auth=Auth.TOKEN, required_role=Role.ADMIN)
  87. def delete_user(name: str) -> APIResponse:
  88. """
  89. Delete a user with the service.
  90. :return: The newly registered User
  91. """
  92. user = user_service.find_by_name(name)
  93. if user is not None:
  94. user_service.delete(user)
  95. return APIResponse(
  96. APIMessage(True, 'Successfully Deleted'), status=200)
  97. return abort(404)
  98. @USER_BLUEPRINT.route('/roles', methods=['GET'])
  99. @return_json
  100. @authentication_middleware.require(
  101. required_auth=Auth.TOKEN, required_role=Role.USER)
  102. def get_roles() -> APIResponse:
  103. """
  104. List the roles available on the service.
  105. :return: The list of roles
  106. """
  107. return APIResponse(
  108. sorted({str(role.data) for role in ROLE_LIST}),
  109. status=200
  110. )