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.
 
 

126 lines
4.1 KiB

  1. #lang racket
  2. (require db
  3. redis
  4. json
  5. threading
  6. racket/match
  7. web-server/http
  8. web-server/http/response
  9. web-server/http/bindings
  10. web-server/servlet-dispatch
  11. web-server/web-server
  12. (prefix-in filter: web-server/dispatchers/dispatch-filter)
  13. (prefix-in sequencer: web-server/dispatchers/dispatch-sequencer)
  14. "db.rkt"
  15. "groups.rkt"
  16. "privileges.rkt"
  17. "resource.rkt")
  18. ;;;; Endpoints
  19. ;; Query available actions for a resource, for a given user
  20. (define (query-available-endpoint req)
  21. (define binds (request-bindings/raw req))
  22. (define (masked-actions actions)
  23. (for/hash ([(k v) (in-hash actions)])
  24. (values k (map car v))))
  25. (define message
  26. (match (list (bindings-assq #"resource" binds)
  27. (bindings-assq #"user" binds))
  28. [(list #f #f)
  29. "provide resource and user id"]
  30. [(list (binding:form _ res-id)
  31. (binding:form _ user-id))
  32. (let* ((res (get-resource res-id))
  33. (mask (get-mask-for-user
  34. res
  35. (bytes->string/utf-8 user-id))))
  36. (~> (apply-mask (dict-ref resource-types
  37. (resource-type res))
  38. mask)
  39. (masked-actions)
  40. (jsexpr->bytes)))]))
  41. (response/output
  42. (lambda (out)
  43. (displayln message out))))
  44. (define (query-available-dispatcher conn req)
  45. (output-response conn (query-available-endpoint req)))
  46. (define (action-params action binds)
  47. (for/hash ([k (action-req-params action)])
  48. (values k
  49. (~> k
  50. (symbol->string)
  51. (string->bytes/utf-8)
  52. (bindings-assq _ binds)
  53. (binding:form-value)))))
  54. (define (run-action-endpoint req)
  55. (define binds (request-bindings/raw req))
  56. (define message
  57. (match (list (bindings-assq #"resource" binds)
  58. (bindings-assq #"user" binds)
  59. (bindings-assq #"branch" binds)
  60. (bindings-assq #"action" binds))
  61. [(list #f #f #f #f)
  62. "provide resource id, user id, and action to perform"]
  63. [(list (binding:form _ res-id)
  64. #f
  65. (binding:form _ branch)
  66. (binding:form _ action))
  67. (let* ((res (get-resource res-id))
  68. (branch (~> branch
  69. (bytes->string/utf-8)
  70. (string->symbol)))
  71. (action (bytes->string/utf-8 action)))
  72. (let ((action (access-action res
  73. (cons branch action))))
  74. (if action
  75. (run-action action
  76. (resource-data res)
  77. (action-params action binds))
  78. "no access")))]
  79. [(list (binding:form _ res-id)
  80. (binding:form _ user-id)
  81. (binding:form _ branch)
  82. (binding:form _ action))
  83. (let* ((res (get-resource res-id))
  84. (branch (~> branch
  85. (bytes->string/utf-8)
  86. (string->symbol)))
  87. (action (bytes->string/utf-8 action)))
  88. (let ((action (access-action res
  89. (cons branch action)
  90. #:user (bytes->string/utf-8 user-id))))
  91. (if action
  92. (run-action action
  93. (resource-data res)
  94. (action-params action binds))
  95. "no access")))]))
  96. (response/output
  97. (lambda (out)
  98. (displayln message out))))
  99. (define (run-action-dispatcher conn req)
  100. (output-response conn (run-action-endpoint req)))
  101. ;; Run the server
  102. (define stop
  103. (serve
  104. #:dispatch (sequencer:make
  105. (filter:make #rx"^/available/"
  106. query-available-dispatcher)
  107. (filter:make #rx"^/run-action/"
  108. run-action-dispatcher))
  109. #:listen-ip "127.0.0.1"
  110. #:port (string->number
  111. (or (getenv "PORT")
  112. "8080"))))
  113. (with-handlers ([exn:break? (lambda (e)
  114. (stop))])
  115. (sync/enable-break never-evt))