Reorganize directory structures
Signed-off-by: Sean Du <do4suki@gmail.com>
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"honoka-chan/internal/utils"
|
||||
"honoka-chan/pkg/db"
|
||||
"honoka-chan/pkg/encrypt"
|
||||
honokautils "honoka-chan/pkg/utils"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/tidwall/gjson"
|
||||
)
|
||||
|
||||
func AuthKey(ctx *gin.Context) {
|
||||
req := gjson.Parse(ctx.PostForm("request_data"))
|
||||
tDummyToken, err := base64.StdEncoding.DecodeString(req.Get("dummy_token").String())
|
||||
utils.CheckErr(err)
|
||||
dummyToken := encrypt.RSADecrypt(tDummyToken)
|
||||
|
||||
// aesKey := dummyToken[0:16]
|
||||
// tAuthData, err := base64.StdEncoding.DecodeString(req.Get("auth_data").String())
|
||||
// utils.CheckErr(err)
|
||||
// authData := utils.Sub16(encrypt.AES_CBC_Decrypt(tAuthData, aesKey))
|
||||
// fmt.Println(string(authData))
|
||||
|
||||
clientToken := base64.StdEncoding.EncodeToString(dummyToken)
|
||||
serverToken := base64.StdEncoding.EncodeToString([]byte(honokautils.RandomStr(32)))
|
||||
authorizeToken := base64.StdEncoding.EncodeToString([]byte(honokautils.RandomStr(32)))
|
||||
|
||||
ctx.Set("dummy_token", serverToken)
|
||||
ctx.Set("authorize_token", authorizeToken)
|
||||
|
||||
authJson, err := json.Marshal(map[string]any{
|
||||
"client_token": clientToken,
|
||||
"server_token": serverToken,
|
||||
})
|
||||
utils.CheckErr(err)
|
||||
err = db.DB.Set([]byte(authorizeToken), authJson)
|
||||
utils.CheckErr(err)
|
||||
|
||||
nonce := ctx.GetInt("nonce")
|
||||
nonce++
|
||||
ctx.Set("nonce", nonce)
|
||||
|
||||
authorize := fmt.Sprintf("consumerKey=lovelive_test&timeStamp=%d&version=1.1&nonce=%d&requestTimeStamp=%d", time.Now().Unix(), nonce, ctx.GetInt64("req_time"))
|
||||
|
||||
ctx.Header("user_id", "")
|
||||
ctx.Header("authorize", authorize)
|
||||
|
||||
ctx.Next()
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"honoka-chan/internal/utils"
|
||||
"honoka-chan/pkg/db"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrorMsg = `{"code":20001,"message":""}`
|
||||
)
|
||||
|
||||
func CheckErr(err error) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func Common(ctx *gin.Context) {
|
||||
ctx.Set("req_time", time.Now().Unix())
|
||||
|
||||
authorize := ctx.Request.Header.Get("Authorize")
|
||||
if authorize == "" {
|
||||
ctx.String(http.StatusForbidden, ErrorMsg)
|
||||
ctx.Abort()
|
||||
}
|
||||
ctx.Set("authorize", authorize)
|
||||
|
||||
params, err := url.ParseQuery(authorize)
|
||||
utils.CheckErr(err)
|
||||
|
||||
nonce, err := strconv.Atoi(params.Get("nonce"))
|
||||
utils.CheckErr(err)
|
||||
nonce++
|
||||
ctx.Set("nonce", nonce)
|
||||
|
||||
token := params.Get("token")
|
||||
ctx.Set("token", token)
|
||||
|
||||
if ctx.Request.URL.String() == "/main.php/login/authkey" ||
|
||||
ctx.Request.URL.String() == "/main.php/login/login" {
|
||||
// 特殊请求
|
||||
fmt.Println("========")
|
||||
} else {
|
||||
userId := ctx.Request.Header.Get("User-ID")
|
||||
if userId == "" {
|
||||
ctx.String(http.StatusForbidden, ErrorMsg)
|
||||
ctx.Abort()
|
||||
}
|
||||
ctx.Set("userid", userId)
|
||||
|
||||
rToken, err := db.DB.Get([]byte(userId))
|
||||
utils.CheckErr(err)
|
||||
if token != string(rToken) {
|
||||
ctx.String(http.StatusForbidden, ErrorMsg)
|
||||
ctx.Abort()
|
||||
}
|
||||
|
||||
if !db.MatchTokenUid(token, userId) {
|
||||
ctx.String(http.StatusForbidden, ErrorMsg)
|
||||
ctx.Abort()
|
||||
}
|
||||
|
||||
ctx.Header("user_id", userId)
|
||||
ctx.Header("authorize", fmt.Sprintf("consumerKey=lovelive_test&timeStamp=%d&version=1.1&token=%s&nonce=%d&user_id=%s&requestTimeStamp=%d", time.Now().Unix(), token, nonce, userId, time.Now().Unix()))
|
||||
}
|
||||
|
||||
ctx.Header("Content-Type", "application/json; charset=utf-8")
|
||||
ctx.Header("X-Powered-By", "KLab Native APP Platform")
|
||||
ctx.Header("server_version", "20120129")
|
||||
ctx.Header("Server-Version", "97.4.6")
|
||||
ctx.Header("version_up", "0")
|
||||
ctx.Header("status_code", "200")
|
||||
|
||||
ctx.Next()
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"honoka-chan/internal/utils"
|
||||
"honoka-chan/pkg/db"
|
||||
"honoka-chan/pkg/encrypt"
|
||||
honokautils "honoka-chan/pkg/utils"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/tidwall/gjson"
|
||||
)
|
||||
|
||||
func Login(ctx *gin.Context) {
|
||||
authData, err := db.DB.Get([]byte(ctx.GetString("token")))
|
||||
utils.CheckErr(err)
|
||||
|
||||
clientToken, err := base64.StdEncoding.DecodeString(gjson.Get(string(authData), "client_token").String())
|
||||
utils.CheckErr(err)
|
||||
serverToken, err := base64.StdEncoding.DecodeString(gjson.Get(string(authData), "server_token").String())
|
||||
utils.CheckErr(err)
|
||||
|
||||
xmcKey := honokautils.SliceXor(clientToken, serverToken)
|
||||
aesKey := xmcKey[0:16]
|
||||
|
||||
req := gjson.Parse(ctx.GetString("request_data"))
|
||||
tKey, err := base64.StdEncoding.DecodeString(req.Get("login_key").String())
|
||||
utils.CheckErr(err)
|
||||
loginKey := honokautils.Sub16(encrypt.AESCBCDecrypt(tKey, aesKey))
|
||||
ctx.Set("login_key", string(loginKey))
|
||||
|
||||
tPasswd, err := base64.StdEncoding.DecodeString(req.Get("login_passwd").String())
|
||||
utils.CheckErr(err)
|
||||
loginPasswd := honokautils.Sub16(encrypt.AESCBCDecrypt(tPasswd, aesKey))
|
||||
ctx.Set("login_passwd", string(loginPasswd))
|
||||
|
||||
nonce := ctx.GetInt("nonce")
|
||||
nonce++
|
||||
ctx.Set("nonce", nonce)
|
||||
|
||||
authorizeToken := base64.StdEncoding.EncodeToString([]byte(honokautils.RandomStr(32)))
|
||||
ctx.Set("authorize_token", authorizeToken)
|
||||
|
||||
ctx.Next()
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"honoka-chan/internal/utils"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func ParseMultipartForm(ctx *gin.Context) {
|
||||
// I don't know why mime.ParseMediaType() is failed
|
||||
// mime.ParseMediaType(ctx.Request.Header.Get("Content-Type"))
|
||||
boundary := strings.ReplaceAll(ctx.Request.Header.Get("Content-Type"), "multipart/form-data; boundary=", "")
|
||||
|
||||
var reqData []byte
|
||||
mReader := multipart.NewReader(ctx.Request.Body, boundary)
|
||||
for {
|
||||
part, err := mReader.NextPart()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
utils.CheckErr(err)
|
||||
|
||||
data, err := io.ReadAll(part)
|
||||
utils.CheckErr(err)
|
||||
|
||||
reqData = data
|
||||
}
|
||||
ctx.Set("request_data", string(reqData))
|
||||
|
||||
ctx.Next()
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-contrib/sessions"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func WebAuth(ctx *gin.Context) {
|
||||
session := sessions.Default(ctx)
|
||||
requestUrl := strings.Split(ctx.Request.URL.String(), "?")[0] // 过滤 GET 参数
|
||||
userId, ok := session.Get("userid").(int)
|
||||
if ok {
|
||||
if requestUrl == "/admin/login" {
|
||||
ctx.Redirect(http.StatusFound, "/admin/index")
|
||||
ctx.Abort()
|
||||
}
|
||||
} else {
|
||||
if requestUrl != "/admin/login" {
|
||||
ctx.Redirect(http.StatusFound, "/admin/login")
|
||||
ctx.Abort()
|
||||
}
|
||||
}
|
||||
ctx.Set("userid", userId)
|
||||
|
||||
ctx.Next()
|
||||
}
|
||||
Reference in New Issue
Block a user