user.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  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) getIntegrationsStatus(w http.ResponseWriter, r *http.Request) {
  109. userID := request.UserID(r)
  110. if _, err := h.store.UserByID(userID); err != nil {
  111. json.NotFound(w, r)
  112. return
  113. }
  114. hasIntegrations := h.store.HasSaveEntry(userID)
  115. response := struct {
  116. HasIntegrations bool `json:"has_integrations"`
  117. }{
  118. HasIntegrations: hasIntegrations,
  119. }
  120. json.OK(w, r, response)
  121. }
  122. func (h *handler) users(w http.ResponseWriter, r *http.Request) {
  123. if !request.IsAdminUser(r) {
  124. json.Forbidden(w, r)
  125. return
  126. }
  127. users, err := h.store.Users()
  128. if err != nil {
  129. json.ServerError(w, r, err)
  130. return
  131. }
  132. users.UseTimezone(request.UserTimezone(r))
  133. json.OK(w, r, users)
  134. }
  135. func (h *handler) userByID(w http.ResponseWriter, r *http.Request) {
  136. if !request.IsAdminUser(r) {
  137. json.Forbidden(w, r)
  138. return
  139. }
  140. userID := request.RouteInt64Param(r, "userID")
  141. user, err := h.store.UserByID(userID)
  142. if err != nil {
  143. json.BadRequest(w, r, errors.New("unable to fetch this user from the database"))
  144. return
  145. }
  146. if user == nil {
  147. json.NotFound(w, r)
  148. return
  149. }
  150. user.UseTimezone(request.UserTimezone(r))
  151. json.OK(w, r, user)
  152. }
  153. func (h *handler) userByUsername(w http.ResponseWriter, r *http.Request) {
  154. if !request.IsAdminUser(r) {
  155. json.Forbidden(w, r)
  156. return
  157. }
  158. username := request.RouteStringParam(r, "username")
  159. user, err := h.store.UserByUsername(username)
  160. if err != nil {
  161. json.BadRequest(w, r, errors.New("unable to fetch this user from the database"))
  162. return
  163. }
  164. if user == nil {
  165. json.NotFound(w, r)
  166. return
  167. }
  168. json.OK(w, r, user)
  169. }
  170. func (h *handler) removeUser(w http.ResponseWriter, r *http.Request) {
  171. if !request.IsAdminUser(r) {
  172. json.Forbidden(w, r)
  173. return
  174. }
  175. userID := request.RouteInt64Param(r, "userID")
  176. user, err := h.store.UserByID(userID)
  177. if err != nil {
  178. json.ServerError(w, r, err)
  179. return
  180. }
  181. if user == nil {
  182. json.NotFound(w, r)
  183. return
  184. }
  185. if user.ID == request.UserID(r) {
  186. json.BadRequest(w, r, errors.New("you cannot remove yourself"))
  187. return
  188. }
  189. h.store.RemoveUserAsync(user.ID)
  190. json.NoContent(w, r)
  191. }