Browse Source

groups: add role placeholder

Signed-off-by: Nicola Murino <[email protected]>
Nicola Murino 1 year ago
parent
commit
26d3105f54
3 changed files with 20 additions and 13 deletions
  1. 4 4
      docs/groups.md
  2. 1 1
      internal/dataprovider/user.go
  3. 15 8
      internal/httpd/httpd_test.go

+ 4 - 4
docs/groups.md

@@ -14,16 +14,16 @@ A user can be a member of a primary group and many secondary and membership grou
 
 The following settings are inherited from the primary group:
 
-- home dir, if set for the group will replace the one defined for the user. The `%username%` placeholder is replaced with the username
-- filesystem config, if the provider set for the group is different from the "local provider" will replace the one defined for the user. The `%username%` placeholder is replaced with the username within the defined "prefix", for any vfs, and the "username" for the SFTP filesystem config
+- home dir, if set for the group will replace the one defined for the user. The `%username%` placeholder is replaced with the username, the `%role%` placeholder will be replaced with the role name
+- filesystem config, if the provider set for the group is different from the "local provider" will replace the one defined for the user. The `%username%` and `%role%` placeholders will be replaced with the username and role name within the defined "prefix", for any vfs, and the "username" for the SFTP filesystem config
 - max sessions, quota size/files, upload/download bandwidth, upload/download/total data transfer, max upload size, external auth cache time, ftp_security, default shares expiration, max shares expiration, password expiration, password strength: if they are set to `0` for the user they are replaced with the value set for the group, if different from `0`. The password strength defined at group level is only enforce when users change their password
 - expires_in, if defined and the user does not have an expiration date set, defines the expiration of the account in number of days from the creation date
 - TLS username, check password hook disabled, pre-login hook disabled, external auth hook disabled, filesystem checks disabled, allow API key authentication, anonymous user: if they are not set for the user they are replaced with the value set for the group
-- starting directory, if the user does not have a starting directory set, the value set for the group is used, if any. The `%username%` placeholder is replaced with the username
+- starting directory, if the user does not have a starting directory set, the value set for the group is used, if any. The `%username%` placeholder is replaced with the username, the `%role%` placeholder will be replaced with the role name
 
 The following settings are inherited from the primary and secondary groups:
 
-- virtual folders, file patterns, permissions: they are added to the user configuration if the user does not already have a setting for the configured path. The `/` path is ignored for secondary groups. The `%username%` placeholder is replaced with the username within the virtual path, the defined "prefix", for any vfs, and the "username" for the SFTP and HTTP filesystem config
+- virtual folders, file patterns, permissions: they are added to the user configuration if the user does not already have a setting for the configured path. The `/` path is ignored for secondary groups. The `%username%`  and `%role%` placeholders are replaced with the username and role name within the virtual path, the defined "prefix", for any vfs, and the "username" for the SFTP and HTTP filesystem config
 - per-source bandwidth limits
 - per-source data transfer limits
 - allowed/denied IPs

+ 1 - 1
internal/dataprovider/user.go

@@ -1695,7 +1695,7 @@ func (u *User) LoadAndApplyGroupSettings() error {
 }
 
 func (u *User) getGroupPlacehodersReplacer() *strings.Replacer {
-	return strings.NewReplacer("%username%", u.Username)
+	return strings.NewReplacer("%username%", u.Username, "%role%", u.Role)
 }
 
 func (u *User) replacePlaceholder(value string, replacer *strings.Replacer) string {

+ 15 - 8
internal/httpd/httpd_test.go

@@ -1315,6 +1315,11 @@ func TestGroupSettingsOverride(t *testing.T) {
 			Type: sdk.GroupTypeSecondary,
 		},
 	}
+
+	r := getTestRole()
+	role, _, err := httpdtest.AddRole(r, http.StatusCreated)
+	assert.NoError(t, err)
+	u.Role = role.Name
 	user, resp, err := httpdtest.AddUser(u, http.StatusCreated)
 	assert.NoError(t, err, string(resp))
 	assert.Len(t, user.VirtualFolders, 0)
