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.

163 lines
4.7 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/internal/auth"
  9. "git.aiterp.net/rpdata/api/models/stories"
  10. "git.aiterp.net/rpdata/api/graph2/input"
  11. "git.aiterp.net/rpdata/api/models"
  12. "git.aiterp.net/rpdata/api/models/chapters"
  13. )
  14. // Queries
  15. func (r *resolver) Chapter(ctx context.Context, id string) (models.Chapter, error) {
  16. return chapters.FindID(id)
  17. }
  18. // Mutations
  19. func (r *mutationResolver) AddChapter(ctx context.Context, input input.ChapterAddInput) (models.Chapter, error) {
  20. story, err := stories.FindID(input.StoryID)
  21. if err != nil {
  22. return models.Chapter{}, errors.New("Story not found")
  23. }
  24. token := auth.TokenFromContext(ctx)
  25. if !token.Permitted("member", "story.add") {
  26. return models.Chapter{}, errors.New("Unauthorized")
  27. }
  28. author := token.UserID
  29. if input.Author != nil && *input.Author != author {
  30. if !token.Permitted("story.add") {
  31. return models.Chapter{}, errors.New("False pretender")
  32. }
  33. author = *input.Author
  34. }
  35. if !story.Open && story.Author != author {
  36. return models.Chapter{}, errors.New("Story is not open")
  37. }
  38. chapter, err := chapters.Add(story, input.Title, author, input.Source, time.Now(), input.FictionalDate)
  39. if err != nil {
  40. return models.Chapter{}, errors.New("Failed to create chapter: " + err.Error())
  41. }
  42. go changes.Submit("Chapter", "add", token.UserID, story.Listed, changekeys.Listed(story, chapter), story, chapter)
  43. return chapter, nil
  44. }
  45. func (r *mutationResolver) MoveChapter(ctx context.Context, input input.ChapterMoveInput) (models.Chapter, error) {
  46. chapter, err := chapters.FindID(input.ID)
  47. if err != nil {
  48. return models.Chapter{}, errors.New("Chapter not found")
  49. }
  50. token := auth.TokenFromContext(ctx)
  51. if !token.Authenticated() || !token.PermittedUser(chapter.Author, "member", "chapter.move") {
  52. return models.Chapter{}, errors.New("You are not allowed to move this chapter")
  53. }
  54. target, err := stories.FindID(input.StoryID)
  55. if err != nil {
  56. return models.Chapter{}, errors.New("Target story not found")
  57. }
  58. if !target.Open && !token.PermittedUser(target.Author, "member", "chapter.move") {
  59. return models.Chapter{}, errors.New("You are not permitted to move chapters to this story")
  60. }
  61. oldStoryID := chapter.StoryID
  62. chapter, err = chapters.Move(chapter, target)
  63. if err != nil {
  64. return models.Chapter{}, errors.New("Failed to move chapter: " + err.Error())
  65. }
  66. go func() {
  67. story, err := stories.FindID(chapter.StoryID)
  68. if err != nil {
  69. story.ID = chapter.StoryID
  70. }
  71. oldStory, err := stories.FindID(oldStoryID)
  72. if err != nil {
  73. oldStory.ID = oldStoryID
  74. }
  75. changes.Submit("Chapter", "move-out", chapter.Author, oldStory.Listed, changekeys.Many(oldStory, chapter), chapter)
  76. changes.Submit("Chapter", "move-in", token.UserID, story.Listed, changekeys.Listed(story, chapter), story, chapter)
  77. }()
  78. return chapter, nil
  79. }
  80. func (r *mutationResolver) EditChapter(ctx context.Context, input input.ChapterEditInput) (models.Chapter, error) {
  81. chapter, err := chapters.FindID(input.ID)
  82. if err != nil {
  83. return models.Chapter{}, errors.New("Chapter not found")
  84. }
  85. token := auth.TokenFromContext(ctx)
  86. if !token.Authenticated() || !token.PermittedUser(chapter.Author, "member", "chapter.edit") {
  87. return models.Chapter{}, errors.New("Unauthorized")
  88. }
  89. if input.ClearFictionalDate != nil && *input.ClearFictionalDate == true {
  90. input.FictionalDate = &time.Time{}
  91. }
  92. chapter, err = chapters.Edit(chapter, input.Title, input.Source, input.FictionalDate)
  93. if err != nil {
  94. return models.Chapter{}, errors.New("Failed to edit chapter: " + err.Error())
  95. }
  96. go func() {
  97. story, err := stories.FindID(chapter.StoryID)
  98. if err != nil {
  99. story.ID = chapter.StoryID
  100. }
  101. changes.Submit("Chapter", "edit", token.UserID, story.Listed, changekeys.Many(story, chapter), chapter)
  102. }()
  103. return chapter, nil
  104. }
  105. func (r *mutationResolver) RemoveChapter(ctx context.Context, input input.ChapterRemoveInput) (models.Chapter, error) {
  106. chapter, err := chapters.FindID(input.ID)
  107. if err != nil {
  108. return models.Chapter{}, errors.New("Chapter not found")
  109. }
  110. token := auth.TokenFromContext(ctx)
  111. if !token.Authenticated() || !token.PermittedUser(chapter.Author, "member", "chapter.remove") {
  112. return models.Chapter{}, errors.New("Unauthorized")
  113. }
  114. chapter, err = chapters.Remove(chapter)
  115. if err != nil {
  116. return models.Chapter{}, errors.New("Failed to remove chapter: " + err.Error())
  117. }
  118. go func() {
  119. story, err := stories.FindID(chapter.StoryID)
  120. if err != nil {
  121. story.ID = chapter.StoryID
  122. }
  123. changes.Submit("Chapter", "remove", token.UserID, story.Listed, changekeys.Many(story, chapter), chapter)
  124. }()
  125. return chapter, nil
  126. }