prouter.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  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. user "imuslab.com/arozos/mod/user"
  15. )
  16. type RouterOption struct {
  17. ModuleName string //The name of module that permission is based on
  18. AdminOnly bool //Require admin permission to use this API endpoint
  19. RequireLAN bool //Require LAN connection (aka no external access)
  20. UserHandler *user.UserHandler //System user handler
  21. DeniedHandler func(http.ResponseWriter, *http.Request) //Things to do when request is rejected
  22. }
  23. type RouterDef struct {
  24. moduleUUID string
  25. adminOnly bool
  26. requireLAN bool
  27. userHandler *user.UserHandler
  28. endpoints map[string]func(http.ResponseWriter, *http.Request)
  29. permissionDeniedHandler func(http.ResponseWriter, *http.Request)
  30. }
  31. func NewModuleRouter(option RouterOption) *RouterDef {
  32. return &RouterDef{
  33. moduleUUID: option.ModuleName,
  34. adminOnly: option.AdminOnly,
  35. userHandler: option.UserHandler,
  36. requireLAN: option.RequireLAN,
  37. endpoints: map[string]func(http.ResponseWriter, *http.Request){},
  38. permissionDeniedHandler: option.DeniedHandler,
  39. }
  40. }
  41. func (router *RouterDef) HandleFunc(endpoint string, handler func(http.ResponseWriter, *http.Request)) error {
  42. //Check if the endpoint already registered
  43. if _, exist := router.endpoints[endpoint]; exist {
  44. log.Println("WARNING! Duplicated registering of web endpoint: " + endpoint)
  45. return errors.New("Endpoint register duplicated")
  46. }
  47. authAgent := router.userHandler.GetAuthAgent()
  48. //OK. Register handler
  49. http.HandleFunc(endpoint, func(w http.ResponseWriter, r *http.Request) {
  50. //Check authentication of the user
  51. authAgent.HandleCheckAuth(w, r, func(w http.ResponseWriter, r *http.Request) {
  52. //Check if the user has permission to access this module
  53. userinfo, err := router.userHandler.GetUserInfoFromRequest(w, r)
  54. if err != nil {
  55. router.permissionDeniedHandler(w, r)
  56. return
  57. }
  58. //Check if the connection fits the RequireLAN requirement
  59. if router.requireLAN == true && checkIfLAN(r) == false {
  60. router.permissionDeniedHandler(w, r)
  61. return
  62. }
  63. //Check if this is a universal accessable router
  64. if router.moduleUUID == "" {
  65. //That means this router can serve anyone as soon as its fit the admin setting
  66. if router.adminOnly && !userinfo.IsAdmin() {
  67. router.permissionDeniedHandler(w, r)
  68. } else {
  69. handler(w, r)
  70. }
  71. return
  72. }
  73. //Check user permission to this module
  74. if userinfo.GetModuleAccessPermission(router.moduleUUID) {
  75. if router.adminOnly == true {
  76. //This module require admin. Check user is admin
  77. if userinfo.IsAdmin() == true {
  78. handler(w, r)
  79. } else {
  80. router.permissionDeniedHandler(w, r)
  81. return
  82. }
  83. } else {
  84. //This module do not require admin. Allow serving
  85. handler(w, r)
  86. }
  87. } else {
  88. //User has no permission to access this module
  89. router.permissionDeniedHandler(w, r)
  90. return
  91. }
  92. })
  93. })
  94. router.endpoints[endpoint] = handler
  95. return nil
  96. }