parent
7ba14ada7b
commit
00be335a7c
|
@ -1,6 +1,7 @@
|
||||||
package filemanager
|
package filemanager
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -11,7 +12,7 @@ import (
|
||||||
|
|
||||||
// FileManager is a file manager instance.
|
// FileManager is a file manager instance.
|
||||||
type FileManager struct {
|
type FileManager struct {
|
||||||
*User
|
*user
|
||||||
Assets *assets
|
Assets *assets
|
||||||
|
|
||||||
// PrefixURL is a part of the URL that is trimmed from the http.Request.URL before
|
// PrefixURL is a part of the URL that is trimmed from the http.Request.URL before
|
||||||
|
@ -28,26 +29,18 @@ type FileManager struct {
|
||||||
// a trailing slash.
|
// a trailing slash.
|
||||||
WebDavURL string
|
WebDavURL string
|
||||||
|
|
||||||
scopes map[string]*scope
|
|
||||||
|
|
||||||
// Users is a map with the different configurations for each user.
|
// Users is a map with the different configurations for each user.
|
||||||
Users map[string]*User
|
Users map[string]*user
|
||||||
|
|
||||||
// TODO: event-based?
|
// TODO: event-based?
|
||||||
BeforeSave CommandFunc
|
BeforeSave CommandFunc
|
||||||
AfterSave CommandFunc
|
AfterSave CommandFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
type scope struct {
|
// user contains the configuration for each user.
|
||||||
path string
|
type user struct {
|
||||||
fileSystem webdav.FileSystem
|
|
||||||
handler *webdav.Handler
|
|
||||||
}
|
|
||||||
|
|
||||||
// User contains the configuration for each user.
|
|
||||||
type User struct {
|
|
||||||
// scope is the physical path the user has access to.
|
// scope is the physical path the user has access to.
|
||||||
scope *scope
|
scope string
|
||||||
|
|
||||||
// fileSystem is the virtual file system the user has access.
|
// fileSystem is the virtual file system the user has access.
|
||||||
fileSystem webdav.FileSystem
|
fileSystem webdav.FileSystem
|
||||||
|
@ -93,12 +86,11 @@ type Rule struct {
|
||||||
Regexp *regexp.Regexp
|
Regexp *regexp.Regexp
|
||||||
}
|
}
|
||||||
|
|
||||||
// CommandFunc ...
|
type CommandFunc func(r *http.Request, c *FileManager, u *user) error
|
||||||
type CommandFunc func(r *http.Request, c *FileManager, u *User) error
|
|
||||||
|
|
||||||
func New() *FileManager {
|
func New() *FileManager {
|
||||||
m := &FileManager{
|
m := &FileManager{
|
||||||
User: &User{
|
user: &user{
|
||||||
AllowCommands: true,
|
AllowCommands: true,
|
||||||
AllowEdit: true,
|
AllowEdit: true,
|
||||||
AllowNew: true,
|
AllowNew: true,
|
||||||
|
@ -109,9 +101,9 @@ func New() *FileManager {
|
||||||
Regexp: regexp.MustCompile("\\/\\..+"),
|
Regexp: regexp.MustCompile("\\/\\..+"),
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
Users: map[string]*User{},
|
Users: map[string]*user{},
|
||||||
BeforeSave: func(r *http.Request, c *FileManager, u *User) error { return nil },
|
BeforeSave: func(r *http.Request, c *FileManager, u *user) error { return nil },
|
||||||
AfterSave: func(r *http.Request, c *FileManager, u *User) error { return nil },
|
AfterSave: func(r *http.Request, c *FileManager, u *user) error { return nil },
|
||||||
Assets: &assets{
|
Assets: &assets{
|
||||||
Templates: rice.MustFindBox("./_assets/templates"),
|
Templates: rice.MustFindBox("./_assets/templates"),
|
||||||
CSS: rice.MustFindBox("./_assets/css"),
|
CSS: rice.MustFindBox("./_assets/css"),
|
||||||
|
@ -119,7 +111,7 @@ func New() *FileManager {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
m.SetScope(".")
|
m.SetScope(".", "")
|
||||||
m.SetBaseURL("/")
|
m.SetBaseURL("/")
|
||||||
m.SetWebDavURL("/webdav")
|
m.SetWebDavURL("/webdav")
|
||||||
|
|
||||||
|
@ -154,21 +146,58 @@ func (m *FileManager) SetWebDavURL(url string) {
|
||||||
url = strings.TrimSuffix(url, "/")
|
url = strings.TrimSuffix(url, "/")
|
||||||
|
|
||||||
m.WebDavURL = m.BaseURL + "/" + url
|
m.WebDavURL = m.BaseURL + "/" + url
|
||||||
m.User.handler = &webdav.Handler{
|
|
||||||
|
// update base user webdav handler
|
||||||
|
m.handler = &webdav.Handler{
|
||||||
Prefix: m.WebDavURL,
|
Prefix: m.WebDavURL,
|
||||||
FileSystem: m.fileSystem,
|
FileSystem: m.fileSystem,
|
||||||
LockSystem: webdav.NewMemLS(),
|
LockSystem: webdav.NewMemLS(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update other users' handlers to match
|
||||||
|
// the new URL
|
||||||
|
for _, u := range m.Users {
|
||||||
|
u.handler = &webdav.Handler{
|
||||||
|
Prefix: m.WebDavURL,
|
||||||
|
FileSystem: u.fileSystem,
|
||||||
|
LockSystem: webdav.NewMemLS(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetScope updates a user scope and its virtual file system.
|
// SetScope updates a user scope and its virtual file system.
|
||||||
func (m *FileManager) SetScope(scope string, user string) {
|
// If the user string is blank, it will change the base scope.
|
||||||
m.scope = strings.TrimSuffix(scope, "/")
|
func (m *FileManager) SetScope(scope string, username string) error {
|
||||||
m.fileSystem = webdav.Dir(m.scope)
|
var u *user
|
||||||
|
|
||||||
|
if username == "" {
|
||||||
|
u = m.user
|
||||||
|
} else {
|
||||||
|
var ok bool
|
||||||
|
u, ok = m.Users[username]
|
||||||
|
if !ok {
|
||||||
|
return errors.New("Inexistent user")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
u.scope = strings.TrimSuffix(scope, "/")
|
||||||
|
u.fileSystem = webdav.Dir(u.scope)
|
||||||
|
|
||||||
|
u.handler = &webdav.Handler{
|
||||||
|
Prefix: m.WebDavURL,
|
||||||
|
FileSystem: u.fileSystem,
|
||||||
|
LockSystem: webdav.NewMemLS(),
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *FileManager) NewUser(name string) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allowed checks if the user has permission to access a directory/file.
|
// Allowed checks if the user has permission to access a directory/file.
|
||||||
func (u User) Allowed(url string) bool {
|
func (u user) Allowed(url string) bool {
|
||||||
var rule *Rule
|
var rule *Rule
|
||||||
i := len(u.Rules) - 1
|
i := len(u.Rules) - 1
|
||||||
|
|
||||||
|
|
4
http.go
4
http.go
|
@ -21,7 +21,7 @@ func (c *FileManager) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, er
|
||||||
fi *FileInfo
|
fi *FileInfo
|
||||||
code int
|
code int
|
||||||
err error
|
err error
|
||||||
user *User
|
user *user
|
||||||
)
|
)
|
||||||
|
|
||||||
// Checks if the URL matches the Assets URL. Returns the asset if the
|
// Checks if the URL matches the Assets URL. Returns the asset if the
|
||||||
|
@ -38,7 +38,7 @@ func (c *FileManager) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, er
|
||||||
if _, ok := c.Users[username]; ok {
|
if _, ok := c.Users[username]; ok {
|
||||||
user = c.Users[username]
|
user = c.Users[username]
|
||||||
} else {
|
} else {
|
||||||
user = c.User
|
user = c.user
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks if the request URL is for the WebDav server
|
// Checks if the request URL is for the WebDav server
|
||||||
|
|
|
@ -22,7 +22,7 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
// command handles the requests for VCS related commands: git, svn and mercurial
|
// command handles the requests for VCS related commands: git, svn and mercurial
|
||||||
func command(w http.ResponseWriter, r *http.Request, c *FileManager, u *User) (int, error) {
|
func command(w http.ResponseWriter, r *http.Request, c *FileManager, u *user) (int, error) {
|
||||||
// Upgrades the connection to a websocket and checks for errors.
|
// Upgrades the connection to a websocket and checks for errors.
|
||||||
conn, err := upgrader.Upgrade(w, r, nil)
|
conn, err := upgrader.Upgrade(w, r, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// serveListing presents the user with a listage of a directory folder.
|
// serveListing presents the user with a listage of a directory folder.
|
||||||
func serveListing(w http.ResponseWriter, r *http.Request, c *FileManager, u *User, i *FileInfo) (int, error) {
|
func serveListing(w http.ResponseWriter, r *http.Request, c *FileManager, u *user, i *FileInfo) (int, error) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
// Loads the content of the directory
|
// Loads the content of the directory
|
||||||
|
|
|
@ -14,7 +14,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// put is used to update a file that was edited
|
// put is used to update a file that was edited
|
||||||
func put(w http.ResponseWriter, r *http.Request, c *FileManager, u *User) (err error) {
|
func put(w http.ResponseWriter, r *http.Request, c *FileManager, u *user) (err error) {
|
||||||
var (
|
var (
|
||||||
data = map[string]interface{}{}
|
data = map[string]interface{}{}
|
||||||
file []byte
|
file []byte
|
||||||
|
|
|
@ -43,7 +43,7 @@ func parseSearch(value string) *searchOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
// search searches for a file or directory.
|
// search searches for a file or directory.
|
||||||
func search(w http.ResponseWriter, r *http.Request, c *FileManager, u *User) (int, error) {
|
func search(w http.ResponseWriter, r *http.Request, c *FileManager, u *user) (int, error) {
|
||||||
// Upgrades the connection to a websocket and checks for errors.
|
// Upgrades the connection to a websocket and checks for errors.
|
||||||
conn, err := upgrader.Upgrade(w, r, nil)
|
conn, err := upgrader.Upgrade(w, r, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
|
|
||||||
// serveSingle serves a single file in an editor (if it is editable), shows the
|
// serveSingle serves a single file in an editor (if it is editable), shows the
|
||||||
// plain file, or downloads it if it can't be shown.
|
// plain file, or downloads it if it can't be shown.
|
||||||
func serveSingle(w http.ResponseWriter, r *http.Request, c *FileManager, u *User, i *FileInfo) (int, error) {
|
func serveSingle(w http.ResponseWriter, r *http.Request, c *FileManager, u *user, i *FileInfo) (int, error) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
if err = i.RetrieveFileType(); err != nil {
|
if err = i.RetrieveFileType(); err != nil {
|
||||||
|
|
2
info.go
2
info.go
|
@ -33,7 +33,7 @@ type FileInfo struct {
|
||||||
|
|
||||||
// GetInfo gets the file information and, in case of error, returns the
|
// GetInfo gets the file information and, in case of error, returns the
|
||||||
// respective HTTP error code
|
// respective HTTP error code
|
||||||
func GetInfo(url *url.URL, c *FileManager, u *User) (*FileInfo, error) {
|
func GetInfo(url *url.URL, c *FileManager, u *user) (*FileInfo, error) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
i := &FileInfo{URL: c.PrefixURL + url.Path}
|
i := &FileInfo{URL: c.PrefixURL + url.Path}
|
||||||
|
|
|
@ -33,7 +33,7 @@ type Listing struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetListing gets the information about a specific directory and its files.
|
// GetListing gets the information about a specific directory and its files.
|
||||||
func GetListing(u *User, filePath string, baseURL string) (*Listing, error) {
|
func GetListing(u *user, filePath string, baseURL string) (*Listing, error) {
|
||||||
// Gets the directory information using the Virtual File System of
|
// Gets the directory information using the Virtual File System of
|
||||||
// the user configuration.
|
// the user configuration.
|
||||||
file, err := u.fileSystem.OpenFile(context.TODO(), filePath, os.O_RDONLY, 0)
|
file, err := u.fileSystem.OpenFile(context.TODO(), filePath, os.O_RDONLY, 0)
|
||||||
|
|
Loading…
Reference in New Issue