fieldperm.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. package permlib
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "io"
  6. "net/http"
  7. )
  8. type fieldPermEntry struct {
  9. jsonName string
  10. permCode string
  11. }
  12. type filterResponseWriter struct {
  13. http.ResponseWriter
  14. buf bytes.Buffer
  15. req *http.Request
  16. perms []string
  17. engine *Engine
  18. code int
  19. }
  20. func newFilterResponseWriter(w http.ResponseWriter, req *http.Request, perms []string, e *Engine) *filterResponseWriter {
  21. return &filterResponseWriter{
  22. ResponseWriter: w,
  23. req: req,
  24. perms: perms,
  25. engine: e,
  26. code: 200,
  27. }
  28. }
  29. func (fw *filterResponseWriter) WriteHeader(code int) {
  30. fw.code = code
  31. }
  32. func (fw *filterResponseWriter) Write(b []byte) (int, error) {
  33. return fw.buf.Write(b)
  34. }
  35. func (fw *filterResponseWriter) flush() {
  36. body := fw.buf.Bytes()
  37. if len(body) > 0 {
  38. body = fw.engine.filterResponseBody(body, fw.req, fw.perms)
  39. }
  40. fw.ResponseWriter.WriteHeader(fw.code)
  41. fw.ResponseWriter.Write(body)
  42. }
  43. func (e *Engine) filterResponseBody(body []byte, req *http.Request, perms []string) []byte {
  44. key := req.Method + " " + req.URL.Path
  45. if fm, ok := e.fieldPerms[key]; ok && len(fm.Response) > 0 {
  46. return filterResponseByMap(body, fm.Response, perms)
  47. }
  48. return body
  49. }
  50. func filterResponseByMap(body []byte, fieldMap map[string]string, perms []string) []byte {
  51. permSet := toPermSet(perms)
  52. body = bytes.TrimSpace(body)
  53. if len(body) == 0 {
  54. return body
  55. }
  56. entries := make([]fieldPermEntry, 0, len(fieldMap))
  57. for jsonField, permCode := range fieldMap {
  58. entries = append(entries, fieldPermEntry{jsonName: jsonField, permCode: permCode})
  59. }
  60. if body[0] == '[' {
  61. var arr []json.RawMessage
  62. if err := json.Unmarshal(body, &arr); err != nil {
  63. return body
  64. }
  65. for i, item := range arr {
  66. arr[i] = filterObject(item, entries, permSet)
  67. }
  68. result, _ := json.Marshal(arr)
  69. return result
  70. }
  71. return filterObject(body, entries, permSet)
  72. }
  73. func filterObject(raw json.RawMessage, entries []fieldPermEntry, permSet map[string]bool) json.RawMessage {
  74. var obj map[string]json.RawMessage
  75. if err := json.Unmarshal(raw, &obj); err != nil {
  76. return raw
  77. }
  78. for _, entry := range entries {
  79. if _, has := obj[entry.jsonName]; has && !permSet[entry.permCode] {
  80. delete(obj, entry.jsonName)
  81. }
  82. }
  83. result, _ := json.Marshal(obj)
  84. return result
  85. }
  86. func toPermSet(perms []string) map[string]bool {
  87. m := make(map[string]bool, len(perms))
  88. for _, p := range perms {
  89. m[p] = true
  90. }
  91. return m
  92. }
  93. func readBody(req *http.Request) ([]byte, error) {
  94. if req.Body == nil {
  95. return nil, nil
  96. }
  97. body, err := io.ReadAll(req.Body)
  98. req.Body.Close()
  99. if err != nil {
  100. return nil, err
  101. }
  102. req.Body = io.NopCloser(bytes.NewReader(body))
  103. return body, nil
  104. }
  105. func restoreBody(req *http.Request, body []byte) {
  106. req.Body = io.NopCloser(bytes.NewReader(body))
  107. }