WebDAV: Allow read access in read-only mode and improve logs #3177 #3183

Signed-off-by: Michael Mayer <michael@photoprism.app>
This commit is contained in:
Michael Mayer 2023-02-09 13:14:56 +01:00
parent ef6e3d3f9d
commit a7b1c1b11e
14 changed files with 61 additions and 33 deletions

View file

@ -43,7 +43,7 @@ func cleanUpAction(ctx *cli.Context) error {
defer conf.Shutdown()
if conf.ReadOnly() {
log.Infof("config: read-only mode enabled")
log.Infof("config: enabled read-only mode")
}
w := get.CleanUp()

View file

@ -241,7 +241,7 @@ func facesIndexAction(ctx *cli.Context) error {
}
if conf.ReadOnly() {
log.Infof("config: read-only mode enabled")
log.Infof("config: enabled read-only mode")
}
var indexed fs.Done

View file

@ -65,7 +65,7 @@ func indexAction(ctx *cli.Context) error {
}
if conf.ReadOnly() {
log.Infof("config: read-only mode enabled")
log.Infof("config: enabled read-only mode")
}
var indexed fs.Done

View file

@ -33,7 +33,7 @@ func momentsAction(ctx *cli.Context) error {
defer conf.Shutdown()
if conf.ReadOnly() {
log.Infof("config: read-only mode enabled")
log.Infof("config: enabled read-only mode")
}
w := get.Moments()

View file

@ -40,7 +40,7 @@ func optimizeAction(ctx *cli.Context) error {
defer conf.Shutdown()
if conf.ReadOnly() {
log.Infof("config: read-only mode enabled")
log.Infof("config: enabled read-only mode")
}
force := ctx.Bool("force")

View file

@ -60,7 +60,7 @@ func purgeAction(ctx *cli.Context) error {
}
if conf.ReadOnly() {
log.Infof("config: read-only mode enabled")
log.Infof("config: enabled read-only mode")
}
w := get.Purge()

View file

@ -113,7 +113,7 @@ func startAction(ctx *cli.Context) error {
}
if conf.ReadOnly() {
log.Infof("config: read-only mode enabled")
log.Infof("config: enabled read-only mode")
}
// Start web server.

View file

@ -4,7 +4,7 @@ var Sponsor = Env(EnvDemo, EnvSponsor, EnvTest)
// DisableWebDAV checks if the built-in WebDAV server should be disabled.
func (c *Config) DisableWebDAV() bool {
if c.Public() || c.ReadOnly() || c.Demo() {
if c.Public() || c.Demo() {
return true
}

View file

@ -30,7 +30,7 @@ func TestConfig_DisableWebDAV(t *testing.T) {
c.options.ReadOnly = true
c.options.Demo = false
assert.True(t, c.DisableWebDAV())
assert.False(t, c.DisableWebDAV())
c.options.Public = false
c.options.ReadOnly = false

View file

@ -107,6 +107,8 @@ func (list Tables) Migrate(db *gorm.DB, opt migrate.Options) {
}
}()
log.Infof("migrate: running database migrations")
// Run pre-migrations, if any.
if err := migrate.Run(db, opt.Pre()); err != nil {
log.Error(err)

View file

@ -73,9 +73,9 @@ func (m *Migrations) Start(db *gorm.DB, opt Options) {
executed := Existing(db, opt.StageName())
if prev := len(executed); prev == 0 {
log.Infof("migrate: no previously executed migrations [%s]", opt.StageName())
log.Debugf("migrate: no previously executed migrations [%s]", opt.StageName())
} else {
log.Infof("migrate: executing %s migrations", opt.StageName())
log.Debugf("migrate: executing %s migrations", opt.StageName())
log.Debugf("migrate: found %s", english.Plural(len(executed), "previous migration", "previous migrations"))
}

View file

@ -15,11 +15,11 @@ func AutoTLS(conf *config.Config) (*autocert.Manager, error) {
// Enable automatic HTTPS via Let's Encrypt?
if !conf.SiteHttps() {
return nil, fmt.Errorf("tls disabled")
return nil, fmt.Errorf("disabled tls")
} else if siteDomain = conf.SiteDomain(); !strings.Contains(siteDomain, ".") {
return nil, fmt.Errorf("no fully qualified site domain")
return nil, fmt.Errorf("fully qualified domain required to enable tls")
} else if tlsEmail = conf.TLSEmail(); tlsEmail == "" {
return nil, fmt.Errorf("automatic tls disabled")
return nil, fmt.Errorf("disabled auto tls")
} else if certDir = conf.CertificatesPath(); certDir == "" {
return nil, fmt.Errorf("certificates path not found")
}

View file

@ -1,6 +1,7 @@
package server
import (
"fmt"
"net/http"
"os"
"path/filepath"
@ -21,14 +22,21 @@ const WebDAVImport = "/import"
// registerWebDAVRoutes configures the built-in WebDAV server.
func registerWebDAVRoutes(router *gin.Engine, conf *config.Config) {
if conf.DisableWebDAV() {
log.Info("webdav: server disabled")
log.Info("webdav: disabled")
} else {
var info string
if conf.ReadOnly() {
info = " in read-only mode"
} else {
info = ""
}
WebDAV(conf.OriginalsPath(), router.Group(conf.BaseUri(WebDAVOriginals), BasicAuth()), conf)
log.Infof("webdav: %s/ enabled, waiting for requests", conf.BaseUri(WebDAVOriginals))
log.Infof("webdav: shared %s/%s", conf.BaseUri(WebDAVOriginals), info)
if conf.ImportPath() != "" {
WebDAV(conf.ImportPath(), router.Group(conf.BaseUri(WebDAVImport), BasicAuth()), conf)
log.Infof("webdav: %s/ enabled, waiting for requests", conf.BaseUri(WebDAVImport))
log.Infof("webdav: shared %s/%s", conf.BaseUri(WebDAVImport), info)
}
}
}
@ -101,21 +109,39 @@ func WebDAV(filePath string, router *gin.RouterGroup, conf *config.Config) {
WebDAVHandler(c, router, srv)
}
// Handle supported HTTP request methods.
router.Handle(MethodHead, "/*path", handlerFunc)
router.Handle(MethodGet, "/*path", handlerFunc)
router.Handle(MethodPut, "/*path", handlerFunc)
router.Handle(MethodPost, "/*path", handlerFunc)
router.Handle(MethodPatch, "/*path", handlerFunc)
router.Handle(MethodDelete, "/*path", handlerFunc)
router.Handle(MethodOptions, "/*path", handlerFunc)
router.Handle(MethodMkcol, "/*path", handlerFunc)
router.Handle(MethodCopy, "/*path", handlerFunc)
router.Handle(MethodMove, "/*path", handlerFunc)
router.Handle(MethodLock, "/*path", handlerFunc)
router.Handle(MethodUnlock, "/*path", handlerFunc)
router.Handle(MethodPropfind, "/*path", handlerFunc)
router.Handle(MethodProppatch, "/*path", handlerFunc)
// handleRead registers WebDAV methods used for browsing and downloading.
handleRead := func(h func(*gin.Context)) {
router.Handle(MethodHead, "/*path", h)
router.Handle(MethodGet, "/*path", h)
router.Handle(MethodOptions, "/*path", h)
router.Handle(MethodLock, "/*path", h)
router.Handle(MethodUnlock, "/*path", h)
router.Handle(MethodPropfind, "/*path", h)
}
// handleWrite registers WebDAV methods to may modify the file system.
handleWrite := func(h func(*gin.Context)) {
router.Handle(MethodPut, "/*path", h)
router.Handle(MethodPost, "/*path", h)
router.Handle(MethodPatch, "/*path", h)
router.Handle(MethodDelete, "/*path", h)
router.Handle(MethodMkcol, "/*path", h)
router.Handle(MethodCopy, "/*path", h)
router.Handle(MethodMove, "/*path", h)
router.Handle(MethodProppatch, "/*path", h)
}
// Handle supported WebDAV request methods.
handleRead(handlerFunc)
// Only supported with read-only mode disabled.
if conf.ReadOnly() {
handleWrite(func(c *gin.Context) {
_ = c.AbortWithError(http.StatusForbidden, fmt.Errorf("forbidden in read-only mode"))
})
} else {
handleWrite(handlerFunc)
}
}
// MarkUploadAsFavorite sets the favorite flag for newly uploaded files.

View file

@ -49,7 +49,6 @@ func Start(ctx context.Context, conf *config.Config) {
// Enable HTTP compression?
switch conf.HttpCompression() {
case "gzip":
log.Infof("server: enabling gzip compression")
router.Use(gzip.Gzip(
gzip.DefaultCompression,
gzip.WithExcludedPaths([]string{
@ -60,6 +59,7 @@ func Start(ctx context.Context, conf *config.Config) {
conf.BaseUri(config.ApiUri + "/labels"),
conf.BaseUri(config.ApiUri + "/videos"),
})))
log.Infof("server: enabled gzip compression")
}
// Find and load templates.