GraphQL API and utilities for the rpdata project
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.

181 lines
5.2 KiB

  1. package queries
  2. import (
  3. "context"
  4. "errors"
  5. "time"
  6. "git.aiterp.net/rpdata/api/models/changekeys"
  7. "git.aiterp.net/rpdata/api/models/changes"
  8. "git.aiterp.net/rpdata/api/graph2/input"
  9. "git.aiterp.net/rpdata/api/internal/auth"
  10. "git.aiterp.net/rpdata/api/models"
  11. "git.aiterp.net/rpdata/api/models/chapters"
  12. "git.aiterp.net/rpdata/api/models/stories"
  13. )
  14. func (r *resolver) Story(ctx context.Context, id string) (models.Story, error) {
  15. return stories.FindID(id)
  16. }
  17. func (r *resolver) Stories(ctx context.Context, filter *stories.Filter) ([]models.Story, error) {
  18. if filter != nil {
  19. if filter.Unlisted != nil && *filter.Unlisted == true {
  20. token := auth.TokenFromContext(ctx)
  21. if !token.Authenticated() {
  22. return nil, errors.New("You are not permitted to view unlisted stories")
  23. }
  24. if !token.Permitted("story.unlisted") {
  25. filter.Author = &token.UserID
  26. }
  27. }
  28. }
  29. return stories.List(filter)
  30. }
  31. // Mutations
  32. func (r *mutationResolver) AddStory(ctx context.Context, input input.StoryAddInput) (models.Story, error) {
  33. token := auth.TokenFromContext(ctx)
  34. if token == nil || !token.Permitted("member", "story.add") {
  35. return models.Story{}, errors.New("Permission denied")
  36. }
  37. author := token.UserID
  38. if input.Author != nil && *input.Author != author {
  39. if !token.Permitted("story.add") {
  40. return models.Story{}, errors.New("You are not permitted to add a story in another author's name")
  41. }
  42. author = *input.Author
  43. }
  44. fictionalDate := time.Time{}
  45. if input.FictionalDate != nil {
  46. fictionalDate = *input.FictionalDate
  47. }
  48. listed := input.Listed != nil && *input.Listed
  49. open := input.Open != nil && *input.Open
  50. story, err := stories.Add(input.Name, author, input.Category, listed, open, input.Tags, time.Now(), fictionalDate)
  51. if err != nil {
  52. return models.Story{}, errors.New("Failed to add story: " + err.Error())
  53. }
  54. go changes.Submit("Story", "add", token.UserID, story.Listed, changekeys.Listed(story), story)
  55. return story, nil
  56. }
  57. func (r *mutationResolver) AddStoryTag(ctx context.Context, input input.StoryTagAddInput) (models.Story, error) {
  58. token := auth.TokenFromContext(ctx)
  59. story, err := stories.FindID(input.ID)
  60. if err != nil {
  61. return models.Story{}, errors.New("Story not found")
  62. }
  63. if story.Open {
  64. if !token.Permitted("member") {
  65. return models.Story{}, errors.New("You are not permitted to edit this story")
  66. }
  67. } else {
  68. if !token.PermittedUser(story.Author, "member", "story.edit") {
  69. return models.Story{}, errors.New("You are not permitted to edit this story")
  70. }
  71. }
  72. story, err = stories.AddTag(story, input.Tag)
  73. if err != nil {
  74. return models.Story{}, errors.New("Failed to add story: " + err.Error())
  75. }
  76. go changes.Submit("Story", "tag", token.UserID, story.Listed, changekeys.Listed(story), story, input.Tag)
  77. return story, nil
  78. }
  79. func (r *mutationResolver) RemoveStoryTag(ctx context.Context, input input.StoryTagRemoveInput) (models.Story, error) {
  80. token := auth.TokenFromContext(ctx)
  81. story, err := stories.FindID(input.ID)
  82. if err != nil {
  83. return models.Story{}, errors.New("Story not found")
  84. }
  85. if story.Open {
  86. if !token.Permitted("member") {
  87. return models.Story{}, errors.New("You are not permitted to edit this story")
  88. }
  89. } else {
  90. if !token.PermittedUser(story.Author, "member", "story.edit") {
  91. return models.Story{}, errors.New("You are not permitted to edit this story")
  92. }
  93. }
  94. story, err = stories.RemoveTag(story, input.Tag)
  95. if err != nil {
  96. return models.Story{}, errors.New("Failed to add story: " + err.Error())
  97. }
  98. go changes.Submit("Story", "untag", token.UserID, story.Listed, changekeys.Listed(story), story, input.Tag)
  99. return story, nil
  100. }
  101. func (r *mutationResolver) EditStory(ctx context.Context, input input.StoryEditInput) (models.Story, error) {
  102. token := auth.TokenFromContext(ctx)
  103. story, err := stories.FindID(input.ID)
  104. if err != nil {
  105. return models.Story{}, errors.New("Story not found")
  106. }
  107. if !token.PermittedUser(story.Author, "member", "story.edit") {
  108. return models.Story{}, errors.New("You are not permitted to remove this story")
  109. }
  110. if input.ClearFictionalDate != nil && *input.ClearFictionalDate {
  111. input.FictionalDate = &time.Time{}
  112. }
  113. story, err = stories.Edit(story, input.Name, input.Category, input.Listed, input.Open, input.FictionalDate)
  114. if err != nil {
  115. return models.Story{}, errors.New("Failed to add story: " + err.Error())
  116. }
  117. go changes.Submit("Story", "edit", token.UserID, story.Listed, changekeys.Listed(story), story)
  118. return story, nil
  119. }
  120. func (r *mutationResolver) RemoveStory(ctx context.Context, input input.StoryRemoveInput) (models.Story, error) {
  121. token := auth.TokenFromContext(ctx)
  122. story, err := stories.FindID(input.ID)
  123. if err != nil {
  124. return models.Story{}, errors.New("Story not found")
  125. }
  126. if !token.PermittedUser(story.Author, "member", "story.remove") {
  127. return models.Story{}, errors.New("You are not permitted to remove this story")
  128. }
  129. story, err = stories.Remove(story)
  130. if err != nil {
  131. return models.Story{}, err
  132. }
  133. err = chapters.RemoveStory(story)
  134. if err != nil {
  135. return models.Story{}, errors.New("Failed to remove chapters, but story is removed: " + err.Error())
  136. }
  137. go changes.Submit("Story", "remove", token.UserID, story.Listed, changekeys.Listed(story), story)
  138. return story, nil
  139. }