@@ -1407,7 +1412,7 @@ func TestGroupSettingsOverride(t *testing.T) {
 			BaseSFTPFsConfig: sdk.BaseSFTPFsConfig{
 				Endpoint: sftpServerAddr,
 				Username: altAdminUsername,
-				Prefix:   "/dirs/%username%",
+				Prefix:   "/dirs/%role%/%username%",
 			},
 			Password: kms.NewPlainSecret(defaultPassword),
 		},
@@ -1423,13 +1428,13 @@ func TestGroupSettingsOverride(t *testing.T) {
 	group1.UserSettings.Filters.PasswordStrength = 70
 	group1.UserSettings.Filters.WebClient = []string{sdk.WebClientInfoChangeDisabled}
 	group1.UserSettings.Permissions = map[string][]string{
-		"/":               {dataprovider.PermListItems, dataprovider.PermUpload},
-		"/sub/%username%": {dataprovider.PermRename},
-		"/%username%":     {dataprovider.PermDelete},
+		"/":                  {dataprovider.PermListItems, dataprovider.PermUpload},
+		"/sub/%username%":    {dataprovider.PermRename},
+		"/%role%/%username%": {dataprovider.PermDelete},
 	}
 	group1.UserSettings.Filters.FilePatterns = []sdk.PatternsFilter{
 		{
-			Path:            "/sub2/%username%test",
+			Path:            "/sub2/%role%/%username%test",
 			AllowedPatterns: []string{},
 			DeniedPatterns:  []string{"*.jpg", "*.zip"},
 		},
@@ -1443,9 +1448,9 @@ func TestGroupSettingsOverride(t *testing.T) {
 	assert.Equal(t, group1.UserSettings.Filters.PasswordStrength, user.Filters.PasswordStrength)
 	assert.Equal(t, sdk.SFTPFilesystemProvider, user.FsConfig.Provider)
 	assert.Equal(t, altAdminUsername, user.FsConfig.SFTPConfig.Username)
-	assert.Equal(t, "/dirs/"+defaultUsername, user.FsConfig.SFTPConfig.Prefix)
+	assert.Equal(t, "/dirs/"+role.Name+"/"+defaultUsername, user.FsConfig.SFTPConfig.Prefix)
 	assert.Equal(t, []string{dataprovider.PermListItems, dataprovider.PermUpload}, user.GetPermissionsForPath("/"))
-	assert.Equal(t, []string{dataprovider.PermDelete}, user.GetPermissionsForPath(path.Join("/", defaultUsername)))
+	assert.Equal(t, []string{dataprovider.PermDelete}, user.GetPermissionsForPath(path.Join("/", role.Name, defaultUsername)))
 	assert.Equal(t, []string{dataprovider.PermRename}, user.GetPermissionsForPath(path.Join("/sub", defaultUsername)))
 	assert.Equal(t, group1.UserSettings.MaxSessions, user.MaxSessions)
 	assert.Equal(t, group1.UserSettings.QuotaFiles, user.QuotaFiles)
@@ -1454,7 +1459,7 @@ func TestGroupSettingsOverride(t *testing.T) {
 	assert.Equal(t, group1.UserSettings.Filters.MaxUploadFileSize, user.Filters.MaxUploadFileSize)
 	assert.Equal(t, "/startdir/"+defaultUsername, user.Filters.StartDirectory)
 	if assert.Len(t, user.Filters.FilePatterns, 1) {
-		assert.Equal(t, "/sub2/"+defaultUsername+"test", user.Filters.FilePatterns[0].Path) //nolint:goconst
+		assert.Equal(t, "/sub2/"+role.Name+"/"+defaultUsername+"test", user.Filters.FilePatterns[0].Path) //nolint:goconst
 	}
 	if assert.Len(t, user.Filters.WebClient, 2) {
 		assert.Contains(t, user.Filters.WebClient, sdk.WebClientInfoChangeDisabled)
@@ -1475,6 +1480,8 @@ func TestGroupSettingsOverride(t *testing.T) {
 	assert.NoError(t, err)
 	_, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: folderName3}, http.StatusOK)
 	assert.NoError(t, err)
+	_, err = httpdtest.RemoveRole(role, http.StatusOK)
+	assert.NoError(t, err)
 }
 
 func TestConfigs(t *testing.T) {