feat: initial blog engine with multi-language, profile, and role system
- Gin + GORM + Tailwind CSS blog engine - OS-aware config (Linux /etc/blog_go/, Windows ./win/etc/blog_go/) - SQLite by default, MySQL support via config - Auto-migrate database + seed admin user on first run - Session-based auth (login/logout) - i18n: Chinese/English with auto-detect + manual switch - Avatar dropdown nav with click-to-toggle menu - Profile page: avatar upload, edit info, change password - Role system: admin (full access) and author (profile only) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-contrib/sessions"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"go_blog/models"
|
||||
)
|
||||
|
||||
// LoginPage renders the login form.
|
||||
func LoginPage() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
tr := getTr(c)
|
||||
data := DefaultData(c)
|
||||
data["Title"] = tr["page_login"]
|
||||
if c.Query("error") == "1" {
|
||||
data["Error"] = tr["login_error"]
|
||||
}
|
||||
c.HTML(http.StatusOK, "login", data)
|
||||
}
|
||||
}
|
||||
|
||||
// Login processes the login form submission.
|
||||
func Login(db *gorm.DB) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
username := c.PostForm("username")
|
||||
password := c.PostForm("password")
|
||||
|
||||
var user models.User
|
||||
if err := db.Where("username = ?", username).First(&user).Error; err != nil {
|
||||
c.Redirect(http.StatusFound, "/login?error=1")
|
||||
return
|
||||
}
|
||||
|
||||
if !user.CheckPassword(password) {
|
||||
c.Redirect(http.StatusFound, "/login?error=1")
|
||||
return
|
||||
}
|
||||
|
||||
// Create session.
|
||||
session := sessions.Default(c)
|
||||
session.Set("user_id", user.ID)
|
||||
session.Set("username", user.Username)
|
||||
if err := session.Save(); err != nil {
|
||||
c.String(http.StatusInternalServerError, "Failed to save session")
|
||||
return
|
||||
}
|
||||
|
||||
c.Redirect(http.StatusFound, "/admin")
|
||||
}
|
||||
}
|
||||
|
||||
// Logout clears the session and redirects home.
|
||||
func Logout() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
session := sessions.Default(c)
|
||||
session.Clear()
|
||||
session.Save()
|
||||
c.Redirect(http.StatusFound, "/")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user