diff --git a/internal/httpd/server.go b/internal/httpd/server.go index d89eba36..99b0d38b 100644 --- a/internal/httpd/server.go +++ b/internal/httpd/server.go @@ -194,8 +194,7 @@ func (s *httpdServer) handleWebClientLogout(w http.ResponseWriter, r *http.Reque func (s *httpdServer) handleWebClientChangePwdPost(w http.ResponseWriter, r *http.Request) { r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize) - err := r.ParseForm() - if err != nil { + if err := r.ParseForm(); err != nil { s.renderClientChangePasswordPage(w, r, err.Error()) return } @@ -203,8 +202,8 @@ func (s *httpdServer) handleWebClientChangePwdPost(w http.ResponseWriter, r *htt s.renderClientForbiddenPage(w, r, err.Error()) return } - err = doChangeUserPassword(r, r.Form.Get("current_password"), r.Form.Get("new_password1"), - r.Form.Get("new_password2")) + err := doChangeUserPassword(r, strings.TrimSpace(r.Form.Get("current_password")), + strings.TrimSpace(r.Form.Get("new_password1")), strings.TrimSpace(r.Form.Get("new_password2"))) if err != nil { s.renderClientChangePasswordPage(w, r, err.Error()) return @@ -230,8 +229,8 @@ func (s *httpdServer) handleWebClientLoginPost(w http.ResponseWriter, r *http.Re return } protocol := common.ProtocolHTTP - username := r.Form.Get("username") - password := r.Form.Get("password") + username := strings.TrimSpace(r.Form.Get("username")) + password := strings.TrimSpace(r.Form.Get("password")) if username == "" || password == "" { updateLoginMetrics(&dataprovider.User{BaseUser: sdk.BaseUser{Username: username}}, dataprovider.LoginMethodPassword, ipAddr, common.ErrNoCredentials) @@ -289,7 +288,8 @@ func (s *httpdServer) handleWebClientPasswordResetPost(w http.ResponseWriter, r s.renderClientForbiddenPage(w, r, err.Error()) return } - _, user, err := handleResetPassword(r, r.Form.Get("code"), r.Form.Get("password"), false) + _, user, err := handleResetPassword(r, strings.TrimSpace(r.Form.Get("code")), + strings.TrimSpace(r.Form.Get("password")), false) if err != nil { s.renderClientResetPwdPage(w, err.Error(), ipAddr) return @@ -323,7 +323,7 @@ func (s *httpdServer) handleWebClientTwoFactorRecoveryPost(w http.ResponseWriter return } username := claims.Username - recoveryCode := r.Form.Get("recovery_code") + recoveryCode := strings.TrimSpace(r.Form.Get("recovery_code")) if username == "" || recoveryCode == "" { s.renderClientTwoFactorRecoveryPage(w, "Invalid credentials", ipAddr) return @@ -384,7 +384,7 @@ func (s *httpdServer) handleWebClientTwoFactorPost(w http.ResponseWriter, r *htt return } username := claims.Username - passcode := r.Form.Get("passcode") + passcode := strings.TrimSpace(r.Form.Get("passcode")) if username == "" || passcode == "" { updateLoginMetrics(&dataprovider.User{BaseUser: sdk.BaseUser{Username: username}}, dataprovider.LoginMethodPassword, ipAddr, common.ErrNoCredentials) @@ -440,7 +440,7 @@ func (s *httpdServer) handleWebAdminTwoFactorRecoveryPost(w http.ResponseWriter, return } username := claims.Username - recoveryCode := r.Form.Get("recovery_code") + recoveryCode := strings.TrimSpace(r.Form.Get("recovery_code")) if username == "" || recoveryCode == "" { s.renderTwoFactorRecoveryPage(w, "Invalid credentials", ipAddr) return @@ -499,7 +499,7 @@ func (s *httpdServer) handleWebAdminTwoFactorPost(w http.ResponseWriter, r *http return } username := claims.Username - passcode := r.Form.Get("passcode") + passcode := strings.TrimSpace(r.Form.Get("passcode")) if username == "" || passcode == "" { s.renderTwoFactorPage(w, "Invalid credentials", ipAddr) return @@ -544,8 +544,8 @@ func (s *httpdServer) handleWebAdminLoginPost(w http.ResponseWriter, r *http.Req s.renderAdminLoginPage(w, err.Error(), ipAddr) return } - username := r.Form.Get("username") - password := r.Form.Get("password") + username := strings.TrimSpace(r.Form.Get("username")) + password := strings.TrimSpace(r.Form.Get("password")) if username == "" || password == "" { s.renderAdminLoginPage(w, "Invalid credentials", ipAddr) return @@ -615,8 +615,8 @@ func (s *httpdServer) handleWebAdminChangePwdPost(w http.ResponseWriter, r *http s.renderForbiddenPage(w, r, err.Error()) return } - err = doChangeAdminPassword(r, r.Form.Get("current_password"), r.Form.Get("new_password1"), - r.Form.Get("new_password2")) + err = doChangeAdminPassword(r, strings.TrimSpace(r.Form.Get("current_password")), + strings.TrimSpace(r.Form.Get("new_password1")), strings.TrimSpace(r.Form.Get("new_password2"))) if err != nil { s.renderChangePasswordPage(w, r, err.Error()) return @@ -637,7 +637,8 @@ func (s *httpdServer) handleWebAdminPasswordResetPost(w http.ResponseWriter, r * s.renderForbiddenPage(w, r, err.Error()) return } - admin, _, err := handleResetPassword(r, r.Form.Get("code"), r.Form.Get("password"), true) + admin, _, err := handleResetPassword(r, strings.TrimSpace(r.Form.Get("code")), + strings.TrimSpace(r.Form.Get("password")), true) if err != nil { if e, ok := err.(*util.ValidationError); ok { s.renderResetPwdPage(w, e.GetErrorString(), ipAddr) @@ -666,10 +667,10 @@ func (s *httpdServer) handleWebAdminSetupPost(w http.ResponseWriter, r *http.Req s.renderForbiddenPage(w, r, err.Error()) return } - username := r.Form.Get("username") - password := r.Form.Get("password") - confirmPassword := r.Form.Get("confirm_password") - installCode := r.Form.Get("install_code") + username := strings.TrimSpace(r.Form.Get("username")) + password := strings.TrimSpace(r.Form.Get("password")) + confirmPassword := strings.TrimSpace(r.Form.Get("confirm_password")) + installCode := strings.TrimSpace(r.Form.Get("install_code")) if installationCode != "" && installCode != resolveInstallationCode() { s.renderAdminSetupPage(w, r, username, fmt.Sprintf("%v mismatch", installationCodeHint)) return diff --git a/internal/httpd/webadmin.go b/internal/httpd/webadmin.go index 341ada24..009c7f74 100644 --- a/internal/httpd/webadmin.go +++ b/internal/httpd/webadmin.go @@ -1504,7 +1504,7 @@ func getFilePatternsFromPostField(r *http.Request) []sdk.PatternsFilter { func getGroupsFromUserPostFields(r *http.Request) []sdk.GroupMapping { var groups []sdk.GroupMapping - primaryGroup := r.Form.Get("primary_group") + primaryGroup := strings.TrimSpace(r.Form.Get("primary_group")) if primaryGroup != "" { groups = append(groups, sdk.GroupMapping{ Name: primaryGroup, @@ -1514,14 +1514,14 @@ func getGroupsFromUserPostFields(r *http.Request) []sdk.GroupMapping { secondaryGroups := r.Form["secondary_groups"] for _, name := range secondaryGroups { groups = append(groups, sdk.GroupMapping{ - Name: name, + Name: strings.TrimSpace(name), Type: sdk.GroupTypeSecondary, }) } membershipGroups := r.Form["membership_groups"] for _, name := range membershipGroups { groups = append(groups, sdk.GroupMapping{ - Name: name, + Name: strings.TrimSpace(name), Type: sdk.GroupTypeMembership, }) } @@ -1565,7 +1565,7 @@ func getFiltersFromUserPostFields(r *http.Request) (sdk.BaseUserFilters, error) filters.DeniedProtocols = r.Form["denied_protocols"] filters.TwoFactorAuthProtocols = r.Form["required_two_factor_protocols"] filters.FilePatterns = getFilePatternsFromPostField(r) - filters.TLSUsername = sdk.TLSUsername(r.Form.Get("tls_username")) + filters.TLSUsername = sdk.TLSUsername(strings.TrimSpace(r.Form.Get("tls_username"))) filters.WebClient = r.Form["web_client_options"] filters.DefaultSharesExpiration = defaultSharesExpiration filters.PasswordExpiration = passwordExpiration @@ -1583,7 +1583,7 @@ func getFiltersFromUserPostFields(r *http.Request) (sdk.BaseUserFilters, error) filters.IsAnonymous = r.Form.Get("is_anonymous") != "" filters.DisableFsChecks = r.Form.Get("disable_fs_checks") != "" filters.AllowAPIKeyAuth = r.Form.Get("allow_api_key_auth") != "" - filters.StartDirectory = r.Form.Get("start_directory") + filters.StartDirectory = strings.TrimSpace(r.Form.Get("start_directory")) filters.MaxUploadFileSize = maxFileSize filters.ExternalAuthCacheTime, err = strconv.ParseInt(r.Form.Get("external_auth_cache_time"), 10, 64) if err != nil { @@ -1614,7 +1614,7 @@ func getS3Config(r *http.Request) (vfs.S3FsConfig, error) { config.Endpoint = strings.TrimSpace(r.Form.Get("s3_endpoint")) config.StorageClass = strings.TrimSpace(r.Form.Get("s3_storage_class")) config.ACL = strings.TrimSpace(r.Form.Get("s3_acl")) - config.KeyPrefix = r.Form.Get("s3_key_prefix") + config.KeyPrefix = strings.TrimSpace(r.Form.Get("s3_key_prefix")) config.UploadPartSize, err = strconv.ParseInt(r.Form.Get("s3_upload_part_size"), 10, 64) if err != nil { return config, fmt.Errorf("invalid s3 upload part size: %w", err) @@ -1650,7 +1650,7 @@ func getGCSConfig(r *http.Request) (vfs.GCSFsConfig, error) { config.Bucket = strings.TrimSpace(r.Form.Get("gcs_bucket")) config.StorageClass = strings.TrimSpace(r.Form.Get("gcs_storage_class")) config.ACL = strings.TrimSpace(r.Form.Get("gcs_acl")) - config.KeyPrefix = r.Form.Get("gcs_key_prefix") + config.KeyPrefix = strings.TrimSpace(r.Form.Get("gcs_key_prefix")) uploadPartSize, err := strconv.ParseInt(r.Form.Get("gcs_upload_part_size"), 10, 64) if err == nil { config.UploadPartSize = uploadPartSize @@ -1689,13 +1689,13 @@ func getSFTPConfig(r *http.Request) (vfs.SFTPFsConfig, error) { var err error config := vfs.SFTPFsConfig{} config.Endpoint = strings.TrimSpace(r.Form.Get("sftp_endpoint")) - config.Username = r.Form.Get("sftp_username") + config.Username = strings.TrimSpace(r.Form.Get("sftp_username")) config.Password = getSecretFromFormField(r, "sftp_password") config.PrivateKey = getSecretFromFormField(r, "sftp_private_key") config.KeyPassphrase = getSecretFromFormField(r, "sftp_key_passphrase") fingerprintsFormValue := r.Form.Get("sftp_fingerprints") config.Fingerprints = getSliceFromDelimitedValues(fingerprintsFormValue, "\n") - config.Prefix = r.Form.Get("sftp_prefix") + config.Prefix = strings.TrimSpace(r.Form.Get("sftp_prefix")) config.DisableCouncurrentReads = r.Form.Get("sftp_disable_concurrent_reads") != "" config.BufferSize, err = strconv.ParseInt(r.Form.Get("sftp_buffer_size"), 10, 64) if r.Form.Get("sftp_equality_check_mode") != "" { @@ -1712,7 +1712,7 @@ func getSFTPConfig(r *http.Request) (vfs.SFTPFsConfig, error) { func getHTTPFsConfig(r *http.Request) vfs.HTTPFsConfig { config := vfs.HTTPFsConfig{} config.Endpoint = strings.TrimSpace(r.Form.Get("http_endpoint")) - config.Username = r.Form.Get("http_username") + config.Username = strings.TrimSpace(r.Form.Get("http_username")) config.SkipTLSVerify = r.Form.Get("http_skip_tls_verify") != "" config.Password = getSecretFromFormField(r, "http_password") config.APIKey = getSecretFromFormField(r, "http_api_key") @@ -1732,7 +1732,7 @@ func getAzureConfig(r *http.Request) (vfs.AzBlobFsConfig, error) { config.AccountKey = getSecretFromFormField(r, "az_account_key") config.SASURL = getSecretFromFormField(r, "az_sas_url") config.Endpoint = strings.TrimSpace(r.Form.Get("az_endpoint")) - config.KeyPrefix = r.Form.Get("az_key_prefix") + config.KeyPrefix = strings.TrimSpace(r.Form.Get("az_key_prefix")) config.AccessTier = strings.TrimSpace(r.Form.Get("az_access_tier")) config.UseEmulator = r.Form.Get("az_use_emulator") != "" config.UploadPartSize, err = strconv.ParseInt(r.Form.Get("az_upload_part_size"), 10, 64) @@ -1841,12 +1841,12 @@ func getAdminFromPostFields(r *http.Request) (dataprovider.Admin, error) { if err != nil { return admin, fmt.Errorf("invalid status: %w", err) } - admin.Username = r.Form.Get("username") - admin.Password = r.Form.Get("password") + admin.Username = strings.TrimSpace(r.Form.Get("username")) + admin.Password = strings.TrimSpace(r.Form.Get("password")) admin.Permissions = r.Form["permissions"] - admin.Email = r.Form.Get("email") + admin.Email = strings.TrimSpace(r.Form.Get("email")) admin.Status = status - admin.Role = r.Form.Get("role") + admin.Role = strings.TrimSpace(r.Form.Get("role")) admin.Filters.AllowList = getSliceFromDelimitedValues(r.Form.Get("allowed_ip"), ",") admin.Filters.AllowAPIKeyAuth = r.Form.Get("allow_api_key_auth") != "" admin.AdditionalInfo = r.Form.Get("additional_info") @@ -2093,11 +2093,11 @@ func getUserFromPostFields(r *http.Request) (dataprovider.User, error) { } user = dataprovider.User{ BaseUser: sdk.BaseUser{ - Username: r.Form.Get("username"), - Email: r.Form.Get("email"), - Password: r.Form.Get("password"), + Username: strings.TrimSpace(r.Form.Get("username")), + Email: strings.TrimSpace(r.Form.Get("email")), + Password: strings.TrimSpace(r.Form.Get("password")), PublicKeys: r.Form["public_keys"], - HomeDir: r.Form.Get("home_dir"), + HomeDir: strings.TrimSpace(r.Form.Get("home_dir")), UID: uid, GID: gid, Permissions: getUserPermissionsFromPostFields(r), @@ -2113,7 +2113,7 @@ func getUserFromPostFields(r *http.Request) (dataprovider.User, error) { ExpirationDate: expirationDateMillis, AdditionalInfo: r.Form.Get("additional_info"), Description: r.Form.Get("description"), - Role: r.Form.Get("role"), + Role: strings.TrimSpace(r.Form.Get("role")), }, Filters: dataprovider.UserFilters{ BaseUserFilters: filters, @@ -2168,12 +2168,12 @@ func getGroupFromPostFields(r *http.Request) (dataprovider.Group, error) { } group = dataprovider.Group{ BaseGroup: sdk.BaseGroup{ - Name: r.Form.Get("name"), + Name: strings.TrimSpace(r.Form.Get("name")), Description: r.Form.Get("description"), }, UserSettings: dataprovider.GroupUserSettings{ BaseGroupUserSettings: sdk.BaseGroupUserSettings{ - HomeDir: r.Form.Get("home_dir"), + HomeDir: strings.TrimSpace(r.Form.Get("home_dir")), MaxSessions: maxSessions, QuotaSize: quotaSize, QuotaFiles: quotaFiles, @@ -2199,7 +2199,7 @@ func getKeyValsFromPostFields(r *http.Request, key, val string) []dataprovider.K if strings.HasPrefix(k, key) { formKey := r.Form.Get(k) idx := strings.TrimPrefix(k, key) - formVal := r.Form.Get(fmt.Sprintf("%s%s", val, idx)) + formVal := strings.TrimSpace(r.Form.Get(fmt.Sprintf("%s%s", val, idx))) if formKey != "" && formVal != "" { res = append(res, dataprovider.KeyValue{ Key: formKey, @@ -2215,7 +2215,7 @@ func getFoldersRetentionFromPostFields(r *http.Request) ([]dataprovider.FolderRe var res []dataprovider.FolderRetention for k := range r.Form { if strings.HasPrefix(k, "folder_retention_path") { - folderPath := r.Form.Get(k) + folderPath := strings.TrimSpace(r.Form.Get(k)) if folderPath != "" { idx := strings.TrimPrefix(k, "folder_retention_path") retention, err := strconv.Atoi(r.Form.Get(fmt.Sprintf("folder_retention_val%s", idx))) @@ -2239,14 +2239,14 @@ func getHTTPPartsFromPostFields(r *http.Request) []dataprovider.HTTPPart { var result []dataprovider.HTTPPart for k := range r.Form { if strings.HasPrefix(k, "http_part_name") { - partName := r.Form.Get(k) + partName := strings.TrimSpace(r.Form.Get(k)) if partName != "" { idx := strings.TrimPrefix(k, "http_part_name") order, err := strconv.Atoi(idx) if err != nil { continue } - filePath := r.Form.Get(fmt.Sprintf("http_part_file%s", idx)) + filePath := strings.TrimSpace(r.Form.Get(fmt.Sprintf("http_part_file%s", idx))) body := r.Form.Get(fmt.Sprintf("http_part_body%s", idx)) concatHeaders := getSliceFromDelimitedValues(r.Form.Get(fmt.Sprintf("http_part_headers%s", idx)), "\n") var headers []dataprovider.KeyValue @@ -2314,8 +2314,8 @@ func getEventActionOptionsFromPostFields(r *http.Request) (dataprovider.BaseEven } options := dataprovider.BaseEventActionOptions{ HTTPConfig: dataprovider.EventActionHTTPConfig{ - Endpoint: r.Form.Get("http_endpoint"), - Username: r.Form.Get("http_username"), + Endpoint: strings.TrimSpace(r.Form.Get("http_endpoint")), + Username: strings.TrimSpace(r.Form.Get("http_username")), Password: getSecretFromFormField(r, "http_password"), Headers: getKeyValsFromPostFields(r, "http_header_key", "http_header_val"), Timeout: httpTimeout, @@ -2326,7 +2326,7 @@ func getEventActionOptionsFromPostFields(r *http.Request) (dataprovider.BaseEven Parts: getHTTPPartsFromPostFields(r), }, CmdConfig: dataprovider.EventActionCommandConfig{ - Cmd: r.Form.Get("cmd_path"), + Cmd: strings.TrimSpace(r.Form.Get("cmd_path")), Args: cmdArgs, Timeout: cmdTimeout, EnvVars: getKeyValsFromPostFields(r, "cmd_env_key", "cmd_env_val"), @@ -2350,7 +2350,7 @@ func getEventActionOptionsFromPostFields(r *http.Request) (dataprovider.BaseEven Exist: getSliceFromDelimitedValues(r.Form.Get("fs_exist_paths"), ","), Copy: getKeyValsFromPostFields(r, "fs_copy_source", "fs_copy_target"), Compress: dataprovider.EventActionFsCompress{ - Name: r.Form.Get("fs_compress_name"), + Name: strings.TrimSpace(r.Form.Get("fs_compress_name")), Paths: getSliceFromDelimitedValues(r.Form.Get("fs_compress_paths"), ","), }, }, @@ -2380,7 +2380,7 @@ func getEventActionFromPostFields(r *http.Request) (dataprovider.BaseEventAction return dataprovider.BaseEventAction{}, err } action := dataprovider.BaseEventAction{ - Name: r.Form.Get("name"), + Name: strings.TrimSpace(r.Form.Get("name")), Description: r.Form.Get("description"), Type: actionType, Options: options, @@ -2404,12 +2404,12 @@ func getEventRuleConditionsFromPostFields(r *http.Request) (dataprovider.EventCo var names, groupNames, roleNames, fsPaths []dataprovider.ConditionPattern for k := range r.Form { if strings.HasPrefix(k, "schedule_hour") { - hour := r.Form.Get(k) + hour := strings.TrimSpace(r.Form.Get(k)) if hour != "" { idx := strings.TrimPrefix(k, "schedule_hour") - dayOfWeek := r.Form.Get(fmt.Sprintf("schedule_day_of_week%s", idx)) - dayOfMonth := r.Form.Get(fmt.Sprintf("schedule_day_of_month%s", idx)) - month := r.Form.Get(fmt.Sprintf("schedule_month%s", idx)) + dayOfWeek := strings.TrimSpace(r.Form.Get(fmt.Sprintf("schedule_day_of_week%s", idx))) + dayOfMonth := strings.TrimSpace(r.Form.Get(fmt.Sprintf("schedule_day_of_month%s", idx))) + month := strings.TrimSpace(r.Form.Get(fmt.Sprintf("schedule_month%s", idx))) schedules = append(schedules, dataprovider.Schedule{ Hours: hour, DayOfWeek: dayOfWeek, @@ -2419,7 +2419,7 @@ func getEventRuleConditionsFromPostFields(r *http.Request) (dataprovider.EventCo } } if strings.HasPrefix(k, "name_pattern") { - pattern := r.Form.Get(k) + pattern := strings.TrimSpace(r.Form.Get(k)) if pattern != "" { idx := strings.TrimPrefix(k, "name_pattern") patternType := r.Form.Get(fmt.Sprintf("type_name_pattern%s", idx)) @@ -2430,7 +2430,7 @@ func getEventRuleConditionsFromPostFields(r *http.Request) (dataprovider.EventCo } } if strings.HasPrefix(k, "group_name_pattern") { - pattern := r.Form.Get(k) + pattern := strings.TrimSpace(r.Form.Get(k)) if pattern != "" { idx := strings.TrimPrefix(k, "group_name_pattern") patternType := r.Form.Get(fmt.Sprintf("type_group_name_pattern%s", idx)) @@ -2441,7 +2441,7 @@ func getEventRuleConditionsFromPostFields(r *http.Request) (dataprovider.EventCo } } if strings.HasPrefix(k, "role_name_pattern") { - pattern := r.Form.Get(k) + pattern := strings.TrimSpace(r.Form.Get(k)) if pattern != "" { idx := strings.TrimPrefix(k, "role_name_pattern") patternType := r.Form.Get(fmt.Sprintf("type_role_name_pattern%s", idx)) @@ -2452,7 +2452,7 @@ func getEventRuleConditionsFromPostFields(r *http.Request) (dataprovider.EventCo } } if strings.HasPrefix(k, "fs_path_pattern") { - pattern := r.Form.Get(k) + pattern := strings.TrimSpace(r.Form.Get(k)) if pattern != "" { idx := strings.TrimPrefix(k, "fs_path_pattern") patternType := r.Form.Get(fmt.Sprintf("type_fs_path_pattern%s", idx)) @@ -2495,7 +2495,7 @@ func getEventRuleActionsFromPostFields(r *http.Request) ([]dataprovider.EventAct var actions []dataprovider.EventAction for k := range r.Form { if strings.HasPrefix(k, "action_name") { - name := r.Form.Get(k) + name := strings.TrimSpace(r.Form.Get(k)) if name != "" { idx := strings.TrimPrefix(k, "action_name") order, err := strconv.Atoi(r.Form.Get(fmt.Sprintf("action_order%s", idx))) @@ -2542,7 +2542,7 @@ func getEventRuleFromPostFields(r *http.Request) (dataprovider.EventRule, error) return dataprovider.EventRule{}, err } rule := dataprovider.EventRule{ - Name: r.Form.Get("name"), + Name: strings.TrimSpace(r.Form.Get("name")), Status: status, Description: r.Form.Get("description"), Trigger: trigger, @@ -2559,7 +2559,7 @@ func getRoleFromPostFields(r *http.Request) (dataprovider.Role, error) { } return dataprovider.Role{ - Name: r.Form.Get("name"), + Name: strings.TrimSpace(r.Form.Get("name")), Description: r.Form.Get("description"), }, nil } @@ -2587,7 +2587,7 @@ func getIPListEntryFromPostFields(r *http.Request, listType dataprovider.IPListT } return dataprovider.IPListEntry{ - IPOrNet: r.Form.Get("ipornet"), + IPOrNet: strings.TrimSpace(r.Form.Get("ipornet")), Mode: mode, Protocols: protocols, Description: r.Form.Get("description"), @@ -2651,14 +2651,14 @@ func getSMTPConfigsFromPostFields(r *http.Request) *dataprovider.SMTPConfigs { oauth2Provider = 1 } return &dataprovider.SMTPConfigs{ - Host: r.Form.Get("smtp_host"), + Host: strings.TrimSpace(r.Form.Get("smtp_host")), Port: port, - From: r.Form.Get("smtp_from"), - User: r.Form.Get("smtp_username"), + From: strings.TrimSpace(r.Form.Get("smtp_from")), + User: strings.TrimSpace(r.Form.Get("smtp_username")), Password: getSecretFromFormField(r, "smtp_password"), AuthType: authType, Encryption: encryption, - Domain: r.Form.Get("smtp_domain"), + Domain: strings.TrimSpace(r.Form.Get("smtp_domain")), Debug: debug, OAuth2: dataprovider.SMTPOAuth2{ Provider: oauth2Provider, @@ -3385,8 +3385,8 @@ func (s *httpdServer) handleWebAddFolderPost(w http.ResponseWriter, r *http.Requ s.renderForbiddenPage(w, r, err.Error()) return } - folder.MappedPath = r.Form.Get("mapped_path") - folder.Name = r.Form.Get("name") + folder.MappedPath = strings.TrimSpace(r.Form.Get("mapped_path")) + folder.Name = strings.TrimSpace(r.Form.Get("name")) folder.Description = r.Form.Get("description") fsConfig, err := getFsConfigFromPostFields(r) if err != nil { @@ -3452,7 +3452,7 @@ func (s *httpdServer) handleWebUpdateFolderPost(w http.ResponseWriter, r *http.R return } updatedFolder := vfs.BaseVirtualFolder{ - MappedPath: r.Form.Get("mapped_path"), + MappedPath: strings.TrimSpace(r.Form.Get("mapped_path")), Description: r.Form.Get("description"), } updatedFolder.ID = folder.ID @@ -4214,8 +4214,16 @@ func (s *httpdServer) handleOAuth2TokenRedirect(w http.ResponseWriter, r *http.R s.renderMessagePage(w, r, errorTitle, "Unable to get token:", http.StatusInternalServerError, err, "") return } + if token.RefreshToken == "" { + errTxt := "the OAuth2 provider returned an empty token. " + + "Some providers only return the token when the user first authorizes. " + + "If you have already registered SFTPGo with this user in the past, revoke access and try again. " + + "This way you will invalidate the previous token." + s.renderMessagePage(w, r, errorTitle, "Unable to get token:", http.StatusBadRequest, errors.New(errTxt), "") + return + } s.renderMessagePage(w, r, successTitle, "", http.StatusOK, nil, - fmt.Sprintf("Copy the following string, without the quotes, into your SMTP OAuth2 Token configuration: %q", token.RefreshToken)) + fmt.Sprintf("Copy the following string, without the quotes, into SMTP OAuth2 Token configuration field: %q", token.RefreshToken)) } func updateSMTPSecrets(newConfigs, currentConfigs *dataprovider.SMTPConfigs) { diff --git a/internal/httpd/webclient.go b/internal/httpd/webclient.go index e03b5891..6ad7d905 100644 --- a/internal/httpd/webclient.go +++ b/internal/httpd/webclient.go @@ -1265,7 +1265,7 @@ func (s *httpdServer) handleWebClientProfilePost(w http.ResponseWriter, r *http. user.Filters.AllowAPIKeyAuth = r.Form.Get("allow_api_key_auth") != "" } if userMerged.CanChangeInfo() { - user.Email = r.Form.Get("email") + user.Email = strings.TrimSpace(r.Form.Get("email")) user.Description = r.Form.Get("description") } err = dataprovider.UpdateUser(&user, dataprovider.ActionExecutorSelf, ipAddr, user.Role) @@ -1297,10 +1297,15 @@ func getShareFromPostFields(r *http.Request) (*dataprovider.Share, error) { if err := r.ParseForm(); err != nil { return share, err } - share.Name = r.Form.Get("name") + share.Name = strings.TrimSpace(r.Form.Get("name")) share.Description = r.Form.Get("description") - share.Paths = r.Form["paths"] - share.Password = r.Form.Get("password") + for _, p := range r.Form["paths"] { + p = strings.TrimSpace(p) + if p != "" { + share.Paths = append(share.Paths, p) + } + } + share.Password = strings.TrimSpace(r.Form.Get("password")) share.AllowFrom = getSliceFromDelimitedValues(r.Form.Get("allowed_ip"), ",") scope, err := strconv.Atoi(r.Form.Get("scope")) if err != nil { @@ -1313,8 +1318,8 @@ func getShareFromPostFields(r *http.Request) (*dataprovider.Share, error) { } share.MaxTokens = maxTokens expirationDateMillis := int64(0) - expirationDateString := r.Form.Get("expiration_date") - if strings.TrimSpace(expirationDateString) != "" { + expirationDateString := strings.TrimSpace(r.Form.Get("expiration_date")) + if expirationDateString != "" { expirationDate, err := time.Parse(webDateTimeFormat, expirationDateString) if err != nil { return share, err @@ -1347,7 +1352,7 @@ func (s *httpdServer) handleWebClientForgotPwdPost(w http.ResponseWriter, r *htt s.renderClientForbiddenPage(w, r, err.Error()) return } - username := r.Form.Get("username") + username := strings.TrimSpace(r.Form.Get("username")) err = handleForgotPassword(r, username, false) if err != nil { if e, ok := err.(*util.ValidationError); ok { @@ -1479,7 +1484,7 @@ func (s *httpdServer) handleClientShareLoginPost(w http.ResponseWriter, r *http. s.renderShareLoginPage(w, r.RequestURI, dataprovider.ErrInvalidCredentials.Error(), ipAddr) return } - match, err := share.CheckCredentials(r.Form.Get("share_password")) + match, err := share.CheckCredentials(strings.TrimSpace(r.Form.Get("share_password"))) if !match || err != nil { s.renderShareLoginPage(w, r.RequestURI, dataprovider.ErrInvalidCredentials.Error(), ipAddr) return