package main import ( "fmt" "path/filepath" "strings" "time" cfg "github.com/jesusperez/cfgsrv" log "github.com/sirupsen/logrus" "github.com/casbin/casbin/v2" "github.com/gin-contrib/cors" "github.com/gin-contrib/multitemplate" "github.com/gin-gonic/gin" "github.com/pkg/browser" ) func loadTemplates(templatesDir string,templatesFiles map[string]cfg.TemplateItem,includesPath string, layoutsPath string) multitemplate.Renderer { r := multitemplate.NewRenderer() layouts, err := filepath.Glob(strings.Replace(layoutsPath,"@",(templatesDir+"/"),-1) + "/*.html") if err != nil { log.Fatalf("Error auth model loaded: %v\n", err) } includes, err := filepath.Glob(strings.Replace(includesPath,"@",(templatesDir+"/"),-1) + "/*.html") if err != nil { log.Fatalf("Error auth model loaded: %v\n", err) } for ky, tpl := range templatesFiles { if strings.Contains(tpl.Path,"@") { r.AddFromFiles(ky,templatesDir + strings.Replace(tpl.Path,"@","/",-1)) } else { r.AddFromFiles(ky,tpl.Path) } } // Generate our templates map from our layouts/ and includes/ directories for _, include := range includes { layoutCopy := make([]string, len(layouts)) copy(layoutCopy, layouts) files := append(layoutCopy, include) r.AddFromFiles(filepath.Base(include), files...) } return r } func run_web(cfg *cfg.Config,users *UsersAccounts,mdlsUsrs map[string]ModelUser, runFlags *RunFlags) { // logger := log.New(os.Stderr, "", 0) var err error var enforcer *casbin.Enforcer if cfg.UseAuthz { enforcer,err = casbin.NewEnforcer(cfg.AuthzModel, cfg.AuthzPolicy) // load the casbin model and policy from files, database is also supported. if err != nil { log.Fatalf("Error auth model loaded: %v\n",err) } } // logger.Println("[WARNING] DON'T USE THE EMBED CERTS FROM THIS EXAMPLE IN PRODUCTION ENVIRONMENT, GENERATE YOUR OWN!") gin.SetMode(gin.ReleaseMode) router := gin.Default() corsConfig := cors.Config{ AllowOrigins: cfg.AllowOrigins, // []string{"*"}, // , // []string{"http://localhost:3333"}, AllowMethods: []string{"GET", "POST", "PUT", "PATCH", "DELETE", "HEAD"}, AllowHeaders: []string{"Origin", "Authorization","Content-Length", "Content-Type","X-Request-With","Accept","Accept-Encoding"}, ExposeHeaders: []string{"Content-Length"}, AllowCredentials: true, MaxAge: 12 * time.Hour, // // AllowOriginFunc: func(origin string) bool { // // return origin == "https://github.com" // // }, } // corsConfig := cors.DefaultConfig() // corsConfig.AllowAllOrigins = []string{"http://localhost:3333'"} // corsConfig.AllowCredentials = true // c.Header("Access-Control-Allow-Origin", "*") // c.Header("Access-Control-Allow-Credentials", "true") // c.Header("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With") // c.Header("Access-Control-Allow-Methods", "POST,HEAD,PATCH, OPTIONS, GET, PUT") corsConfig.AllowOrigins = cfg.AllowOrigins // []string{"http://localhost:3333"}, router.Use(cors.New(corsConfig)) log.WithFields(log.Fields{ "run": "run_web", }).Info(fmt.Sprintf("templates path: %v\n", cfg.TemplatesFiles)) //var templ //templ := template.Must(template.New("").ParseFS(f,cfg.TemplatesPaths[:]...)) //templ := template.Must(template.ParseFS(f,cfg.TemplatesPaths[:]...)) //templ := template.Must(template.ParseFS(f,"templates")) //templ := template.Must(template.ParseFS(f,cfg.TemplatesPaths[:]...)) //router.SetHTMLTemplate(templ) //router.LoadHTMLGlob("templates/*.tmpl") router.HTMLRender = loadTemplates(cfg.TemplatesRoot,cfg.TemplatesFiles,cfg.TemplatesIncludes,cfg.TemplatesLayouts) // router.Use(ginI18n.Localize( // ginI18n.WithGetLngHandle( // func(context *gin.Context, defaultLng string) string { // lng := context.Query("lng") // if lng == "" { // return defaultLng // } // return lng // }, // ), // )) // apply i18n middleware // router.StaticFS("/public", http.FS(f)) router.Static(cfg.AssetsURL,cfg.AssetsPath) var store interface{} if len(cfg.RedisHost) > 0 { store = load_redis(cfg) } getRoutes(router,cfg,users,mdlsUsrs,enforcer,&store,runFlags) hostport := fmt.Sprintf("%s:%d",cfg.Host,cfg.Port) log.WithFields(log.Fields{ "run": "run_web", }).Info(fmt.Sprintf("Running on %s://%s",cfg.Protocol,hostport)) if cfg.OpenBrowser { if len(runFlags.url) == 0 { browser.OpenURL(fmt.Sprintf("%s://%s",cfg.Protocol,hostport)) } else { browser.OpenURL(fmt.Sprintf(runFlags.url)) } } if cfg.Protocol == "https" { err = router.RunTLS(hostport, cfg.CertPem, cfg.KeyPem) } else { err = router.Run(hostport) } if err != nil { log.Fatalf("Error run webserver: %v", err) } } func webservice(runFlags RunFlags) int { cfg,err := loadDataConfig(runFlags) //fmt.Printf("Loaded config: %#v\n", cfg) if err != nil { return 1 } if cfg.GenDist { errModel := createRootModels(cfg) if errModel != nil { fmt.Printf("Error createRootModels: %v\n",errModel) return 1 } generr := genJsonModels(cfg) if generr != nil { fmt.Printf("Error genJsonModels: %v\n",generr) return 1 } } acc,err := loadUsersAccounts(cfg.UsersPath) if err != nil { return 1 } mdlsUsrs,err := loadModelsUsers(cfg.UsersModelsPath) if err != nil { return 1 } setLog(cfg) run_web(cfg,acc,mdlsUsrs,&runFlags) return 0 }