filemanager

package module
v1.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 3, 2017 License: Apache-2.0 Imports: 29 Imported by: 0

README

Preview

filemanager

Build Go Report Card Documentation

filemanager provides a file managing interface within a specified directory and it can be used to upload, delete, preview, rename and edit your files. It allows the creation of multiple users and each user can have its own directory. It can be used as a standalone app or as a middleware.

Table of contents

Getting started

You can find the Getting Started guide on the documentation.

Features

Easy login system.

Login Page

Listings of your files, available in two styles: mosaic and list. You can delete, move, rename, upload and create new files, as well as directories. Single files can be downloaded directly, and multiple files as .zip, .tar, .tar.gz, .tar.bz2 or .tar.xz.

Mosaic Listing

File Manager editor is powered by Codemirror and if you're working with markdown files with metadata, both parts will be separated from each other so you can focus on the content.

Markdown Editor

On the settings page, a regular user can set its own custom CSS to personalize the experience and change its password. For admins, they can manage the permissions of each user, set commands which can be executed when certain events are triggered (such as before saving and after saving) and change plugin's settings.

Settings

We also allow the users to search in the directories and execute commands if allowed.

Users

We support multiple users and each user can have its own scope and custom stylesheet. The administrator is able to choose which permissions should be given to the users, as well as the commands they can execute. Each user also have a set of rules, in which he can be prevented or allowed to access some directories (regular expressions included!).

Users

FileManager allows you to search through your files and it has some options. By default, your search will be something like this:

this are keywords

If you search for that it will look at every file that contains "this", "are" or "keywords" on their name. If you want to search for an exact term, you should surround your search by double quotes:

"this is the name"

That will search for any file that contains "this is the name" on its name. It won't search for each separated term this time.

By default, every search will be case sensitive. Although, you can make a case insensitive search by adding case:insensitive to the search terms, like this:

this are keywords case:insensitive

Contributing

The contributing guidelines can be found here.

Donate

Enjoying this project? You can donate to its creator. He will appreciate.

Documentation

Overview

Package filemanager provides a web interface to access your files wherever you are. To use this package as a middleware for your app, you'll need to import both File Manager and File Manager HTTP packages.

import (
	fm "github.com/hacdias/filemanager"
	h "github.com/hacdias/filemanager/http"
)

Then, you should create a new FileManager object with your options. In this case, I'm using BoltDB (via Storm package) as a Store. So, you'll also need to import "github.com/hacdias/filemanager/bolt".

db, _ := storm.Open("bolt.db")

m := &fm.FileManager{
	NoAuth: false,
	DefaultUser: &fm.User{
		AllowCommands: true,
		AllowEdit:     true,
		AllowNew:      true,
		AllowPublish:  true,
		Commands:      []string{"git"},
		Rules:         []*fm.Rule{},
		Locale:        "en",
		CSS:           "",
		Scope:         ".",
		FileSystem:    fileutils.Dir("."),
	},
	Store: &fm.Store{
		Config: bolt.ConfigStore{DB: db},
		Users:  bolt.UsersStore{DB: db},
		Share:  bolt.ShareStore{DB: db},
	},
	NewFS: func(scope string) fm.FileSystem {
		return fileutils.Dir(scope)
	},
}

The credentials for the first user are always 'admin' for both the user and the password, and they can be changed later through the settings. The first user is always an Admin and has all of the permissions set to 'true'.

Then, you should set the Prefix URL and the Base URL, using the following functions:

m.SetBaseURL("/")
m.SetPrefixURL("/")

The Prefix URL is a part of the path that is already stripped from the r.URL.Path variable before the request arrives to File Manager's handler. This is a function that will rarely be used. You can see one example on Caddy filemanager plugin.

The Base URL is the URL path where you want File Manager to be available in. If you want to be available at the root path, you should call:

m.SetBaseURL("/")

But if you want to access it at '/admin', you would call:

m.SetBaseURL("/admin")

Now, that you already have a File Manager instance created, you just need to add it to your handlers using m.ServeHTTP which is compatible to http.Handler. We also have a m.ServeWithErrorsHTTP that returns the status code and an error.

