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.

56 lines
1.3 KiB

  1. package auth
  2. import (
  3. "context"
  4. "log"
  5. "reflect"
  6. "git.aiterp.net/rpdata/api/models"
  7. )
  8. // CheckPermission does some magic.
  9. func CheckPermission(ctx context.Context, op string, obj interface{}) error {
  10. token := TokenFromContext(ctx)
  11. if token == nil {
  12. return ErrUnauthenticated
  13. }
  14. if reflect.TypeOf(obj).Kind() != reflect.Ptr {
  15. return CheckPermission(ctx, op, &obj)
  16. }
  17. var authorized = false
  18. switch v := obj.(type) {
  19. case *models.Channel:
  20. authorized = token.Permitted("channel." + op)
  21. case *models.Character:
  22. authorized = token.PermittedUser(v.Author, "member", "character."+op)
  23. case *models.Chapter:
  24. authorized = token.PermittedUser(v.Author, "member", "chapter."+op)
  25. case *models.Comment:
  26. if op == "add" && v.Author != token.UserID {
  27. return ErrInvalidOperation
  28. }
  29. authorized = token.PermittedUser(v.Author, "member", "comment."+op)
  30. case *models.File:
  31. authorized = token.PermittedUser(v.Author, "member", "file."+op)
  32. case *models.Log:
  33. authorized = token.Permitted("log." + op)
  34. case *models.Post:
  35. authorized = token.Permitted("post." + op)
  36. case *models.Story:
  37. authorized = token.PermittedUser(v.Author, "member", "story."+op)
  38. case *models.User:
  39. authorized = token.Permitted("user." + op)
  40. default:
  41. log.Panicf("Invalid model %T: %#+v", v, v)
  42. }
  43. if !authorized {
  44. return ErrUnauthorized
  45. }
  46. return nil
  47. }