223 lines
3.9 KiB
Go
223 lines
3.9 KiB
Go
package types
|
|
|
|
import (
|
|
"os"
|
|
"path"
|
|
"syscall"
|
|
"time"
|
|
|
|
"github.com/spf13/afero"
|
|
)
|
|
|
|
type userFs struct {
|
|
source afero.Fs
|
|
user *User
|
|
settings *Settings
|
|
}
|
|
|
|
type userFile struct {
|
|
f afero.File
|
|
path string
|
|
fs *userFs
|
|
}
|
|
|
|
func (u *userFs) isAllowed(name string) bool {
|
|
if !isAllowed(name, u.user.Rules) {
|
|
return false
|
|
}
|
|
|
|
return isAllowed(name, u.settings.Rules)
|
|
}
|
|
|
|
func (u *userFs) FullPath(path string) string {
|
|
return afero.FullBaseFsPath(u.source.(*afero.BasePathFs), path)
|
|
}
|
|
|
|
func (u *userFs) Chtimes(name string, a, m time.Time) error {
|
|
if !u.isAllowed(name) {
|
|
return syscall.ENOENT
|
|
}
|
|
|
|
return u.source.Chtimes(name, a, m)
|
|
}
|
|
|
|
func (u *userFs) Chmod(name string, mode os.FileMode) error {
|
|
if !u.isAllowed(name) {
|
|
return syscall.ENOENT
|
|
}
|
|
|
|
return u.source.Chmod(name, mode)
|
|
}
|
|
|
|
func (u *userFs) Name() string {
|
|
return "userFs"
|
|
}
|
|
|
|
func (u *userFs) Stat(name string) (os.FileInfo, error) {
|
|
if !u.isAllowed(name) {
|
|
return nil, syscall.ENOENT
|
|
}
|
|
|
|
return u.source.Stat(name)
|
|
}
|
|
|
|
func (u *userFs) Rename(oldname, newname string) error {
|
|
if !u.user.Perm.Rename {
|
|
return os.ErrPermission
|
|
}
|
|
|
|
if !u.isAllowed(oldname) || !u.isAllowed(newname) {
|
|
return syscall.ENOENT
|
|
}
|
|
|
|
return u.source.Rename(oldname, newname)
|
|
}
|
|
|
|
func (u *userFs) RemoveAll(name string) error {
|
|
if !u.user.Perm.Delete {
|
|
return os.ErrPermission
|
|
}
|
|
|
|
if !u.isAllowed(name) {
|
|
return syscall.ENOENT
|
|
}
|
|
|
|
return u.source.RemoveAll(name)
|
|
}
|
|
|
|
func (u *userFs) Remove(name string) error {
|
|
if !u.user.Perm.Delete {
|
|
return os.ErrPermission
|
|
}
|
|
|
|
if !u.isAllowed(name) {
|
|
return syscall.ENOENT
|
|
}
|
|
|
|
return u.source.Remove(name)
|
|
}
|
|
|
|
func (u *userFs) OpenFile(name string, flag int, perm os.FileMode) (afero.File, error) {
|
|
if !u.isAllowed(name) {
|
|
return nil, syscall.ENOENT
|
|
}
|
|
|
|
return u.source.OpenFile(name, flag, perm)
|
|
}
|
|
|
|
func (u *userFs) Open(name string) (afero.File, error) {
|
|
if !u.isAllowed(name) {
|
|
return nil, syscall.ENOENT
|
|
}
|
|
|
|
f, err := u.source.Open(name)
|
|
return &userFile{fs: u, path: name, f: f}, err
|
|
}
|
|
|
|
func (u *userFs) Mkdir(name string, perm os.FileMode) error {
|
|
if !u.user.Perm.Create {
|
|
return os.ErrPermission
|
|
}
|
|
|
|
if !u.isAllowed(name) {
|
|
return syscall.ENOENT
|
|
}
|
|
|
|
return u.source.Mkdir(name, perm)
|
|
}
|
|
|
|
func (u *userFs) MkdirAll(name string, perm os.FileMode) error {
|
|
if !u.user.Perm.Create {
|
|
return os.ErrPermission
|
|
}
|
|
|
|
if !u.isAllowed(name) {
|
|
return syscall.ENOENT
|
|
}
|
|
|
|
return u.source.MkdirAll(name, perm)
|
|
}
|
|
|
|
func (u *userFs) Create(name string) (afero.File, error) {
|
|
if !u.user.Perm.Create {
|
|
return nil, os.ErrPermission
|
|
}
|
|
|
|
if !u.isAllowed(name) {
|
|
return nil, syscall.ENOENT
|
|
}
|
|
|
|
return u.source.Create(name)
|
|
}
|
|
|
|
func (f *userFile) Close() error {
|
|
return f.f.Close()
|
|
}
|
|
|
|
func (f *userFile) Read(s []byte) (int, error) {
|
|
return f.f.Read(s)
|
|
}
|
|
|
|
func (f *userFile) ReadAt(s []byte, o int64) (int, error) {
|
|
return f.f.ReadAt(s, o)
|
|
}
|
|
|
|
func (f *userFile) Seek(o int64, w int) (int64, error) {
|
|
return f.f.Seek(o, w)
|
|
}
|
|
|
|
func (f *userFile) Write(s []byte) (int, error) {
|
|
return f.f.Write(s)
|
|
}
|
|
|
|
func (f *userFile) WriteAt(s []byte, o int64) (int, error) {
|
|
return f.f.WriteAt(s, o)
|
|
}
|
|
|
|
func (f *userFile) Name() string {
|
|
return f.f.Name()
|
|
}
|
|
|
|
func (f *userFile) Readdir(c int) (fi []os.FileInfo, err error) {
|
|
var rfi []os.FileInfo
|
|
rfi, err = f.f.Readdir(c)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for _, i := range rfi {
|
|
if f.fs.isAllowed(path.Join(f.path, i.Name())) {
|
|
fi = append(fi, i)
|
|
}
|
|
}
|
|
return fi, nil
|
|
}
|
|
|
|
func (f *userFile) Readdirnames(c int) (n []string, err error) {
|
|
fi, err := f.Readdir(c)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for _, s := range fi {
|
|
if f.fs.isAllowed(s.Name()) {
|
|
n = append(n, s.Name())
|
|
}
|
|
}
|
|
return n, nil
|
|
}
|
|
|
|
func (f *userFile) Stat() (os.FileInfo, error) {
|
|
return f.f.Stat()
|
|
}
|
|
|
|
func (f *userFile) Sync() error {
|
|
return f.f.Sync()
|
|
}
|
|
|
|
func (f *userFile) Truncate(s int64) error {
|
|
return f.f.Truncate(s)
|
|
}
|
|
|
|
func (f *userFile) WriteString(s string) (int, error) {
|
|
return f.f.WriteString(s)
|
|
}
|