diff --git a/s3/s3.go b/s3/s3.go
index 3f4cafb9c5b9ea5ab104bafbbedc84dc609730df..dee365b31e3b0a092961352d5de6656c4cc82da1 100644
--- a/s3/s3.go
+++ b/s3/s3.go
@@ -28,14 +28,14 @@ type S3UploadResponse struct {
 }
 
 type S3UploadSettings struct {
-	MimeType                  MIMEType
-	RetrieveSignedUrl         bool
-	ExpiryDuration            *time.Duration // Used to set expiry datetime of download links. NB: does not affect deletion of object from S3 bucket.
-	AddContentDisposition     bool
-	FileName                  string
-	GenerateFileNameFromParts bool   // Whether the file extension needs to be specified. If true, supply FilePrefix and FileExt.
-	FilePrefix                string // Required when GenerateFileNameFromParts is true
-	FileExt                   string // Required when GenerateFileNameFromParts is true
+	MimeType              MIMEType
+	RetrieveSignedUrl     bool
+	ExpiryDuration        *time.Duration // Used to set expiry datetime of download links. NB: does not affect deletion of object from S3 bucket.
+	AddContentDisposition bool
+	FilePath              string
+	FileName              string
+	FileExt               string
+	InsertUUID            bool
 }
 
 // Duration constants
@@ -154,22 +154,39 @@ func (s SessionWithHelpers) UploadWithSettings(data []byte, bucket, fileName str
 
 // UploadWithSettingsRevised can be renamed to UploadWithSettings once original function has been deprecated.
 func (s SessionWithHelpers) UploadWithSettingsRevised(data []byte, bucket string, settings S3UploadSettings) (S3UploadResponse, error) {
-	var fileName, uploadUrl string
+	var fullFileName, uploadUrl string
 
-	if settings.FileName != "" {
-		fileName = settings.FileName
+	uuidString := ""
+	if settings.InsertUUID {
+		uuidString = fmt.Sprintf("_%s", uuid.New().String())
 	}
-	if settings.GenerateFileNameFromParts {
-		fileName = fmt.Sprintf("%s_%s.%s", settings.FilePrefix, uuid.New().String(), settings.FileExt)
+
+	if len(settings.FileExt) > 0 {
+		if settings.FileExt[0] != '.' {
+			settings.FileExt = fmt.Sprintf(".%s", settings.FileExt)
+		}
+	}
+
+	if len(settings.FilePath) > 0 {
+		if settings.FilePath[len(settings.FilePath)-1] != '/' {
+			settings.FilePath = fmt.Sprintf("%s/", settings.FilePath)
+		}
+	}
+
+	fullFileName = fmt.Sprintf("%s%s%s%s", settings.FilePath, settings.FileName, uuidString, settings.FileExt)
+
+	// Uploaded objects require a key
+	if fullFileName == "" {
+		return S3UploadResponse{}, errors.Error("no file name supplied for upload")
 	}
 
 	if settings.MimeType == "" {
-		settings.MimeType = getTypeForFilename(fileName)
+		settings.MimeType = getTypeForFilename(fullFileName)
 	}
 
 	putInput := &s3.PutObjectInput{
 		Bucket:      aws.String(bucket),
-		Key:         aws.String(fileName),
+		Key:         aws.String(fullFileName),
 		ContentType: aws.String(string(settings.MimeType)),
 		Body:        bytes.NewReader(data),
 	}
@@ -187,14 +204,9 @@ func (s SessionWithHelpers) UploadWithSettingsRevised(data []byte, bucket string
 	if settings.RetrieveSignedUrl {
 		var headers map[string]string
 
-		fileNameHeader := fileName
-		if settings.FileName != "" {
-			fileNameHeader = settings.FileName
-		}
-
 		if settings.AddContentDisposition {
 			headers = map[string]string{
-				"content-disposition": "attachment; filename=\"" + fileNameHeader + "\"",
+				"content-disposition": fmt.Sprintf("attachment; filename=\"%s.%s\"", settings.FileName, settings.FileExt),
 			}
 		}
 
@@ -202,7 +214,8 @@ func (s SessionWithHelpers) UploadWithSettingsRevised(data []byte, bucket string
 		if settings.ExpiryDuration != nil {
 			downloadUrlExpiry = *settings.ExpiryDuration
 		}
-		uploadUrl, err = s.GetSignedDownloadURL(bucket, fileName, downloadUrlExpiry, headers)
+
+		uploadUrl, err = s.GetSignedDownloadURL(bucket, fullFileName, downloadUrlExpiry, headers)
 		if err != nil {
 			return S3UploadResponse{}, err
 		}
@@ -213,7 +226,7 @@ func (s SessionWithHelpers) UploadWithSettingsRevised(data []byte, bucket string
 
 	response := S3UploadResponse{
 		URL:      uploadUrl,
-		Filename: fileName,
+		Filename: fullFileName,
 		Bucket:   bucket,
 		FileSize: fileSizeInBytes,
 	}