init
This commit is contained in:
commit
b10790c212
40 changed files with 4149 additions and 0 deletions
127
api/auth.go
Normal file
127
api/auth.go
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"caddydash/config"
|
||||
"caddydash/db"
|
||||
"caddydash/user"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/fenthope/sessions"
|
||||
"github.com/infinite-iroha/touka"
|
||||
)
|
||||
|
||||
var (
|
||||
exactMatchPaths = map[string]struct{}{
|
||||
"/login": {},
|
||||
"/login.html": {},
|
||||
"/v0/api/auth/login": {},
|
||||
"/v0/api/auth/init": {},
|
||||
"/init.html": {},
|
||||
"/favicon.ico": {},
|
||||
}
|
||||
prefixMatchPaths = []string{ // 保持前缀匹配,因为数量少
|
||||
"/js/",
|
||||
"/css/",
|
||||
}
|
||||
loginMatchPaths = map[string]struct{}{
|
||||
"/login": {},
|
||||
"/login.html": {},
|
||||
"/v0/api/auth/login": {},
|
||||
}
|
||||
initMatchPaths = map[string]struct{}{
|
||||
"/v0/api/auth/init": {},
|
||||
"/init.html": {},
|
||||
}
|
||||
)
|
||||
|
||||
func isPassPath(requestPath string) bool {
|
||||
// 精确匹配
|
||||
if _, ok := exactMatchPaths[requestPath]; ok {
|
||||
return true
|
||||
}
|
||||
|
||||
// 前缀匹配
|
||||
for _, prefix := range prefixMatchPaths {
|
||||
if strings.HasPrefix(requestPath, prefix) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isLoginPath(requestPath string) bool {
|
||||
if _, ok := loginMatchPaths[requestPath]; ok {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isInitPath(requestPath string) bool {
|
||||
if _, ok := initMatchPaths[requestPath]; ok {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func SessionMiddleware(cdb *db.ConfigDB) touka.HandlerFunc {
|
||||
return func(c *touka.Context) {
|
||||
session := sessions.Default(c)
|
||||
requestPath := c.Request.URL.Path
|
||||
pass := isPassPath(requestPath)
|
||||
if !user.IsAdminInit() && !pass || !user.IsAdminInit() && isLoginPath(requestPath) {
|
||||
c.Redirect(http.StatusFound, "/init.html")
|
||||
c.Abort()
|
||||
return
|
||||
} else if user.IsAdminInit() && isInitPath(requestPath) {
|
||||
c.Redirect(http.StatusFound, "/login.html")
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
if session.Get("authenticated") != true && !pass {
|
||||
c.Redirect(http.StatusFound, "/login.html")
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
c.Next()
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func AuthLogin(c *touka.Context, cfg *config.Config, cdb *db.ConfigDB) {
|
||||
username := c.PostForm("username")
|
||||
password := c.PostForm("password")
|
||||
// 输入验证
|
||||
if username == "" || password == "" {
|
||||
c.Errorf("Username or password not provided")
|
||||
c.JSON(http.StatusBadRequest, touka.H{"error": "Need username and password"})
|
||||
return
|
||||
}
|
||||
|
||||
// 验证账户密码
|
||||
pass, err := user.CheckLogin(username, password, cdb)
|
||||
if err != nil {
|
||||
c.Errorf("Failed to check login: %v", err)
|
||||
c.JSON(http.StatusInternalServerError, touka.H{"error": "Internal Auth Check Error"})
|
||||
return
|
||||
}
|
||||
if !pass {
|
||||
c.Errorf("Invalid username or password")
|
||||
c.JSON(http.StatusUnauthorized, touka.H{"error": "Invalid username or password"})
|
||||
return
|
||||
}
|
||||
session := sessions.Default(c)
|
||||
session.Set("authenticated", true)
|
||||
session.Save()
|
||||
c.Infof("Login successful for user: %s", username)
|
||||
c.JSON(http.StatusOK, touka.H{"success": true})
|
||||
}
|
||||
|
||||
func AuthLogout(c *touka.Context) {
|
||||
session := sessions.Default(c)
|
||||
session.Clear()
|
||||
session.Set("authenticated", false)
|
||||
session.Save()
|
||||
c.Redirect(http.StatusFound, "/login.html")
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue