mirror of
https://github.com/drakkan/sftpgo.git
synced 2025-12-06 14:20:55 +03:00
WebAdmin: allow to pre-select groups on add user page
The admin will still be able to choose different groups Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
@@ -34,7 +34,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
sqlDatabaseVersion = 21
|
||||
sqlDatabaseVersion = 22
|
||||
defaultSQLQueryTimeout = 10 * time.Second
|
||||
longSQLQueryTimeout = 60 * time.Second
|
||||
)
|
||||
@@ -65,6 +65,7 @@ func sqlReplaceAll(sql string) string {
|
||||
sql = strings.ReplaceAll(sql, "{{groups}}", sqlTableGroups)
|
||||
sql = strings.ReplaceAll(sql, "{{users_folders_mapping}}", sqlTableUsersFoldersMapping)
|
||||
sql = strings.ReplaceAll(sql, "{{users_groups_mapping}}", sqlTableUsersGroupsMapping)
|
||||
sql = strings.ReplaceAll(sql, "{{admins_groups_mapping}}", sqlTableAdminsGroupsMapping)
|
||||
sql = strings.ReplaceAll(sql, "{{groups_folders_mapping}}", sqlTableGroupsFoldersMapping)
|
||||
sql = strings.ReplaceAll(sql, "{{api_keys}}", sqlTableAPIKeys)
|
||||
sql = strings.ReplaceAll(sql, "{{shares}}", sqlTableShares)
|
||||
@@ -392,7 +393,11 @@ func sqlCommonGetAdminByUsername(username string, dbHandle sqlQuerier) (Admin, e
|
||||
q := getAdminByUsernameQuery()
|
||||
row := dbHandle.QueryRowContext(ctx, q, username)
|
||||
|
||||
return getAdminFromDbRow(row)
|
||||
admin, err := getAdminFromDbRow(row)
|
||||
if err != nil {
|
||||
return admin, err
|
||||
}
|
||||
return getAdminWithGroups(ctx, admin, dbHandle)
|
||||
}
|
||||
|
||||
func sqlCommonValidateAdminAndPass(username, password, ip string, dbHandle *sql.DB) (Admin, error) {
|
||||
@@ -411,10 +416,6 @@ func sqlCommonAddAdmin(admin *Admin, dbHandle *sql.DB) error {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
|
||||
defer cancel()
|
||||
|
||||
q := getAddAdminQuery()
|
||||
perms, err := json.Marshal(admin.Permissions)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -425,10 +426,19 @@ func sqlCommonAddAdmin(admin *Admin, dbHandle *sql.DB) error {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = dbHandle.ExecContext(ctx, q, admin.Username, admin.Password, admin.Status, admin.Email, string(perms),
|
||||
string(filters), admin.AdditionalInfo, admin.Description, util.GetTimeAsMsSinceEpoch(time.Now()),
|
||||
util.GetTimeAsMsSinceEpoch(time.Now()))
|
||||
return err
|
||||
ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
|
||||
defer cancel()
|
||||
|
||||
return sqlCommonExecuteTx(ctx, dbHandle, func(tx *sql.Tx) error {
|
||||
q := getAddAdminQuery()
|
||||
_, err = tx.ExecContext(ctx, q, admin.Username, admin.Password, admin.Status, admin.Email, string(perms),
|
||||
string(filters), admin.AdditionalInfo, admin.Description, util.GetTimeAsMsSinceEpoch(time.Now()),
|
||||
util.GetTimeAsMsSinceEpoch(time.Now()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return generateAdminGroupMapping(ctx, admin, tx)
|
||||
})
|
||||
}
|
||||
|
||||
func sqlCommonUpdateAdmin(admin *Admin, dbHandle *sql.DB) error {
|
||||
@@ -437,10 +447,6 @@ func sqlCommonUpdateAdmin(admin *Admin, dbHandle *sql.DB) error {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
|
||||
defer cancel()
|
||||
|
||||
q := getUpdateAdminQuery()
|
||||
perms, err := json.Marshal(admin.Permissions)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -451,9 +457,18 @@ func sqlCommonUpdateAdmin(admin *Admin, dbHandle *sql.DB) error {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = dbHandle.ExecContext(ctx, q, admin.Password, admin.Status, admin.Email, string(perms), string(filters),
|
||||
admin.AdditionalInfo, admin.Description, util.GetTimeAsMsSinceEpoch(time.Now()), admin.Username)
|
||||
return err
|
||||
ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
|
||||
defer cancel()
|
||||
|
||||
return sqlCommonExecuteTx(ctx, dbHandle, func(tx *sql.Tx) error {
|
||||
q := getUpdateAdminQuery()
|
||||
_, err = tx.ExecContext(ctx, q, admin.Password, admin.Status, admin.Email, string(perms), string(filters),
|
||||
admin.AdditionalInfo, admin.Description, util.GetTimeAsMsSinceEpoch(time.Now()), admin.Username)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return generateAdminGroupMapping(ctx, admin, tx)
|
||||
})
|
||||
}
|
||||
|
||||
func sqlCommonDeleteAdmin(admin Admin, dbHandle *sql.DB) error {
|
||||
@@ -488,8 +503,11 @@ func sqlCommonGetAdmins(limit, offset int, order string, dbHandle sqlQuerier) ([
|
||||
a.HideConfidentialData()
|
||||
admins = append(admins, a)
|
||||
}
|
||||
|
||||
return admins, rows.Err()
|
||||
err = rows.Err()
|
||||
if err != nil {
|
||||
return admins, err
|
||||
}
|
||||
return getAdminsWithGroups(ctx, admins, dbHandle)
|
||||
}
|
||||
|
||||
func sqlCommonDumpAdmins(dbHandle sqlQuerier) ([]Admin, error) {
|
||||
@@ -511,8 +529,11 @@ func sqlCommonDumpAdmins(dbHandle sqlQuerier) ([]Admin, error) {
|
||||
}
|
||||
admins = append(admins, a)
|
||||
}
|
||||
|
||||
return admins, rows.Err()
|
||||
err = rows.Err()
|
||||
if err != nil {
|
||||
return admins, err
|
||||
}
|
||||
return getAdminsWithGroups(ctx, admins, dbHandle)
|
||||
}
|
||||
|
||||
func sqlCommonGetGroupByName(name string, dbHandle sqlQuerier) (Group, error) {
|
||||
@@ -530,7 +551,11 @@ func sqlCommonGetGroupByName(name string, dbHandle sqlQuerier) (Group, error) {
|
||||
if err != nil {
|
||||
return group, err
|
||||
}
|
||||
return getGroupWithUsers(ctx, group, dbHandle)
|
||||
group, err = getGroupWithUsers(ctx, group, dbHandle)
|
||||
if err != nil {
|
||||
return group, err
|
||||
}
|
||||
return getGroupWithAdmins(ctx, group, dbHandle)
|
||||
}
|
||||
|
||||
func sqlCommonDumpGroups(dbHandle sqlQuerier) ([]Group, error) {
|
||||
@@ -664,6 +689,10 @@ func sqlCommonGetGroups(limit int, offset int, order string, minimal bool, dbHan
|
||||
if err != nil {
|
||||
return groups, err
|
||||
}
|
||||
groups, err = getGroupsWithAdmins(ctx, groups, dbHandle)
|
||||
if err != nil {
|
||||
return groups, err
|
||||
}
|
||||
for idx := range groups {
|
||||
groups[idx].PrepareForRendering()
|
||||
}
|
||||
@@ -2040,6 +2069,12 @@ func sqlCommonAddUserFolderMapping(ctx context.Context, user *User, folder *vfs.
|
||||
return err
|
||||
}
|
||||
|
||||
func sqlCommonClearAdminGroupMapping(ctx context.Context, admin *Admin, dbHandle sqlQuerier) error {
|
||||
q := getClearAdminGroupMappingQuery()
|
||||
_, err := dbHandle.ExecContext(ctx, q, admin.Username)
|
||||
return err
|
||||
}
|
||||
|
||||
func sqlCommonAddGroupFolderMapping(ctx context.Context, group *Group, folder *vfs.VirtualFolder, dbHandle sqlQuerier) error {
|
||||
q := getAddGroupFolderMappingQuery()
|
||||
_, err := dbHandle.ExecContext(ctx, q, folder.VirtualPath, folder.QuotaSize, folder.QuotaFiles, folder.Name, group.Name)
|
||||
@@ -2052,6 +2087,18 @@ func sqlCommonAddUserGroupMapping(ctx context.Context, username, groupName strin
|
||||
return err
|
||||
}
|
||||
|
||||
func sqlCommonAddAdminGroupMapping(ctx context.Context, username, groupName string, mappingOptions AdminGroupMappingOptions,
|
||||
dbHandle sqlQuerier,
|
||||
) error {
|
||||
options, err := json.Marshal(mappingOptions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
q := getAddAdminGroupMappingQuery()
|
||||
_, err = dbHandle.ExecContext(ctx, q, username, groupName, string(options))
|
||||
return err
|
||||
}
|
||||
|
||||
func generateGroupVirtualFoldersMapping(ctx context.Context, group *Group, dbHandle sqlQuerier) error {
|
||||
err := sqlCommonClearGroupFolderMapping(ctx, group, dbHandle)
|
||||
if err != nil {
|
||||
@@ -2104,6 +2151,20 @@ func generateUserGroupMapping(ctx context.Context, user *User, dbHandle sqlQueri
|
||||
return err
|
||||
}
|
||||
|
||||
func generateAdminGroupMapping(ctx context.Context, admin *Admin, dbHandle sqlQuerier) error {
|
||||
err := sqlCommonClearAdminGroupMapping(ctx, admin, dbHandle)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, group := range admin.Groups {
|
||||
err = sqlCommonAddAdminGroupMapping(ctx, admin.Username, group.Name, group.Options, dbHandle)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func getDefenderHostsWithScores(ctx context.Context, hosts []DefenderEntry, from int64, idForScores []int64,
|
||||
dbHandle sqlQuerier) (
|
||||
[]DefenderEntry,
|
||||
@@ -2152,6 +2213,57 @@ func getDefenderHostsWithScores(ctx context.Context, hosts []DefenderEntry, from
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func getAdminWithGroups(ctx context.Context, admin Admin, dbHandle sqlQuerier) (Admin, error) {
|
||||
admins, err := getAdminsWithGroups(ctx, []Admin{admin}, dbHandle)
|
||||
if err != nil {
|
||||
return admin, err
|
||||
}
|
||||
if len(admins) == 0 {
|
||||
return admin, errSQLGroupsAssociation
|
||||
}
|
||||
return admins[0], err
|
||||
}
|
||||
|
||||
func getAdminsWithGroups(ctx context.Context, admins []Admin, dbHandle sqlQuerier) ([]Admin, error) {
|
||||
if len(admins) == 0 {
|
||||
return admins, nil
|
||||
}
|
||||
adminsGroups := make(map[int64][]AdminGroupMapping)
|
||||
q := getRelatedGroupsForAdminsQuery(admins)
|
||||
rows, err := dbHandle.QueryContext(ctx, q)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
for rows.Next() {
|
||||
var group AdminGroupMapping
|
||||
var adminID int64
|
||||
var options []byte
|
||||
err = rows.Scan(&group.Name, &options, &adminID)
|
||||
if err != nil {
|
||||
return admins, err
|
||||
}
|
||||
err = json.Unmarshal(options, &group.Options)
|
||||
if err != nil {
|
||||
return admins, err
|
||||
}
|
||||
adminsGroups[adminID] = append(adminsGroups[adminID], group)
|
||||
}
|
||||
err = rows.Err()
|
||||
if err != nil {
|
||||
return admins, err
|
||||
}
|
||||
if len(adminsGroups) == 0 {
|
||||
return admins, err
|
||||
}
|
||||
for idx := range admins {
|
||||
ref := &admins[idx]
|
||||
ref.Groups = adminsGroups[ref.ID]
|
||||
}
|
||||
return admins, err
|
||||
}
|
||||
|
||||
func getUserWithVirtualFolders(ctx context.Context, user User, dbHandle sqlQuerier) (User, error) {
|
||||
users, err := getUsersWithVirtualFolders(ctx, []User{user}, dbHandle)
|
||||
if err != nil {
|
||||
@@ -2271,6 +2383,17 @@ func getGroupWithUsers(ctx context.Context, group Group, dbHandle sqlQuerier) (G
|
||||
return groups[0], err
|
||||
}
|
||||
|
||||
func getGroupWithAdmins(ctx context.Context, group Group, dbHandle sqlQuerier) (Group, error) {
|
||||
groups, err := getGroupsWithAdmins(ctx, []Group{group}, dbHandle)
|
||||
if err != nil {
|
||||
return group, err
|
||||
}
|
||||
if len(groups) == 0 {
|
||||
return group, errSQLUsersAssociation
|
||||
}
|
||||
return groups[0], err
|
||||
}
|
||||
|
||||
func getGroupWithVirtualFolders(ctx context.Context, group Group, dbHandle sqlQuerier) (Group, error) {
|
||||
groups, err := getGroupsWithVirtualFolders(ctx, []Group{group}, dbHandle)
|
||||
if err != nil {
|
||||
@@ -2368,6 +2491,40 @@ func getGroupsWithUsers(ctx context.Context, groups []Group, dbHandle sqlQuerier
|
||||
return groups, err
|
||||
}
|
||||
|
||||
func getGroupsWithAdmins(ctx context.Context, groups []Group, dbHandle sqlQuerier) ([]Group, error) {
|
||||
if len(groups) == 0 {
|
||||
return groups, nil
|
||||
}
|
||||
q := getRelatedAdminsForGroupsQuery(groups)
|
||||
rows, err := dbHandle.QueryContext(ctx, q)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
groupsAdmins := make(map[int64][]string)
|
||||
for rows.Next() {
|
||||
var groupID int64
|
||||
var username string
|
||||
err = rows.Scan(&groupID, &username)
|
||||
if err != nil {
|
||||
return groups, err
|
||||
}
|
||||
groupsAdmins[groupID] = append(groupsAdmins[groupID], username)
|
||||
}
|
||||
err = rows.Err()
|
||||
if err != nil {
|
||||
return groups, err
|
||||
}
|
||||
if len(groupsAdmins) > 0 {
|
||||
for idx := range groups {
|
||||
ref := &groups[idx]
|
||||
ref.Admins = groupsAdmins[ref.ID]
|
||||
}
|
||||
}
|
||||
return groups, nil
|
||||
}
|
||||
|
||||
func getVirtualFoldersWithGroups(folders []vfs.BaseVirtualFolder, dbHandle sqlQuerier) ([]vfs.BaseVirtualFolder, error) {
|
||||
if len(folders) == 0 {
|
||||
return folders, nil
|
||||
|
||||
Reference in New Issue
Block a user