One simple implementation for this, at port 80, in the root of the domain, would be:

http.ListenAndServe(":80", h.Handler(m))

Index

Constants

View Source
const Version = "1.3.0"

Version is the current File Manager version.

Variables

View Source
var (
	ErrExist              = errors.New("the resource already exists")
	ErrNotExist           = errors.New("the resource does not exist")
	ErrEmptyRequest       = errors.New("request body is empty")
	ErrEmptyPassword      = errors.New("password is empty")
	ErrEmptyUsername      = errors.New("username is empty")
	ErrEmptyScope         = errors.New("scope is empty")
	ErrWrongDataType      = errors.New("wrong data type")
	ErrInvalidUpdateField = errors.New("invalid field to update")
	ErrInvalidOption      = errors.New("Invalid option")
)
View Source
var DefaultUser = User{
	AllowCommands: true,
	AllowEdit:     true,
	AllowNew:      true,
	AllowPublish:  true,
	LockPassword:  false,
	Commands:      []string{},
	Rules:         []*Rule{},
	CSS:           "",
	Admin:         true,
	Locale:        "en",
	Scope:         ".",
	FileSystem:    fileutils.Dir("."),
}

DefaultUser is used on New, when no 'base' user is provided.

Functions

func CheckPasswordHash added in v1.2.4

func CheckPasswordHash(password, hash string) bool

CheckPasswordHash compares a password with an hash to check if they match.

func GenerateRandomBytes added in v1.2.4

func GenerateRandomBytes(n int) ([]byte, error)

GenerateRandomBytes returns securely generated random bytes. It will return an fm.Error if the system's secure random number generator fails to function correctly, in which case the caller should not continue.

func HashPassword added in v1.2.4

func HashPassword(password string) (string, error)

HashPassword generates an hash from a password using bcrypt.

Types

type Command

type Command func(r *http.Request, m *FileManager, u *User) error

Command is a command function.

type ConfigStore added in v1.2.4

type ConfigStore interface {
	Get(name string, to interface{}) error
	Save(name string, from interface{}) error
}

ConfigStore is the interface to manage configuration.

type Context added in v1.2.4

type Context struct {
	*FileManager
	User *User
	File *File
	// On API handlers, Router is the APi handler we want.
	Router string
}

Context contains the needed information to make handlers work.

type FSBuilder added in v1.2.4

type FSBuilder func(scope string) FileSystem

FSBuilder is the File System Builder.

type File added in v1.2.4

type File struct {
	// Indicates the Kind of view on the front-end (Listing, editor or preview).
	Kind string `json:"kind"`
	// The name of the file.
	Name string `json:"name"`
	// The Size of the file.
	Size int64 `json:"size"`
	// The absolute URL.
	URL string `json:"url"`
	// The extension of the file.
	Extension string `json:"extension"`
	// The last modified time.
	ModTime time.Time `json:"modified"`
	// The File Mode.
	Mode os.FileMode `json:"mode"`
	// Indicates if this file is a directory.
	IsDir bool `json:"isDir"`
	// Absolute path.
	Path string `json:"path"`
	// Relative path to user's virtual File System.
	VirtualPath string `json:"virtualPath"`
	// Indicates the file content type: video, text, image, music or blob.
	Type string `json:"type"`
	// Stores the content of a text file.
	Content string `json:"content,omitempty"`

	*Listing `json:",omitempty"`

	Metadata string `json:"metadata,omitempty"`
	Language string `json:"language,omitempty"`
}

File contains the information about a particular file or directory.

func GetInfo added in v1.2.4

func GetInfo(url *url.URL, c *FileManager, u *User) (*File, error)

GetInfo gets the file information and, in case of error, returns the respective HTTP error code

func (File) CanBeEdited added in v1.2.4

func (i File) CanBeEdited() bool

CanBeEdited checks if the extension of a file is supported by the editor

func (File) Checksum added in v1.2.4

func (i File) Checksum(algo string) (string, error)

