mirror of
https://github.com/filebrowser/filebrowser.git
synced 2024-06-07 23:00:43 +00:00
Rename manager to browser (#406)
* rename File Manager to File Browser * rename fm to fb
This commit is contained in:
parent
cd0ab77388
commit
7643b0c4e3
48
.github/ISSUE_TEMPLATE.md
vendored
48
.github/ISSUE_TEMPLATE.md
vendored
@ -1,24 +1,24 @@
|
|||||||
### Instructions (remove before submitting):
|
### Instructions (remove before submitting):
|
||||||
|
|
||||||
1. Are you asking for help with using Caddy or File Manager? Please use our forum instead: https://forum.caddyserver.com.
|
1. Are you asking for help with using Caddy or File Browser? Please use our forum instead: https://forum.caddyserver.com.
|
||||||
2. If you are filing a bug report, please answer the following questions.
|
2. If you are filing a bug report, please answer the following questions.
|
||||||
3. If your issue is not a bug report, you do not need to use this template.
|
3. If your issue is not a bug report, you do not need to use this template.
|
||||||
4. If not using with Caddy, ignore questions 1 and 2.
|
4. If not using with Caddy, ignore questions 1 and 2.
|
||||||
|
|
||||||
### 1. Have you downloaded File Manager from caddyserver.com? If yes, when have you done that? If no, and you are running a custom build, which is the revision of File Manager's repository?
|
### 1. Have you downloaded File Browser from caddyserver.com? If yes, when have you done that? If no, and you are running a custom build, which is the revision of File Browser's repository?
|
||||||
|
|
||||||
### 2. What is your entire Caddyfile?
|
### 2. What is your entire Caddyfile?
|
||||||
```text
|
```text
|
||||||
(Put Caddyfile here)
|
(Put Caddyfile here)
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. What are you trying to do?
|
### 3. What are you trying to do?
|
||||||
|
|
||||||
|
|
||||||
### 4. What did you expect to see?
|
### 4. What did you expect to see?
|
||||||
|
|
||||||
|
|
||||||
### 5. What did you see instead (give full error messages and/or log)?
|
### 5. What did you see instead (give full error messages and/or log)?
|
||||||
|
|
||||||
|
|
||||||
### 6. How can someone who is starting from scratch reproduce this behaviour as minimally as possible?
|
### 6. How can someone who is starting from scratch reproduce this behaviour as minimally as possible?
|
||||||
|
150
README.md
150
README.md
@ -1,75 +1,75 @@
|
|||||||
![Preview](https://user-images.githubusercontent.com/5447088/28537288-39be4288-70a2-11e7-8ce9-0813d59f46b7.gif)
|
![Preview](https://user-images.githubusercontent.com/5447088/28537288-39be4288-70a2-11e7-8ce9-0813d59f46b7.gif)
|
||||||
|
|
||||||
# filebrowser
|
# filebrowser
|
||||||
|
|
||||||
[![CircleCI](https://img.shields.io/circleci/project/github/filebrowser/filebrowser.svg?style=flat-square)](https://circleci.com/gh/filebrowser/filebrowser)
|
[![CircleCI](https://img.shields.io/circleci/project/github/filebrowser/filebrowser.svg?style=flat-square)](https://circleci.com/gh/filebrowser/filebrowser)
|
||||||
[![Go Report Card](https://goreportcard.com/badge/github.com/filebrowser/filebrowser?style=flat-square)](https://goreportcard.com/report/github.com/filebrowser/filebrowser)
|
[![Go Report Card](https://goreportcard.com/badge/github.com/filebrowser/filebrowser?style=flat-square)](https://goreportcard.com/report/github.com/filebrowser/filebrowser)
|
||||||
[![Documentation](https://img.shields.io/badge/godoc-reference-blue.svg?style=flat-square)](http://godoc.org/github.com/filebrowser/filebrowser)
|
[![Documentation](https://img.shields.io/badge/godoc-reference-blue.svg?style=flat-square)](http://godoc.org/github.com/filebrowser/filebrowser)
|
||||||
[![Version](https://img.shields.io/github/release/filebrowser/filebrowser.svg?style=flat-square)](https://github.com/filebrowser/filebrowser/releases/latest)
|
[![Version](https://img.shields.io/github/release/filebrowser/filebrowser.svg?style=flat-square)](https://github.com/filebrowser/filebrowser/releases/latest)
|
||||||
|
|
||||||
filebrowser 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.
|
filebrowser 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
|
# Table of contents
|
||||||
|
|
||||||
+ [Getting started](#getting-started)
|
+ [Getting started](#getting-started)
|
||||||
+ [Features](#features)
|
+ [Features](#features)
|
||||||
- [Users](#users)
|
- [Users](#users)
|
||||||
- [Search](#search)
|
- [Search](#search)
|
||||||
+ [Contributing](#contributing)
|
+ [Contributing](#contributing)
|
||||||
+ [Donate](#donate)
|
+ [Donate](#donate)
|
||||||
|
|
||||||
# Getting started
|
# Getting started
|
||||||
|
|
||||||
You can find the Getting Started guide on the [documentation](https://filebrowser.github.io/quick-start/).
|
You can find the Getting Started guide on the [documentation](https://filebrowser.github.io/quick-start/).
|
||||||
|
|
||||||
# Features
|
# Features
|
||||||
|
|
||||||
Easy login system.
|
Easy login system.
|
||||||
|
|
||||||
![Login Page](https://user-images.githubusercontent.com/5447088/28432382-975493dc-6d7f-11e7-9190-23f8037159dc.jpg)
|
![Login Page](https://user-images.githubusercontent.com/5447088/28432382-975493dc-6d7f-11e7-9190-23f8037159dc.jpg)
|
||||||
|
|
||||||
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*.
|
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](https://user-images.githubusercontent.com/5447088/28432384-9771bb4c-6d7f-11e7-8564-3a9bd6a3ce3a.jpg)
|
![Mosaic Listing](https://user-images.githubusercontent.com/5447088/28432384-9771bb4c-6d7f-11e7-8564-3a9bd6a3ce3a.jpg)
|
||||||
|
|
||||||
File Manager editor is powered by [Codemirror](https://codemirror.net/) 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.
|
File Browser editor is powered by [Codemirror](https://codemirror.net/) 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](https://user-images.githubusercontent.com/5447088/28432383-9756fdac-6d7f-11e7-8e58-fec49470d15f.jpg)
|
![Markdown Editor](https://user-images.githubusercontent.com/5447088/28432383-9756fdac-6d7f-11e7-8e58-fec49470d15f.jpg)
|
||||||
|
|
||||||
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.
|
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](https://user-images.githubusercontent.com/5447088/28432385-9776ec66-6d7f-11e7-90a5-891bacd4d02f.jpg)
|
![Settings](https://user-images.githubusercontent.com/5447088/28432385-9776ec66-6d7f-11e7-90a5-891bacd4d02f.jpg)
|
||||||
|
|
||||||
We also allow the users to search in the directories and execute commands if allowed.
|
We also allow the users to search in the directories and execute commands if allowed.
|
||||||
|
|
||||||
## Users
|
## 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!).
|
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](https://user-images.githubusercontent.com/5447088/28432386-977f388a-6d7f-11e7-9006-87d16f05f1f8.jpg)
|
![Users](https://user-images.githubusercontent.com/5447088/28432386-977f388a-6d7f-11e7-9006-87d16f05f1f8.jpg)
|
||||||
|
|
||||||
## Search
|
## Search
|
||||||
|
|
||||||
File Browser allows you to search through your files and it has some options. By default, your search will be something like this:
|
File Browser allows you to search through your files and it has some options. By default, your search will be something like this:
|
||||||
|
|
||||||
```
|
```
|
||||||
this are keywords
|
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:
|
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"
|
"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.
|
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:
|
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
|
this are keywords case:insensitive
|
||||||
```
|
```
|
||||||
|
|
||||||
# Contributing
|
# Contributing
|
||||||
|
|
||||||
The contributing guidelines can be found [here](https://github.com/filebrowser/community).
|
The contributing guidelines can be found [here](https://github.com/filebrowser/community).
|
||||||
|
@ -2,7 +2,7 @@ package bolt
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/asdine/storm"
|
"github.com/asdine/storm"
|
||||||
fm "github.com/filebrowser/filebrowser"
|
fb "github.com/filebrowser/filebrowser"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ConfigStore is a configuration store.
|
// ConfigStore is a configuration store.
|
||||||
@ -14,7 +14,7 @@ type ConfigStore struct {
|
|||||||
func (c ConfigStore) Get(name string, to interface{}) error {
|
func (c ConfigStore) Get(name string, to interface{}) error {
|
||||||
err := c.DB.Get("config", name, to)
|
err := c.DB.Get("config", name, to)
|
||||||
if err == storm.ErrNotFound {
|
if err == storm.ErrNotFound {
|
||||||
return fm.ErrNotExist
|
return fb.ErrNotExist
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
|
@ -3,7 +3,7 @@ package bolt
|
|||||||
import (
|
import (
|
||||||
"github.com/asdine/storm"
|
"github.com/asdine/storm"
|
||||||
"github.com/asdine/storm/q"
|
"github.com/asdine/storm/q"
|
||||||
fm "github.com/filebrowser/filebrowser"
|
fb "github.com/filebrowser/filebrowser"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ShareStore is a shareable links store.
|
// ShareStore is a shareable links store.
|
||||||
@ -12,55 +12,55 @@ type ShareStore struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get gets a Share Link from an hash.
|
// Get gets a Share Link from an hash.
|
||||||
func (s ShareStore) Get(hash string) (*fm.ShareLink, error) {
|
func (s ShareStore) Get(hash string) (*fb.ShareLink, error) {
|
||||||
var v fm.ShareLink
|
var v fb.ShareLink
|
||||||
err := s.DB.One("Hash", hash, &v)
|
err := s.DB.One("Hash", hash, &v)
|
||||||
if err == storm.ErrNotFound {
|
if err == storm.ErrNotFound {
|
||||||
return nil, fm.ErrNotExist
|
return nil, fb.ErrNotExist
|
||||||
}
|
}
|
||||||
|
|
||||||
return &v, err
|
return &v, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPermanent gets the permanent link from a path.
|
// GetPermanent gets the permanent link from a path.
|
||||||
func (s ShareStore) GetPermanent(path string) (*fm.ShareLink, error) {
|
func (s ShareStore) GetPermanent(path string) (*fb.ShareLink, error) {
|
||||||
var v fm.ShareLink
|
var v fb.ShareLink
|
||||||
err := s.DB.Select(q.Eq("Path", path), q.Eq("Expires", false)).First(&v)
|
err := s.DB.Select(q.Eq("Path", path), q.Eq("Expires", false)).First(&v)
|
||||||
if err == storm.ErrNotFound {
|
if err == storm.ErrNotFound {
|
||||||
return nil, fm.ErrNotExist
|
return nil, fb.ErrNotExist
|
||||||
}
|
}
|
||||||
|
|
||||||
return &v, err
|
return &v, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetByPath gets all the links for a specific path.
|
// GetByPath gets all the links for a specific path.
|
||||||
func (s ShareStore) GetByPath(hash string) ([]*fm.ShareLink, error) {
|
func (s ShareStore) GetByPath(hash string) ([]*fb.ShareLink, error) {
|
||||||
var v []*fm.ShareLink
|
var v []*fb.ShareLink
|
||||||
err := s.DB.Find("Path", hash, &v)
|
err := s.DB.Find("Path", hash, &v)
|
||||||
if err == storm.ErrNotFound {
|
if err == storm.ErrNotFound {
|
||||||
return v, fm.ErrNotExist
|
return v, fb.ErrNotExist
|
||||||
}
|
}
|
||||||
|
|
||||||
return v, err
|
return v, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets retrieves all the shareable links.
|
// Gets retrieves all the shareable links.
|
||||||
func (s ShareStore) Gets() ([]*fm.ShareLink, error) {
|
func (s ShareStore) Gets() ([]*fb.ShareLink, error) {
|
||||||
var v []*fm.ShareLink
|
var v []*fb.ShareLink
|
||||||
err := s.DB.All(&v)
|
err := s.DB.All(&v)
|
||||||
if err == storm.ErrNotFound {
|
if err == storm.ErrNotFound {
|
||||||
return v, fm.ErrNotExist
|
return v, fb.ErrNotExist
|
||||||
}
|
}
|
||||||
|
|
||||||
return v, err
|
return v, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save stores a Share Link on the database.
|
// Save stores a Share Link on the database.
|
||||||
func (s ShareStore) Save(l *fm.ShareLink) error {
|
func (s ShareStore) Save(l *fb.ShareLink) error {
|
||||||
return s.DB.Save(l)
|
return s.DB.Save(l)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete deletes a Share Link from the database.
|
// Delete deletes a Share Link from the database.
|
||||||
func (s ShareStore) Delete(hash string) error {
|
func (s ShareStore) Delete(hash string) error {
|
||||||
return s.DB.DeleteStruct(&fm.ShareLink{Hash: hash})
|
return s.DB.DeleteStruct(&fb.ShareLink{Hash: hash})
|
||||||
}
|
}
|
||||||
|
8
doc.go
8
doc.go
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
Package filebrowser provides a web interface to access your files
|
Package filebrowser provides a web interface to access your files
|
||||||
wherever you are. To use this package as a middleware for your app,
|
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.
|
you'll need to import both File Browser and File Browser HTTP packages.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
fm "github.com/filebrowser/filebrowser"
|
fm "github.com/filebrowser/filebrowser"
|
||||||
@ -49,11 +49,11 @@ functions:
|
|||||||
m.SetPrefixURL("/")
|
m.SetPrefixURL("/")
|
||||||
|
|
||||||
The Prefix URL is a part of the path that is already stripped from the
|
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.
|
r.URL.Path variable before the request arrives to File Browser's handler.
|
||||||
This is a function that will rarely be used. You can see one example on Caddy
|
This is a function that will rarely be used. You can see one example on Caddy
|
||||||
filemanager plugin.
|
filemanager plugin.
|
||||||
|
|
||||||
The Base URL is the URL path where you want File Manager to be available in. If
|
The Base URL is the URL path where you want File Browser to be available in. If
|
||||||
you want to be available at the root path, you should call:
|
you want to be available at the root path, you should call:
|
||||||
|
|
||||||
m.SetBaseURL("/")
|
m.SetBaseURL("/")
|
||||||
@ -62,7 +62,7 @@ But if you want to access it at '/admin', you would call:
|
|||||||
|
|
||||||
m.SetBaseURL("/admin")
|
m.SetBaseURL("/admin")
|
||||||
|
|
||||||
Now, that you already have a File Manager instance created, you just need to
|
Now, that you already have a File Browser instance created, you just need to
|
||||||
add it to your handlers using m.ServeHTTP which is compatible to http.Handler.
|
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.
|
We also have a m.ServeWithErrorsHTTP that returns the status code and an error.
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// Version is the current File Manager version.
|
// Version is the current File Browser version.
|
||||||
Version = "(untracked)"
|
Version = "(untracked)"
|
||||||
|
|
||||||
ListViewMode = "list"
|
ListViewMode = "list"
|
||||||
@ -58,7 +58,7 @@ type FileBrowser struct {
|
|||||||
Store *Store
|
Store *Store
|
||||||
|
|
||||||
// PrefixURL is a part of the URL that is already trimmed from the request URL before it
|
// 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
|
// arrives to our handlers. It may be useful when using File Browser as a middleware
|
||||||
// such as in caddy-filemanager plugin. It is only useful in certain situations.
|
// such as in caddy-filemanager plugin. It is only useful in certain situations.
|
||||||
PrefixURL string
|
PrefixURL string
|
||||||
|
|
||||||
@ -115,9 +115,9 @@ type FSBuilder func(scope string) FileSystem
|
|||||||
|
|
||||||
// Setup loads the configuration from the database and configures
|
// Setup loads the configuration from the database and configures
|
||||||
// the Assets and the Cron job. It must always be run after
|
// the Assets and the Cron job. It must always be run after
|
||||||
// creating a File Manager object.
|
// creating a File Browser object.
|
||||||
func (m *FileBrowser) Setup() error {
|
func (m *FileBrowser) Setup() error {
|
||||||
// Creates a new File Manager instance with the Users
|
// Creates a new File Browser instance with the Users
|
||||||
// map and Assets box.
|
// map and Assets box.
|
||||||
m.Assets = rice.MustFindBox("./node_modules/filebrowser-frontend/dist")
|
m.Assets = rice.MustFindBox("./node_modules/filebrowser-frontend/dist")
|
||||||
m.Cron = cron.New()
|
m.Cron = cron.New()
|
||||||
@ -221,7 +221,7 @@ func (m *FileBrowser) Setup() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RootURL returns the actual URL where
|
// RootURL returns the actual URL where
|
||||||
// File Manager interface can be accessed.
|
// File Browser interface can be accessed.
|
||||||
func (m FileBrowser) RootURL() string {
|
func (m FileBrowser) RootURL() string {
|
||||||
return m.PrefixURL + m.BaseURL
|
return m.PrefixURL + m.BaseURL
|
||||||
}
|
}
|
||||||
@ -235,7 +235,7 @@ func (m *FileBrowser) SetPrefixURL(url string) {
|
|||||||
m.PrefixURL = strings.TrimSuffix(url, "/")
|
m.PrefixURL = strings.TrimSuffix(url, "/")
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetBaseURL updates the baseURL of a File Manager
|
// SetBaseURL updates the baseURL of a File Browser
|
||||||
// object.
|
// object.
|
||||||
func (m *FileBrowser) SetBaseURL(url string) {
|
func (m *FileBrowser) SetBaseURL(url string) {
|
||||||
url = strings.TrimPrefix(url, "/")
|
url = strings.TrimPrefix(url, "/")
|
||||||
@ -244,7 +244,7 @@ func (m *FileBrowser) SetBaseURL(url string) {
|
|||||||
m.BaseURL = strings.TrimSuffix(url, "/")
|
m.BaseURL = strings.TrimSuffix(url, "/")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attach attaches a static generator to the current File Manager.
|
// Attach attaches a static generator to the current File Browser.
|
||||||
func (m *FileBrowser) Attach(s StaticGen) error {
|
func (m *FileBrowser) Attach(s StaticGen) error {
|
||||||
if reflect.TypeOf(s).Kind() != reflect.Ptr {
|
if reflect.TypeOf(s).Kind() != reflect.Ptr {
|
||||||
return errors.New("data should be a pointer to interface, not interface")
|
return errors.New("data should be a pointer to interface, not interface")
|
||||||
@ -290,7 +290,7 @@ func (m FileBrowser) ShareCleaner() {
|
|||||||
func (m FileBrowser) Runner(event string, path string, destination string, user *User) error {
|
func (m FileBrowser) Runner(event string, path string, destination string, user *User) error {
|
||||||
commands := []string{}
|
commands := []string{}
|
||||||
|
|
||||||
// Get the commands from the File Manager instance itself.
|
// Get the commands from the File Browser instance itself.
|
||||||
if val, ok := m.Commands[event]; ok {
|
if val, ok := m.Commands[event]; ok {
|
||||||
commands = append(commands, val...)
|
commands = append(commands, val...)
|
||||||
}
|
}
|
||||||
|
18
http/auth.go
18
http/auth.go
@ -9,7 +9,7 @@ import (
|
|||||||
|
|
||||||
"github.com/dgrijalva/jwt-go"
|
"github.com/dgrijalva/jwt-go"
|
||||||
"github.com/dgrijalva/jwt-go/request"
|
"github.com/dgrijalva/jwt-go/request"
|
||||||
fm "github.com/filebrowser/filebrowser"
|
fb "github.com/filebrowser/filebrowser"
|
||||||
)
|
)
|
||||||
|
|
||||||
const reCaptchaAPI = "/recaptcha/api/siteverify"
|
const reCaptchaAPI = "/recaptcha/api/siteverify"
|
||||||
@ -50,7 +50,7 @@ func reCaptcha(host, secret, response string) (bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// authHandler processes the authentication for the user.
|
// authHandler processes the authentication for the user.
|
||||||
func authHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func authHandler(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
// NoAuth instances shouldn't call this method.
|
// NoAuth instances shouldn't call this method.
|
||||||
if c.NoAuth {
|
if c.NoAuth {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
@ -86,7 +86,7 @@ func authHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, er
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Checks if the password is correct.
|
// Checks if the password is correct.
|
||||||
if !fm.CheckPasswordHash(cred.Password, u.Password) {
|
if !fb.CheckPasswordHash(cred.Password, u.Password) {
|
||||||
return http.StatusForbidden, nil
|
return http.StatusForbidden, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,7 +96,7 @@ func authHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, er
|
|||||||
|
|
||||||
// renewAuthHandler is used when the front-end already has a JWT token
|
// renewAuthHandler is used when the front-end already has a JWT token
|
||||||
// and is checking if it is up to date. If so, updates its info.
|
// and is checking if it is up to date. If so, updates its info.
|
||||||
func renewAuthHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func renewAuthHandler(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
ok, u := validateAuth(c, r)
|
ok, u := validateAuth(c, r)
|
||||||
if !ok {
|
if !ok {
|
||||||
return http.StatusForbidden, nil
|
return http.StatusForbidden, nil
|
||||||
@ -108,15 +108,15 @@ func renewAuthHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (in
|
|||||||
|
|
||||||
// claims is the JWT claims.
|
// claims is the JWT claims.
|
||||||
type claims struct {
|
type claims struct {
|
||||||
fm.User
|
fb.User
|
||||||
jwt.StandardClaims
|
jwt.StandardClaims
|
||||||
}
|
}
|
||||||
|
|
||||||
// printToken prints the final JWT token to the user.
|
// printToken prints the final JWT token to the user.
|
||||||
func printToken(c *fm.Context, w http.ResponseWriter) (int, error) {
|
func printToken(c *fb.Context, w http.ResponseWriter) (int, error) {
|
||||||
// Creates a copy of the user and removes it password
|
// Creates a copy of the user and removes it password
|
||||||
// hash so it never arrives to the user.
|
// hash so it never arrives to the user.
|
||||||
u := fm.User{}
|
u := fb.User{}
|
||||||
u = *c.User
|
u = *c.User
|
||||||
u.Password = ""
|
u.Password = ""
|
||||||
|
|
||||||
@ -125,7 +125,7 @@ func printToken(c *fm.Context, w http.ResponseWriter) (int, error) {
|
|||||||
u,
|
u,
|
||||||
jwt.StandardClaims{
|
jwt.StandardClaims{
|
||||||
ExpiresAt: time.Now().Add(time.Hour * 24).Unix(),
|
ExpiresAt: time.Now().Add(time.Hour * 24).Unix(),
|
||||||
Issuer: "File Manager",
|
Issuer: "File Browser",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,7 +165,7 @@ func (e extractor) ExtractToken(r *http.Request) (string, error) {
|
|||||||
|
|
||||||
// validateAuth is used to validate the authentication and returns the
|
// validateAuth is used to validate the authentication and returns the
|
||||||
// User if it is valid.
|
// User if it is valid.
|
||||||
func validateAuth(c *fm.Context, r *http.Request) (bool, *fm.User) {
|
func validateAuth(c *fb.Context, r *http.Request) (bool, *fb.User) {
|
||||||
if c.NoAuth {
|
if c.NoAuth {
|
||||||
c.User = c.DefaultUser
|
c.User = c.DefaultUser
|
||||||
return true, c.User
|
return true, c.User
|
||||||
|
@ -7,14 +7,14 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
fm "github.com/filebrowser/filebrowser"
|
fb "github.com/filebrowser/filebrowser"
|
||||||
"github.com/hacdias/fileutils"
|
"github.com/hacdias/fileutils"
|
||||||
"github.com/mholt/archiver"
|
"github.com/mholt/archiver"
|
||||||
)
|
)
|
||||||
|
|
||||||
// downloadHandler creates an archive in one of the supported formats (zip, tar,
|
// downloadHandler creates an archive in one of the supported formats (zip, tar,
|
||||||
// tar.gz or tar.bz2) and sends it to be downloaded.
|
// tar.gz or tar.bz2) and sends it to be downloaded.
|
||||||
func downloadHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func downloadHandler(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
// If the file isn't a directory, serve it using http.ServeFile. We display it
|
// If the file isn't a directory, serve it using http.ServeFile. We display it
|
||||||
// inline if it is requested.
|
// inline if it is requested.
|
||||||
if !c.File.IsDir {
|
if !c.File.IsDir {
|
||||||
@ -77,7 +77,7 @@ func downloadHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int
|
|||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func downloadFileHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func downloadFileHandler(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
file, err := os.Open(c.File.Path)
|
file, err := os.Open(c.File.Path)
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
|
30
http/http.go
30
http/http.go
@ -10,13 +10,13 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
fm "github.com/filebrowser/filebrowser"
|
fb "github.com/filebrowser/filebrowser"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Handler returns a function compatible with http.HandleFunc.
|
// Handler returns a function compatible with http.HandleFunc.
|
||||||
func Handler(m *fm.FileBrowser) http.Handler {
|
func Handler(m *fb.FileBrowser) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
code, err := serve(&fm.Context{
|
code, err := serve(&fb.Context{
|
||||||
FileBrowser: m,
|
FileBrowser: m,
|
||||||
User: nil,
|
User: nil,
|
||||||
File: nil,
|
File: nil,
|
||||||
@ -37,9 +37,9 @@ func Handler(m *fm.FileBrowser) http.Handler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// serve is the main entry point of this HTML application.
|
// serve is the main entry point of this HTML application.
|
||||||
func serve(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func serve(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
// Checks if the URL contains the baseURL and strips it. Otherwise, it just
|
// Checks if the URL contains the baseURL and strips it. Otherwise, it just
|
||||||
// returns a 404 fm.Error because we're not supposed to be here!
|
// returns a 404 fb.Error because we're not supposed to be here!
|
||||||
p := strings.TrimPrefix(r.URL.Path, c.BaseURL)
|
p := strings.TrimPrefix(r.URL.Path, c.BaseURL)
|
||||||
|
|
||||||
if len(p) >= len(r.URL.Path) && c.BaseURL != "" {
|
if len(p) >= len(r.URL.Path) && c.BaseURL != "" {
|
||||||
@ -93,7 +93,7 @@ func serve(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// staticHandler handles the static assets path.
|
// staticHandler handles the static assets path.
|
||||||
func staticHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func staticHandler(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
if r.URL.Path != "/static/manifest.json" {
|
if r.URL.Path != "/static/manifest.json" {
|
||||||
http.FileServer(c.Assets.HTTPBox()).ServeHTTP(w, r)
|
http.FileServer(c.Assets.HTTPBox()).ServeHTTP(w, r)
|
||||||
return 0, nil
|
return 0, nil
|
||||||
@ -103,7 +103,7 @@ func staticHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// apiHandler is the main entry point for the /api endpoint.
|
// apiHandler is the main entry point for the /api endpoint.
|
||||||
func apiHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func apiHandler(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
if r.URL.Path == "/auth/get" {
|
if r.URL.Path == "/auth/get" {
|
||||||
return authHandler(c, w, r)
|
return authHandler(c, w, r)
|
||||||
}
|
}
|
||||||
@ -139,7 +139,7 @@ func apiHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, err
|
|||||||
|
|
||||||
if c.Router == "checksum" || c.Router == "download" {
|
if c.Router == "checksum" || c.Router == "download" {
|
||||||
var err error
|
var err error
|
||||||
c.File, err = fm.GetInfo(r.URL, c.FileBrowser, c.User)
|
c.File, err = fb.GetInfo(r.URL, c.FileBrowser, c.User)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ErrorToHTTP(err, false), err
|
return ErrorToHTTP(err, false), err
|
||||||
}
|
}
|
||||||
@ -173,11 +173,11 @@ func apiHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, err
|
|||||||
}
|
}
|
||||||
|
|
||||||
// serveChecksum calculates the hash of a file. Supports MD5, SHA1, SHA256 and SHA512.
|
// serveChecksum calculates the hash of a file. Supports MD5, SHA1, SHA256 and SHA512.
|
||||||
func checksumHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func checksumHandler(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
query := r.URL.Query().Get("algo")
|
query := r.URL.Query().Get("algo")
|
||||||
|
|
||||||
val, err := c.File.Checksum(query)
|
val, err := c.File.Checksum(query)
|
||||||
if err == fm.ErrInvalidOption {
|
if err == fb.ErrInvalidOption {
|
||||||
return http.StatusBadRequest, err
|
return http.StatusBadRequest, err
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return http.StatusInternalServerError, err
|
return http.StatusInternalServerError, err
|
||||||
@ -205,7 +205,7 @@ func splitURL(path string) (string, string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// renderFile renders a file using a template with some needed variables.
|
// renderFile renders a file using a template with some needed variables.
|
||||||
func renderFile(c *fm.Context, w http.ResponseWriter, file string) (int, error) {
|
func renderFile(c *fb.Context, w http.ResponseWriter, file string) (int, error) {
|
||||||
tpl := template.Must(template.New("file").Parse(c.Assets.MustString(file)))
|
tpl := template.Must(template.New("file").Parse(c.Assets.MustString(file)))
|
||||||
|
|
||||||
var contentType string
|
var contentType string
|
||||||
@ -225,7 +225,7 @@ func renderFile(c *fm.Context, w http.ResponseWriter, file string) (int, error)
|
|||||||
data := map[string]interface{}{
|
data := map[string]interface{}{
|
||||||
"BaseURL": c.RootURL(),
|
"BaseURL": c.RootURL(),
|
||||||
"NoAuth": c.NoAuth,
|
"NoAuth": c.NoAuth,
|
||||||
"Version": fm.Version,
|
"Version": fb.Version,
|
||||||
"CSS": template.CSS(c.CSS),
|
"CSS": template.CSS(c.CSS),
|
||||||
"ReCaptcha": c.ReCaptchaKey != "" && c.ReCaptchaSecret != "",
|
"ReCaptcha": c.ReCaptchaKey != "" && c.ReCaptchaSecret != "",
|
||||||
"ReCaptchaHost": c.ReCaptchaHost,
|
"ReCaptchaHost": c.ReCaptchaHost,
|
||||||
@ -246,9 +246,9 @@ func renderFile(c *fm.Context, w http.ResponseWriter, file string) (int, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// sharePage build the share page.
|
// sharePage build the share page.
|
||||||
func sharePage(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func sharePage(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
s, err := c.Store.Share.Get(r.URL.Path)
|
s, err := c.Store.Share.Get(r.URL.Path)
|
||||||
if err == fm.ErrNotExist {
|
if err == fb.ErrNotExist {
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
return renderFile(c, w, "static/share/404.html")
|
return renderFile(c, w, "static/share/404.html")
|
||||||
}
|
}
|
||||||
@ -271,7 +271,7 @@ func sharePage(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, erro
|
|||||||
return ErrorToHTTP(err, false), err
|
return ErrorToHTTP(err, false), err
|
||||||
}
|
}
|
||||||
|
|
||||||
c.File = &fm.File{
|
c.File = &fb.File{
|
||||||
Path: s.Path,
|
Path: s.Path,
|
||||||
Name: info.Name(),
|
Name: info.Name(),
|
||||||
ModTime: info.ModTime(),
|
ModTime: info.ModTime(),
|
||||||
|
@ -13,7 +13,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
fm "github.com/filebrowser/filebrowser"
|
fb "github.com/filebrowser/filebrowser"
|
||||||
"github.com/hacdias/fileutils"
|
"github.com/hacdias/fileutils"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ func sanitizeURL(url string) string {
|
|||||||
return path
|
return path
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourceHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func resourceHandler(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
r.URL.Path = sanitizeURL(r.URL.Path)
|
r.URL.Path = sanitizeURL(r.URL.Path)
|
||||||
|
|
||||||
switch r.Method {
|
switch r.Method {
|
||||||
@ -62,9 +62,9 @@ func resourceHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int
|
|||||||
return http.StatusNotImplemented, nil
|
return http.StatusNotImplemented, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourceGetHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func resourceGetHandler(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
// Gets the information of the directory/file.
|
// Gets the information of the directory/file.
|
||||||
f, err := fm.GetInfo(r.URL, c.FileBrowser, c.User)
|
f, err := fb.GetInfo(r.URL, c.FileBrowser, c.User)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ErrorToHTTP(err, false), err
|
return ErrorToHTTP(err, false), err
|
||||||
}
|
}
|
||||||
@ -104,7 +104,7 @@ func resourceGetHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (
|
|||||||
return renderJSON(w, f)
|
return renderJSON(w, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
func listingHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func listingHandler(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
f := c.File
|
f := c.File
|
||||||
f.Kind = "listing"
|
f.Kind = "listing"
|
||||||
|
|
||||||
@ -133,7 +133,7 @@ func listingHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int,
|
|||||||
return renderJSON(w, f)
|
return renderJSON(w, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourceDeleteHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func resourceDeleteHandler(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
// Prevent the removal of the root directory.
|
// Prevent the removal of the root directory.
|
||||||
if r.URL.Path == "/" || !c.User.AllowEdit {
|
if r.URL.Path == "/" || !c.User.AllowEdit {
|
||||||
return http.StatusForbidden, nil
|
return http.StatusForbidden, nil
|
||||||
@ -158,7 +158,7 @@ func resourceDeleteHandler(c *fm.Context, w http.ResponseWriter, r *http.Request
|
|||||||
return http.StatusOK, nil
|
return http.StatusOK, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourcePostPutHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func resourcePostPutHandler(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
if !c.User.AllowNew && r.Method == http.MethodPost {
|
if !c.User.AllowNew && r.Method == http.MethodPost {
|
||||||
return http.StatusForbidden, nil
|
return http.StatusForbidden, nil
|
||||||
}
|
}
|
||||||
@ -240,7 +240,7 @@ func resourcePostPutHandler(c *fm.Context, w http.ResponseWriter, r *http.Reques
|
|||||||
return http.StatusOK, nil
|
return http.StatusOK, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourcePublishSchedule(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func resourcePublishSchedule(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
publish := r.Header.Get("Publish")
|
publish := r.Header.Get("Publish")
|
||||||
schedule := r.Header.Get("Schedule")
|
schedule := r.Header.Get("Schedule")
|
||||||
|
|
||||||
@ -271,7 +271,7 @@ func resourcePublishSchedule(c *fm.Context, w http.ResponseWriter, r *http.Reque
|
|||||||
return http.StatusOK, nil
|
return http.StatusOK, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourcePublish(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func resourcePublish(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
path := filepath.Join(c.User.Scope, r.URL.Path)
|
path := filepath.Join(c.User.Scope, r.URL.Path)
|
||||||
|
|
||||||
// Before save command handler.
|
// Before save command handler.
|
||||||
@ -293,7 +293,7 @@ func resourcePublish(c *fm.Context, w http.ResponseWriter, r *http.Request) (int
|
|||||||
}
|
}
|
||||||
|
|
||||||
// resourcePatchHandler is the entry point for resource handler.
|
// resourcePatchHandler is the entry point for resource handler.
|
||||||
func resourcePatchHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func resourcePatchHandler(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
if !c.User.AllowEdit {
|
if !c.User.AllowEdit {
|
||||||
return http.StatusForbidden, nil
|
return http.StatusForbidden, nil
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
fm "github.com/filebrowser/filebrowser"
|
fb "github.com/filebrowser/filebrowser"
|
||||||
"github.com/mitchellh/mapstructure"
|
"github.com/mitchellh/mapstructure"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ type option struct {
|
|||||||
func parsePutSettingsRequest(r *http.Request) (*modifySettingsRequest, error) {
|
func parsePutSettingsRequest(r *http.Request) (*modifySettingsRequest, error) {
|
||||||
// Checks if the request body is empty.
|
// Checks if the request body is empty.
|
||||||
if r.Body == nil {
|
if r.Body == nil {
|
||||||
return nil, fm.ErrEmptyRequest
|
return nil, fb.ErrEmptyRequest
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parses the request body and checks if it's well formed.
|
// Parses the request body and checks if it's well formed.
|
||||||
@ -40,13 +40,13 @@ func parsePutSettingsRequest(r *http.Request) (*modifySettingsRequest, error) {
|
|||||||
|
|
||||||
// Checks if the request type is right.
|
// Checks if the request type is right.
|
||||||
if mod.What != "settings" {
|
if mod.What != "settings" {
|
||||||
return nil, fm.ErrWrongDataType
|
return nil, fb.ErrWrongDataType
|
||||||
}
|
}
|
||||||
|
|
||||||
return mod, nil
|
return mod, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func settingsHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func settingsHandler(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
if r.URL.Path != "" && r.URL.Path != "/" {
|
if r.URL.Path != "" && r.URL.Path != "/" {
|
||||||
return http.StatusNotFound, nil
|
return http.StatusNotFound, nil
|
||||||
}
|
}
|
||||||
@ -67,7 +67,7 @@ type settingsGetRequest struct {
|
|||||||
StaticGen []option `json:"staticGen"`
|
StaticGen []option `json:"staticGen"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func settingsGetHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func settingsGetHandler(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
if !c.User.Admin {
|
if !c.User.Admin {
|
||||||
return http.StatusForbidden, nil
|
return http.StatusForbidden, nil
|
||||||
}
|
}
|
||||||
@ -97,7 +97,7 @@ func settingsGetHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (
|
|||||||
return renderJSON(w, result)
|
return renderJSON(w, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
func settingsPutHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func settingsPutHandler(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
if !c.User.Admin {
|
if !c.User.Admin {
|
||||||
return http.StatusForbidden, nil
|
return http.StatusForbidden, nil
|
||||||
}
|
}
|
||||||
|
@ -8,10 +8,10 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
fm "github.com/filebrowser/filebrowser"
|
fb "github.com/filebrowser/filebrowser"
|
||||||
)
|
)
|
||||||
|
|
||||||
func shareHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func shareHandler(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
r.URL.Path = sanitizeURL(r.URL.Path)
|
r.URL.Path = sanitizeURL(r.URL.Path)
|
||||||
|
|
||||||
switch r.Method {
|
switch r.Method {
|
||||||
@ -26,10 +26,10 @@ func shareHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, e
|
|||||||
return http.StatusNotImplemented, nil
|
return http.StatusNotImplemented, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func shareGetHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func shareGetHandler(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
path := filepath.Join(c.User.Scope, r.URL.Path)
|
path := filepath.Join(c.User.Scope, r.URL.Path)
|
||||||
s, err := c.Store.Share.GetByPath(path)
|
s, err := c.Store.Share.GetByPath(path)
|
||||||
if err == fm.ErrNotExist {
|
if err == fb.ErrNotExist {
|
||||||
return http.StatusNotFound, nil
|
return http.StatusNotFound, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,10 +51,10 @@ func shareGetHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int
|
|||||||
return renderJSON(w, s)
|
return renderJSON(w, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
func sharePostHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func sharePostHandler(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
path := filepath.Join(c.User.Scope, r.URL.Path)
|
path := filepath.Join(c.User.Scope, r.URL.Path)
|
||||||
|
|
||||||
var s *fm.ShareLink
|
var s *fb.ShareLink
|
||||||
expire := r.URL.Query().Get("expires")
|
expire := r.URL.Query().Get("expires")
|
||||||
unit := r.URL.Query().Get("unit")
|
unit := r.URL.Query().Get("unit")
|
||||||
|
|
||||||
@ -67,14 +67,14 @@ func sharePostHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (in
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes, err := fm.GenerateRandomBytes(6)
|
bytes, err := fb.GenerateRandomBytes(6)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return http.StatusInternalServerError, err
|
return http.StatusInternalServerError, err
|
||||||
}
|
}
|
||||||
|
|
||||||
str := base64.URLEncoding.EncodeToString(bytes)
|
str := base64.URLEncoding.EncodeToString(bytes)
|
||||||
|
|
||||||
s = &fm.ShareLink{
|
s = &fb.ShareLink{
|
||||||
Path: path,
|
Path: path,
|
||||||
Hash: str,
|
Hash: str,
|
||||||
Expires: expire != "",
|
Expires: expire != "",
|
||||||
@ -108,9 +108,9 @@ func sharePostHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (in
|
|||||||
return renderJSON(w, s)
|
return renderJSON(w, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
func shareDeleteHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func shareDeleteHandler(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
s, err := c.Store.Share.Get(strings.TrimPrefix(r.URL.Path, "/"))
|
s, err := c.Store.Share.Get(strings.TrimPrefix(r.URL.Path, "/"))
|
||||||
if err == fm.ErrNotExist {
|
if err == fb.ErrNotExist {
|
||||||
return http.StatusNotFound, nil
|
return http.StatusNotFound, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
fm "github.com/filebrowser/filebrowser"
|
fb "github.com/filebrowser/filebrowser"
|
||||||
)
|
)
|
||||||
|
|
||||||
type modifyRequest struct {
|
type modifyRequest struct {
|
||||||
@ -19,12 +19,12 @@ type modifyRequest struct {
|
|||||||
|
|
||||||
type modifyUserRequest struct {
|
type modifyUserRequest struct {
|
||||||
modifyRequest
|
modifyRequest
|
||||||
Data *fm.User `json:"data"`
|
Data *fb.User `json:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// usersHandler is the entry point of the users API. It's just a router
|
// usersHandler is the entry point of the users API. It's just a router
|
||||||
// to send the request to its
|
// to send the request to its
|
||||||
func usersHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func usersHandler(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
// If the user isn't admin and isn't making a PUT
|
// If the user isn't admin and isn't making a PUT
|
||||||
// request, then return forbidden.
|
// request, then return forbidden.
|
||||||
if !c.User.Admin && r.Method != http.MethodPut {
|
if !c.User.Admin && r.Method != http.MethodPut {
|
||||||
@ -47,7 +47,7 @@ func usersHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, e
|
|||||||
|
|
||||||
// getUserID returns the id from the user which is present
|
// getUserID returns the id from the user which is present
|
||||||
// in the request url. If the url is invalid and doesn't
|
// in the request url. If the url is invalid and doesn't
|
||||||
// contain a valid ID, it returns an fm.Error.
|
// contain a valid ID, it returns an fb.Error.
|
||||||
func getUserID(r *http.Request) (int, error) {
|
func getUserID(r *http.Request) (int, error) {
|
||||||
// Obtains the ID in string from the URL and converts
|
// Obtains the ID in string from the URL and converts
|
||||||
// it into an integer.
|
// it into an integer.
|
||||||
@ -63,11 +63,11 @@ func getUserID(r *http.Request) (int, error) {
|
|||||||
|
|
||||||
// getUser returns the user which is present in the request
|
// getUser returns the user which is present in the request
|
||||||
// body. If the body is empty or the JSON is invalid, it
|
// body. If the body is empty or the JSON is invalid, it
|
||||||
// returns an fm.Error.
|
// returns an fb.Error.
|
||||||
func getUser(c *fm.Context, r *http.Request) (*fm.User, string, error) {
|
func getUser(c *fb.Context, r *http.Request) (*fb.User, string, error) {
|
||||||
// Checks if the request body is empty.
|
// Checks if the request body is empty.
|
||||||
if r.Body == nil {
|
if r.Body == nil {
|
||||||
return nil, "", fm.ErrEmptyRequest
|
return nil, "", fb.ErrEmptyRequest
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parses the request body and checks if it's well formed.
|
// Parses the request body and checks if it's well formed.
|
||||||
@ -79,14 +79,14 @@ func getUser(c *fm.Context, r *http.Request) (*fm.User, string, error) {
|
|||||||
|
|
||||||
// Checks if the request type is right.
|
// Checks if the request type is right.
|
||||||
if mod.What != "user" {
|
if mod.What != "user" {
|
||||||
return nil, "", fm.ErrWrongDataType
|
return nil, "", fb.ErrWrongDataType
|
||||||
}
|
}
|
||||||
|
|
||||||
mod.Data.FileSystem = c.NewFS(mod.Data.Scope)
|
mod.Data.FileSystem = c.NewFS(mod.Data.Scope)
|
||||||
return mod.Data, mod.Which, nil
|
return mod.Data, mod.Which, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func usersGetHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func usersGetHandler(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
// Request for the default user data.
|
// Request for the default user data.
|
||||||
if r.URL.Path == "/base" {
|
if r.URL.Path == "/base" {
|
||||||
return renderJSON(w, c.DefaultUser)
|
return renderJSON(w, c.DefaultUser)
|
||||||
@ -118,7 +118,7 @@ func usersGetHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int
|
|||||||
}
|
}
|
||||||
|
|
||||||
u, err := c.Store.Users.Get(id, c.NewFS)
|
u, err := c.Store.Users.Get(id, c.NewFS)
|
||||||
if err == fm.ErrExist {
|
if err == fb.ErrExist {
|
||||||
return http.StatusNotFound, err
|
return http.StatusNotFound, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +130,7 @@ func usersGetHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int
|
|||||||
return renderJSON(w, u)
|
return renderJSON(w, u)
|
||||||
}
|
}
|
||||||
|
|
||||||
func usersPostHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func usersPostHandler(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
if r.URL.Path != "/" {
|
if r.URL.Path != "/" {
|
||||||
return http.StatusMethodNotAllowed, nil
|
return http.StatusMethodNotAllowed, nil
|
||||||
}
|
}
|
||||||
@ -142,22 +142,22 @@ func usersPostHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (in
|
|||||||
|
|
||||||
// Checks if username isn't empty.
|
// Checks if username isn't empty.
|
||||||
if u.Username == "" {
|
if u.Username == "" {
|
||||||
return http.StatusBadRequest, fm.ErrEmptyUsername
|
return http.StatusBadRequest, fb.ErrEmptyUsername
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks if scope isn't empty.
|
// Checks if scope isn't empty.
|
||||||
if u.Scope == "" {
|
if u.Scope == "" {
|
||||||
return http.StatusBadRequest, fm.ErrEmptyScope
|
return http.StatusBadRequest, fb.ErrEmptyScope
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks if password isn't empty.
|
// Checks if password isn't empty.
|
||||||
if u.Password == "" {
|
if u.Password == "" {
|
||||||
return http.StatusBadRequest, fm.ErrEmptyPassword
|
return http.StatusBadRequest, fb.ErrEmptyPassword
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize rules if they're not initialized.
|
// Initialize rules if they're not initialized.
|
||||||
if u.Rules == nil {
|
if u.Rules == nil {
|
||||||
u.Rules = []*fm.Rule{}
|
u.Rules = []*fb.Rule{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the view mode is empty, initialize with the default one.
|
// If the view mode is empty, initialize with the default one.
|
||||||
@ -181,17 +181,17 @@ func usersPostHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (in
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Hashes the password.
|
// Hashes the password.
|
||||||
pw, err := fm.HashPassword(u.Password)
|
pw, err := fb.HashPassword(u.Password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return http.StatusInternalServerError, err
|
return http.StatusInternalServerError, err
|
||||||
}
|
}
|
||||||
|
|
||||||
u.Password = pw
|
u.Password = pw
|
||||||
u.ViewMode = fm.MosaicViewMode
|
u.ViewMode = fb.MosaicViewMode
|
||||||
|
|
||||||
// Saves the user to the database.
|
// Saves the user to the database.
|
||||||
err = c.Store.Users.Save(u)
|
err = c.Store.Users.Save(u)
|
||||||
if err == fm.ErrExist {
|
if err == fb.ErrExist {
|
||||||
return http.StatusConflict, err
|
return http.StatusConflict, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,7 +228,7 @@ func checkFS(path string) (int, error) {
|
|||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func usersDeleteHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func usersDeleteHandler(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
if r.URL.Path == "/" {
|
if r.URL.Path == "/" {
|
||||||
return http.StatusMethodNotAllowed, nil
|
return http.StatusMethodNotAllowed, nil
|
||||||
}
|
}
|
||||||
@ -240,8 +240,8 @@ func usersDeleteHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (
|
|||||||
|
|
||||||
// Deletes the user from the database.
|
// Deletes the user from the database.
|
||||||
err = c.Store.Users.Delete(id)
|
err = c.Store.Users.Delete(id)
|
||||||
if err == fm.ErrNotExist {
|
if err == fb.ErrNotExist {
|
||||||
return http.StatusNotFound, fm.ErrNotExist
|
return http.StatusNotFound, fb.ErrNotExist
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -251,7 +251,7 @@ func usersDeleteHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (
|
|||||||
return http.StatusOK, nil
|
return http.StatusOK, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func usersPutHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func usersPutHandler(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
// New users should be created on /api/users.
|
// New users should be created on /api/users.
|
||||||
if r.URL.Path == "/" {
|
if r.URL.Path == "/" {
|
||||||
return http.StatusMethodNotAllowed, nil
|
return http.StatusMethodNotAllowed, nil
|
||||||
@ -298,14 +298,14 @@ func usersPutHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int
|
|||||||
// Updates the Password.
|
// Updates the Password.
|
||||||
if which == "password" {
|
if which == "password" {
|
||||||
if u.Password == "" {
|
if u.Password == "" {
|
||||||
return http.StatusBadRequest, fm.ErrEmptyPassword
|
return http.StatusBadRequest, fb.ErrEmptyPassword
|
||||||
}
|
}
|
||||||
|
|
||||||
if id == c.User.ID && c.User.LockPassword {
|
if id == c.User.ID && c.User.LockPassword {
|
||||||
return http.StatusForbidden, nil
|
return http.StatusForbidden, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
c.User.Password, err = fm.HashPassword(u.Password)
|
c.User.Password, err = fb.HashPassword(u.Password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return http.StatusInternalServerError, err
|
return http.StatusInternalServerError, err
|
||||||
}
|
}
|
||||||
@ -320,17 +320,17 @@ func usersPutHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int
|
|||||||
|
|
||||||
// If can only be all.
|
// If can only be all.
|
||||||
if which != "all" {
|
if which != "all" {
|
||||||
return http.StatusBadRequest, fm.ErrInvalidUpdateField
|
return http.StatusBadRequest, fb.ErrInvalidUpdateField
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks if username isn't empty.
|
// Checks if username isn't empty.
|
||||||
if u.Username == "" {
|
if u.Username == "" {
|
||||||
return http.StatusBadRequest, fm.ErrEmptyUsername
|
return http.StatusBadRequest, fb.ErrEmptyUsername
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks if filesystem isn't empty.
|
// Checks if filesystem isn't empty.
|
||||||
if u.Scope == "" {
|
if u.Scope == "" {
|
||||||
return http.StatusBadRequest, fm.ErrEmptyScope
|
return http.StatusBadRequest, fb.ErrEmptyScope
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks if the scope exists.
|
// Checks if the scope exists.
|
||||||
@ -340,7 +340,7 @@ func usersPutHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int
|
|||||||
|
|
||||||
// Initialize rules if they're not initialized.
|
// Initialize rules if they're not initialized.
|
||||||
if u.Rules == nil {
|
if u.Rules == nil {
|
||||||
u.Rules = []*fm.Rule{}
|
u.Rules = []*fb.Rule{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize commands if not initialized.
|
// Initialize commands if not initialized.
|
||||||
@ -350,7 +350,7 @@ func usersPutHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int
|
|||||||
|
|
||||||
// Gets the current saved user from the in-memory map.
|
// Gets the current saved user from the in-memory map.
|
||||||
suser, err := c.Store.Users.Get(id, c.NewFS)
|
suser, err := c.Store.Users.Get(id, c.NewFS)
|
||||||
if err == fm.ErrNotExist {
|
if err == fb.ErrNotExist {
|
||||||
return http.StatusNotFound, nil
|
return http.StatusNotFound, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -362,7 +362,7 @@ func usersPutHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int
|
|||||||
|
|
||||||
// Changes the password if the request wants it.
|
// Changes the password if the request wants it.
|
||||||
if u.Password != "" {
|
if u.Password != "" {
|
||||||
pw, err := fm.HashPassword(u.Password)
|
pw, err := fb.HashPassword(u.Password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return http.StatusInternalServerError, err
|
return http.StatusInternalServerError, err
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
fm "github.com/filebrowser/filebrowser"
|
fb "github.com/filebrowser/filebrowser"
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -27,8 +27,8 @@ 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(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func command(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
// Upgrades the connection to a websocket and checks for fm.Errors.
|
// Upgrades the connection to a websocket and checks for fb.Errors.
|
||||||
conn, err := upgrader.Upgrade(w, r, nil)
|
conn, err := upgrader.Upgrade(w, r, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
@ -93,7 +93,7 @@ func command(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error)
|
|||||||
cmd.Stderr = buff
|
cmd.Stderr = buff
|
||||||
cmd.Stdout = buff
|
cmd.Stdout = buff
|
||||||
|
|
||||||
// Starts the command and checks for fm.Errors.
|
// Starts the command and checks for fb.Errors.
|
||||||
err = cmd.Start()
|
err = cmd.Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return http.StatusInternalServerError, err
|
return http.StatusInternalServerError, err
|
||||||
@ -241,8 +241,8 @@ func parseSearch(value string) *searchOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// search searches for a file or directory.
|
// search searches for a file or directory.
|
||||||
func search(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func search(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
// Upgrades the connection to a websocket and checks for fm.Errors.
|
// Upgrades the connection to a websocket and checks for fb.Errors.
|
||||||
conn, err := upgrader.Upgrade(w, r, nil)
|
conn, err := upgrader.Upgrade(w, r, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
fm "github.com/filebrowser/filebrowser"
|
fb "github.com/filebrowser/filebrowser"
|
||||||
"github.com/hacdias/varutils"
|
"github.com/hacdias/varutils"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ func (h Hugo) Name() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Hook is the pre-api handler.
|
// Hook is the pre-api handler.
|
||||||
func (h Hugo) Hook(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func (h Hugo) Hook(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
// If we are not using HTTP Post, we shall return Method Not Allowed
|
// If we are not using HTTP Post, we shall return Method Not Allowed
|
||||||
// since we are only working with this method.
|
// since we are only working with this method.
|
||||||
if r.Method != http.MethodPost {
|
if r.Method != http.MethodPost {
|
||||||
@ -108,7 +108,7 @@ func (h Hugo) Hook(c *fm.Context, w http.ResponseWriter, r *http.Request) (int,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Publish publishes a post.
|
// Publish publishes a post.
|
||||||
func (h Hugo) Publish(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func (h Hugo) Publish(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
filename := filepath.Join(c.User.Scope, r.URL.Path)
|
filename := filepath.Join(c.User.Scope, r.URL.Path)
|
||||||
|
|
||||||
// We only run undraft command if it is a file.
|
// We only run undraft command if it is a file.
|
||||||
@ -125,7 +125,7 @@ func (h Hugo) Publish(c *fm.Context, w http.ResponseWriter, r *http.Request) (in
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Preview handles the preview path.
|
// Preview handles the preview path.
|
||||||
func (h *Hugo) Preview(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func (h *Hugo) Preview(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
// Get a new temporary path if there is none.
|
// Get a new temporary path if there is none.
|
||||||
if h.previewPath == "" {
|
if h.previewPath == "" {
|
||||||
path, err := ioutil.TempDir("", "")
|
path, err := ioutil.TempDir("", "")
|
||||||
|
@ -9,7 +9,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
fm "github.com/filebrowser/filebrowser"
|
fb "github.com/filebrowser/filebrowser"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Jekyll is the Jekyll static website generator.
|
// Jekyll is the Jekyll static website generator.
|
||||||
@ -39,12 +39,12 @@ func (j Jekyll) SettingsPath() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Hook is the pre-api handler.
|
// Hook is the pre-api handler.
|
||||||
func (j Jekyll) Hook(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func (j Jekyll) Hook(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Publish publishes a post.
|
// Publish publishes a post.
|
||||||
func (j Jekyll) Publish(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func (j Jekyll) Publish(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
filename := filepath.Join(c.User.Scope, r.URL.Path)
|
filename := filepath.Join(c.User.Scope, r.URL.Path)
|
||||||
|
|
||||||
// We only run undraft command if it is a file.
|
// We only run undraft command if it is a file.
|
||||||
@ -59,7 +59,7 @@ func (j Jekyll) Publish(c *fm.Context, w http.ResponseWriter, r *http.Request) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Preview handles the preview path.
|
// Preview handles the preview path.
|
||||||
func (j *Jekyll) Preview(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func (j *Jekyll) Preview(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
// Get a new temporary path if there is none.
|
// Get a new temporary path if there is none.
|
||||||
if j.previewPath == "" {
|
if j.previewPath == "" {
|
||||||
path, err := ioutil.TempDir("", "")
|
path, err := ioutil.TempDir("", "")
|
||||||
|
Loading…
Reference in New Issue
Block a user