Browse Source

pre-upload: execute the hook just before opening the target file

Nicola Murino 4 years ago
parent
commit
969c992bfd
3 changed files with 11 additions and 10 deletions
  1. 1 1
      docs/custom-actions.md
  2. 4 4
      ftpd/handler.go
  3. 6 5
      sftpd/handler.go

+ 1 - 1
docs/custom-actions.md

@@ -61,7 +61,7 @@ If the `hook` defines an HTTP URL then this URL will be invoked as HTTP POST. Th
 - `endpoint`, included for S3, SFTP and Azure backend if configured. For Azure this is the SAS URL, if configured, otherwise the endpoint
 - `status`, integer. Status for `upload`, `download` and `ssh_cmd` actions. 0 means a generic error occurred. 1 means no error, 2 means quota exceeded error
 - `protocol`, string. Possible values are `SSH`, `SFTP`, `SCP`, `FTP`, `DAV`, `HTTP`
-- `open_flags`, integer, File open flags, can be non-zero for `pre-upload` action. If `file_size` is greater than zero and `file_size&512 == 0` the target file will not be truncated
+- `open_flags`, integer. File open flags, can be non-zero for `pre-upload` action. If `file_size` is greater than zero and `file_size&512 == 0` the target file will not be truncated
 
 The HTTP hook will use the global configuration for HTTP clients and will respect the retry configurations.
 

+ 4 - 4
ftpd/handler.go

@@ -388,10 +388,6 @@ func (c *Connection) handleFTPUploadToExistingFile(fs vfs.Fs, flags int, resolve
 		c.Log(logger.LevelInfo, "denying file write due to quota limits")
 		return nil, common.ErrQuotaExceeded
 	}
-	if err := common.ExecutePreAction(&c.User, common.OperationPreUpload, resolvedPath, requestPath, c.GetProtocol(), fileSize, flags); err != nil {
-		c.Log(logger.LevelDebug, "upload for file %#v denied by pre action: %v", requestPath, err)
-		return nil, c.GetPermissionDeniedError()
-	}
 	minWriteOffset := int64(0)
 	// ftpserverlib sets:
 	// - os.O_WRONLY | os.O_APPEND for APPE and COMB
@@ -406,6 +402,10 @@ func (c *Connection) handleFTPUploadToExistingFile(fs vfs.Fs, flags int, resolve
 		c.Log(logger.LevelDebug, "unable to get max write size: %v", err)
 		return nil, err
 	}
+	if err := common.ExecutePreAction(&c.User, common.OperationPreUpload, resolvedPath, requestPath, c.GetProtocol(), fileSize, flags); err != nil {
+		c.Log(logger.LevelDebug, "upload for file %#v denied by pre action: %v", requestPath, err)
+		return nil, c.GetPermissionDeniedError()
+	}
 
 	if common.Config.IsAtomicUploadEnabled() && fs.IsAtomicUploadSupported() {
 		err = fs.Rename(resolvedPath, filePath)

+ 6 - 5
sftpd/handler.go

@@ -361,12 +361,8 @@ func (c *Connection) handleSFTPUploadToExistingFile(fs vfs.Fs, pflags sftp.FileO
 		c.Log(logger.LevelInfo, "denying file write due to quota limits")
 		return nil, sftp.ErrSSHFxFailure
 	}
-	osFlags := getOSOpenFlags(pflags)
-	if err := common.ExecutePreAction(&c.User, common.OperationPreUpload, resolvedPath, requestPath, c.GetProtocol(), fileSize, osFlags); err != nil {
-		c.Log(logger.LevelDebug, "upload for file %#v denied by pre action: %v", requestPath, err)
-		return nil, c.GetPermissionDeniedError()
-	}
 
+	osFlags := getOSOpenFlags(pflags)
 	minWriteOffset := int64(0)
 	isTruncate := osFlags&os.O_TRUNC != 0
 	// for upload resumes OpenSSH sets the APPEND flag while WinSCP does not set it,
@@ -381,6 +377,11 @@ func (c *Connection) handleSFTPUploadToExistingFile(fs vfs.Fs, pflags sftp.FileO
 		return nil, err
 	}
 
+	if err := common.ExecutePreAction(&c.User, common.OperationPreUpload, resolvedPath, requestPath, c.GetProtocol(), fileSize, osFlags); err != nil {
+		c.Log(logger.LevelDebug, "upload for file %#v denied by pre action: %v", requestPath, err)
+		return nil, c.GetPermissionDeniedError()
+	}
+
 	if common.Config.IsAtomicUploadEnabled() && fs.IsAtomicUploadSupported() {
 		err = fs.Rename(resolvedPath, filePath)
 		if err != nil {