prouter.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. package prouter
  2. /*
  3. ArOZ Online System Permission Router
  4. author: tobychui
  5. This request router implement the permission handling of aroz online
  6. user authentication systems, permission system and user system
  7. and is used as a wrapper to handle all http request within the system
  8. (aka. the replacement for http.HandleFunc)
  9. */
  10. import (
  11. "errors"
  12. "log"
  13. "net/http"
  14. "imuslab.com/arozos/mod/security/csrf"
  15. user "imuslab.com/arozos/mod/user"
  16. )
  17. type RouterOption struct {
  18. ModuleName string //The name of module that permission is based on
  19. AdminOnly bool //Require admin permission to use this API endpoint
  20. RequireLAN bool //Require LAN connection (aka no external access)
  21. CSRFTManager *csrf.TokenManager //The CSRF Token Manager, can be nil if CSRFT is false
  22. RequireCSRFT bool //Require CSRF Token to be accessiable
  23. UserHandler *user.UserHandler //System user handler
  24. DeniedHandler func(http.ResponseWriter, *http.Request) //Things to do when request is rejected
  25. }
  26. type RouterDef struct {
  27. moduleUUID string
  28. adminOnly bool
  29. requireLAN bool
  30. userHandler *user.UserHandler
  31. endpoints map[string]func(http.ResponseWriter, *http.Request)
  32. permissionDeniedHandler func(http.ResponseWriter, *http.Request)
  33. }
  34. func NewModuleRouter(option RouterOption) *RouterDef {
  35. return &RouterDef{
  36. moduleUUID: option.ModuleName,
  37. adminOnly: option.AdminOnly,
  38. userHandler: option.UserHandler,
  39. requireLAN: option.RequireLAN,
  40. endpoints: map[string]func(http.ResponseWriter, *http.Request){},
  41. permissionDeniedHandler: option.DeniedHandler,
  42. }
  43. }
  44. func (router *RouterDef) HandleFunc(endpoint string, handler func(http.ResponseWriter, *http.Request)) error {
  45. //Check if the endpoint already registered
  46. if _, exist := router.endpoints[endpoint]; exist {
  47. log.Println("WARNING! Duplicated registering of web endpoint: " + endpoint)
  48. return errors.New("Endpoint register duplicated")
  49. }
  50. authAgent := router.userHandler.GetAuthAgent()
  51. //OK. Register handler
  52. http.HandleFunc(endpoint, func(w http.ResponseWriter, r *http.Request) {
  53. //Check authentication of the user
  54. authAgent.HandleCheckAuth(w, r, func(w http.ResponseWriter, r *http.Request) {
  55. //Check if the user has permission to access this module
  56. userinfo, err := router.userHandler.GetUserInfoFromRequest(w, r)
  57. if err != nil {
  58. router.permissionDeniedHandler(w, r)
  59. return
  60. }
  61. //Check if the connection fits the RequireLAN requirement
  62. if router.requireLAN == true && checkIfLAN(r) == false {
  63. router.permissionDeniedHandler(w, r)
  64. return
  65. }
  66. //Check if this is a universal accessable router
  67. if router.moduleUUID == "" {
  68. //That means this router can serve anyone as soon as its fit the admin setting
  69. if router.adminOnly && !userinfo.IsAdmin() {
  70. router.permissionDeniedHandler(w, r)
  71. } else {
  72. handler(w, r)
  73. }
  74. return
  75. }
  76. //Check user permission to this module
  77. if userinfo.GetModuleAccessPermission(router.moduleUUID) {
  78. if router.adminOnly == true {
  79. //This module require admin. Check user is admin
  80. if userinfo.IsAdmin() == true {
  81. handler(w, r)
  82. } else {
  83. router.permissionDeniedHandler(w, r)
  84. return
  85. }
  86. } else {
  87. //This module do not require admin. Allow serving
  88. handler(w, r)
  89. }
  90. } else {
  91. //User has no permission to access this module
  92. router.permissionDeniedHandler(w, r)
  93. return
  94. }
  95. })
  96. })
  97. router.endpoints[endpoint] = handler
  98. return nil
  99. }