// // app.go // Copyright (C) 2024 veypi // 2024-10-22 15:42 // Distributed under terms of the GPL license. // package fs import ( "net/http" "oa/cfg" "oa/errs" "oa/libs/auth" "oa/libs/webdav" "os" "strings" "github.com/veypi/utils" "github.com/veypi/utils/logv" ) func NewAppFs(prefix string) func(http.ResponseWriter, *http.Request) { if strings.HasSuffix(prefix, "/") { prefix = prefix[:len(prefix)-1] } tmp := utils.PathJoin(cfg.Config.FsPath, "app") if !utils.FileExists(tmp) { logv.AssertError(os.MkdirAll(tmp, 0744)) } client := webdav.NewWebdav(tmp) client.Prefix = prefix client.GenSubPathFunc = func(r *http.Request) (string, error) { // /:aid/*p dir := strings.TrimPrefix(r.URL.Path, prefix) dirs := strings.Split(dir[1:], "/") aid := "" root := "/" if len(dirs) > 0 { aid = dirs[0] } if len(dirs) > 1 { root = "/" + strings.Join(dirs[1:], "/") } if root == "/" { // if !utils.FileExists(tmp + "/" + aid) { // os.MkdirAll(tmp+"/"+aid, 0744) // } } if aid == "" { return "", errs.AuthNoPerm } if root == "/pub" || strings.HasPrefix(root, "/pub/") { switch r.Method { case "OPTIONS", "GET", "HEAD", "POST": return "", nil default: } } // appfs权限等于app权限 // TODO: 存在空文件覆盖重要文件的风险 handlerLevle := auth.Do switch r.Method { case "PUT", "MKCOL", "COPY", "MOVE": handlerLevle = auth.DoCreate case "DELETE": handlerLevle = auth.DoDelete default: handlerLevle = auth.DoRead } payload, err := getToken(r) if err != nil { return "", err } if payload.Access.Check("app", aid, handlerLevle) { return "", nil } return "", errs.AuthNoPerm } return client.ServeHTTP }