user.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. // SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
  2. // SPDX-License-Identifier: Apache-2.0
  3. package api // import "miniflux.app/v2/internal/api"
  4. import (
  5. json_parser "encoding/json"
  6. "errors"
  7. "net/http"
  8. "regexp"
  9. "miniflux.app/v2/internal/http/request"
  10. "miniflux.app/v2/internal/http/response/json"
  11. "miniflux.app/v2/internal/model"
  12. "miniflux.app/v2/internal/validator"
  13. )
  14. func (h *handler) currentUser(w http.ResponseWriter, r *http.Request) {
  15. user, err := h.store.UserByID(request.UserID(r))
  16. if err != nil {
  17. json.ServerError(w, r, err)
  18. return
  19. }
  20. json.OK(w, r, user)
  21. }
  22. func (h *handler) createUser(w http.ResponseWriter, r *http.Request) {
  23. if !request.IsAdminUser(r) {
  24. json.Forbidden(w, r)
  25. return
  26. }
  27. var userCreationRequest model.UserCreationRequest
  28. if err := json_parser.NewDecoder(r.Body).Decode(&userCreationRequest); err != nil {
  29. json.BadRequest(w, r, err)
  30. return
  31. }
  32. if validationErr := validator.ValidateUserCreationWithPassword(h.store, &userCreationRequest); validationErr != nil {
  33. json.BadRequest(w, r, validationErr.Error())
  34. return
  35. }
  36. user, err := h.store.CreateUser(&userCreationRequest)
  37. if err != nil {
  38. json.ServerError(w, r, err)
  39. return
  40. }
  41. json.Created(w, r, user)
  42. }
  43. func (h *handler) updateUser(w http.ResponseWriter, r *http.Request) {
  44. userID := request.RouteInt64Param(r, "userID")
  45. var userModificationRequest model.UserModificationRequest
  46. if err := json_parser.NewDecoder(r.Body).Decode(&userModificationRequest); err != nil {
  47. json.BadRequest(w, r, err)
  48. return
  49. }
  50. originalUser, err := h.store.UserByID(userID)
  51. if err != nil {
  52. json.ServerError(w, r, err)
  53. return
  54. }
  55. if originalUser == nil {
  56. json.NotFound(w, r)
  57. return
  58. }
  59. if !request.IsAdminUser(r) {
  60. if originalUser.ID != request.UserID(r) {
  61. json.Forbidden(w, r)
  62. return
  63. }
  64. if userModificationRequest.IsAdmin != nil && *userModificationRequest.IsAdmin {
  65. json.BadRequest(w, r, errors.New("only administrators can change permissions of standard users"))
  66. return
  67. }
  68. }
  69. cleanEnd := regexp.MustCompile(`(?m)\r\n\s*$`)
  70. if userModificationRequest.BlockFilterEntryRules != nil {
  71. *userModificationRequest.BlockFilterEntryRules = cleanEnd.ReplaceAllLiteralString(*userModificationRequest.BlockFilterEntryRules, "")
  72. }
  73. if userModificationRequest.KeepFilterEntryRules != nil {
  74. *userModificationRequest.KeepFilterEntryRules = cleanEnd.ReplaceAllLiteralString(*userModificationRequest.KeepFilterEntryRules, "")
  75. }
  76. if validationErr := validator.ValidateUserModification(h.store, originalUser.ID, &userModificationRequest); validationErr != nil {
  77. json.BadRequest(w, r, validationErr.Error())
  78. return
  79. }
  80. userModificationRequest.Patch(originalUser)
  81. if err = h.store.UpdateUser(originalUser); err != nil {
  82. json.ServerError(w, r, err)
  83. return
  84. }
  85. json.Created(w, r, originalUser)
  86. }
  87. func (h *handler) markUserAsRead(w http.ResponseWriter, r *http.Request) {
  88. userID := request.RouteInt64Param(r, "userID")
  89. if userID != request.UserID(r) {
  90. json.Forbidden(w, r)
  91. return
  92. }
  93. if _, err := h.store.UserByID(userID); err != nil {
  94. json.NotFound(w, r)
  95. return
  96. }
  97. if err := h.store.MarkAllAsRead(userID); err != nil {
  98. json.ServerError(w, r, err)
  99. return
  100. }
  101. json.NoContent(w, r)
  102. }
  103. func (h *handler) users(w http.ResponseWriter, r *http.Request) {
  104. if !request.IsAdminUser(r) {
  105. json.Forbidden(w, r)
  106. return
  107. }
  108. users, err := h.store.Users()
  109. if err != nil {
  110. json.ServerError(w, r, err)
  111. return
  112. }
  113. users.UseTimezone(request.UserTimezone(r))
  114. json.OK(w, r, users)
  115. }
  116. func (h *handler) userByID(w http.ResponseWriter, r *http.Request) {
  117. if !request.IsAdminUser(r) {
  118. json.Forbidden(w, r)
  119. return
  120. }
  121. userID := request.RouteInt64Param(r, "userID")
  122. user, err := h.store.UserByID(userID)
  123. if err != nil {
  124. json.BadRequest(w, r, errors.New("unable to fetch this user from the database"))
  125. return
  126. }
  127. if user == nil {
  128. json.NotFound(w, r)
  129. return
  130. }
  131. user.UseTimezone(request.UserTimezone(r))
  132. json.OK(w, r, user)
  133. }
  134. func (h *handler) userByUsername(w http.ResponseWriter, r *http.Request) {
  135. if !request.IsAdminUser(r) {
  136. json.Forbidden(w, r)
  137. return
  138. }
  139. username := request.RouteStringParam(r, "username")
  140. user, err := h.store.UserByUsername(username)
  141. if err != nil {
  142. json.BadRequest(w, r, errors.New("unable to fetch this user from the database"))
  143. return
  144. }
  145. if user == nil {
  146. json.NotFound(w, r)
  147. return
  148. }
  149. json.OK(w, r, user)
  150. }
  151. func (h *handler) removeUser(w http.ResponseWriter, r *http.Request) {
  152. if !request.IsAdminUser(r) {
  153. json.Forbidden(w, r)
  154. return
  155. }
  156. userID := request.RouteInt64Param(r, "userID")
  157. user, err := h.store.UserByID(userID)
  158. if err != nil {
  159. json.ServerError(w, r, err)
  160. return
  161. }
  162. if user == nil {
  163. json.NotFound(w, r)
  164. return
  165. }
  166. if user.ID == request.UserID(r) {
  167. json.BadRequest(w, r, errors.New("you cannot remove yourself"))
  168. return
  169. }
  170. h.store.RemoveUserAsync(user.ID)
  171. json.NoContent(w, r)
  172. }