diff --git a/README.md b/README.md index 971eb5fa..eec59e1b 100644 --- a/README.md +++ b/README.md @@ -479,17 +479,24 @@ The `command` can also read the following environment variables: - `SFTPGO_USER_ACTION` - `SFTPGO_USER_USERNAME` +- `SFTPGO_USER_PASSWORD`, hashed password as stored inside the data provider, can be empty if the user does not login using a password - `SFTPGO_USER_ID` - `SFTPGO_USER_STATUS` - `SFTPGO_USER_EXPIRATION_DATE` - `SFTPGO_USER_HOME_DIR` - `SFTPGO_USER_UID` - `SFTPGO_USER_GID` +- `SFTPGO_USER_QUOTA_FILES` +- `SFTPGO_USER_QUOTA_SIZE` +- `SFTPGO_USER_UPLOAD_BANDWIDTH` +- `SFTPGO_USER_DOWNLOAD_BANDWIDTH` +- `SFTPGO_USER_MAX_SESSIONS` +- `SFTPGO_USER_FS_PROVIDER` Previous global environment variables aren't cleared when the script is called. The `command` must finish within 15 seconds. -The `http_notification_url`, if defined, will be called invoked as http POST. The action is added to the query string, for example `?action=update` and the user is sent serialized as JSON inside the POST body +The `http_notification_url`, if defined, will be called invoked as http POST. The action is added to the query string, for example `?action=update` and the user is sent serialized as JSON inside the POST body with sensitive fields removed. The HTTP request has a 15 seconds timeout. diff --git a/dataprovider/dataprovider.go b/dataprovider/dataprovider.go index faa4608f..60286a84 100644 --- a/dataprovider/dataprovider.go +++ b/dataprovider/dataprovider.go @@ -993,7 +993,7 @@ func providerLog(level logger.LogLevel, format string, v ...interface{}) { logger.Log(level, logSender, "", format, v...) } -func executeNotificationCommand(operation string, user *User) error { +func executeNotificationCommand(operation string, user User) error { ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) defer cancel() commandArgs := user.getNotificationFieldsAsSlice(operation) @@ -1015,18 +1015,17 @@ func executeAction(operation string, user User) { var err error user, err = provider.userExists(user.Username) if err != nil { - providerLog(logger.LevelWarn, "unable to get the user to notify operation %#v: %v", operation, err) + providerLog(logger.LevelWarn, "unable to get the user to notify for operation %#v: %v", operation, err) return } } - HideUserSensitiveData(&user) if len(config.Actions.Command) > 0 && filepath.IsAbs(config.Actions.Command) { // we are in a goroutine but if we have to send an HTTP notification we don't want to wait for the // end of the command if len(config.Actions.HTTPNotificationURL) > 0 { - go executeNotificationCommand(operation, &user) + go executeNotificationCommand(operation, user) } else { - executeNotificationCommand(operation, &user) + executeNotificationCommand(operation, user) } } if len(config.Actions.HTTPNotificationURL) > 0 { @@ -1040,6 +1039,7 @@ func executeAction(operation string, user User) { q := url.Query() q.Add("action", operation) url.RawQuery = q.Encode() + HideUserSensitiveData(&user) userAsJSON, err := json.Marshal(user) if err != nil { return diff --git a/dataprovider/user.go b/dataprovider/user.go index eb90bca6..d55277bd 100644 --- a/dataprovider/user.go +++ b/dataprovider/user.go @@ -465,12 +465,19 @@ func (u *User) getNotificationFieldsAsSlice(action string) []string { func (u *User) getNotificationFieldsAsEnvVars(action string) []string { return []string{fmt.Sprintf("SFTPGO_USER_ACTION=%v", action), fmt.Sprintf("SFTPGO_USER_USERNAME=%v", u.Username), + fmt.Sprintf("SFTPGO_USER_PASSWORD=%v", u.Password), fmt.Sprintf("SFTPGO_USER_ID=%v", u.ID), fmt.Sprintf("SFTPGO_USER_STATUS=%v", u.Status), fmt.Sprintf("SFTPGO_USER_EXPIRATION_DATE=%v", u.ExpirationDate), fmt.Sprintf("SFTPGO_USER_HOME_DIR=%v", u.HomeDir), fmt.Sprintf("SFTPGO_USER_UID=%v", u.UID), - fmt.Sprintf("SFTPGO_USER_GID=%v", u.GID)} + fmt.Sprintf("SFTPGO_USER_GID=%v", u.GID), + fmt.Sprintf("SFTPGO_USER_QUOTA_FILES=%v", u.QuotaFiles), + fmt.Sprintf("SFTPGO_USER_QUOTA_SIZE=%v", u.QuotaSize), + fmt.Sprintf("SFTPGO_USER_UPLOAD_BANDWIDTH=%v", u.UploadBandwidth), + fmt.Sprintf("SFTPGO_USER_DOWNLOAD_BANDWIDTH=%v", u.DownloadBandwidth), + fmt.Sprintf("SFTPGO_USER_MAX_SESSIONS=%v", u.MaxSessions), + fmt.Sprintf("SFTPGO_USER_FS_PROVIDER=%v", u.FsConfig.Provider)} } func (u *User) getGCSCredentialsFilePath() string {