|
|
|
@ -8,16 +8,24 @@
|
|
|
|
|
package fs
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"bufio"
|
|
|
|
|
"encoding/base64"
|
|
|
|
|
"net/http"
|
|
|
|
|
"oa/cfg"
|
|
|
|
|
"oa/errs"
|
|
|
|
|
"oa/libs/auth"
|
|
|
|
|
"oa/libs/webdav"
|
|
|
|
|
"os"
|
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
|
|
"github.com/veypi/utils"
|
|
|
|
|
"github.com/veypi/utils/logv"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func NewUserFs(prefix string) func(http.ResponseWriter, *http.Request) {
|
|
|
|
|
if strings.HasSuffix(prefix, "/") {
|
|
|
|
|
prefix = prefix[:len(prefix)-1]
|
|
|
|
|
}
|
|
|
|
|
tmp := utils.PathJoin(cfg.Config.FsPath, "u")
|
|
|
|
|
if !utils.FileExists(tmp) {
|
|
|
|
|
logv.AssertError(os.MkdirAll(tmp, 0744))
|
|
|
|
@ -25,8 +33,67 @@ func NewUserFs(prefix string) func(http.ResponseWriter, *http.Request) {
|
|
|
|
|
|
|
|
|
|
client := webdav.NewWebdav(tmp)
|
|
|
|
|
client.Prefix = prefix
|
|
|
|
|
client.GenSubPathFunc = func(r *http.Request) string {
|
|
|
|
|
return ""
|
|
|
|
|
client.Logger = func(r *http.Request, err error) {
|
|
|
|
|
}
|
|
|
|
|
client.GenSubPathFunc = func(r *http.Request) (string, error) {
|
|
|
|
|
dir := strings.TrimPrefix(r.URL.Path, prefix)
|
|
|
|
|
logv.Warn().Msg(dir)
|
|
|
|
|
payload, err := getToken(r)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", err
|
|
|
|
|
}
|
|
|
|
|
if !strings.HasPrefix(dir, "/") {
|
|
|
|
|
dir = "/" + dir
|
|
|
|
|
}
|
|
|
|
|
if payload.Access.CheckPrefix("fs", dir, auth.Do) {
|
|
|
|
|
if dir == "/" {
|
|
|
|
|
if !utils.FileExists(tmp + "/" + payload.UID) {
|
|
|
|
|
os.MkdirAll(tmp+"/"+payload.UID, 0744)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return "/" + payload.UID + dir, nil
|
|
|
|
|
}
|
|
|
|
|
return "", errs.AuthNoPerm
|
|
|
|
|
}
|
|
|
|
|
return client.ServeHTTP
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func getToken(r *http.Request) (*auth.Claims, error) {
|
|
|
|
|
authHeader := r.Header.Get("Authorization")
|
|
|
|
|
token := ""
|
|
|
|
|
if authHeader != "" {
|
|
|
|
|
if strings.HasPrefix(authHeader, "Basic ") {
|
|
|
|
|
decodedAuth, err := base64.StdEncoding.DecodeString(authHeader[6:])
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, errs.AuthInvalid
|
|
|
|
|
}
|
|
|
|
|
// 通常认证信息格式为 username:password
|
|
|
|
|
credentials := string(decodedAuth)
|
|
|
|
|
reader := bufio.NewReader(strings.NewReader(credentials))
|
|
|
|
|
username, _ := reader.ReadString(':')
|
|
|
|
|
password := credentials[len(username):]
|
|
|
|
|
|
|
|
|
|
username = strings.TrimSuffix(username, "\n")
|
|
|
|
|
username = strings.TrimSuffix(username, ":")
|
|
|
|
|
token = strings.TrimPrefix(password, "\n")
|
|
|
|
|
logv.Warn().Msgf("username: %s, password: %s", username, token)
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
if strings.HasPrefix(authHeader, "Bearer ") {
|
|
|
|
|
token = strings.TrimPrefix(authHeader, "Bearer ")
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
acookie, err := r.Cookie("fstoken")
|
|
|
|
|
if err == nil {
|
|
|
|
|
token = acookie.Value
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if token == "" {
|
|
|
|
|
return nil, errs.AuthNotFound
|
|
|
|
|
}
|
|
|
|
|
payload, err := auth.ParseJwt(token)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return payload, nil
|
|
|
|
|
}
|
|
|
|
|