mirror of
https://github.com/drakkan/sftpgo.git
synced 2024-11-25 09:00:27 +00:00
WebAdmin: fix parsing form field
some field names changed with the new UI Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
parent
73d7779d89
commit
86eab21be8
3 changed files with 114 additions and 59 deletions
|
@ -1242,8 +1242,8 @@ func getUsersForTemplate(r *http.Request) []userTemplateFields {
|
||||||
tplPublicKeys := r.Form["tpl_public_keys"]
|
tplPublicKeys := r.Form["tpl_public_keys"]
|
||||||
|
|
||||||
users := make(map[string]bool)
|
users := make(map[string]bool)
|
||||||
for idx, username := range tplUsernames {
|
for idx := range tplUsernames {
|
||||||
username = strings.TrimSpace(username)
|
username := tplUsernames[idx]
|
||||||
password := ""
|
password := ""
|
||||||
publicKey := ""
|
publicKey := ""
|
||||||
if len(tplPasswords) > idx {
|
if len(tplPasswords) > idx {
|
||||||
|
@ -1277,7 +1277,6 @@ func getVirtualFoldersFromPostFields(r *http.Request) []vfs.VirtualFolder {
|
||||||
folderQuotaSizes := r.Form["vfolder_quota_size"]
|
folderQuotaSizes := r.Form["vfolder_quota_size"]
|
||||||
folderQuotaFiles := r.Form["vfolder_quota_files"]
|
folderQuotaFiles := r.Form["vfolder_quota_files"]
|
||||||
for idx, p := range folderPaths {
|
for idx, p := range folderPaths {
|
||||||
p = strings.TrimSpace(p)
|
|
||||||
name := ""
|
name := ""
|
||||||
if len(folderNames) > idx {
|
if len(folderNames) > idx {
|
||||||
name = folderNames[idx]
|
name = folderNames[idx]
|
||||||
|
@ -1298,7 +1297,7 @@ func getVirtualFoldersFromPostFields(r *http.Request) []vfs.VirtualFolder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(folderQuotaFiles) > idx {
|
if len(folderQuotaFiles) > idx {
|
||||||
quotaFiles, err := strconv.Atoi(strings.TrimSpace(folderQuotaFiles[idx]))
|
quotaFiles, err := strconv.Atoi(folderQuotaFiles[idx])
|
||||||
if err == nil {
|
if err == nil {
|
||||||
vfolder.QuotaFiles = quotaFiles
|
vfolder.QuotaFiles = quotaFiles
|
||||||
}
|
}
|
||||||
|
@ -1313,13 +1312,9 @@ func getVirtualFoldersFromPostFields(r *http.Request) []vfs.VirtualFolder {
|
||||||
func getSubDirPermissionsFromPostFields(r *http.Request) map[string][]string {
|
func getSubDirPermissionsFromPostFields(r *http.Request) map[string][]string {
|
||||||
permissions := make(map[string][]string)
|
permissions := make(map[string][]string)
|
||||||
|
|
||||||
for k := range r.Form {
|
for idx, p := range r.Form["sub_perm_path"] {
|
||||||
if strings.HasPrefix(k, "sub_perm_path") {
|
if p != "" {
|
||||||
p := strings.TrimSpace(r.Form.Get(k))
|
permissions[p] = r.Form["sub_perm_permissions"+strconv.Itoa(idx)]
|
||||||
if p != "" {
|
|
||||||
idx := strings.TrimPrefix(k, "sub_perm_path")
|
|
||||||
permissions[p] = r.Form[fmt.Sprintf("sub_perm_permissions%v", idx)]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1335,33 +1330,39 @@ func getUserPermissionsFromPostFields(r *http.Request) map[string][]string {
|
||||||
|
|
||||||
func getBandwidthLimitsFromPostFields(r *http.Request) ([]sdk.BandwidthLimit, error) {
|
func getBandwidthLimitsFromPostFields(r *http.Request) ([]sdk.BandwidthLimit, error) {
|
||||||
var result []sdk.BandwidthLimit
|
var result []sdk.BandwidthLimit
|
||||||
|
bwSources := r.Form["bandwidth_limit_sources"]
|
||||||
|
uploadSources := r.Form["upload_bandwidth_source"]
|
||||||
|
downloadSources := r.Form["download_bandwidth_source"]
|
||||||
|
|
||||||
for k := range r.Form {
|
for idx, bwSource := range bwSources {
|
||||||
if strings.HasPrefix(k, "bandwidth_limit_sources") {
|
sources := getSliceFromDelimitedValues(bwSource, ",")
|
||||||
sources := getSliceFromDelimitedValues(r.Form.Get(k), ",")
|
if len(sources) > 0 {
|
||||||
if len(sources) > 0 {
|
bwLimit := sdk.BandwidthLimit{
|
||||||
bwLimit := sdk.BandwidthLimit{
|
Sources: sources,
|
||||||
Sources: sources,
|
|
||||||
}
|
|
||||||
idx := strings.TrimPrefix(k, "bandwidth_limit_sources")
|
|
||||||
ul := r.Form.Get(fmt.Sprintf("upload_bandwidth_source%v", idx))
|
|
||||||
dl := r.Form.Get(fmt.Sprintf("download_bandwidth_source%v", idx))
|
|
||||||
if ul != "" {
|
|
||||||
bandwidthUL, err := strconv.ParseInt(ul, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return result, fmt.Errorf("invalid upload_bandwidth_source%v %q: %w", idx, ul, err)
|
|
||||||
}
|
|
||||||
bwLimit.UploadBandwidth = bandwidthUL
|
|
||||||
}
|
|
||||||
if dl != "" {
|
|
||||||
bandwidthDL, err := strconv.ParseInt(dl, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return result, fmt.Errorf("invalid download_bandwidth_source%v %q: %w", idx, ul, err)
|
|
||||||
}
|
|
||||||
bwLimit.DownloadBandwidth = bandwidthDL
|
|
||||||
}
|
|
||||||
result = append(result, bwLimit)
|
|
||||||
}
|
}
|
||||||
|
ul := ""
|
||||||
|
dl := ""
|
||||||
|
if len(uploadSources) > idx {
|
||||||
|
ul = uploadSources[idx]
|
||||||
|
}
|
||||||
|
if len(downloadSources) > idx {
|
||||||
|
dl = downloadSources[idx]
|
||||||
|
}
|
||||||
|
if ul != "" {
|
||||||
|
bandwidthUL, err := strconv.ParseInt(ul, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return result, fmt.Errorf("invalid upload_bandwidth_source%v %q: %w", idx, ul, err)
|
||||||
|
}
|
||||||
|
bwLimit.UploadBandwidth = bandwidthUL
|
||||||
|
}
|
||||||
|
if dl != "" {
|
||||||
|
bandwidthDL, err := strconv.ParseInt(dl, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return result, fmt.Errorf("invalid download_bandwidth_source%v %q: %w", idx, ul, err)
|
||||||
|
}
|
||||||
|
bwLimit.DownloadBandwidth = bandwidthDL
|
||||||
|
}
|
||||||
|
result = append(result, bwLimit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1378,28 +1379,37 @@ func getPatterDenyPolicyFromString(policy string) int {
|
||||||
|
|
||||||
func getFilePatternsFromPostField(r *http.Request) []sdk.PatternsFilter {
|
func getFilePatternsFromPostField(r *http.Request) []sdk.PatternsFilter {
|
||||||
var result []sdk.PatternsFilter
|
var result []sdk.PatternsFilter
|
||||||
|
patternPaths := r.Form["pattern_path"]
|
||||||
|
patterns := r.Form["patterns"]
|
||||||
|
patternTypes := r.Form["pattern_type"]
|
||||||
|
policies := r.Form["pattern_policy"]
|
||||||
|
|
||||||
allowedPatterns := make(map[string][]string)
|
allowedPatterns := make(map[string][]string)
|
||||||
deniedPatterns := make(map[string][]string)
|
deniedPatterns := make(map[string][]string)
|
||||||
patternPolicies := make(map[string]string)
|
patternPolicies := make(map[string]string)
|
||||||
|
|
||||||
for k := range r.Form {
|
for idx := range patternPaths {
|
||||||
if strings.HasPrefix(k, "pattern_path") {
|
p := patternPaths[idx]
|
||||||
p := strings.TrimSpace(r.Form.Get(k))
|
filters := ""
|
||||||
idx := strings.TrimPrefix(k, "pattern_path")
|
patternType := ""
|
||||||
filters := strings.TrimSpace(r.Form.Get(fmt.Sprintf("patterns%v", idx)))
|
patternPolicy := ""
|
||||||
filters = strings.ReplaceAll(filters, " ", "")
|
if len(patterns) > idx {
|
||||||
patternType := r.Form.Get(fmt.Sprintf("pattern_type%v", idx))
|
filters = strings.ReplaceAll(patterns[idx], " ", "")
|
||||||
patternPolicy := r.Form.Get(fmt.Sprintf("pattern_policy%v", idx))
|
}
|
||||||
if p != "" && filters != "" {
|
if len(patternTypes) > idx {
|
||||||
if patternType == "allowed" {
|
patternType = patternTypes[idx]
|
||||||
allowedPatterns[p] = append(allowedPatterns[p], strings.Split(filters, ",")...)
|
}
|
||||||
} else {
|
if len(patternPolicies) > idx {
|
||||||
deniedPatterns[p] = append(deniedPatterns[p], strings.Split(filters, ",")...)
|
patternPolicy = policies[idx]
|
||||||
}
|
}
|
||||||
if patternPolicy != "" && patternPolicy != "0" {
|
if p != "" && filters != "" {
|
||||||
patternPolicies[p] = patternPolicy
|
if patternType == "allowed" {
|
||||||
}
|
allowedPatterns[p] = append(allowedPatterns[p], strings.Split(filters, ",")...)
|
||||||
|
} else {
|
||||||
|
deniedPatterns[p] = append(deniedPatterns[p], strings.Split(filters, ",")...)
|
||||||
|
}
|
||||||
|
if patternPolicy != "" && patternPolicy != "0" {
|
||||||
|
patternPolicies[p] = patternPolicy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1972,6 +1982,51 @@ func getQuotaLimits(r *http.Request) (int64, int, error) {
|
||||||
return quotaSize, quotaFiles, nil
|
return quotaSize, quotaFiles, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func updateUserFormFields(r *http.Request) {
|
||||||
|
for k := range r.Form {
|
||||||
|
if hasPrefixAndSuffix(k, "public_keys[", "][public_key]") {
|
||||||
|
r.Form.Add("public_keys", r.Form.Get(k))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if hasPrefixAndSuffix(k, "virtual_folders[", "][vfolder_path]") {
|
||||||
|
base, _ := strings.CutSuffix(k, "[vfolder_path]")
|
||||||
|
r.Form.Add("vfolder_path", strings.TrimSpace(r.Form.Get(k)))
|
||||||
|
r.Form.Add("vfolder_name", strings.TrimSpace(r.Form.Get(base+"[vfolder_name]")))
|
||||||
|
r.Form.Add("vfolder_quota_files", strings.TrimSpace(r.Form.Get(base+"[vfolder_quota_files]")))
|
||||||
|
r.Form.Add("vfolder_quota_size", strings.TrimSpace(r.Form.Get(base+"[vfolder_quota_size]")))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if hasPrefixAndSuffix(k, "directory_permissions[", "][sub_perm_path]") {
|
||||||
|
base, _ := strings.CutSuffix(k, "[sub_perm_path]")
|
||||||
|
r.Form.Add("sub_perm_path", strings.TrimSpace(r.Form.Get(k)))
|
||||||
|
r.Form["sub_perm_permissions"+strconv.Itoa(len(r.Form["sub_perm_path"])-1)] = r.Form[base+"[sub_perm_permissions][]"]
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if hasPrefixAndSuffix(k, "directory_patterns[", "][pattern_path]") {
|
||||||
|
base, _ := strings.CutSuffix(k, "[pattern_path]")
|
||||||
|
r.Form.Add("pattern_path", strings.TrimSpace(r.Form.Get(k)))
|
||||||
|
r.Form.Add("patterns", strings.TrimSpace(r.Form.Get(base+"[patterns]")))
|
||||||
|
r.Form.Add("pattern_type", strings.TrimSpace(r.Form.Get(base+"[pattern_type]")))
|
||||||
|
r.Form.Add("pattern_policy", strings.TrimSpace(r.Form.Get(base+"[pattern_policy]")))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if hasPrefixAndSuffix(k, "src_bandwidth_limits[", "][bandwidth_limit_sources]") {
|
||||||
|
base, _ := strings.CutSuffix(k, "[bandwidth_limit_sources]")
|
||||||
|
r.Form.Add("bandwidth_limit_sources", r.Form.Get(k))
|
||||||
|
r.Form.Add("upload_bandwidth_source", strings.TrimSpace(r.Form.Get(base+"[upload_bandwidth_source]")))
|
||||||
|
r.Form.Add("download_bandwidth_source", strings.TrimSpace(r.Form.Get(base+"[download_bandwidth_source]")))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if hasPrefixAndSuffix(k, "template_users[", "][tpl_username]") {
|
||||||
|
base, _ := strings.CutSuffix(k, "[tpl_username]")
|
||||||
|
r.Form.Add("tpl_username", strings.TrimSpace(r.Form.Get(k)))
|
||||||
|
r.Form.Add("tpl_password", strings.TrimSpace(r.Form.Get(base+"[tpl_password]")))
|
||||||
|
r.Form.Add("tpl_public_keys", strings.TrimSpace(r.Form.Get(base+"[tpl_public_keys]")))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func getUserFromPostFields(r *http.Request) (dataprovider.User, error) {
|
func getUserFromPostFields(r *http.Request) (dataprovider.User, error) {
|
||||||
user := dataprovider.User{}
|
user := dataprovider.User{}
|
||||||
err := r.ParseMultipartForm(maxRequestSize)
|
err := r.ParseMultipartForm(maxRequestSize)
|
||||||
|
@ -1979,6 +2034,7 @@ func getUserFromPostFields(r *http.Request) (dataprovider.User, error) {
|
||||||
return user, util.NewI18nError(err, util.I18nErrorInvalidForm)
|
return user, util.NewI18nError(err, util.I18nErrorInvalidForm)
|
||||||
}
|
}
|
||||||
defer r.MultipartForm.RemoveAll() //nolint:errcheck
|
defer r.MultipartForm.RemoveAll() //nolint:errcheck
|
||||||
|
updateUserFormFields(r)
|
||||||
uid, err := strconv.Atoi(r.Form.Get("uid"))
|
uid, err := strconv.Atoi(r.Form.Get("uid"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return user, fmt.Errorf("invalid uid: %w", err)
|
return user, fmt.Errorf("invalid uid: %w", err)
|
||||||
|
|
|
@ -158,13 +158,13 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
||||||
<div class="form-group row mt-10 fsconfig fsconfig-s3fs">
|
<div class="form-group row mt-10 fsconfig fsconfig-s3fs">
|
||||||
<label for="idS3UploadTimeout" data-i18n="storage.ul_part_timeout" class="col-md-3 col-form-label">UL Part Timeout (secs)</label>
|
<label for="idS3UploadTimeout" data-i18n="storage.ul_part_timeout" class="col-md-3 col-form-label">UL Part Timeout (secs)</label>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<input id="idS3UploadTimeout" type="number" min="0" class="form-control" name="s3_upload_part_max_time" value="{{.S3Config.DownloadPartSize}}" aria-describedby="idS3UploadTimeoutHelp" />
|
<input id="idS3UploadTimeout" type="number" min="0" class="form-control" name="s3_upload_part_max_time" value="{{.S3Config.UploadPartMaxTime}}" aria-describedby="idS3UploadTimeoutHelp" />
|
||||||
<div id="idS3UploadTimeoutHelp" class="form-text" data-i18n="storage.ul_part_timeout_help"></div>
|
<div id="idS3UploadTimeoutHelp" class="form-text" data-i18n="storage.ul_part_timeout_help"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-1"></div>
|
<div class="col-md-1"></div>
|
||||||
<label for="idS3DownloadTimeout" data-i18n="storage.dl_part_timeout" class="col-md-2 col-form-label">DL Part Timeout (secs)</label>
|
<label for="idS3DownloadTimeout" data-i18n="storage.dl_part_timeout" class="col-md-2 col-form-label">DL Part Timeout (secs)</label>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<input id="idS3DownloadTimeout" type="number" min="0" class="form-control" name="s3_download_part_max_time" value="{{.S3Config.DownloadConcurrency}}" aria-describedby="idS3DownloadTimeoutHelp" />
|
<input id="idS3DownloadTimeout" type="number" min="0" class="form-control" name="s3_download_part_max_time" value="{{.S3Config.DownloadPartMaxTime}}" aria-describedby="idS3DownloadTimeoutHelp" />
|
||||||
<div id="idS3DownloadTimeoutHelp" class="form-text" data-i18n="storage.dl_part_timeout_help"></div>
|
<div id="idS3DownloadTimeoutHelp" class="form-text" data-i18n="storage.dl_part_timeout_help"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -291,7 +291,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
||||||
<input type="text" class="form-control" name="vfolder_quota_size" value="{{HumanizeBytes $val.QuotaSize}}" />
|
<input type="text" class="form-control" name="vfolder_quota_size" value="{{HumanizeBytes $val.QuotaSize}}" />
|
||||||
<div class="form-text" data-i18n="virtual_folders.quota_size"></div>
|
<div class="form-text" data-i18n="virtual_folders.quota_size"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-2">
|
<div class="col-md-2 mt-3 mt-md-8">
|
||||||
<input type="number" min="-1" class="form-control" name="vfolder_quota_files" value="{{$val.QuotaFiles}}" />
|
<input type="number" min="-1" class="form-control" name="vfolder_quota_files" value="{{$val.QuotaFiles}}" />
|
||||||
<div class="form-text" data-i18n="virtual_folders.quota_files"></div>
|
<div class="form-text" data-i18n="virtual_folders.quota_files"></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -435,8 +435,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
||||||
<div class="form-group row mt-10">
|
<div class="form-group row mt-10">
|
||||||
<label for="idDescription" data-i18n="general.description" class="col-md-3 col-form-label">Description</label>
|
<label for="idDescription" data-i18n="general.description" class="col-md-3 col-form-label">Description</label>
|
||||||
<div class="col-md-9">
|
<div class="col-md-9">
|
||||||
<input id="idDescription" type="text" class="form-control" name="description" maxlength="255"
|
<input id="idDescription" type="text" class="form-control" name="description" value="{{.User.Description}}" maxlength="255">
|
||||||
placeholder="">{{.User.Description}}</textarea>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -909,7 +908,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
||||||
<div class="form-group row mt-10">
|
<div class="form-group row mt-10">
|
||||||
<label for="idFTPSecurity" data-i18n="filters.ftp_security" class="col-md-3 col-form-label">FTP security</label>
|
<label for="idFTPSecurity" data-i18n="filters.ftp_security" class="col-md-3 col-form-label">FTP security</label>
|
||||||
<div class="col-md-9">
|
<div class="col-md-9">
|
||||||
<select id="idFTPSecurity" name="tls_username" class="form-select" data-control="i18n-select2" data-hide-search="true" aria-describedby="idFTPSecurityHelp">
|
<select id="idFTPSecurity" name="ftp_security" class="form-select" data-control="i18n-select2" data-hide-search="true" aria-describedby="idFTPSecurityHelp">
|
||||||
<option value="" data-i18n="general.global_settings" {{if eq .User.Filters.FTPSecurity 0 }}selected{{end}}>Server settings</option>
|
<option value="" data-i18n="general.global_settings" {{if eq .User.Filters.FTPSecurity 0 }}selected{{end}}>Server settings</option>
|
||||||
<option value="1" data-i18n="general.mandatory_encryption" {{if eq .User.Filters.FTPSecurity 1 }}selected{{end}}>Mandatory encryption</option>
|
<option value="1" data-i18n="general.mandatory_encryption" {{if eq .User.Filters.FTPSecurity 1 }}selected{{end}}>Mandatory encryption</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
Loading…
Reference in a new issue