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.

299 lines
7.0 KiB

  1. package resolver
  2. import (
  3. "context"
  4. "errors"
  5. "strings"
  6. "git.aiterp.net/rpdata/api/internal/session"
  7. "git.aiterp.net/rpdata/api/loader"
  8. "git.aiterp.net/rpdata/api/model/change"
  9. "git.aiterp.net/rpdata/api/model/character"
  10. "git.aiterp.net/rpdata/api/model/log"
  11. "git.aiterp.net/rpdata/api/resolver/types"
  12. )
  13. // CharacterArgs is an arg
  14. type CharacterArgs struct {
  15. ID *string
  16. Nick *string
  17. }
  18. // Character resolver
  19. func (r *QueryResolver) Character(ctx context.Context, args *CharacterArgs) (*types.CharacterResolver, error) {
  20. var char character.Character
  21. var err error
  22. loader := loader.FromContext(ctx)
  23. if loader == nil {
  24. return nil, errors.New("no loader")
  25. }
  26. switch {
  27. case args.ID != nil:
  28. char, err = character.FindID(*args.ID)
  29. case args.Nick != nil:
  30. char, err = character.FindNick(*args.Nick)
  31. default:
  32. err = ErrCannotResolve
  33. }
  34. if err != nil {
  35. return nil, err
  36. }
  37. return &types.CharacterResolver{C: char}, nil
  38. }
  39. // CharactersArgs is an arg
  40. type CharactersArgs struct {
  41. IDs *[]string
  42. Nicks *[]string
  43. Author *string
  44. }
  45. // Characters resolves the characters query
  46. func (r *QueryResolver) Characters(ctx context.Context, args *CharactersArgs) ([]*types.CharacterResolver, error) {
  47. var chars []character.Character
  48. var err error
  49. loader := loader.FromContext(ctx)
  50. if loader == nil {
  51. return nil, errors.New("no loader")
  52. }
  53. switch {
  54. case args.IDs != nil:
  55. chars, err = character.ListIDs(*args.IDs...)
  56. case args.Nicks != nil:
  57. chars, err = character.ListNicks(*args.Nicks...)
  58. case args.Author != nil:
  59. chars, err = character.ListAuthor(*args.Author)
  60. default:
  61. chars, err = character.List()
  62. }
  63. if err != nil {
  64. return nil, err
  65. }
  66. resolvers := make([]*types.CharacterResolver, 0, len(chars))
  67. for i := range chars {
  68. if chars[i].ID == "" {
  69. continue
  70. }
  71. resolvers = append(resolvers, &types.CharacterResolver{C: chars[i]})
  72. }
  73. return resolvers, nil
  74. }
  75. // AddCharacterInput is args for the addCharacter mutation
  76. type AddCharacterInput struct {
  77. Nick string
  78. Name string
  79. ShortName *string
  80. Author *string
  81. Description *string
  82. }
  83. // AddCharacter resolves the addCharacter mutation
  84. func (r *MutationResolver) AddCharacter(ctx context.Context, args struct{ Input *AddCharacterInput }) (*types.CharacterResolver, error) {
  85. input := args.Input
  86. user := session.FromContext(ctx).User()
  87. if user == nil || !user.Permitted("member", "character.add") {
  88. return nil, ErrUnauthorized
  89. }
  90. nick := input.Nick
  91. name := input.Name
  92. shortName := ""
  93. if input.ShortName != nil {
  94. shortName = *input.ShortName
  95. } else {
  96. shortName = strings.SplitN(input.Name, " ", 2)[0]
  97. }
  98. author := user.ID
  99. if input.Author != nil {
  100. author = *input.Author
  101. if author != user.ID && !user.Permitted("character.add") {
  102. return nil, ErrPermissionDenied
  103. }
  104. }
  105. description := ""
  106. if input.Description != nil {
  107. description = *input.Description
  108. }
  109. character, err := character.New(nick, name, shortName, author, description)
  110. if err != nil {
  111. return nil, err
  112. }
  113. go change.Submit("Character", "add", user.ID, character.ID, map[string]interface{}{
  114. "name": character.Name,
  115. "nick": character.Nicks[0],
  116. "author": character.Author,
  117. })
  118. log.ScheduleCharacterUpdate()
  119. return &types.CharacterResolver{C: character}, nil
  120. }
  121. // CharacterNickInput is args for mutation addCharacterNick/removeCharacterNick
  122. type CharacterNickInput struct {
  123. ID string
  124. Nick string
  125. }
  126. // AddCharacterNick resolves the addCharacterNick mutation
  127. func (r *MutationResolver) AddCharacterNick(ctx context.Context, args struct{ Input *CharacterNickInput }) (*types.CharacterResolver, error) {
  128. input := args.Input
  129. user := session.FromContext(ctx).User()
  130. if user == nil || !user.Permitted("member") {
  131. return nil, ErrUnauthorized
  132. }
  133. character, err := character.FindID(input.ID)
  134. if err != nil {
  135. return nil, err
  136. }
  137. if character.Author != user.ID && !user.Permitted("character.edit") {
  138. return nil, ErrPermissionDenied
  139. }
  140. err = character.AddNick(input.Nick)
  141. if err != nil {
  142. return nil, err
  143. }
  144. go change.Submit("Character", "add.nick", user.ID, character.ID, map[string]interface{}{
  145. "nick": input.Nick,
  146. })
  147. log.ScheduleCharacterUpdate()
  148. return &types.CharacterResolver{C: character}, nil
  149. }
  150. // RemoveCharacterNick resolves the removeCharacterNick mutation
  151. func (r *MutationResolver) RemoveCharacterNick(ctx context.Context, args struct{ Input *CharacterNickInput }) (*types.CharacterResolver, error) {
  152. input := args.Input
  153. user := session.FromContext(ctx).User()
  154. if user == nil || !user.Permitted("member") {
  155. return nil, ErrUnauthorized
  156. }
  157. character, err := character.FindID(input.ID)
  158. if err != nil {
  159. return nil, err
  160. }
  161. if character.Author != user.ID && !user.Permitted("character.edit") {
  162. return nil, ErrPermissionDenied
  163. }
  164. err = character.RemoveNick(input.Nick)
  165. if err != nil {
  166. return nil, err
  167. }
  168. go change.Submit("Character", "remove.nick", user.ID, character.ID, map[string]interface{}{
  169. "nick": input.Nick,
  170. })
  171. log.ScheduleCharacterUpdate()
  172. return &types.CharacterResolver{C: character}, nil
  173. }
  174. // CharacterEditInput is args for mutation addCharacterNick/removeCharacterNick
  175. type CharacterEditInput struct {
  176. ID string
  177. Name *string
  178. ShortName *string
  179. Description *string
  180. }
  181. // EditCharacter resolves the editCharacter mutation
  182. func (r *MutationResolver) EditCharacter(ctx context.Context, args struct{ Input *CharacterEditInput }) (*types.CharacterResolver, error) {
  183. input := args.Input
  184. user := session.FromContext(ctx).User()
  185. if user == nil || !user.Permitted("member") {
  186. return nil, ErrUnauthorized
  187. }
  188. character, err := character.FindID(input.ID)
  189. if err != nil {
  190. return nil, err
  191. }
  192. if character.Author != user.ID && !user.Permitted("character.edit") {
  193. return nil, ErrPermissionDenied
  194. }
  195. name := ""
  196. if input.Name != nil {
  197. name = *input.Name
  198. }
  199. shortName := ""
  200. if input.ShortName != nil {
  201. shortName = *input.ShortName
  202. }
  203. description := ""
  204. if input.Description != nil {
  205. description = *input.Description
  206. }
  207. err = character.Edit(name, shortName, description)
  208. if err != nil {
  209. return nil, err
  210. }
  211. go change.Submit("Character", "edit", user.ID, character.ID, map[string]interface{}{
  212. "name": character.Name,
  213. "shortName": character.ShortName,
  214. "description": character.Description,
  215. })
  216. return &types.CharacterResolver{C: character}, nil
  217. }
  218. // RemoveCharacter resolves the removeCharacter mutation
  219. func (r *MutationResolver) RemoveCharacter(ctx context.Context, args struct{ ID string }) (*types.CharacterResolver, error) {
  220. user := session.FromContext(ctx).User()
  221. if user == nil || !user.Permitted("member") {
  222. return nil, ErrUnauthorized
  223. }
  224. character, err := character.FindID(args.ID)
  225. if err != nil {
  226. return nil, err
  227. }
  228. if character.Author != user.ID && !user.Permitted("character.remove") {
  229. return nil, ErrPermissionDenied
  230. }
  231. err = character.Remove()
  232. if err != nil {
  233. return nil, err
  234. }
  235. go change.Submit("Character", "remove", user.ID, character.ID, map[string]interface{}{
  236. "name": character.Name,
  237. "author": character.Author,
  238. "nicks": character.Nicks,
  239. })
  240. return &types.CharacterResolver{C: character}, nil
  241. }