diff --git a/README.md b/README.md
index f1ec8ad..f60ca97 100644
--- a/README.md
+++ b/README.md
@@ -80,6 +80,7 @@ PATH = data/gobsidian.db
REQUIRE_ADMIN_ACTIVATION = true
REQUIRE_EMAIL_CONFIRMATION = false
MFA_ENABLED_BY_DEFAULT = false
+LOGIN_AND_EDITS = true
[SECURITY]
PWD_FAILURES_THRESHOLD = 5
diff --git a/internal/config/config.go b/internal/config/config.go
index 294eaed..441b4ab 100644
--- a/internal/config/config.go
+++ b/internal/config/config.go
@@ -45,6 +45,7 @@ type Config struct {
RequireAdminActivation bool
RequireEmailConfirmation bool
MFAEnabledByDefault bool
+ LoginAndEdits bool
// Security settings (failed-login thresholds and auto-ban config)
PwdFailuresThreshold int
@@ -92,6 +93,7 @@ var defaultConfig = map[string]map[string]string{
"REQUIRE_ADMIN_ACTIVATION": "true",
"REQUIRE_EMAIL_CONFIRMATION": "false",
"MFA_ENABLED_BY_DEFAULT": "false",
+ "LOGIN_AND_EDITS": "true",
},
"SECURITY": {
"PWD_FAILURES_THRESHOLD": "5",
@@ -219,6 +221,7 @@ func Load() (*Config, error) {
config.RequireAdminActivation, _ = authSection.Key("REQUIRE_ADMIN_ACTIVATION").Bool()
config.RequireEmailConfirmation, _ = authSection.Key("REQUIRE_EMAIL_CONFIRMATION").Bool()
config.MFAEnabledByDefault, _ = authSection.Key("MFA_ENABLED_BY_DEFAULT").Bool()
+ config.LoginAndEdits, _ = authSection.Key("LOGIN_AND_EDITS").Bool()
// Load SECURITY section
secSection := cfg.Section("SECURITY")
@@ -395,6 +398,8 @@ func (c *Config) SaveSetting(section, key, value string) error {
c.RequireEmailConfirmation = value == "true"
case "MFA_ENABLED_BY_DEFAULT":
c.MFAEnabledByDefault = value == "true"
+ case "LOGIN_AND_EDITS":
+ c.LoginAndEdits = value == "true"
}
case "SECURITY":
switch key {
diff --git a/internal/handlers/handlers.go b/internal/handlers/handlers.go
index 19259c1..7ee7ff2 100644
--- a/internal/handlers/handlers.go
+++ b/internal/handlers/handlers.go
@@ -972,6 +972,7 @@ func (h *Handlers) IndexHandler(c *gin.Context) {
"breadcrumbs": utils.GenerateBreadcrumbs(""),
"allowed_image_extensions": h.config.AllowedImageExtensions,
"allowed_file_extensions": h.config.AllowedFileExtensions,
+ "LoginAndEdits": h.config.LoginAndEdits,
"Authenticated": isAuthenticated(c),
"IsAdmin": isAdmin(c),
"ContentTemplate": "folder_content",
diff --git a/internal/server/middleware.go b/internal/server/middleware.go
index 5b7bd28..96cedbb 100644
--- a/internal/server/middleware.go
+++ b/internal/server/middleware.go
@@ -13,6 +13,18 @@ import (
const csrfSessionKey = "csrf_token"
+// RequireLoginAndEdits blocks access if LoginAndEdits setting is false.
+func (s *Server) RequireLoginAndEdits() gin.HandlerFunc {
+ return func(c *gin.Context) {
+ if !s.config.LoginAndEdits {
+ c.Redirect(http.StatusFound, s.config.URLPrefix+"/?error=not_found")
+ c.Abort()
+ return
+ }
+ c.Next()
+ }
+}
+
func (s *Server) randomToken(n int) (string, error) {
b := make([]byte, n)
if _, err := rand.Read(b); err != nil {
diff --git a/internal/server/server.go b/internal/server/server.go
index 8c9e30b..8cacf70 100644
--- a/internal/server/server.go
+++ b/internal/server/server.go
@@ -105,15 +105,15 @@ func (s *Server) setupRoutes() {
r.GET("/view_text/*path", h.ViewTextHandler)
// Auth routes
- r.GET("/editor/login", h.LoginPage)
- r.POST("/editor/login", s.CSRFRequire(), h.LoginPost)
+ r.GET("/editor/login", s.RequireLoginAndEdits(), h.LoginPage)
+ r.POST("/editor/login", s.RequireLoginAndEdits(), s.CSRFRequire(), h.LoginPost)
r.POST("/editor/logout", s.RequireAuth(), s.CSRFRequire(), h.LogoutPost)
// MFA challenge routes (no auth yet, but CSRF)
- r.GET("/editor/mfa", s.CSRFRequire(), h.MFALoginPage)
- r.POST("/editor/mfa", s.CSRFRequire(), h.MFALoginVerify)
+ r.GET("/editor/mfa", s.RequireLoginAndEdits(), s.CSRFRequire(), h.MFALoginPage)
+ r.POST("/editor/mfa", s.RequireLoginAndEdits(), s.CSRFRequire(), h.MFALoginVerify)
- // New /editor group protected by auth + CSRF
- editor := r.Group("/editor", s.RequireAuth(), s.CSRFRequire())
+ // New /editor group protected by auth + CSRF + LoginAndEdits
+ editor := r.Group("/editor", s.RequireLoginAndEdits(), s.RequireAuth(), s.CSRFRequire())
{
editor.GET("/create", h.CreateNotePageHandler)
editor.POST("/create", h.CreateNoteHandler)
diff --git a/web/templates/base.html b/web/templates/base.html
index 20e4130..e74c330 100644
--- a/web/templates/base.html
+++ b/web/templates/base.html
@@ -308,9 +308,11 @@
{{else}}
+ {{if .LoginAndEdits}}
+ {{end}}
{{end}}