Skip to content

Commit

Permalink
feat!: rename 'scope' to 'directory'
Browse files Browse the repository at this point in the history
Directory makes it more clear of what it is. In addition, this will make it easier when
allowing for multiple directories in the future, since we can just name it 'directories', which is more clear than 'scopes'.
  • Loading branch information
hacdias committed Jul 26, 2024
1 parent 5ff18af commit 164f461
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 30 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ For usage information regarding the CLI, run `webdav --help`.

### Docker

To use with Docker, you need to provide a configuration file and mount the data directories. For example, let's take the following configuration file that simply sets the port to `6060` and the scope to `/data`.
To use with Docker, you need to provide a configuration file and mount the data directories. For example, let's take the following configuration file that simply sets the port to `6060` and the directory to `/data`.

```yaml
port: 6060
scope: /data
directory: /data
```
You can now run with the following Docker command, where you mount the configuration file inside the container, and the data directory too, as well as forwarding the port 6060. You will need to change this to match your own configuration.
Expand Down Expand Up @@ -69,9 +69,9 @@ prefix: /
debug: false

# The directory that will be able to be accessed by the users when connecting.
# This directory will be used by users unless they have their own 'scope' defined.
# This directory will be used by users unless they have their own 'directory' defined.
# Default is "." (current directory).
scope: .
directory: .

# Whether the users can, by default, modify the contents. Default is false.
modify: true
Expand All @@ -84,10 +84,10 @@ users:
# Example 'admin' user with plaintext password.
- username: admin
password: admin
# Example 'john' user with bcrypt encrypted password, with custom scope.
# Example 'john' user with bcrypt encrypted password, with custom directory.
- username: john
password: "{bcrypt}$2y$10$zEP6oofmXFeHaeMfBNLnP.DO8m.H.Mwhd24/TOX2MWLxAExXi4qgi"
scope: /another/path
directory: /another/path
# Example user whose details will be picked up from the environment.
- username: "{env}ENV_USERNAME"
password: "{env}ENV_PASSWORD"
Expand Down
10 changes: 5 additions & 5 deletions lib/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
)

