chore: slight improvement of the encrypt feature to be more in line with others features

This commit is contained in:
Julien Neuhart
2025-05-28 15:21:41 +02:00
parent 99307befdd
commit ba944f9dc2
19 changed files with 318 additions and 797 deletions

View File

@@ -104,7 +104,7 @@ type PdfEngine interface {
// Flatten merges existing annotation appearances with page content,
// effectively deleting the original annotations. This process can flatten
// forms as well, as forms share a relationship with annotations. Note that
// forms as well as forms share a relationship with annotations. Note that
// this operation is irreversible.
Flatten(ctx context.Context, logger *zap.Logger, inputPath string) error

View File

@@ -264,6 +264,11 @@ func convertRoute(libreOffice libreofficeapi.Uno, engine gotenberg.PdfEngine) ap
}
}
err = pdfengines.EncryptPdfStub(ctx, engine, userPassword, ownerPassword, outputPaths)
if err != nil {
return fmt.Errorf("encrypt PDFs: %w", err)
}
if len(outputPaths) > 1 && splitMode == zeroValuedSplitMode {
// If .zip archive, document.docx -> document.docx.pdf.
for i, inputPath := range inputPaths {
@@ -278,11 +283,6 @@ func convertRoute(libreOffice libreofficeapi.Uno, engine gotenberg.PdfEngine) ap
}
}
err = pdfengines.EncryptPdfStub(ctx, engine, userPassword, ownerPassword, outputPaths)
if err != nil {
return fmt.Errorf("encrypt PDFs: %w", err)
}
err = ctx.AddOutputPaths(outputPaths...)
if err != nil {
return fmt.Errorf("add output paths: %w", err)

View File

@@ -177,17 +177,16 @@ func (engine *PdfCpu) Encrypt(ctx context.Context, logger *zap.Logger, inputPath
return errors.New("user password cannot be empty")
}
// If owner password is not provided, use the user password as owner password
if ownerPassword == "" {
ownerPassword = userPassword
}
var args []string
args = append(args, "encrypt")
args = append(args, "-mode", "aes") // Use AES encryption
args = append(args, "-mode", "aes")
args = append(args, "-upw", userPassword)
args = append(args, "-opw", ownerPassword)
args = append(args, "-perm", "all") // Grant all permissions with owner password
args = append(args, "-perm", "all")
args = append(args, inputPath, inputPath)
cmd, err := gotenberg.CommandContext(ctx, logger, engine.binPath, args...)

View File

@@ -41,8 +41,8 @@ func newMultiPdfEngines(
}
}
// Merge tries to merge the given PDFs into a unique PDF thanks to its
// children. If the context is done, it stops and returns an error.
// Merge combines multiple PDF files into a single document using the first
// available engine that supports PDF merging.
func (multi *multiPdfEngines) Merge(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error {
var err error
errChan := make(chan error, 1)
@@ -71,8 +71,8 @@ type splitResult struct {
err error
}
// Split tries to split at intervals a given PDF thanks to its children. If the
// context is done, it stops and returns an error.
// Split divides the PDF into separate pages using the first available engine
// that supports PDF splitting.
func (multi *multiPdfEngines) Split(ctx context.Context, logger *zap.Logger, mode gotenberg.SplitMode, inputPath, outputDirPath string) ([]string, error) {
var err error
var mu sync.Mutex // to safely append errors.
@@ -102,8 +102,8 @@ func (multi *multiPdfEngines) Split(ctx context.Context, logger *zap.Logger, mod
return nil, fmt.Errorf("split PDF with multi PDF engines: %w", err)
}
// Flatten merges existing annotation appearances with page content, thanks to
// its children. If the context is done, it stops and returns an error
// Flatten merges existing annotation appearances with page content using the
// first available engine that supports flattening.
func (multi *multiPdfEngines) Flatten(ctx context.Context, logger *zap.Logger, inputPath string) error {
var err error
errChan := make(chan error, 1)
@@ -127,8 +127,8 @@ func (multi *multiPdfEngines) Flatten(ctx context.Context, logger *zap.Logger, i
return fmt.Errorf("flatten PDF with multi PDF engines: %w", err)
}
// Convert converts the given PDF to a specific PDF format, thanks to its
// children. If the context is done, it stops and returns an error.
// Convert transforms the given PDF to a specific PDF format using the first
// available engine that supports PDF conversion.
func (multi *multiPdfEngines) Convert(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error {
var err error
errChan := make(chan error, 1)
@@ -157,6 +157,8 @@ type readMetadataResult struct {
err error
}
// ReadMetadata extracts metadata from a PDF file using the first available
// engine that supports metadata reading.
func (multi *multiPdfEngines) ReadMetadata(ctx context.Context, logger *zap.Logger, inputPath string) (map[string]interface{}, error) {
var err error
var mu sync.Mutex // to safely append errors.
@@ -186,6 +188,8 @@ func (multi *multiPdfEngines) ReadMetadata(ctx context.Context, logger *zap.Logg
return nil, fmt.Errorf("read PDF metadata with multi PDF engines: %w", err)
}
// WriteMetadata embeds metadata into a PDF file using the first available
// engine that supports metadata writing.
func (multi *multiPdfEngines) WriteMetadata(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error {
var err error
errChan := make(chan error, 1)
@@ -209,8 +213,8 @@ func (multi *multiPdfEngines) WriteMetadata(ctx context.Context, logger *zap.Log
return fmt.Errorf("write PDF metadata with multi PDF engines: %w", err)
}
// Encrypt adds password protection to a PDF file using the first available engine
// that supports password protection.
// Encrypt adds password protection to a PDF file using the first available
// engine that supports password protection.
func (multi *multiPdfEngines) Encrypt(ctx context.Context, logger *zap.Logger, inputPath, userPassword, ownerPassword string) error {
var err error
errChan := make(chan error, 1)

View File

@@ -210,7 +210,7 @@ func (mod *PdfEngines) SystemMessages() []string {
fmt.Sprintf("convert engines - %s", strings.Join(mod.convertNames[:], " ")),
fmt.Sprintf("read metadata engines - %s", strings.Join(mod.readMetadataNames[:], " ")),
fmt.Sprintf("write metadata engines - %s", strings.Join(mod.writeMetadataNames[:], " ")),
fmt.Sprintf("password protection engines - %s", strings.Join(mod.encryptNames[:], " ")),
fmt.Sprintf("encrypt engines - %s", strings.Join(mod.encryptNames[:], " ")),
}
}

View File

@@ -254,7 +254,6 @@ func WriteMetadataStub(ctx *api.Context, engine gotenberg.PdfEngine, metadata ma
return nil
}
// EncryptPdfStub adds password protection to PDF files.
// FormDataPdfEncrypt extracts encryption parameters from form data.
func FormDataPdfEncrypt(form *api.FormData) (userPassword, ownerPassword string) {
form.String("userPassword", &userPassword, "")
@@ -262,6 +261,7 @@ func FormDataPdfEncrypt(form *api.FormData) (userPassword, ownerPassword string)
return userPassword, ownerPassword
}
// EncryptPdfStub adds password protection to PDF files.
func EncryptPdfStub(ctx *api.Context, engine gotenberg.PdfEngine, userPassword, ownerPassword string, inputPaths []string) error {
if userPassword == "" {
return nil
@@ -459,7 +459,6 @@ func convertRoute(engine gotenberg.PdfEngine) api.Route {
form := ctx.FormData()
pdfFormats := FormDataPdfFormats(form)
userPassword, ownerPassword := FormDataPdfEncrypt(form)
var inputPaths []string
err := form.
@@ -496,11 +495,6 @@ func convertRoute(engine gotenberg.PdfEngine) api.Route {
}
}
err = EncryptPdfStub(ctx, engine, userPassword, ownerPassword, outputPaths)
if err != nil {
return fmt.Errorf("encrypt PDFs: %w", err)
}
err = ctx.AddOutputPaths(outputPaths...)
if err != nil {
return fmt.Errorf("add output paths: %w", err)

View File

@@ -151,7 +151,6 @@ func (engine *PdfTk) Encrypt(ctx context.Context, logger *zap.Logger, inputPath,
return errors.New("user password cannot be empty")
}
// If owner password is not provided, use the user password as owner password
if ownerPassword == "" {
ownerPassword = userPassword
}
@@ -160,14 +159,8 @@ func (engine *PdfTk) Encrypt(ctx context.Context, logger *zap.Logger, inputPath,
args = append(args, inputPath)
args = append(args, "output", inputPath)
args = append(args, "encrypt_128bit")
if userPassword != "" {
args = append(args, "user_pw", userPassword)
}
if ownerPassword != "" {
args = append(args, "owner_pw", ownerPassword)
}
args = append(args, "user_pw", userPassword)
args = append(args, "owner_pw", ownerPassword)
cmd, err := gotenberg.CommandContext(ctx, logger, engine.binPath, args...)
if err != nil {

View File

@@ -178,12 +178,10 @@ func (engine *QPdf) Encrypt(ctx context.Context, logger *zap.Logger, inputPath,
return errors.New("user password cannot be empty")
}
// If owner password is not provided, use the user password as owner password
if ownerPassword == "" {
ownerPassword = userPassword
}
// QPDF command to encrypt a PDF
var args []string
args = append(args, inputPath)
args = append(args, engine.globalArgs...)