Checksum retrieves the checksum of a file.

func (*File) GetEditor added in v1.2.4

func (i *File) GetEditor() error

GetEditor gets the editor based on a Info struct

func (*File) GetFileType added in v1.2.4

func (i *File) GetFileType(checkContent bool) error

GetFileType obtains the mimetype and converts it to a simple type nomenclature.

func (*File) GetListing added in v1.2.4

func (i *File) GetListing(u *User, r *http.Request) error

GetListing gets the information about a specific directory and its files.

type FileManager

type FileManager struct {
	// Cron job to manage schedulings.
	Cron *cron.Cron

	// The key used to sign the JWT tokens.
	Key []byte

	// The static assets.
	Assets *rice.Box

	// The Store is used to manage users, shareable links and
	// other stuff that is saved on the database.
	Store *Store

	// PrefixURL is a part of the URL that is already trimmed from the request URL before it
	// arrives to our handlers. It may be useful when using File Manager as a middleware
	// such as in caddy-filemanager plugin. It is only useful in certain situations.
	PrefixURL string

	// BaseURL is the path where the GUI will be accessible. It musn't end with
	// a trailing slash and mustn't contain PrefixURL, if set. It shouldn't be
	// edited directly. Use SetBaseURL.
	BaseURL string

	// NoAuth disables the authentication. When the authentication is disabled,
	// there will only exist one user, called "admin".
	NoAuth bool

	// StaticGen is the static websit generator handler.
	StaticGen StaticGen

	// The Default User needed to build the New User page.
	DefaultUser *User

	// A map of events to a slice of commands.
	Commands map[string][]string

	// NewFS should build a new file system for a given path.
	NewFS FSBuilder
}

FileManager is a file manager instance. It should be creating using the 'New' function and not directly.

func (*FileManager) Attach added in v1.2.4

func (m *FileManager) Attach(s StaticGen) error

Attach attaches a static generator to the current File Manager.

func (FileManager) RootURL

func (m FileManager) RootURL() string

RootURL returns the actual URL where File Manager interface can be accessed.

func (FileManager) Runner

func (m FileManager) Runner(event string, path string) error

Runner runs the commands for a certain event type.

func (*FileManager) SetBaseURL

func (m *FileManager) SetBaseURL(url string)

SetBaseURL updates the baseURL of a File Manager object.

func (*FileManager) SetPrefixURL

func (m *FileManager) SetPrefixURL(url string)

SetPrefixURL updates the prefixURL of a File Manager object.

func (*FileManager) Setup added in v1.2.4

func (m *FileManager) Setup() error

Setup loads the configuration from the database and configures the Assets and the Cron job. It must always be run after creating a File Manager object.

func (FileManager) ShareCleaner added in v1.2.4

func (m FileManager) ShareCleaner()

ShareCleaner removes sharing links that are no longer active. This function is set to run periodically.

type FileSystem added in v1.2.4

type FileSystem interface {
	Mkdir(name string, perm os.FileMode) error
	OpenFile(name string, flag int, perm os.FileMode) (*os.File, error)
	RemoveAll(name string) error
	Rename(oldName, newName string) error
	Stat(name string) (os.FileInfo, error)
	Copy(src, dst string) error
}

FileSystem is the interface to work with the file system.

type Listing added in v1.2.4

type Listing struct {
	// The items (files and folders) in the path.
	Items []*File `json:"items"`
	// The number of directories in the Listing.
	NumDirs int `json:"numDirs"`
	// The number of files (items that aren't directories) in the Listing.
	NumFiles int `json:"numFiles"`
	// Which sorting order is used.
	Sort string `json:"sort"`
	// And which order.
	Order string `json:"order"`
	// Displays in mosaic or list.
	Display string `json:"display"`
}

A Listing is the context used to fill out a template.

func (Listing) ApplySort added in v1.2.4

func (l Listing) ApplySort()

ApplySort applies the sort order using .Order and .Sort

type Regexp

type Regexp struct {
	Raw string `json:"raw"`
	// contains filtered or unexported fields
}

