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.

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