mirror of
https://github.com/gotenberg/gotenberg.git
synced 2026-08-08 00:22:14 +01:00
fix(pdgengines): encrypt behavior accross different engines
This commit is contained in:
2
Makefile
2
Makefile
@@ -62,6 +62,7 @@ PDFENGINES_FLATTEN_ENGINES=qpdf
|
||||
PDFENGINES_CONVERT_ENGINES=libreoffice-pdfengine
|
||||
PDFENGINES_READ_METADATA_ENGINES=exiftool
|
||||
PDFENGINES_WRITE_METADATA_ENGINES=exiftool
|
||||
PDFENGINES_ENCRYPT_ENGINES=qpdf,pdfcpu,pdftk
|
||||
PDFENGINES_DISABLE_ROUTES=false
|
||||
PROMETHEUS_NAMESPACE=gotenberg
|
||||
PROMETHEUS_COLLECT_INTERVAL=1s
|
||||
@@ -136,6 +137,7 @@ run: ## Start a Gotenberg container
|
||||
--pdfengines-convert-engines=$(PDFENGINES_CONVERT_ENGINES) \
|
||||
--pdfengines-read-metadata-engines=$(PDFENGINES_READ_METADATA_ENGINES) \
|
||||
--pdfengines-write-metadata-engines=$(PDFENGINES_WRITE_METADATA_ENGINES) \
|
||||
--pdfengines-encrypt-engines=$(PDFENGINES_ENCRYPT_ENGINES) \
|
||||
--pdfengines-disable-routes=$(PDFENGINES_DISABLE_ROUTES) \
|
||||
--prometheus-namespace=$(PROMETHEUS_NAMESPACE) \
|
||||
--prometheus-collect-interval=$(PROMETHEUS_COLLECT_INTERVAL) \
|
||||
|
||||
@@ -27,6 +27,10 @@ var (
|
||||
// ErrPdfEncryptionNotSupported is returned when encryption
|
||||
// is not supported by the PDF engine.
|
||||
ErrPdfEncryptionNotSupported = errors.New("encryption not supported")
|
||||
|
||||
// ErrPdfEngineEncryptionPasswordsNotSupported is returned when provided
|
||||
// passwords are not supported by the PDF engine.
|
||||
ErrPdfEngineEncryptionPasswordsNotSupported = errors.New("passwords not supported")
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -270,6 +270,16 @@ func EncryptPdfStub(ctx *api.Context, engine gotenberg.PdfEngine, userPassword,
|
||||
for _, inputPath := range inputPaths {
|
||||
err := engine.Encrypt(ctx, ctx.Log(), inputPath, userPassword, ownerPassword)
|
||||
if err != nil {
|
||||
if errors.Is(err, gotenberg.ErrPdfEngineEncryptionPasswordsNotSupported) {
|
||||
return api.WrapError(
|
||||
err,
|
||||
api.NewSentinelHttpError(
|
||||
http.StatusBadRequest,
|
||||
"Invalid form data: both 'userPassword' and 'ownerPassword' form fields must be provided and different",
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
return fmt.Errorf("encrypt PDF '%s': %w", inputPath, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,13 +151,16 @@ func (engine *PdfTk) Encrypt(ctx context.Context, logger *zap.Logger, inputPath,
|
||||
return errors.New("user password cannot be empty")
|
||||
}
|
||||
|
||||
if ownerPassword == "" {
|
||||
ownerPassword = userPassword
|
||||
if ownerPassword == userPassword || ownerPassword == "" {
|
||||
return gotenberg.ErrPdfEngineEncryptionPasswordsNotSupported
|
||||
}
|
||||
|
||||
// Create a temp output file in the same directory.
|
||||
tmpPath := inputPath + ".tmp"
|
||||
|
||||
var args []string
|
||||
args = append(args, inputPath)
|
||||
args = append(args, "output", inputPath)
|
||||
args = append(args, "output", tmpPath)
|
||||
args = append(args, "encrypt_128bit")
|
||||
args = append(args, "user_pw", userPassword)
|
||||
args = append(args, "owner_pw", ownerPassword)
|
||||
@@ -172,6 +175,11 @@ func (engine *PdfTk) Encrypt(ctx context.Context, logger *zap.Logger, inputPath,
|
||||
return fmt.Errorf("encrypt PDF with PDFtk: %w", err)
|
||||
}
|
||||
|
||||
err = os.Rename(tmpPath, inputPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("rename temporary output file with input file: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -185,8 +185,8 @@ func (engine *QPdf) Encrypt(ctx context.Context, logger *zap.Logger, inputPath,
|
||||
var args []string
|
||||
args = append(args, inputPath)
|
||||
args = append(args, engine.globalArgs...)
|
||||
args = append(args, "--encrypt", userPassword, ownerPassword, "256", "--use-aes=y", "--")
|
||||
args = append(args, inputPath)
|
||||
args = append(args, "--replace-input")
|
||||
args = append(args, "--encrypt", userPassword, ownerPassword, "256", "--")
|
||||
|
||||
cmd, err := gotenberg.CommandContext(ctx, logger, engine.binPath, args...)
|
||||
if err != nil {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Feature: /forms/pdfengines/encrypt
|
||||
|
||||
Scenario: POST /forms/pdfengines/encrypt (default - QPDF - user password only)
|
||||
Scenario: POST /forms/pdfengines/encrypt (default - user password only)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/encrypt" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
@@ -10,7 +10,31 @@ Feature: /forms/pdfengines/encrypt
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then the response PDF(s) should be encrypted
|
||||
|
||||
Scenario: POST /forms/pdfengines/encrypt (default - QPDF - both user and owner passwords)
|
||||
Scenario: POST /forms/pdfengines/encrypt (default - both user and owner passwords)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/encrypt" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| userPassword | foo | field |
|
||||
| ownerPassword | bar | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then the response PDF(s) should be encrypted
|
||||
|
||||
Scenario: POST /forms/pdfengines/encrypt (QPDF - user password only)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| PDFENGINES_ENCRYPT_ENGINES | qpdf |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/encrypt" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| userPassword | foo | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then the response PDF(s) should be encrypted
|
||||
|
||||
Scenario: POST /forms/pdfengines/encrypt (QPDF - both user and owner passwords)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| PDFENGINES_ENCRYPT_ENGINES | qpdf |
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/encrypt" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
@@ -23,18 +47,19 @@ Feature: /forms/pdfengines/encrypt
|
||||
|
||||
Scenario: POST /forms/pdfengines/encrypt (PDFtk - user password only)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| PDFENGINES_PASSWORD_ENGINES | pdftk |
|
||||
| PDFENGINES_ENCRYPT_ENGINES | pdftk |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/encrypt" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| userPassword | foo | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then the response PDF(s) should be encrypted
|
||||
Then the response status code should be 400
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: both 'userPassword' and 'ownerPassword' form fields must be provided and different
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/pdfengines/encrypt (PDFtk - both user and owner passwords)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| PDFENGINES_PASSWORD_ENGINES | pdftk |
|
||||
| PDFENGINES_ENCRYPT_ENGINES | pdftk |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/encrypt" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| userPassword | foo | field |
|
||||
@@ -46,7 +71,7 @@ Feature: /forms/pdfengines/encrypt
|
||||
|
||||
Scenario: POST /forms/pdfengines/encrypt (pdfcpu - user password only)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| PDFENGINES_PASSWORD_ENGINES | pdfcpu |
|
||||
| PDFENGINES_ENCRYPT_ENGINES | pdfcpu |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/encrypt" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| userPassword | foo | field |
|
||||
@@ -57,7 +82,7 @@ Feature: /forms/pdfengines/encrypt
|
||||
|
||||
Scenario: POST /forms/pdfengines/encrypt (pdfcpu - both user and owner passwords)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| PDFENGINES_PASSWORD_ENGINES | pdfcpu |
|
||||
| PDFENGINES_ENCRYPT_ENGINES | pdfcpu |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/encrypt" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| userPassword | foo | field |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Feature: /forms/pdfengines/merge
|
||||
|
||||
Scenario: POST /forms/pdfengines/merge (default - QPDF)
|
||||
Scenario: POST /forms/pdfengines/merge (default)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/merge" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
@@ -21,6 +21,28 @@ Feature: /forms/pdfengines/merge
|
||||
Page 2
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/pdfengines/merge (QPDF)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| PDFENGINES_MERGE_ENGINES | qpdf |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/merge" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| files | testdata/page_2.pdf | file |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 2 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "foo.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/pdfengines/merge (pdfcpu)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| PDFENGINES_MERGE_ENGINES | pdfcpu |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Feature: /forms/pdfengines/split
|
||||
|
||||
Scenario: POST /forms/pdfengines/split (Intervals - Default - pdfcpu)
|
||||
Scenario: POST /forms/pdfengines/split (Intervals - Default)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/split" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.pdf | file |
|
||||
@@ -27,7 +27,7 @@ Feature: /forms/pdfengines/split
|
||||
Page 3
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/pdfengines/split (Pages - Default - pdfcpu)
|
||||
Scenario: POST /forms/pdfengines/split (Pages - Default)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/split" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.pdf | file |
|
||||
@@ -50,7 +50,7 @@ Feature: /forms/pdfengines/split
|
||||
Page 3
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/pdfengines/split (Pages & Unify - Default - pdfcpu)
|
||||
Scenario: POST /forms/pdfengines/split (Pages & Unify - Default)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/split" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.pdf | file |
|
||||
@@ -72,6 +72,81 @@ Feature: /forms/pdfengines/split
|
||||
Page 3
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/pdfengines/split (Intervals - pdfcpu)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| PDFENGINES_SPLIT_ENGINES | pdfcpu |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/split" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.pdf | file |
|
||||
| splitMode | intervals | field |
|
||||
| splitSpan | 2 | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
Then there should be 2 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| pages_3_0.pdf |
|
||||
| pages_3_1.pdf |
|
||||
Then the "pages_3_0.pdf" PDF should have 2 page(s)
|
||||
Then the "pages_3_1.pdf" PDF should have 1 page(s)
|
||||
Then the "pages_3_0.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "pages_3_0.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the "pages_3_1.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/pdfengines/split (Pages - pdfcpu)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| PDFENGINES_SPLIT_ENGINES | pdfcpu |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/split" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.pdf | file |
|
||||
| splitMode | pages | field |
|
||||
| splitSpan | 2- | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
Then there should be 2 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| pages_3_0.pdf |
|
||||
| pages_3_1.pdf |
|
||||
Then the "pages_3_0.pdf" PDF should have 1 page(s)
|
||||
Then the "pages_3_1.pdf" PDF should have 1 page(s)
|
||||
Then the "pages_3_0.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the "pages_3_1.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/pdfengines/split (Pages & Unify - pdfcpu)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| PDFENGINES_SPLIT_ENGINES | pdfcpu |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/split" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.pdf | file |
|
||||
| splitMode | pages | field |
|
||||
| splitSpan | 2- | field |
|
||||
| splitUnify | true | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| pages_3.pdf |
|
||||
Then the "pages_3.pdf" PDF should have 2 page(s)
|
||||
Then the "pages_3.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the "pages_3.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/pdfengines/split (Pages & Unify - QPDF)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| PDFENGINES_SPLIT_ENGINES | qpdf |
|
||||
|
||||
Reference in New Issue
Block a user