Regexp is a regular expression wrapper around native regexp.

func (*Regexp) MatchString

func (r *Regexp) MatchString(s string) bool

MatchString checks if this string matches the regular expression.

type Rule

type Rule struct {
	// Regex indicates if this rule uses Regular Expressions or not.
	Regex bool `json:"regex"`

	// Allow indicates if this is an allow rule. Set 'false' to be a disallow rule.
	Allow bool `json:"allow"`

	// Path is the corresponding URL path for this rule.
	Path string `json:"path"`

	// Regexp is the regular expression. Only use this when 'Regex' was set to true.
	Regexp *Regexp `json:"regexp"`
}

Rule is a dissalow/allow rule.

type ShareLink struct {
	Hash       string    `json:"hash" storm:"id,index"`
	Path       string    `json:"path" storm:"index"`
	Expires    bool      `json:"expires"`
	ExpireDate time.Time `json:"expireDate"`
}

ShareLink is the information needed to build a shareable link.

type ShareStore added in v1.2.4

type ShareStore interface {
	Get(hash string) (*ShareLink, error)
	GetPermanent(path string) (*ShareLink, error)
	GetByPath(path string) ([]*ShareLink, error)
	Gets() ([]*ShareLink, error)
	Save(s *ShareLink) error
	Delete(hash string) error
}

ShareStore is the interface to manage share links.

type StaticGen added in v1.2.0

type StaticGen interface {
	SettingsPath() string
	Name() string
	Setup() error

	Hook(c *Context, w http.ResponseWriter, r *http.Request) (int, error)
	Preview(c *Context, w http.ResponseWriter, r *http.Request) (int, error)
	Publish(c *Context, w http.ResponseWriter, r *http.Request) (int, error)
}

StaticGen is a static website generator.

type Store added in v1.2.4

type Store struct {
	Users  UsersStore
	Config ConfigStore
	Share  ShareStore
}

Store is a collection of the stores needed to get and save information.

type User

type User struct {
	// ID is the required primary key with auto increment0
	ID int `storm:"id,increment"`

	// Username is the user username used to login.
	Username string `json:"username" storm:"index,unique"`

	// The hashed password. This never reaches the front-end because it's temporarily
	// emptied during JSON marshall.
	Password string `json:"password"`

	// Tells if this user is an admin.
	Admin bool `json:"admin"`

	// Scope is the path the user has access to.
	Scope string `json:"filesystem"`

	// FileSystem is the virtual file system the user has access.
	FileSystem FileSystem `json:"-"`

	// Rules is an array of access and deny rules.
	Rules []*Rule `json:"rules"`

	// Custom styles for this user.
	CSS string `json:"css"`

	// Locale is the language of the user.
	Locale string `json:"locale"`

	// Prevents the user to change its password.
	LockPassword bool `json:"lockPassword"`

	// These indicate if the user can perform certain actions.
	AllowNew      bool `json:"allowNew"`      // Create files and folders
	AllowEdit     bool `json:"allowEdit"`     // Edit/rename files
	AllowCommands bool `json:"allowCommands"` // Execute commands
	AllowPublish  bool `json:"allowPublish"`  // Publish content (to use with static gen)

	// Commands is the list of commands the user can execute.
	Commands []string `json:"commands"`
}

User contains the configuration for each user.

func (User) Allowed

func (u User) Allowed(url string) bool

Allowed checks if the user has permission to access a directory/file.

type UsersStore added in v1.2.4

type UsersStore interface {
	Get(id int, builder FSBuilder) (*User, error)
	GetByUsername(username string, builder FSBuilder) (*User, error)
	Gets(builder FSBuilder) ([]*User, error)
	Save(u *User) error
	Update(u *User, fields ...string) error
	Delete(id int) error
}

UsersStore is the interface to manage users.

Directories

Path Synopsis
caddy
filemanager
Package filemanager provides middleware for managing files in a directory when directory path is requested instead of a specific file.
Package filemanager provides middleware for managing files in a directory when directory path is requested instead of a specific file.
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL