//SharedData fills in common data, such as user info, etc... func SharedData() gin.HandlerFunc { return func(c *gin.Context) { session := sessions.Default(c) if uID := session.Get("UserID"); uID != nil { user, _ := models.GetUser(uID) if user.ID != 0 { c.Set("User", user) } } if system.GetConfig().SignupEnabled { c.Set("SignupEnabled", true) } c.Next() } }
//setSessions initializes sessions & csrf middlewares func setSessions(router *gin.Engine) { config := system.GetConfig() //https://github.com/gin-gonic/contrib/tree/master/sessions store := sessions.NewCookieStore([]byte(config.SessionSecret)) store.Options(sessions.Options{HttpOnly: true, MaxAge: 7 * 86400}) //Also set Secure: true if using SSL, you should though router.Use(sessions.Sessions("gin-session", store)) //https://github.com/utrack/gin-csrf router.Use(csrf.Middleware(csrf.Options{ Secret: config.SessionSecret, ErrorFunc: func(c *gin.Context) { c.String(400, "CSRF token mismatch") c.Abort() }, })) }
//RssGet handles GET /rss route func RssGet(c *gin.Context) { now := time.Now() domain := system.GetConfig().Domain feed := &feeds.Feed{ Title: "ginblog", Link: &feeds.Link{Href: domain}, Description: "GIN-powered blog boilerplate", Author: &feeds.Author{Name: "Blog Author", Email: "*****@*****.**"}, //hide email from spammers? Created: now, Copyright: "This work is copyright © Ginblog", } feed.Items = make([]*feeds.Item, 0) posts, err := models.GetPublishedPosts() if err != nil { c.HTML(404, "errors/404", nil) return } for i := range posts { feed.Items = append(feed.Items, &feeds.Item{ Id: fmt.Sprintf("%s/posts/%d", domain, posts[i].ID), Title: posts[i].Name, Link: &feeds.Link{Href: fmt.Sprintf("%s/posts/%d", domain, posts[i].ID)}, Description: string(posts[i].Excerpt()), Author: &feeds.Author{Name: posts[i].Author.Name}, Created: now, }) } rss, err := feed.ToRss() if err != nil { c.HTML(500, "errors/500", nil) return } c.Data(200, "text/xml", []byte(rss)) }
func main() { migration := flag.String("migrate", "", "Run DB migrations: up, down, redo, new [MIGRATION_NAME] and then os.Exit(0)") flag.Parse() setLogger() loadConfig() connectToDB() runMigrations(migration) //Periodic tasks gocron.Every(1).Day().Do(system.CreateXMLSitemap) gocron.Start() // Creates a gin router with default middleware: // logger and recovery (crash-free) middleware router := gin.Default() setTemplate(router) //initialize templates setSessions(router) //initialize session storage & use sessiom/csrf middlewares router.StaticFS("/public", http.Dir(system.PublicPath())) //better use nginx to serve assets (Cache-Control, Etag, fast gzip, etc) router.Use(SharedData()) router.GET("/", controllers.HomeGet) router.NoRoute(controllers.NotFound) router.NoMethod(controllers.MethodNotAllowed) if system.GetConfig().SignupEnabled { router.GET("/signup", controllers.SignUpGet) router.POST("/signup", controllers.SignUpPost) } router.GET("/signin", controllers.SignInGet) router.POST("/signin", controllers.SignInPost) router.GET("/logout", controllers.LogoutGet) router.GET("/pages/:id", controllers.PageGet) router.GET("/posts/:id", controllers.PostGet) router.GET("/tags/:name", controllers.TagGet) router.GET("/archives/:year/:month", controllers.ArchiveGet) router.GET("/rss", controllers.RssGet) authorized := router.Group("/admin") authorized.Use(AuthRequired()) { authorized.GET("/", controllers.AdminGet) authorized.POST("/upload", controllers.UploadPost) //image upload authorized.GET("/users", controllers.UserIndex) authorized.GET("/new_user", controllers.UserNew) authorized.POST("/new_user", controllers.UserCreate) authorized.GET("/users/:id/edit", controllers.UserEdit) authorized.POST("/users/:id/edit", controllers.UserUpdate) authorized.POST("/users/:id/delete", controllers.UserDelete) authorized.GET("/pages", controllers.PageIndex) authorized.GET("/new_page", controllers.PageNew) authorized.POST("/new_page", controllers.PageCreate) authorized.GET("/pages/:id/edit", controllers.PageEdit) authorized.POST("/pages/:id/edit", controllers.PageUpdate) authorized.POST("/pages/:id/delete", controllers.PageDelete) authorized.GET("/posts", controllers.PostIndex) authorized.GET("/new_post", controllers.PostNew) authorized.POST("/new_post", controllers.PostCreate) authorized.GET("/posts/:id/edit", controllers.PostEdit) authorized.POST("/posts/:id/edit", controllers.PostUpdate) authorized.POST("/posts/:id/delete", controllers.PostDelete) authorized.GET("/tags", controllers.TagIndex) authorized.GET("/new_tag", controllers.TagNew) authorized.POST("/new_tag", controllers.TagCreate) authorized.POST("/tags/:name/delete", controllers.TagDelete) } // Listen and server on 0.0.0.0:8080 router.Run(":8080") }
//connectToDB initializes *sqlx.DB handler func connectToDB() { config := system.GetConfig() connection := fmt.Sprintf("host=%s user=%s password=%s dbname=%s sslmode=disable", config.Database.Host, config.Database.User, config.Database.Password, config.Database.Name) models.SetDB(connection) }