diff options
Diffstat (limited to 'back/cmd/authfs/authfs.go')
| -rw-r--r-- | back/cmd/authfs/authfs.go | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/back/cmd/authfs/authfs.go b/back/cmd/authfs/authfs.go new file mode 100644 index 0000000..e2a8bf9 --- /dev/null +++ b/back/cmd/authfs/authfs.go @@ -0,0 +1,130 @@ +package main + +import ( + "fmt" + "path" + "sync" + + p9 "github.com/Harvey-OS/ninep/protocol" + + "git.samanthony.xyz/buth/back/auth" +) + +const ( + _ uint64 = iota + rootQidPath + usersQidPath + sessionsQidPath +) + +type File interface { + Qid() (p9.QID, error) + // TODO +} + +type Dir interface { + File + // TODO: walk, create +} + +// Authfs is the root p9.NineServer. +type Authfs struct { + *RootDir + *UsersDir + *SessionsDir + + mu sync.Mutex // guards below + files map[p9.FID]File +} + +func NewAuthfs(rootPath string) (*Authfs, error) { + root := NewRootDir() + users, err := NewUsersDir(rootPath, root.Version) + if err != nil { + return nil, err + } + return &Authfs{ + root, + users, + NewSessionsDir(root.Version), + sync.Mutex{}, + make(map[p9.FID]File), + }, nil +} + +func (fs *Authfs) Close() { + fs.RootDir.Close() + fs.UsersDir.Close() + fs.SessionsDir.Close() +} + +func (fs *Authfs) Rattach(fid, afid p9.FID, uname, aname string) (p9.QID, error) { + if afid != p9.NOFID { + return p9.QID{}, fmt.Errorf("authfs: no authentication required") + } + + var ( + f File + err error + ok bool + ) + + aname = path.Clean(path.Join("/", aname)) + dir, file := path.Split(aname) + switch dir { + case "/": + switch file { + case "": + f = fs.RootDir + case "users": + f = fs.UsersDir + case "sessions": + f = fs.SessionsDir + default: + return p9.QID{}, ErrFileNotExist + } + + case "/users/": + f, err = fs.UsersDir.Walk(file) + if err != nil { + return p9.QID{}, err + } + + case "/sessions/": + sessid, err := auth.ParseSessId(file) + if err != nil { + return p9.QID{}, err + } + f, ok = fs.SessionsDir.Get(sessid) + if !ok { + return p9.QID{}, ErrFileNotExist + } + + default: + return p9.QID{}, ErrFileNotExist + } + if f == nil { + panic("unreachable") + } + + qid, err := f.Qid() + if err != nil { + return p9.QID{}, err + } + if err := fs.attach(fid, f); err != nil { + return p9.QID{}, err + } + return qid, nil +} + +func (fs *Authfs) attach(fid p9.FID, f File) error { + fs.mu.Lock() + defer fs.mu.Unlock() + + if _, exists := fs.files[fid]; exists { + return ErrFidExist + } + + fs.files[fid] = f + return nil +} |