user.go 5.2 KB

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