| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 | package prouter/*	ArOZ Online System Permission Router	author: tobychui	This request router implement the permission handling of aroz online	user authentication systems, permission system and user system	and is used as a wrapper to handle all http request within the system	(aka. the replacement for http.HandleFunc)*/import (	"errors"	"log"	"net/http"	"imuslab.com/arozos/mod/security/csrf"	user "imuslab.com/arozos/mod/user")type RouterOption struct {	ModuleName    string                                   //The name of module that permission is based on	AdminOnly     bool                                     //Require admin permission to use this API endpoint	RequireLAN    bool                                     //Require LAN connection (aka no external access)	CSRFTManager  *csrf.TokenManager                       //The CSRF Token Manager, can be nil if CSRFT is false	RequireCSRFT  bool                                     //Require CSRF Token to be accessiable	UserHandler   *user.UserHandler                        //System user handler	DeniedHandler func(http.ResponseWriter, *http.Request) //Things to do when request is rejected}type RouterDef struct {	moduleUUID              string	adminOnly               bool	requireLAN              bool	userHandler             *user.UserHandler	endpoints               map[string]func(http.ResponseWriter, *http.Request)	permissionDeniedHandler func(http.ResponseWriter, *http.Request)}func NewModuleRouter(option RouterOption) *RouterDef {	return &RouterDef{		moduleUUID:              option.ModuleName,		adminOnly:               option.AdminOnly,		userHandler:             option.UserHandler,		requireLAN:              option.RequireLAN,		endpoints:               map[string]func(http.ResponseWriter, *http.Request){},		permissionDeniedHandler: option.DeniedHandler,	}}func (router *RouterDef) HandleFunc(endpoint string, handler func(http.ResponseWriter, *http.Request)) error {	//Check if the endpoint already registered	if _, exist := router.endpoints[endpoint]; exist {		log.Println("WARNING! Duplicated registering of web endpoint: " + endpoint)		return errors.New("Endpoint register duplicated")	}	authAgent := router.userHandler.GetAuthAgent()	//OK. Register handler	http.HandleFunc(endpoint, func(w http.ResponseWriter, r *http.Request) {		//Check authentication of the user		authAgent.HandleCheckAuth(w, r, func(w http.ResponseWriter, r *http.Request) {			//Check if the user has permission to access this module			userinfo, err := router.userHandler.GetUserInfoFromRequest(w, r)			if err != nil {				router.permissionDeniedHandler(w, r)				return			}			//Check if the connection fits the RequireLAN requirement			if router.requireLAN == true && checkIfLAN(r) == false {				router.permissionDeniedHandler(w, r)				return			}			//Check if this is a universal accessable router			if router.moduleUUID == "" {				//That means this router can serve anyone as soon as its fit the admin setting				if router.adminOnly && !userinfo.IsAdmin() {					router.permissionDeniedHandler(w, r)				} else {					handler(w, r)				}				return			}			//Check user permission to this module			if userinfo.GetModuleAccessPermission(router.moduleUUID) {				if router.adminOnly == true {					//This module require admin. Check user is admin					if userinfo.IsAdmin() == true {						handler(w, r)					} else {						router.permissionDeniedHandler(w, r)						return					}				} else {					//This module do not require admin. Allow serving					handler(w, r)				}			} else {				//User has no permission to access this module				router.permissionDeniedHandler(w, r)				return			}		})	})	router.endpoints[endpoint] = handler	return nil}
 |