const (
DefaultScope = "."
DefaultDirectory = "."
DefaultModify = false
DefaultDebug = false
DefaultNoSniff = false
Expand Down Expand Up @@ -74,7 +74,7 @@ func ParseConfig(filename string, flags *pflag.FlagSet) (*Config, error) {
// empty or false.

// Defaults shared with flags
v.SetDefault("Scope", DefaultScope)
v.SetDefault("Directory", DefaultDirectory)
v.SetDefault("Modify", DefaultModify)
v.SetDefault("Debug", DefaultDebug)
v.SetDefault("NoSniff", DefaultNoSniff)
Expand Down Expand Up @@ -111,8 +111,8 @@ func ParseConfig(filename string, flags *pflag.FlagSet) (*Config, error) {

// Cascade user settings
for i := range cfg.Users {
if !v.IsSet(fmt.Sprintf("Users.%d.Scope", i)) {
cfg.Users[i].Scope = cfg.Scope
if !v.IsSet(fmt.Sprintf("Users.%d.Directory", i)) {
cfg.Users[i].Directory = cfg.Directory
}

if !v.IsSet(fmt.Sprintf("Users.%d.Modify", i)) {
Expand All @@ -139,7 +139,7 @@ func (c *Config) Validate() error {
zap.L().Warn("unprotected config: no users have been set, so no authentication will be used")
}

c.Scope, err = filepath.Abs(c.Scope)
c.Directory, err = filepath.Abs(c.Directory)
if err != nil {
return fmt.Errorf("invalid config: %w", err)
}
Expand Down
28 changes: 14 additions & 14 deletions lib/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func TestConfigDefaults(t *testing.T) {

dir, err := os.Getwd()
require.NoError(t, err)
require.Equal(t, dir, cfg.Scope)
require.Equal(t, dir, cfg.Directory)

require.EqualValues(t, []string{"*"}, cfg.CORS.AllowedHeaders)
require.EqualValues(t, []string{"*"}, cfg.CORS.AllowedHosts)
Expand All @@ -48,23 +48,23 @@ func TestConfigCascade(t *testing.T) {

check := func(t *testing.T, cfg *Config) {
require.True(t, cfg.Modify)
require.Equal(t, "/", cfg.Scope)
require.Equal(t, "/", cfg.Directory)
require.Len(t, cfg.Rules, 1)

require.Len(t, cfg.Users, 2)

require.True(t, cfg.Users[0].Modify)
require.Equal(t, "/", cfg.Users[0].Scope)
require.Equal(t, "/", cfg.Users[0].Directory)
require.Len(t, cfg.Users[0].Rules, 1)

require.False(t, cfg.Users[1].Modify)
require.Equal(t, "/basic", cfg.Users[1].Scope)
require.Equal(t, "/basic", cfg.Users[1].Directory)
require.Len(t, cfg.Users[1].Rules, 0)
}

t.Run("YAML", func(t *testing.T) {
content := `
scope: /
directory: /
modify: true
rules:
- path: /public/access/
Expand All @@ -75,7 +75,7 @@ users:
password: admin
- username: basic
password: basic
scope: /basic
directory: /basic
modify: false
rules: []`

Expand All @@ -87,7 +87,7 @@ users:

t.Run("JSON", func(t *testing.T) {
content := `{
"scope": "/",
"directory": "/",
"modify": true,
"rules": [
{
Expand All @@ -103,7 +103,7 @@ users:
{
"username": "basic",
"password": "basic",
"scope": "/basic",
"directory": "/basic",
"modify": false,
"rules": []
}
Expand All @@ -118,7 +118,7 @@ users:

t.Run("`TOML", func(t *testing.T) {
content := `
scope = "/"
directory = "/"
modify = true
[[rules]]
Expand All @@ -132,7 +132,7 @@ password = "admin"
[[users]]
username = "basic"
password = "basic"
scope = "/basic"
directory = "/basic"
modify = false
rules = []
`
Expand Down Expand Up @@ -172,7 +172,7 @@ cors:

func TestConfigRules(t *testing.T) {
content := `
scope: /
directory: /
modify: true
rules:
- regex: '^.+\.js$'
Expand All @@ -198,19 +198,19 @@ func TestConfigEnv(t *testing.T) {
require.NoError(t, os.Setenv("WD_PORT", "1234"))
require.NoError(t, os.Setenv("WD_DEBUG", "true"))
require.NoError(t, os.Setenv("WD_MODIFY", "true"))
require.NoError(t, os.Setenv("WD_SCOPE", "/test"))
require.NoError(t, os.Setenv("WD_DIRECTORY", "/test"))

cfg, err := ParseConfig("", nil)
require.NoError(t, err)

assert.Equal(t, 1234, cfg.Port)
assert.Equal(t, "/test", cfg.Scope)
assert.Equal(t, "/test", cfg.Directory)
assert.Equal(t, true, cfg.Debug)
assert.Equal(t, true, cfg.Modify)

// Reset
require.NoError(t, os.Setenv("WD_PORT", ""))
require.NoError(t, os.Setenv("WD_DEBUG", ""))
require.NoError(t, os.Setenv("WD_MODIFY", ""))
require.NoError(t, os.Setenv("WD_SCOPE", ""))
require.NoError(t, os.Setenv("WD_DIRECTORY", ""))
}
4 changes: 2 additions & 2 deletions lib/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func NewHandler(c *Config) (http.Handler, error) {
Handler: webdav.Handler{
Prefix: c.Prefix,
FileSystem: Dir{
Dir: webdav.Dir(c.Scope),
Dir: webdav.Dir(c.Directory),
noSniff: c.NoSniff,
},
LockSystem: webdav.NewMemLS(),
Expand All @@ -43,7 +43,7 @@ func NewHandler(c *Config) (http.Handler, error) {
Handler: webdav.Handler{
Prefix: c.Prefix,
FileSystem: Dir{
Dir: webdav.Dir(u.Scope),
Dir: webdav.Dir(u.Directory),
noSniff: c.NoSniff,
},
LockSystem: webdav.NewMemLS(),
Expand Down
14 changes: 11 additions & 3 deletions lib/permissions.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"net/http"
"path/filepath"
"regexp"
"strings"
)
Expand Down Expand Up @@ -40,9 +41,9 @@ func (r *Rule) Matches(path string) bool {
}

type Permissions struct {
Scope string
Modify bool
Rules []*Rule
Directory string
Modify bool
Rules []*Rule
}

// Allowed checks if the user has permission to access a directory/file
Expand All @@ -69,6 +70,13 @@ func (p Permissions) Allowed(r *http.Request) bool {
}

func (p *Permissions) Validate() error {
var err error

p.Directory, err = filepath.Abs(p.Directory)
if err != nil {
return fmt.Errorf("invalid permissions: %w", err)
}

for _, r := range p.Rules {
if err := r.Validate(); err != nil {
return fmt.Errorf("invalid permissions: %w", err)
Expand Down

0 comments on commit 164f461

Please sign in to comment.