subdir perms: allow empty perms

empty perms will allow nothing on the specified subdir.

Non empty permissions for the "/" dir are still required.

Fixes #70
This commit is contained in:
Nicola Murino 2020-02-10 19:28:35 +01:00
parent 7bfe0ddf80
commit 8eff2df39c
5 changed files with 39 additions and 4 deletions

View file

@ -505,7 +505,7 @@ func validatePermissions(user *User) error {
return &ValidationError{err: fmt.Sprintf("permissions for the root dir \"/\" must be set")}
}
for dir, perms := range user.Permissions {
if len(perms) == 0 {
if len(perms) == 0 && dir == "/" {
return &ValidationError{err: fmt.Sprintf("no permissions granted for the directory: %#v", dir)}
}
for _, p := range perms {
@ -520,6 +520,9 @@ func validatePermissions(user *User) error {
if !path.IsAbs(cleanedDir) {
return &ValidationError{err: fmt.Sprintf("cannot set permissions for non absolute path: %#v", dir)}
}
if dir != cleanedDir && cleanedDir == "/" {
return &ValidationError{err: fmt.Sprintf("cannot set permissions for invalid subdirectory: %#v is an alias for \"/\"", dir)}
}
if utils.IsStringInSlice(PermAny, perms) {
permissions[cleanedDir] = []string{PermAny}
} else {

View file

@ -285,11 +285,18 @@ func TestAddUserInvalidPerms(t *testing.T) {
t.Errorf("unexpected error adding user with invalid perms: %v", err)
}
// permissions for root dir are mandatory
u.Permissions["/"] = []string{}
u.Permissions["/somedir"] = []string{dataprovider.PermAny}
_, _, err = httpd.AddUser(u, http.StatusBadRequest)
if err != nil {
t.Errorf("unexpected error adding user with no root dir perms: %v", err)
}
u.Permissions["/"] = []string{dataprovider.PermAny}
u.Permissions["/subdir/.."] = []string{dataprovider.PermAny}
_, _, err = httpd.AddUser(u, http.StatusBadRequest)
if err != nil {
t.Errorf("unexpected error adding user with invalid dir perms: %v", err)
}
}
func TestAddUserInvalidFilters(t *testing.T) {
@ -407,6 +414,14 @@ func TestUpdateUser(t *testing.T) {
if err != nil {
t.Errorf("unable to update user: %v", err)
}
user.Permissions["/subdir"] = []string{}
user, _, err = httpd.UpdateUser(user, http.StatusOK)
if err != nil {
t.Errorf("unable to update user: %v", err)
}
if len(user.Permissions["/subdir"]) > 0 {
t.Errorf("unexpected subdir permissions, must be empty")
}
_, err = httpd.RemoveUser(user, http.StatusOK)
if err != nil {
t.Errorf("unable to remove: %v", err)
@ -1136,12 +1151,18 @@ func TestUserPermissionsMock(t *testing.T) {
if err != nil {
t.Errorf("Error get user: %v", err)
}
user.Permissions["/somedir"] = []string{}
user.Permissions["/somedir"] = []string{"invalid"}
userAsJSON = getUserAsJSON(t, user)
req, _ = http.NewRequest(http.MethodPut, userPath+"/"+strconv.FormatInt(user.ID, 10), bytes.NewBuffer(userAsJSON))
rr = executeRequest(req)
checkResponseCode(t, http.StatusBadRequest, rr.Code)
delete(user.Permissions, "/somedir")
user.Permissions["/somedir/.."] = []string{dataprovider.PermAny}
userAsJSON = getUserAsJSON(t, user)
req, _ = http.NewRequest(http.MethodPut, userPath+"/"+strconv.FormatInt(user.ID, 10), bytes.NewBuffer(userAsJSON))
rr = executeRequest(req)
checkResponseCode(t, http.StatusBadRequest, rr.Code)
delete(user.Permissions, "/somedir/..")
user.Permissions["not_abs_path"] = []string{dataprovider.PermAny}
userAsJSON = getUserAsJSON(t, user)
req, _ = http.NewRequest(http.MethodPut, userPath+"/"+strconv.FormatInt(user.ID, 10), bytes.NewBuffer(userAsJSON))

View file

@ -200,7 +200,7 @@ func getUserPermissionsFromPostFields(r *http.Request) map[string][]string {
perms = append(perms, cleanedPerm)
}
}
if len(dir) > 0 && len(perms) > 0 {
if len(dir) > 0 {
permissions[dir] = perms
}
}

View file

@ -111,7 +111,7 @@ class SFTPGoApiRequests:
directory = value
else:
values = [v.strip() for v in value.split(',') if v.strip()]
if directory and values:
if directory:
permissions.update({directory:values})
return permissions

View file

@ -3250,6 +3250,17 @@ func TestUserPerms(t *testing.T) {
}
}
func TestUserEmptySubDirPerms(t *testing.T) {
user := getTestUser(true)
user.Permissions = make(map[string][]string)
user.Permissions["/emptyperms"] = []string{}
for _, p := range dataprovider.ValidPerms {
if user.HasPerm(p, "/emptyperms") {
t.Errorf("unexpected permission %#v for dir /emptyperms", p)
}
}
}
func TestUserFiltersIPMaskConditions(t *testing.T) {
user := getTestUser(true)
// with no filter login must be allowed even if the remoteIP is invalid