From 039719eda5a85eaef71c2fc820934ce784daf769 Mon Sep 17 00:00:00 2001 From: Jason Gladish Date: Tue, 15 Nov 2022 19:03:31 -0500 Subject: [PATCH 01/19] Release v3.0.0 --- .review/generated_files/README.md | 6 +++--- CHANGELOG.md | 2 +- README.md | 2 +- build.gradle | 2 +- generator-config.json | 2 +- pom.xml | 2 +- src/main/java/com/docraptor/ApiClient.java | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.review/generated_files/README.md b/.review/generated_files/README.md index 8453a81..d393d3b 100644 --- a/.review/generated_files/README.md +++ b/.review/generated_files/README.md @@ -40,7 +40,7 @@ Add this dependency to your project's POM: com.docraptor docraptor - 2.0.0 + 3.0.0 compile ``` @@ -56,7 +56,7 @@ Add this dependency to your project's build file: } dependencies { - implementation "com.docraptor:docraptor:2.0.0" + implementation "com.docraptor:docraptor:3.0.0" } ``` @@ -70,7 +70,7 @@ mvn clean package Then manually install the following JARs: -- `target/docraptor-2.0.0.jar` +- `target/docraptor-3.0.0.jar` - `target/lib/*.jar` ## Getting Started diff --git a/CHANGELOG.md b/CHANGELOG.md index 9680413..530f708 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -### 3.0.0 [TBD] +### 3.0.0 [November 15, 2022] * Switch API host to more secure api.docraptor.com (dropping old TLS) * Switch from swagger to openapi-generator v6.0.1 (better maintained) * Remove support for java <8 diff --git a/README.md b/README.md index e87376a..eab11eb 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ After the client library is installed/deployed, you can use it in your Maven pro com.docraptor docraptor - 2.0.0 + 3.0.0 ``` diff --git a/build.gradle b/build.gradle index 85b418b..98a5920 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'idea' apply plugin: 'eclipse' group = 'com.docraptor' -version = '2.0.0' +version = '3.0.0' buildscript { repositories { diff --git a/generator-config.json b/generator-config.json index 6008146..6089c43 100644 --- a/generator-config.json +++ b/generator-config.json @@ -4,7 +4,7 @@ "apiPackage": "com.docraptor", "groupId": "com.docraptor", "artifactId": "docraptor", - "artifactVersion": "2.0.0", + "artifactVersion": "3.0.0", "artifactUrl": "https://github.com/DocRaptor/docraptor-java", "artifactDescription": "A native client library for the DocRaptor HTML to PDF/XLS service.", "scmConnection": "scm:git:git@github.com:DocRaptor/docraptor-java.git", diff --git a/pom.xml b/pom.xml index 18b7b0a..6c7bdb0 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ docraptor jar docraptor - 2.0.0 + 3.0.0 https://github.com/DocRaptor/docraptor-java A native client library for the DocRaptor HTML to PDF/XLS service. diff --git a/src/main/java/com/docraptor/ApiClient.java b/src/main/java/com/docraptor/ApiClient.java index 3772fe3..d17cd02 100644 --- a/src/main/java/com/docraptor/ApiClient.java +++ b/src/main/java/com/docraptor/ApiClient.java @@ -98,7 +98,7 @@ public ApiClient() { dateFormat = ApiClient.buildDefaultDateFormat(); // Set default User-Agent. - setUserAgent("OpenAPI-Generator/2.0.0/java"); + setUserAgent("OpenAPI-Generator/3.0.0/java"); // Setup authentications (key: authentication name, value: authentication). authentications = new HashMap(); From 7ccaab3c86c432b54fbbdbc79255bf68f9082930 Mon Sep 17 00:00:00 2001 From: Jason Gladish Date: Wed, 16 Nov 2022 18:32:31 -0500 Subject: [PATCH 02/19] Fix release issue with nexus-staging-maven-plugin Why is this change needed? -------------------------- The generated pom.xml doesn't include this plugin, and it is necessary to publish the finished package. Because it's a big XML file it's not very obvious that it gets removed on generation. We want the rest of the generated file so we get reasonable dependency version updates. How does it address the issue? ------------------------------ This commit adds the plugin back, which allows `mvn clean deploy -P sign-artifacts` to work. This is slightly different than the previous `mvn clean deploy` because the generated file moved artifact signing into a different profile, in theory to keep most tasks faster. `-P sign-artifacts` tell maven to apply the `sign-artifacts` profile, which augments the deafult profile. This plugin is added to the default profile in case the gpg plugin is moved to the default profile in the future (then we could remove the `-P sign-artifacts` above). At the moment, though, it doesn't really matter. The next commit will add an automatically applied patch after client gneration that will reapply this change when necessary. This will help by handling the situation automatically, or failing that complain that the patch can't be applied which will indicate to the user that things have changed and roughly what needs to happen next (fix and apply the patch). The generated code seems to have some support to publishing to maven using grandle, but it didn't seem to just work out of the box so this commit preserves the previous behavior. In the future it might be worth attempting to get closer to the golden path by switching to gradle. Any links to any relevant tickets, articles, or other resources? --------------------------------------------------------------- https://central.sonatype.org/publish/publish-guide/#initial-setup https://central.sonatype.org/publish/publish-maven/#nexus-staging-maven-plugin-for-deployment-and-release https://books.sonatype.com/mvnref-book/reference/profiles-sect-maven-profiles.html https://stackoverflow.com/questions/31740785/why-order-of-maven-dependencies-matter Any screenshots? ---------------- Did you complete all of the following? -------------------------------------- - Run test suite? - Add new tests? - Consider security implications and practices? --- pom.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pom.xml b/pom.xml index 6c7bdb0..f918a1c 100644 --- a/pom.xml +++ b/pom.xml @@ -179,6 +179,17 @@ + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.8 + true + + ossrh + https://oss.sonatype.org/ + true + + From db6cf1ca96b68b1d2964dd4598fd272fb4d2f7da Mon Sep 17 00:00:00 2001 From: Jason Gladish Date: Wed, 16 Nov 2022 19:08:58 -0500 Subject: [PATCH 03/19] Add patch to fix publishing issue in the future Why is this change needed? -------------------------- See the patch or the previous commit for the details. How does it address the issue? ------------------------------ This encapsulates the change that is needed after each client generation to allow publishing. Any links to any relevant tickets, articles, or other resources? --------------------------------------------------------------- Any screenshots? ---------------- Did you complete all of the following? -------------------------------------- - Run test suite? - Add new tests? - Consider security implications and practices? --- patches/01_add_maven_publishing_plugin.patch | 77 ++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 patches/01_add_maven_publishing_plugin.patch diff --git a/patches/01_add_maven_publishing_plugin.patch b/patches/01_add_maven_publishing_plugin.patch new file mode 100644 index 0000000..c6d418e --- /dev/null +++ b/patches/01_add_maven_publishing_plugin.patch @@ -0,0 +1,77 @@ +commit 7ccaab3c86c432b54fbbdbc79255bf68f9082930 +Author: Jason Gladish +Date: Wed Nov 16 18:32:31 2022 -0500 + + Fix release issue with nexus-staging-maven-plugin + + Why is this change needed? + -------------------------- + The generated pom.xml doesn't include this plugin, and it is necessary + to publish the finished package. Because it's a big XML file it's not + very obvious that it gets removed on generation. We want the rest of the + generated file so we get reasonable dependency version updates. + + How does it address the issue? + ------------------------------ + This commit adds the plugin back, which allows + `mvn clean deploy -P sign-artifacts` to work. This is slightly different + than the previous `mvn clean deploy` because the generated file moved + artifact signing into a different profile, in theory to keep most tasks + faster. `-P sign-artifacts` tell maven to apply the `sign-artifacts` + profile, which augments the deafult profile. + + This plugin is added to the default profile in case the gpg plugin is + moved to the default profile in the future (then we could remove the + `-P sign-artifacts` above). At the moment, though, it doesn't really + matter. + + The next commit will add an automatically applied patch after client + gneration that will reapply this change when necessary. This will help + by handling the situation automatically, or failing that complain that + the patch can't be applied which will indicate to the user that things + have changed and roughly what needs to happen next (fix and apply the + patch). + + The generated code seems to have some support to publishing to maven + using grandle, but it didn't seem to just work out of the box so this + commit preserves the previous behavior. In the future it might be worth + attempting to get closer to the golden path by switching to gradle. + + Any links to any relevant tickets, articles, or other resources? + --------------------------------------------------------------- + https://central.sonatype.org/publish/publish-guide/#initial-setup + https://central.sonatype.org/publish/publish-maven/#nexus-staging-maven-plugin-for-deployment-and-release + https://books.sonatype.com/mvnref-book/reference/profiles-sect-maven-profiles.html + https://stackoverflow.com/questions/31740785/why-order-of-maven-dependencies-matter + + Any screenshots? + ---------------- + + Did you complete all of the following? + -------------------------------------- + - Run test suite? + - Add new tests? + - Consider security implications and practices? + +diff --git a/pom.xml b/pom.xml +index 6c7bdb0..f918a1c 100644 +--- a/pom.xml ++++ b/pom.xml +@@ -179,6 +179,17 @@ + + + ++ ++ org.sonatype.plugins ++ nexus-staging-maven-plugin ++ 1.6.8 ++ true ++ ++ ossrh ++ https://oss.sonatype.org/ ++ true ++ ++ + + + From 0d034769b21e2878b0112d64c8e3e49e8914d811 Mon Sep 17 00:00:00 2001 From: Jason Gladish Date: Wed, 16 Nov 2022 19:10:21 -0500 Subject: [PATCH 04/19] Improve release process Why is this change needed? -------------------------- Ideally releasing uses docker to prevent environment issues. How does it address the issue? ------------------------------ Add `script/release` to allowing scripting the process. This includes facilitating the setup of a gpg key for maven publishing. This whole process has been difficult to remember and execute correctly every time, so this scripts as much as is reasonable to help the developer along. Any links to any relevant tickets, articles, or other resources? --------------------------------------------------------------- https://3.basecamp.com/3093825/buckets/29124557/todos/5284412189 https://3.basecamp.com/3093825/buckets/29124557/todos/5284421778 https://stackoverflow.com/questions/57591432/gpg-signing-failed-inappropriate-ioctl-for-device-on-macos-with-maven https://www.gnupg.org/documentation/manuals/gnupg/GPG-Configuration.html https://github.com/keybase/keybase-issues/issues/2798 https://askubuntu.com/questions/29889/how-do-i-check-if-my-openpgp-key-is-in-the-ubuntu-keyserver https://stackoverflow.com/questions/51504367/gpg-agent-forwarding-inappropriate-ioctl-for-device https://superuser.com/questions/1150165/get-list-of-secret-key-ids https://serverfault.com/questions/691120/how-to-generate-gpg-key-without-user-interaction Any screenshots? ---------------- Did you complete all of the following? -------------------------------------- - Run test suite? - Add new tests? - Consider security implications and practices? --- .docker_env.list | 1 + README.md | 11 ++--- RELEASE_SETUP.md | 22 +++++++--- script/docker | 5 +++ script/release | 111 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 138 insertions(+), 12 deletions(-) create mode 100755 script/release diff --git a/.docker_env.list b/.docker_env.list index 291bd70..f79b976 100644 --- a/.docker_env.list +++ b/.docker_env.list @@ -1,2 +1,3 @@ TRACE TEST_OUTPUT_DIR=/app/tmp/test_output +INSIDE_DOCKER=true diff --git a/README.md b/README.md index eab11eb..3a1a8e2 100644 --- a/README.md +++ b/README.md @@ -109,13 +109,10 @@ If you haven't released before, please see the [release setup guide](RELEASE_SET 7. Commit "Release vX.Y.Z" 8. Push to GitHub 9. Tag version: `git tag 'vX.Y.Z' && git push --tags` -10. `eval $(gpg-agent --daemon)` -11. `gpg --use-agent --armor --detach-sign` and press ^C after authenticating - - if you run into issues with gpg [this](https://stackoverflow.com/questions/57591432/gpg-signing-failed-inappropriate-ioctl-for-device-on-macos-with-maven) might help -12. `mvn clean deploy` -13. Verify package release at [Central](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.docraptor%22%20AND%20a%3A%22docraptor%22) (takes anywhere from minutes to days) -14. Use the git tag and make a new release with `target/docraptor-*` attached, https://github.com/DocRaptor/docraptor-java/tags -15. Refresh documentation on docraptor.com +10. `script/release` +11. Verify package release at [Central](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.docraptor%22%20AND%20a%3A%22docraptor%22) (takes anywhere from minutes to days) +12. Open https://github.com/DocRaptor/docraptor-java/tags and make a new release for the version. Use the git tag as the name, CHANGELOG entries as the description, and attach `target/docraptor-*` to the release +13. Refresh documentation on docraptor.com ## Version Policy diff --git a/RELEASE_SETUP.md b/RELEASE_SETUP.md index 548d3a3..bc469fb 100644 --- a/RELEASE_SETUP.md +++ b/RELEASE_SETUP.md @@ -1,15 +1,23 @@ If you haven't released this package before, there are a few things you'll need to do ## Create a GPG key + +`script/release` should handle this for you, but if you run into trouble +read more. + `brew install gpg2` Use [this guide](http://central.sonatype.org/pages/working-with-pgp-signatures.html) for generating a key. ## Publish your public key to several key servers +`script/release` should handle this for you, but if you run into trouble +read more. Note you may get a verification email for keys.openpgp.org and you +may need to click the link in that email. + Get your key id `gpg2 --list-keys` (looks something like `453D1C92`) -- `gpg2 --keyserver hkp://pool.sks-keyservers.net --send-keys KEY_ID` +- `gpg --keyserver keys.openpgp.org --send-keys KEY_ID` - `gpg --keyserver keyserver.ubuntu.com --send-keys KEY_ID` - `gpg --keyserver pgp.mit.edu --send-keys KEY_ID` @@ -17,10 +25,14 @@ Then verify that your key is on one of those servers by looking on those servers - http://pgp.mit.edu/ - http://keyserver.ubuntu.com/ -- https://sks-keyservers.net/i/ +- https://keys.openpgp.org/ ## Sign up for Sonatype jira account at https://issues.sonatype.org -## Put those Sonatype credentials in ~/.m2/settings.xml + +`script/release` should handle this for you, but if you run into trouble +read more. + +Put those Sonatype credentials in ~/.m2/settings.xml it will look like ``` @@ -28,8 +40,8 @@ it will look like ossrh - divanov-oss.sonatype.org-account - divanov-oss.sonatype.org-password + YOUR_USERNAME + YOUR_PASSWORD diff --git a/script/docker b/script/docker index 49d6fbe..1bb2ccc 100755 --- a/script/docker +++ b/script/docker @@ -36,11 +36,16 @@ command="$1" cache_dir="$(pwd)/tmp/cache_${image}" mkdir -p "$cache_dir" +dr_gpg_home="${HOME}/.gnupg/docraptor" +mkdir -p "$dr_gpg_home" +chmod -R 700 "$(dirname "$dr_gpg_home")" + set -x docker run -it --rm \ --env-file .docker_env.list \ --env RUNTIME_ENV="${image}" \ --mount type=bind,source="$(pwd)",target=/app \ + --mount type=bind,source="$dr_gpg_home",target=/root/.gnupg \ --mount type=bind,source="${cache_dir}",target=/app/tmp/cache \ "$image" \ "$command" diff --git a/script/release b/script/release new file mode 100755 index 0000000..ab2d035 --- /dev/null +++ b/script/release @@ -0,0 +1,111 @@ +#!/bin/bash +set -e +[[ "$TRACE" == "true" ]] && set -x +cd "$(dirname "$0")/.." + +if [[ "$INSIDE_DOCKER" != "true" ]]; then + exec script/docker "/app/script/$(basename "$0")" +fi + +maven_settings_path="tmp/settings.xml" +if ! [ -f "$maven_settings_path" ]; then + echo "If you haven't already, you need to sign up for a Sonatype jira account" + echo "at https://issues.sonatype.org" + echo "Storing jira login information for maven publishing..." + read -p "Username: " username + read -s -p "Password: " password + echo + echo + cat >"$maven_settings_path" < + + + ossrh + ${username} + ${password} + + + +EOF +fi + +echo "Moving maven $maven_settings_path into place..." +mkdir -pv ~/.m2 +cp -vb "$maven_settings_path" ~/.m2/"$(basename "$maven_settings_path")" +echo "Moved." +echo + +echo "Installing gpg-agent..." +apt-get update +DEBIAN_FRONTEND=noninteractive apt-get install -qq gpg-agent +echo "gpg-agent installed." +echo + +if [[ "$(gpg --list-keys)" == "" ]]; then + + echo "Collecting information for new gpg key used for maven publishing..." + read -p "Enter your first and last name: " name + read -p "Enter your email address: " email + + cat >tmp/keydetails < /dev/null` because we don't actually care about the +# signature output. This whole exercise is just to make sure the key is +# decrypted in the agent so mvn can sign files below. +export GPG_TTY=$(tty) +echo | gpg --use-agent --armor --detach-sign > /dev/null +echo "GPG key unlocked." +echo + +echo "Releasing..." +mvn clean deploy -P sign-artifacts +echo "Released." +echo From b8912f1d53c8dfab7e0459ff92688f1fec04b65b Mon Sep 17 00:00:00 2001 From: Jason Gladish Date: Thu, 1 Jun 2023 19:54:25 -0400 Subject: [PATCH 05/19] Refactor volume mounting be configurable via a file Why is this change needed? -------------------------- Different clients have different requirements. Ruby needs ssh to publish a release because it needs to connect to github. This should support whatever the client needs. How does it address the issue? ------------------------------ This moves the magic ssh configuration into the file with the rest of the volume info. We need to jump through a few hoops because the cache dir has a colon in it, and that's the field separator for docker `--volume` mounts. We need `--volume` instead of `--mount` because the ssh magic path needs `--volume`. We do some eval so we can replace the colon with an underscore in the volume list. Any links to any relevant tickets, articles, or other resources? --------------------------------------------------------------- https://3.basecamp.com/3093825/buckets/29007795/todolists/5257298552 https://gist.github.com/d11wtq/8699521 Did you complete all of the following? -------------------------------------- - Run test suite? - Add new tests? - Consider security implications and practices? --- .docker_mounts.list | 4 ++++ script/docker | 19 ++++++++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) create mode 100644 .docker_mounts.list diff --git a/.docker_mounts.list b/.docker_mounts.list new file mode 100644 index 0000000..7fb6f8d --- /dev/null +++ b/.docker_mounts.list @@ -0,0 +1,4 @@ +# Specify mounts in `docker run --volume` format (source:target). Bash +# expressions will be evaluated. +# $(pwd)/tmp/cache_${image//:/_}:/app/tmp/cache +${HOME}/.gnupg/docraptor:/root/.gnupg diff --git a/script/docker b/script/docker index 1bb2ccc..082f968 100755 --- a/script/docker +++ b/script/docker @@ -1,6 +1,7 @@ #!/bin/bash set -e cd "$(dirname "$0")/.." +[[ "$TRACE" == "true" ]] && set -x OPTIND=1 @@ -33,19 +34,23 @@ fi command="$1" -cache_dir="$(pwd)/tmp/cache_${image}" -mkdir -p "$cache_dir" +mounts=() +while IFS=':' read -r source target; do + # Create the directory if it's not a special/magic path (like for ssh) + mkdir -p -m 700 "$source" &> /dev/null || true -dr_gpg_home="${HOME}/.gnupg/docraptor" -mkdir -p "$dr_gpg_home" -chmod -R 700 "$(dirname "$dr_gpg_home")" + mounts+=(--volume) + mounts+=("${source}:${target}") + + # Can't pipe to the while loop because that causes a subshell, which means + # the variables set in the loop aren't available outside of it. +done < <(eval echo "\"$(grep -v '^#' .docker_mounts.list)\"") set -x docker run -it --rm \ --env-file .docker_env.list \ --env RUNTIME_ENV="${image}" \ --mount type=bind,source="$(pwd)",target=/app \ - --mount type=bind,source="$dr_gpg_home",target=/root/.gnupg \ - --mount type=bind,source="${cache_dir}",target=/app/tmp/cache \ + "${mounts[@]}" \ "$image" \ "$command" From 2cc50ea6ba52745a922a6d79dc4f22eb3f61e610 Mon Sep 17 00:00:00 2001 From: Jason Gladish Date: Thu, 1 Jun 2023 20:35:38 -0400 Subject: [PATCH 06/19] Switch to more explicit docker detection Why is this change needed? -------------------------- I believe I had an issue with one of the clients where the previous check was ambiguous inside the container. In any case this is more explicit. How does it address the issue? ------------------------------ Use the INSIDE_DOCKER env var from .docker_env.list to determine if we are inside the container. Any links to any relevant tickets, articles, or other resources? --------------------------------------------------------------- https://3.basecamp.com/3093825/buckets/29007795/todolists/5257298600 Did you complete all of the following? -------------------------------------- - Run test suite? - Add new tests? - Consider security implications and practices? --- script/build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/build b/script/build index 1844ca5..08340fd 100755 --- a/script/build +++ b/script/build @@ -7,7 +7,7 @@ if [[ `ls target/*.jar` ]] && [ "$1" == "lazy" ]; then exit fi -if uname | grep Darwin; then +if [[ "$INSIDE_DOCKER" != "true" ]]; then exec script/docker /app/script/build fi From 136f58b7d0c48f79d5e9fa4973aca2db8efaa1f3 Mon Sep 17 00:00:00 2001 From: Jason Gladish Date: Thu, 1 Jun 2023 21:31:15 -0400 Subject: [PATCH 07/19] Standardize tracing across clients Why is this change needed? -------------------------- Tracing is helpful for debugging, so let's apply it consistently across clients. How does it address the issue? ------------------------------ Add a TRACE flag to the top of each script. Any links to any relevant tickets, articles, or other resources? --------------------------------------------------------------- https://3.basecamp.com/3093825/buckets/29007795/todolists/5257298600 Did you complete all of the following? -------------------------------------- - Run test suite? - Add new tests? - Consider security implications and practices? --- script/docker | 2 +- script/generate_language | 1 + script/post_generate_language | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/script/docker b/script/docker index 082f968..fef2769 100755 --- a/script/docker +++ b/script/docker @@ -1,7 +1,7 @@ #!/bin/bash set -e -cd "$(dirname "$0")/.." [[ "$TRACE" == "true" ]] && set -x +cd "$(dirname "$0")/.." OPTIND=1 diff --git a/script/generate_language b/script/generate_language index 9221df1..abb31cb 100755 --- a/script/generate_language +++ b/script/generate_language @@ -1,5 +1,6 @@ #!/bin/bash set -e +[[ "$TRACE" == "true" ]] && set -x cd "$(dirname "$0")/.." LANGUAGE="$(cat .generator-language-identifier)" diff --git a/script/post_generate_language b/script/post_generate_language index ab1acfe..fb5ea90 100755 --- a/script/post_generate_language +++ b/script/post_generate_language @@ -1,5 +1,6 @@ #!/bin/bash set -e +[[ "$TRACE" == "true" ]] && set -x cd "$(dirname "$0")/.." echo "Removing autogenerated tests..." From 844179dd6e1d7cd640fb082f927996e42db9a218 Mon Sep 17 00:00:00 2001 From: Jason Gladish Date: Thu, 1 Jun 2023 21:54:23 -0400 Subject: [PATCH 08/19] Improve generated file review Why is this change needed? -------------------------- Reviewing generated files can let us know when there are important changes. Ideally we can review files that aren't overriding files of our own in case they contain important changes as well. How does it address the issue? ------------------------------ This change allows us to add files to the .review directory that we generally don't want to keep in the repo. Things like the generated docs that usually aren't super useful, but might contain important changes. Any links to any relevant tickets, articles, or other resources? --------------------------------------------------------------- https://3.basecamp.com/3093825/buckets/29007795/todolists/5257298600 Did you complete all of the following? -------------------------------------- - Run test suite? - Add new tests? - Consider security implications and practices? --- script/generate_language | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/script/generate_language b/script/generate_language index abb31cb..42b637d 100755 --- a/script/generate_language +++ b/script/generate_language @@ -23,10 +23,18 @@ fi echo "Facilitating generated content review" tmp_dir=".review/tmp" review_root=".review/generated_files" +# Clear the tmp_dir, where we'll temporarily store our files so they aren't +# overwritten by the generated files. rm -rf "$tmp_dir" (cd "$review_root" && find . -type f) | while read file_path; do - mkdir -p "$(dirname "${tmp_dir}/$file_path")" - mv -v "$file_path" "${tmp_dir}/$file_path" + # Move our file out of the way so it doesn't get overwritten by the generated + # file, but only if the file exists. Some files, like the generated docs and + # tests, aren't useful to users to we generally remove them, but we still + # want to facilitate review of these generated files. + if [ -e "$file_path" ]; then + mkdir -p "$(dirname "${tmp_dir}/$file_path")" + mv -v "$file_path" "${tmp_dir}/$file_path" + fi done ./script/swagger generate \ @@ -42,6 +50,19 @@ fi # See .review/README.md echo "Facilitating generated content review" (cd "$review_root" && find . -type f) | while read file_path; do - mv -v "$file_path" "$review_root/$file_path" - mv -v "${tmp_dir}/$file_path" "$file_path" + # Update $review_root to match the generated files. + if [ -e "$file_path" ]; then + # Move the newly generated file into the review directory so we'll be able to + # see it in the diff. + mv -v "$file_path" "$review_root/$file_path" + else + # If the file doesn't exist, then it was removed by the generator, so we + # should remove it from the review directory as well. + rm -v "$review_root/$file_path" + fi + # If we temporarily stored a file (meaning it existed before the generation) + # then move it back into place. + if [ -e "${tmp_dir}/$file_path" ]; then + mv -v "${tmp_dir}/$file_path" "$file_path" + fi done From 458eb23f80ca96674a67604cb375739cfbde4a98 Mon Sep 17 00:00:00 2001 From: Jason Gladish Date: Fri, 2 Jun 2023 18:28:08 -0400 Subject: [PATCH 09/19] Improve generated file review Why is this change needed? -------------------------- These files might have useful changes that we want to review. How does it address the issue? ------------------------------ Don't remove these since we'll want to review the diffs between the old and new versions to see if we should make any updates to non-generated code. Any links to any relevant tickets, articles, or other resources? --------------------------------------------------------------- https://3.basecamp.com/3093825/buckets/29007795/todolists/5257298600 Did you complete all of the following? -------------------------------------- - Run test suite? - Add new tests? - Consider security implications and practices? --- script/post_generate_language | 3 --- 1 file changed, 3 deletions(-) diff --git a/script/post_generate_language b/script/post_generate_language index fb5ea90..37f8560 100755 --- a/script/post_generate_language +++ b/script/post_generate_language @@ -3,9 +3,6 @@ set -e [[ "$TRACE" == "true" ]] && set -x cd "$(dirname "$0")/.." -echo "Removing autogenerated tests..." -rm -r src/test - echo "Removing trailing whitespace..." find src -name "*.java" -type f -exec sed -E -i '' 's/[[:space:]]+$//g' {} + find . -name "*.gradle" -depth 1 -type f -exec sed -E -i '' 's/[[:space:]]+$//g' {} + From f15edd6a7ca0c73509eea97533d1a67f3c8fcc0f Mon Sep 17 00:00:00 2001 From: Jason Gladish Date: Fri, 2 Jun 2023 18:38:14 -0400 Subject: [PATCH 10/19] Improve generated file review Why is this change needed? -------------------------- These files might have useful changes that we want to review. How does it address the issue? ------------------------------ Don't remove these since we'll want to review the diffs between the old and new versions to see if we should make any updates to non-generated code. Any links to any relevant tickets, articles, or other resources? --------------------------------------------------------------- https://3.basecamp.com/3093825/buckets/29007795/todolists/5257298600 Did you complete all of the following? -------------------------------------- - Run test suite? - Add new tests? - Consider security implications and practices? --- .openapi-generator-ignore | 10 ---------- .openapi-generator/FILES | 5 +++++ 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/.openapi-generator-ignore b/.openapi-generator-ignore index f391b91..eb1e4dc 100644 --- a/.openapi-generator-ignore +++ b/.openapi-generator-ignore @@ -23,16 +23,6 @@ #!docs/README.md -# These are autogenerated and aren't exactly what we want. We rely on the -# readme, and website documentation. -# TODO: Ideally, when updating the agent, it would be nice to see the -# differences between when the previous version and the new version generated. -# This would help make it more obvious when the agent supported a newer usage -# pattern that we might prefer. -# TODO: Consider if it's possible to make the generated docs more useful so we -# might actually want to use them. -docs/ - # This seems to be a script related to developing openapi-generator and making # new test APIs. git_push.sh diff --git a/.openapi-generator/FILES b/.openapi-generator/FILES index bf233dd..77a720c 100644 --- a/.openapi-generator/FILES +++ b/.openapi-generator/FILES @@ -5,6 +5,11 @@ README.md api/openapi.yaml build.gradle build.sbt +docs/AsyncDoc.md +docs/Doc.md +docs/DocApi.md +docs/DocStatus.md +docs/PrinceOptions.md gradle.properties gradle/wrapper/gradle-wrapper.jar gradle/wrapper/gradle-wrapper.properties From 66cd2819fe7f887ea049f8ad4b8bc553c9e10bf7 Mon Sep 17 00:00:00 2001 From: Jason Gladish Date: Fri, 2 Jun 2023 18:44:41 -0400 Subject: [PATCH 11/19] Improve generated file review Why is this change needed? -------------------------- These files might have useful changes that we want to review. How does it address the issue? ------------------------------ Commit these files to the review directory so we'll be able to more easily review changes in the future. Any links to any relevant tickets, articles, or other resources? --------------------------------------------------------------- https://3.basecamp.com/3093825/buckets/29007795/todolists/5257298600 Did you complete all of the following? -------------------------------------- - Run test suite? - Add new tests? - Consider security implications and practices? --- .review/generated_files/docs/AsyncDoc.md | 13 + .review/generated_files/docs/Doc.md | 48 ++ .review/generated_files/docs/DocApi.md | 547 ++++++++++++++++++ .review/generated_files/docs/DocStatus.md | 18 + .review/generated_files/docs/PrinceOptions.md | 52 ++ .../test/java/com/docraptor/AsyncDocTest.java | 50 ++ .../test/java/com/docraptor/DocApiTest.java | 143 +++++ .../java/com/docraptor/DocStatusTest.java | 90 +++ .../src/test/java/com/docraptor/DocTest.java | 179 ++++++ .../java/com/docraptor/PrinceOptionsTest.java | 282 +++++++++ 10 files changed, 1422 insertions(+) create mode 100644 .review/generated_files/docs/AsyncDoc.md create mode 100644 .review/generated_files/docs/Doc.md create mode 100644 .review/generated_files/docs/DocApi.md create mode 100644 .review/generated_files/docs/DocStatus.md create mode 100644 .review/generated_files/docs/PrinceOptions.md create mode 100644 .review/generated_files/src/test/java/com/docraptor/AsyncDocTest.java create mode 100644 .review/generated_files/src/test/java/com/docraptor/DocApiTest.java create mode 100644 .review/generated_files/src/test/java/com/docraptor/DocStatusTest.java create mode 100644 .review/generated_files/src/test/java/com/docraptor/DocTest.java create mode 100644 .review/generated_files/src/test/java/com/docraptor/PrinceOptionsTest.java diff --git a/.review/generated_files/docs/AsyncDoc.md b/.review/generated_files/docs/AsyncDoc.md new file mode 100644 index 0000000..d35681e --- /dev/null +++ b/.review/generated_files/docs/AsyncDoc.md @@ -0,0 +1,13 @@ + + +# AsyncDoc + + +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +|**statusId** | **String** | The identifier used to get the status of the document using the status API. | [optional] | + + + diff --git a/.review/generated_files/docs/Doc.md b/.review/generated_files/docs/Doc.md new file mode 100644 index 0000000..ed58936 --- /dev/null +++ b/.review/generated_files/docs/Doc.md @@ -0,0 +1,48 @@ + + +# Doc + + +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +|**name** | **String** | A name for identifying your document. | | +|**documentType** | [**DocumentTypeEnum**](#DocumentTypeEnum) | The type of document being created. | | +|**documentContent** | **String** | The HTML data to be transformed into a document. You must supply content using document_content or document_url. | | +|**documentUrl** | **String** | The URL to fetch the HTML data to be transformed into a document. You must supply content using document_content or document_url. | [optional] | +|**test** | **Boolean** | Enable test mode for this document. Test documents are not charged for but include a watermark. | [optional] | +|**pipeline** | **String** | Specify a specific verison of the DocRaptor Pipeline to use. | [optional] | +|**strict** | [**StrictEnum**](#StrictEnum) | Force strict HTML validation. | [optional] | +|**ignoreResourceErrors** | **Boolean** | Failed loading of images/javascripts/stylesheets/etc. will not cause the rendering to stop. | [optional] | +|**ignoreConsoleMessages** | **Boolean** | Prevent console.log from stopping document rendering during JavaScript execution. | [optional] | +|**tag** | **String** | A field for storing a small amount of metadata with this document. | [optional] | +|**help** | **Boolean** | Request support help with this request if it succeeds. | [optional] | +|**javascript** | **Boolean** | Enable DocRaptor JavaScript parsing. PrinceXML JavaScript parsing is also available elsewhere. | [optional] | +|**referrer** | **String** | Set HTTP referrer when generating this document. | [optional] | +|**callbackUrl** | **String** | A URL that will receive a POST request after successfully completing an asynchronous document. The POST data will include download_url and download_id similar to status API responses. WARNING: this only works on asynchronous documents. | [optional] | +|**hostedDownloadLimit** | **Integer** | The number of times a hosted document can be downloaded. If no limit is specified, the document will be available for an unlimited number of downloads. | [optional] | +|**hostedExpiresAt** | **String** | The date and time at which a hosted document will be removed and no longer available. Must be a properly formatted ISO 8601 datetime, like 1981-01-23T08:02:30-05:00. | [optional] | +|**princeOptions** | [**PrinceOptions**](PrinceOptions.md) | | [optional] | + + + +## Enum: DocumentTypeEnum + +| Name | Value | +|---- | -----| +| PDF | "pdf" | +| XLS | "xls" | +| XLSX | "xlsx" | + + + +## Enum: StrictEnum + +| Name | Value | +|---- | -----| +| NONE | "none" | +| HTML | "html" | + + + diff --git a/.review/generated_files/docs/DocApi.md b/.review/generated_files/docs/DocApi.md new file mode 100644 index 0000000..833e544 --- /dev/null +++ b/.review/generated_files/docs/DocApi.md @@ -0,0 +1,547 @@ +# DocApi + +All URIs are relative to *https://api.docraptor.com* + +| Method | HTTP request | Description | +|------------- | ------------- | -------------| +| [**createAsyncDoc**](DocApi.md#createAsyncDoc) | **POST** /async_docs | | +| [**createDoc**](DocApi.md#createDoc) | **POST** /docs | | +| [**createHostedAsyncDoc**](DocApi.md#createHostedAsyncDoc) | **POST** /hosted_async_docs | | +| [**createHostedDoc**](DocApi.md#createHostedDoc) | **POST** /hosted_docs | | +| [**expire**](DocApi.md#expire) | **PATCH** /expire/{id} | | +| [**getAsyncDoc**](DocApi.md#getAsyncDoc) | **GET** /download/{id} | | +| [**getAsyncDocStatus**](DocApi.md#getAsyncDocStatus) | **GET** /status/{id} | | + + + +## createAsyncDoc + +> AsyncDoc createAsyncDoc(doc) + + + +Creates a document asynchronously. You must use a callback url or the returned status id and the status API to find out when it completes. Then use the download API to get the document. + +### Example + +```java +// Import classes: +import com.docraptor.ApiClient; +import com.docraptor.ApiException; +import com.docraptor.Configuration; +import com.docraptor.auth.*; +import com.docraptor.models.*; +import com.docraptor.DocApi; + +public class Example { + public static void main(String[] args) { + ApiClient defaultClient = Configuration.getDefaultApiClient(); + defaultClient.setBasePath("https://api.docraptor.com"); + + // Configure HTTP basic authorization: basicAuth + HttpBasicAuth basicAuth = (HttpBasicAuth) defaultClient.getAuthentication("basicAuth"); + basicAuth.setUsername("YOUR USERNAME"); + basicAuth.setPassword("YOUR PASSWORD"); + + DocApi apiInstance = new DocApi(defaultClient); + Doc doc = new Doc(); // Doc | The document to be created. + try { + AsyncDoc result = apiInstance.createAsyncDoc(doc); + System.out.println(result); + } catch (ApiException e) { + System.err.println("Exception when calling DocApi#createAsyncDoc"); + System.err.println("Status code: " + e.getCode()); + System.err.println("Reason: " + e.getResponseBody()); + System.err.println("Response headers: " + e.getResponseHeaders()); + e.printStackTrace(); + } + } +} +``` + +### Parameters + + +| Name | Type | Description | Notes | +|------------- | ------------- | ------------- | -------------| +| **doc** | [**Doc**](Doc.md)| The document to be created. | | + +### Return type + +[**AsyncDoc**](AsyncDoc.md) + +### Authorization + +[basicAuth](../README.md#basicAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json, application/xml, application/pdf, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet + + +### HTTP response details +| Status code | Description | Response headers | +|-------------|-------------|------------------| +| **200** | Successful response | - | +| **400** | Bad Request | - | +| **401** | Unauthorized | - | +| **403** | Forbidden | - | +| **422** | Unprocessable Entity | - | +| **500** | Server Error | - | + + +## createDoc + +> byte[] createDoc(doc) + + + +Creates a document synchronously. + +### Example + +```java +// Import classes: +import com.docraptor.ApiClient; +import com.docraptor.ApiException; +import com.docraptor.Configuration; +import com.docraptor.auth.*; +import com.docraptor.models.*; +import com.docraptor.DocApi; + +public class Example { + public static void main(String[] args) { + ApiClient defaultClient = Configuration.getDefaultApiClient(); + defaultClient.setBasePath("https://api.docraptor.com"); + + // Configure HTTP basic authorization: basicAuth + HttpBasicAuth basicAuth = (HttpBasicAuth) defaultClient.getAuthentication("basicAuth"); + basicAuth.setUsername("YOUR USERNAME"); + basicAuth.setPassword("YOUR PASSWORD"); + + DocApi apiInstance = new DocApi(defaultClient); + Doc doc = new Doc(); // Doc | The document to be created. + try { + byte[] result = apiInstance.createDoc(doc); + System.out.println(result); + } catch (ApiException e) { + System.err.println("Exception when calling DocApi#createDoc"); + System.err.println("Status code: " + e.getCode()); + System.err.println("Reason: " + e.getResponseBody()); + System.err.println("Response headers: " + e.getResponseHeaders()); + e.printStackTrace(); + } + } +} +``` + +### Parameters + + +| Name | Type | Description | Notes | +|------------- | ------------- | ------------- | -------------| +| **doc** | [**Doc**](Doc.md)| The document to be created. | | + +### Return type + +**byte[]** + +### Authorization + +[basicAuth](../README.md#basicAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json, application/xml, application/pdf, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet + + +### HTTP response details +| Status code | Description | Response headers | +|-------------|-------------|------------------| +| **200** | Successful response | - | +| **400** | Bad Request | - | +| **401** | Unauthorized | - | +| **403** | Forbidden | - | +| **422** | Unprocessable Entity | - | +| **500** | Server Error | - | + + +## createHostedAsyncDoc + +> AsyncDoc createHostedAsyncDoc(doc) + + + +Creates a hosted document asynchronously. You must use a callback url or the returned status id and the status API to find out when it completes. Then use the download API to get the document. + +### Example + +```java +// Import classes: +import com.docraptor.ApiClient; +import com.docraptor.ApiException; +import com.docraptor.Configuration; +import com.docraptor.auth.*; +import com.docraptor.models.*; +import com.docraptor.DocApi; + +public class Example { + public static void main(String[] args) { + ApiClient defaultClient = Configuration.getDefaultApiClient(); + defaultClient.setBasePath("https://api.docraptor.com"); + + // Configure HTTP basic authorization: basicAuth + HttpBasicAuth basicAuth = (HttpBasicAuth) defaultClient.getAuthentication("basicAuth"); + basicAuth.setUsername("YOUR USERNAME"); + basicAuth.setPassword("YOUR PASSWORD"); + + DocApi apiInstance = new DocApi(defaultClient); + Doc doc = new Doc(); // Doc | The document to be created. + try { + AsyncDoc result = apiInstance.createHostedAsyncDoc(doc); + System.out.println(result); + } catch (ApiException e) { + System.err.println("Exception when calling DocApi#createHostedAsyncDoc"); + System.err.println("Status code: " + e.getCode()); + System.err.println("Reason: " + e.getResponseBody()); + System.err.println("Response headers: " + e.getResponseHeaders()); + e.printStackTrace(); + } + } +} +``` + +### Parameters + + +| Name | Type | Description | Notes | +|------------- | ------------- | ------------- | -------------| +| **doc** | [**Doc**](Doc.md)| The document to be created. | | + +### Return type + +[**AsyncDoc**](AsyncDoc.md) + +### Authorization + +[basicAuth](../README.md#basicAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json, application/xml, application/pdf, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet + + +### HTTP response details +| Status code | Description | Response headers | +|-------------|-------------|------------------| +| **200** | Successful response | - | +| **400** | Bad Request | - | +| **401** | Unauthorized | - | +| **403** | Forbidden | - | +| **422** | Unprocessable Entity | - | +| **500** | Server Error | - | + + +## createHostedDoc + +> DocStatus createHostedDoc(doc) + + + +Creates a hosted document synchronously. + +### Example + +```java +// Import classes: +import com.docraptor.ApiClient; +import com.docraptor.ApiException; +import com.docraptor.Configuration; +import com.docraptor.auth.*; +import com.docraptor.models.*; +import com.docraptor.DocApi; + +public class Example { + public static void main(String[] args) { + ApiClient defaultClient = Configuration.getDefaultApiClient(); + defaultClient.setBasePath("https://api.docraptor.com"); + + // Configure HTTP basic authorization: basicAuth + HttpBasicAuth basicAuth = (HttpBasicAuth) defaultClient.getAuthentication("basicAuth"); + basicAuth.setUsername("YOUR USERNAME"); + basicAuth.setPassword("YOUR PASSWORD"); + + DocApi apiInstance = new DocApi(defaultClient); + Doc doc = new Doc(); // Doc | The document to be created. + try { + DocStatus result = apiInstance.createHostedDoc(doc); + System.out.println(result); + } catch (ApiException e) { + System.err.println("Exception when calling DocApi#createHostedDoc"); + System.err.println("Status code: " + e.getCode()); + System.err.println("Reason: " + e.getResponseBody()); + System.err.println("Response headers: " + e.getResponseHeaders()); + e.printStackTrace(); + } + } +} +``` + +### Parameters + + +| Name | Type | Description | Notes | +|------------- | ------------- | ------------- | -------------| +| **doc** | [**Doc**](Doc.md)| The document to be created. | | + +### Return type + +[**DocStatus**](DocStatus.md) + +### Authorization + +[basicAuth](../README.md#basicAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json, application/xml, application/pdf, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet + + +### HTTP response details +| Status code | Description | Response headers | +|-------------|-------------|------------------| +| **200** | Successful response | - | +| **400** | Bad Request | - | +| **401** | Unauthorized | - | +| **403** | Forbidden | - | +| **422** | Unprocessable Entity | - | +| **500** | Server Error | - | + + +## expire + +> expire(id) + + + +Expires a previously created hosted doc. + +### Example + +```java +// Import classes: +import com.docraptor.ApiClient; +import com.docraptor.ApiException; +import com.docraptor.Configuration; +import com.docraptor.auth.*; +import com.docraptor.models.*; +import com.docraptor.DocApi; + +public class Example { + public static void main(String[] args) { + ApiClient defaultClient = Configuration.getDefaultApiClient(); + defaultClient.setBasePath("https://api.docraptor.com"); + + // Configure HTTP basic authorization: basicAuth + HttpBasicAuth basicAuth = (HttpBasicAuth) defaultClient.getAuthentication("basicAuth"); + basicAuth.setUsername("YOUR USERNAME"); + basicAuth.setPassword("YOUR PASSWORD"); + + DocApi apiInstance = new DocApi(defaultClient); + String id = "id_example"; // String | The download_id returned from status request or hosted document response. + try { + apiInstance.expire(id); + } catch (ApiException e) { + System.err.println("Exception when calling DocApi#expire"); + System.err.println("Status code: " + e.getCode()); + System.err.println("Reason: " + e.getResponseBody()); + System.err.println("Response headers: " + e.getResponseHeaders()); + e.printStackTrace(); + } + } +} +``` + +### Parameters + + +| Name | Type | Description | Notes | +|------------- | ------------- | ------------- | -------------| +| **id** | **String**| The download_id returned from status request or hosted document response. | | + +### Return type + +null (empty response body) + +### Authorization + +[basicAuth](../README.md#basicAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + + +### HTTP response details +| Status code | Description | Response headers | +|-------------|-------------|------------------| +| **200** | Successful response | - | +| **401** | Unauthorized | - | +| **403** | Forbidden | - | +| **500** | Server Error | - | + + +## getAsyncDoc + +> byte[] getAsyncDoc(id) + + + +Downloads a finished document. + +### Example + +```java +// Import classes: +import com.docraptor.ApiClient; +import com.docraptor.ApiException; +import com.docraptor.Configuration; +import com.docraptor.auth.*; +import com.docraptor.models.*; +import com.docraptor.DocApi; + +public class Example { + public static void main(String[] args) { + ApiClient defaultClient = Configuration.getDefaultApiClient(); + defaultClient.setBasePath("https://api.docraptor.com"); + + // Configure HTTP basic authorization: basicAuth + HttpBasicAuth basicAuth = (HttpBasicAuth) defaultClient.getAuthentication("basicAuth"); + basicAuth.setUsername("YOUR USERNAME"); + basicAuth.setPassword("YOUR PASSWORD"); + + DocApi apiInstance = new DocApi(defaultClient); + String id = "id_example"; // String | The download_id returned from an async status request or callback. + try { + byte[] result = apiInstance.getAsyncDoc(id); + System.out.println(result); + } catch (ApiException e) { + System.err.println("Exception when calling DocApi#getAsyncDoc"); + System.err.println("Status code: " + e.getCode()); + System.err.println("Reason: " + e.getResponseBody()); + System.err.println("Response headers: " + e.getResponseHeaders()); + e.printStackTrace(); + } + } +} +``` + +### Parameters + + +| Name | Type | Description | Notes | +|------------- | ------------- | ------------- | -------------| +| **id** | **String**| The download_id returned from an async status request or callback. | | + +### Return type + +**byte[]** + +### Authorization + +[basicAuth](../README.md#basicAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json, application/xml, application/pdf, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet + + +### HTTP response details +| Status code | Description | Response headers | +|-------------|-------------|------------------| +| **200** | Successful response | - | +| **400** | Bad Request | - | +| **403** | Forbidden | - | +| **500** | Server Error | - | + + +## getAsyncDocStatus + +> DocStatus getAsyncDocStatus(id) + + + +Check on the status of an asynchronously created document. + +### Example + +```java +// Import classes: +import com.docraptor.ApiClient; +import com.docraptor.ApiException; +import com.docraptor.Configuration; +import com.docraptor.auth.*; +import com.docraptor.models.*; +import com.docraptor.DocApi; + +public class Example { + public static void main(String[] args) { + ApiClient defaultClient = Configuration.getDefaultApiClient(); + defaultClient.setBasePath("https://api.docraptor.com"); + + // Configure HTTP basic authorization: basicAuth + HttpBasicAuth basicAuth = (HttpBasicAuth) defaultClient.getAuthentication("basicAuth"); + basicAuth.setUsername("YOUR USERNAME"); + basicAuth.setPassword("YOUR PASSWORD"); + + DocApi apiInstance = new DocApi(defaultClient); + String id = "id_example"; // String | The status_id returned when creating an asynchronous document. + try { + DocStatus result = apiInstance.getAsyncDocStatus(id); + System.out.println(result); + } catch (ApiException e) { + System.err.println("Exception when calling DocApi#getAsyncDocStatus"); + System.err.println("Status code: " + e.getCode()); + System.err.println("Reason: " + e.getResponseBody()); + System.err.println("Response headers: " + e.getResponseHeaders()); + e.printStackTrace(); + } + } +} +``` + +### Parameters + + +| Name | Type | Description | Notes | +|------------- | ------------- | ------------- | -------------| +| **id** | **String**| The status_id returned when creating an asynchronous document. | | + +### Return type + +[**DocStatus**](DocStatus.md) + +### Authorization + +[basicAuth](../README.md#basicAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json, application/xml, application/pdf, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet + + +### HTTP response details +| Status code | Description | Response headers | +|-------------|-------------|------------------| +| **200** | Successful response | - | +| **401** | Unauthorized | - | +| **403** | Forbidden | - | +| **500** | Server Error | - | + diff --git a/.review/generated_files/docs/DocStatus.md b/.review/generated_files/docs/DocStatus.md new file mode 100644 index 0000000..c13a64c --- /dev/null +++ b/.review/generated_files/docs/DocStatus.md @@ -0,0 +1,18 @@ + + +# DocStatus + + +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +|**status** | **String** | The present status of the document. Can be queued, working, completed, and failed. | [optional] | +|**downloadUrl** | **String** | The URL where the document can be retrieved. This URL may only be used a few times. | [optional] | +|**downloadId** | **String** | The identifier for downloading the document with the download API. | [optional] | +|**message** | **String** | Additional information. | [optional] | +|**numberOfPages** | **Integer** | Number of PDF pages in document. | [optional] | +|**validationErrors** | **String** | Error information. | [optional] | + + + diff --git a/.review/generated_files/docs/PrinceOptions.md b/.review/generated_files/docs/PrinceOptions.md new file mode 100644 index 0000000..fbf7d2c --- /dev/null +++ b/.review/generated_files/docs/PrinceOptions.md @@ -0,0 +1,52 @@ + + +# PrinceOptions + + +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +|**baseurl** | **String** | Set the baseurl for assets. | [optional] | +|**noXinclude** | **Boolean** | Disable XML inclusion. | [optional] | +|**noNetwork** | **Boolean** | Disable network access. | [optional] | +|**noParallelDownloads** | **Boolean** | Disables parallel fetching of assets during PDF creation. Useful if your asset host has strict rate limiting. | [optional] | +|**httpUser** | **String** | Set the user for HTTP authentication. | [optional] | +|**httpPassword** | **String** | Set the password for HTTP authentication. | [optional] | +|**httpProxy** | **String** | Set the HTTP proxy server. | [optional] | +|**httpTimeout** | **Integer** | Set the HTTP request timeout. | [optional] | +|**insecure** | **Boolean** | Disable SSL verification. | [optional] | +|**media** | **String** | Specify the CSS media type. Defaults to \"print\" but you may want to use \"screen\" for web styles. | [optional] | +|**noAuthorStyle** | **Boolean** | Ignore author stylesheets. | [optional] | +|**noDefaultStyle** | **Boolean** | Ignore default stylesheets. | [optional] | +|**noEmbedFonts** | **Boolean** | Disable font embedding in PDFs. | [optional] | +|**noSubsetFonts** | **Boolean** | Disable font subsetting in PDFs. | [optional] | +|**noCompress** | **Boolean** | Disable PDF compression. | [optional] | +|**encrypt** | **Boolean** | Encrypt PDF output. | [optional] | +|**keyBits** | **Integer** | Set encryption key size. | [optional] | +|**userPassword** | **String** | Set the PDF user password. | [optional] | +|**ownerPassword** | **String** | Set the PDF owner password. | [optional] | +|**disallowPrint** | **Boolean** | Disallow printing of this PDF. | [optional] | +|**disallowCopy** | **Boolean** | Disallow copying of this PDF. | [optional] | +|**disallowAnnotate** | **Boolean** | Disallow annotation of this PDF. | [optional] | +|**disallowModify** | **Boolean** | Disallow modification of this PDF. | [optional] | +|**debug** | **Boolean** | Enable Prince debug mode. | [optional] | +|**input** | [**InputEnum**](#InputEnum) | Specify the input format. | [optional] | +|**version** | **String** | Deprecated, use the appropriate `pipeline` version. Specify a specific verison of PrinceXML to use. | [optional] | +|**javascript** | **Boolean** | Enable PrinceXML JavaScript. DocRaptor JavaScript parsing is also available elsewhere. | [optional] | +|**cssDpi** | **Integer** | Set the DPI when rendering CSS. Defaults to 96 but can be set with Prince 9.0 and up. | [optional] | +|**profile** | **String** | In Prince 9.0 and up you can set the PDF profile. | [optional] | +|**pdfTitle** | **String** | Specify the PDF title, part of the document's metadata. | [optional] | + + + +## Enum: InputEnum + +| Name | Value | +|---- | -----| +| HTML | "html" | +| XML | "xml" | +| AUTO | "auto" | + + + diff --git a/.review/generated_files/src/test/java/com/docraptor/AsyncDocTest.java b/.review/generated_files/src/test/java/com/docraptor/AsyncDocTest.java new file mode 100644 index 0000000..f725cf2 --- /dev/null +++ b/.review/generated_files/src/test/java/com/docraptor/AsyncDocTest.java @@ -0,0 +1,50 @@ +/* + * DocRaptor + * A native client library for the DocRaptor HTML to PDF/XLS service. + * + * The version of the OpenAPI document: 2.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.docraptor; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + + +/** + * Model tests for AsyncDoc + */ +public class AsyncDocTest { + private final AsyncDoc model = new AsyncDoc(); + + /** + * Model tests for AsyncDoc + */ + @Test + public void testAsyncDoc() { + // TODO: test AsyncDoc + } + + /** + * Test the property 'statusId' + */ + @Test + public void statusIdTest() { + // TODO: test statusId + } + +} diff --git a/.review/generated_files/src/test/java/com/docraptor/DocApiTest.java b/.review/generated_files/src/test/java/com/docraptor/DocApiTest.java new file mode 100644 index 0000000..556c7ed --- /dev/null +++ b/.review/generated_files/src/test/java/com/docraptor/DocApiTest.java @@ -0,0 +1,143 @@ +/* + * DocRaptor + * A native client library for the DocRaptor HTML to PDF/XLS service. + * + * The version of the OpenAPI document: 2.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.docraptor; + +import com.docraptor.ApiException; +import com.docraptor.AsyncDoc; +import com.docraptor.Doc; +import com.docraptor.DocStatus; +import org.junit.Test; +import org.junit.Ignore; +import org.junit.Assert; + +import java.time.LocalDate; +import java.time.OffsetDateTime; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * API tests for DocApi + */ +public class DocApiTest { + + private final DocApi api = new DocApi(); + + /** + * Creates a document asynchronously. You must use a callback url or the returned status id and the status API to find out when it completes. Then use the download API to get the document. + * + * @throws ApiException + * if the Api call fails + */ + @Test + public void createAsyncDocTest() throws ApiException { + // + //Doc doc = null; + // + //AsyncDoc response = api.createAsyncDoc(doc); + + // TODO: test validations + } + /** + * Creates a document synchronously. + * + * @throws ApiException + * if the Api call fails + */ + @Test + public void createDocTest() throws ApiException { + // + //Doc doc = null; + // + //byte[] response = api.createDoc(doc); + + // TODO: test validations + } + /** + * Creates a hosted document asynchronously. You must use a callback url or the returned status id and the status API to find out when it completes. Then use the download API to get the document. + * + * @throws ApiException + * if the Api call fails + */ + @Test + public void createHostedAsyncDocTest() throws ApiException { + // + //Doc doc = null; + // + //AsyncDoc response = api.createHostedAsyncDoc(doc); + + // TODO: test validations + } + /** + * Creates a hosted document synchronously. + * + * @throws ApiException + * if the Api call fails + */ + @Test + public void createHostedDocTest() throws ApiException { + // + //Doc doc = null; + // + //DocStatus response = api.createHostedDoc(doc); + + // TODO: test validations + } + /** + * Expires a previously created hosted doc. + * + * @throws ApiException + * if the Api call fails + */ + @Test + public void expireTest() throws ApiException { + // + //String id = null; + // + //api.expire(id); + + // TODO: test validations + } + /** + * Downloads a finished document. + * + * @throws ApiException + * if the Api call fails + */ + @Test + public void getAsyncDocTest() throws ApiException { + // + //String id = null; + // + //byte[] response = api.getAsyncDoc(id); + + // TODO: test validations + } + /** + * Check on the status of an asynchronously created document. + * + * @throws ApiException + * if the Api call fails + */ + @Test + public void getAsyncDocStatusTest() throws ApiException { + // + //String id = null; + // + //DocStatus response = api.getAsyncDocStatus(id); + + // TODO: test validations + } +} diff --git a/.review/generated_files/src/test/java/com/docraptor/DocStatusTest.java b/.review/generated_files/src/test/java/com/docraptor/DocStatusTest.java new file mode 100644 index 0000000..1ac08c5 --- /dev/null +++ b/.review/generated_files/src/test/java/com/docraptor/DocStatusTest.java @@ -0,0 +1,90 @@ +/* + * DocRaptor + * A native client library for the DocRaptor HTML to PDF/XLS service. + * + * The version of the OpenAPI document: 2.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.docraptor; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + + +/** + * Model tests for DocStatus + */ +public class DocStatusTest { + private final DocStatus model = new DocStatus(); + + /** + * Model tests for DocStatus + */ + @Test + public void testDocStatus() { + // TODO: test DocStatus + } + + /** + * Test the property 'status' + */ + @Test + public void statusTest() { + // TODO: test status + } + + /** + * Test the property 'downloadUrl' + */ + @Test + public void downloadUrlTest() { + // TODO: test downloadUrl + } + + /** + * Test the property 'downloadId' + */ + @Test + public void downloadIdTest() { + // TODO: test downloadId + } + + /** + * Test the property 'message' + */ + @Test + public void messageTest() { + // TODO: test message + } + + /** + * Test the property 'numberOfPages' + */ + @Test + public void numberOfPagesTest() { + // TODO: test numberOfPages + } + + /** + * Test the property 'validationErrors' + */ + @Test + public void validationErrorsTest() { + // TODO: test validationErrors + } + +} diff --git a/.review/generated_files/src/test/java/com/docraptor/DocTest.java b/.review/generated_files/src/test/java/com/docraptor/DocTest.java new file mode 100644 index 0000000..eef598c --- /dev/null +++ b/.review/generated_files/src/test/java/com/docraptor/DocTest.java @@ -0,0 +1,179 @@ +/* + * DocRaptor + * A native client library for the DocRaptor HTML to PDF/XLS service. + * + * The version of the OpenAPI document: 2.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.docraptor; + +import com.docraptor.PrinceOptions; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + + +/** + * Model tests for Doc + */ +public class DocTest { + private final Doc model = new Doc(); + + /** + * Model tests for Doc + */ + @Test + public void testDoc() { + // TODO: test Doc + } + + /** + * Test the property 'name' + */ + @Test + public void nameTest() { + // TODO: test name + } + + /** + * Test the property 'documentType' + */ + @Test + public void documentTypeTest() { + // TODO: test documentType + } + + /** + * Test the property 'documentContent' + */ + @Test + public void documentContentTest() { + // TODO: test documentContent + } + + /** + * Test the property 'documentUrl' + */ + @Test + public void documentUrlTest() { + // TODO: test documentUrl + } + + /** + * Test the property 'test' + */ + @Test + public void testTest() { + // TODO: test test + } + + /** + * Test the property 'pipeline' + */ + @Test + public void pipelineTest() { + // TODO: test pipeline + } + + /** + * Test the property 'strict' + */ + @Test + public void strictTest() { + // TODO: test strict + } + + /** + * Test the property 'ignoreResourceErrors' + */ + @Test + public void ignoreResourceErrorsTest() { + // TODO: test ignoreResourceErrors + } + + /** + * Test the property 'ignoreConsoleMessages' + */ + @Test + public void ignoreConsoleMessagesTest() { + // TODO: test ignoreConsoleMessages + } + + /** + * Test the property 'tag' + */ + @Test + public void tagTest() { + // TODO: test tag + } + + /** + * Test the property 'help' + */ + @Test + public void helpTest() { + // TODO: test help + } + + /** + * Test the property 'javascript' + */ + @Test + public void javascriptTest() { + // TODO: test javascript + } + + /** + * Test the property 'referrer' + */ + @Test + public void referrerTest() { + // TODO: test referrer + } + + /** + * Test the property 'callbackUrl' + */ + @Test + public void callbackUrlTest() { + // TODO: test callbackUrl + } + + /** + * Test the property 'hostedDownloadLimit' + */ + @Test + public void hostedDownloadLimitTest() { + // TODO: test hostedDownloadLimit + } + + /** + * Test the property 'hostedExpiresAt' + */ + @Test + public void hostedExpiresAtTest() { + // TODO: test hostedExpiresAt + } + + /** + * Test the property 'princeOptions' + */ + @Test + public void princeOptionsTest() { + // TODO: test princeOptions + } + +} diff --git a/.review/generated_files/src/test/java/com/docraptor/PrinceOptionsTest.java b/.review/generated_files/src/test/java/com/docraptor/PrinceOptionsTest.java new file mode 100644 index 0000000..f971a0d --- /dev/null +++ b/.review/generated_files/src/test/java/com/docraptor/PrinceOptionsTest.java @@ -0,0 +1,282 @@ +/* + * DocRaptor + * A native client library for the DocRaptor HTML to PDF/XLS service. + * + * The version of the OpenAPI document: 2.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.docraptor; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + + +/** + * Model tests for PrinceOptions + */ +public class PrinceOptionsTest { + private final PrinceOptions model = new PrinceOptions(); + + /** + * Model tests for PrinceOptions + */ + @Test + public void testPrinceOptions() { + // TODO: test PrinceOptions + } + + /** + * Test the property 'baseurl' + */ + @Test + public void baseurlTest() { + // TODO: test baseurl + } + + /** + * Test the property 'noXinclude' + */ + @Test + public void noXincludeTest() { + // TODO: test noXinclude + } + + /** + * Test the property 'noNetwork' + */ + @Test + public void noNetworkTest() { + // TODO: test noNetwork + } + + /** + * Test the property 'noParallelDownloads' + */ + @Test + public void noParallelDownloadsTest() { + // TODO: test noParallelDownloads + } + + /** + * Test the property 'httpUser' + */ + @Test + public void httpUserTest() { + // TODO: test httpUser + } + + /** + * Test the property 'httpPassword' + */ + @Test + public void httpPasswordTest() { + // TODO: test httpPassword + } + + /** + * Test the property 'httpProxy' + */ + @Test + public void httpProxyTest() { + // TODO: test httpProxy + } + + /** + * Test the property 'httpTimeout' + */ + @Test + public void httpTimeoutTest() { + // TODO: test httpTimeout + } + + /** + * Test the property 'insecure' + */ + @Test + public void insecureTest() { + // TODO: test insecure + } + + /** + * Test the property 'media' + */ + @Test + public void mediaTest() { + // TODO: test media + } + + /** + * Test the property 'noAuthorStyle' + */ + @Test + public void noAuthorStyleTest() { + // TODO: test noAuthorStyle + } + + /** + * Test the property 'noDefaultStyle' + */ + @Test + public void noDefaultStyleTest() { + // TODO: test noDefaultStyle + } + + /** + * Test the property 'noEmbedFonts' + */ + @Test + public void noEmbedFontsTest() { + // TODO: test noEmbedFonts + } + + /** + * Test the property 'noSubsetFonts' + */ + @Test + public void noSubsetFontsTest() { + // TODO: test noSubsetFonts + } + + /** + * Test the property 'noCompress' + */ + @Test + public void noCompressTest() { + // TODO: test noCompress + } + + /** + * Test the property 'encrypt' + */ + @Test + public void encryptTest() { + // TODO: test encrypt + } + + /** + * Test the property 'keyBits' + */ + @Test + public void keyBitsTest() { + // TODO: test keyBits + } + + /** + * Test the property 'userPassword' + */ + @Test + public void userPasswordTest() { + // TODO: test userPassword + } + + /** + * Test the property 'ownerPassword' + */ + @Test + public void ownerPasswordTest() { + // TODO: test ownerPassword + } + + /** + * Test the property 'disallowPrint' + */ + @Test + public void disallowPrintTest() { + // TODO: test disallowPrint + } + + /** + * Test the property 'disallowCopy' + */ + @Test + public void disallowCopyTest() { + // TODO: test disallowCopy + } + + /** + * Test the property 'disallowAnnotate' + */ + @Test + public void disallowAnnotateTest() { + // TODO: test disallowAnnotate + } + + /** + * Test the property 'disallowModify' + */ + @Test + public void disallowModifyTest() { + // TODO: test disallowModify + } + + /** + * Test the property 'debug' + */ + @Test + public void debugTest() { + // TODO: test debug + } + + /** + * Test the property 'input' + */ + @Test + public void inputTest() { + // TODO: test input + } + + /** + * Test the property 'version' + */ + @Test + public void versionTest() { + // TODO: test version + } + + /** + * Test the property 'javascript' + */ + @Test + public void javascriptTest() { + // TODO: test javascript + } + + /** + * Test the property 'cssDpi' + */ + @Test + public void cssDpiTest() { + // TODO: test cssDpi + } + + /** + * Test the property 'profile' + */ + @Test + public void profileTest() { + // TODO: test profile + } + + /** + * Test the property 'pdfTitle' + */ + @Test + public void pdfTitleTest() { + // TODO: test pdfTitle + } + +} From 3b2935e8c89e283d3c1532d400b347fce9a91520 Mon Sep 17 00:00:00 2001 From: Jason Gladish Date: Fri, 2 Jun 2023 19:48:34 -0400 Subject: [PATCH 12/19] Add a new test for prince_options[insecure]=true Why is this change needed? -------------------------- Csharp had an issue with PrinceOptions, so I made a test. Since the basic test exists I'll copy it to the other clients to verify everything continues to work in the future. How does it address the issue? ------------------------------ Add a test for PrinceOptions. Any links to any relevant tickets, articles, or other resources? --------------------------------------------------------------- https://3.basecamp.com/3093825/buckets/29007795/todolists/5257298600 Did you complete all of the following? -------------------------------------- - Run test suite? - Add new tests? - Consider security implications and practices? --- test/PrinceOptionsTest.java | 59 +++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 test/PrinceOptionsTest.java diff --git a/test/PrinceOptionsTest.java b/test/PrinceOptionsTest.java new file mode 100644 index 0000000..03f8acd --- /dev/null +++ b/test/PrinceOptionsTest.java @@ -0,0 +1,59 @@ +import java.io.*; +import java.net.*; +import com.docraptor.*; + +public class PrinceOptionsTest { + public static void main(String[] args) throws Exception { + DocApi docraptor = new DocApi(); + ApiClient client = docraptor.getApiClient(); + client.setUsername("YOUR_API_KEY_HERE"); + // client.setDebugging(true); + + + // Verify the test works as expected by confirming that this url will fail + // without prince_options[insecure]=true. + Doc doc = new Doc(); + doc.setName("java-sync.pdf"); + doc.setDocumentType(Doc.DocumentTypeEnum.PDF); + doc.setDocumentUrl("https://expired.badssl.com/"); + doc.setTest(true); + + try { + docraptor.createDoc(doc); + } catch (com.docraptor.ApiException ex) { + String expected_message = "SSL Error downloading document content from supplied url."; + if (!ex.getMessage().contains(expected_message)) { + System.out.println("Wrong exception, expected: " + expected_message + ", got: " + ex.getMessage()); + System.exit(1); + } + } + + + // Verify prince_options works by testing a url that will fail without + // prince_options[insecure]=true. + doc = new Doc(); + doc.setName("java-sync.pdf"); + doc.setDocumentType(Doc.DocumentTypeEnum.PDF); + doc.setDocumentUrl("https://expired.badssl.com/"); + doc.setTest(true); + PrinceOptions prince_options = new PrinceOptions(); + prince_options.setInsecure(true); + doc.setPrinceOptions(prince_options); + + byte data[] = docraptor.createDoc(doc); + + String output_file = System.getenv("TEST_OUTPUT_DIR") + + "/" + System.getenv("TEST_NAME") + "_csharp_" + + System.getenv("RUNTIME_ENV") + ".pdf"; + + FileOutputStream out = new FileOutputStream(output_file); + out.write(data); + out.close(); + + BufferedReader br = new BufferedReader(new FileReader(output_file)); + String line = br.readLine(); + if (!line.contains("%PDF-1.5")) { + throw new IllegalArgumentException("unexpected file header: " + line); + } + } +} From 93da3256648cf5183f1242ba94d1559e12a37cc4 Mon Sep 17 00:00:00 2001 From: Jason Gladish Date: Tue, 11 Jul 2023 21:23:05 -0400 Subject: [PATCH 13/19] Remove some EOL java versions Why is this change needed? -------------------------- It appears Debian has rotated the apt keys so `apt update` fails on these images. Since these java versions are EOL, we're just removing them from the list of images to test. How does it address the issue? ------------------------------ Remove the EOL java versions from the list of images to test. Also add a comment so future maintainers know why these images are missing. Also update some scripts to better handle removing comments from the runtime environments file. Any links to any relevant tickets, articles, or other resources? --------------------------------------------------------------- https://endoflife.date/java https://unix.stackexchange.com/questions/157328/how-can-i-remove-all-comments-from-a-file Did you complete all of the following? -------------------------------------- - Run test suite? - Add new tests? - Consider security implications and practices? --- .runtime-environments | 7 +++++-- script/docker | 2 +- script/test | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.runtime-environments b/.runtime-environments index b39cc24..9bfb83b 100644 --- a/.runtime-environments +++ b/.runtime-environments @@ -9,6 +9,9 @@ maven:3.8.6-eclipse-temurin maven:3.8.6-eclipse-temurin-19 maven:3.8.6-eclipse-temurin-17 maven:3.8.6-eclipse-temurin-11 -maven:3-jdk-10 -maven:3-jdk-9 maven:3.8.6-eclipse-temurin-8-focal + +# These are EOL and debian rotated apt keys, so `apt update` will fail. Leaving +# these commented so it's obvious why they're missing in the future. +# maven:3-jdk-10 +# maven:3-jdk-9 diff --git a/script/docker b/script/docker index fef2769..2dfe0e5 100755 --- a/script/docker +++ b/script/docker @@ -21,7 +21,7 @@ done shift $((OPTIND-1)) if [[ "$image" == "" ]]; then - image="$(cat .runtime-environments | grep -v '^#' | tail -n 1)" + image="$(cat .runtime-environments | sed 's/[[:blank:]]*#.*//;/^[[:blank:]]*$/d' | tail -n 1)" echo "docker image (-i) unset, defaulting to: $image" fi diff --git a/script/test b/script/test index 7c482c7..e3a14ab 100755 --- a/script/test +++ b/script/test @@ -32,7 +32,7 @@ run_tests() { success="true" -for runtime_env in $(cat .runtime-environments | grep -v '^#'); do +for runtime_env in $(cat .runtime-environments | sed 's/[[:blank:]]*#.*//;/^[[:blank:]]*$/d'); do echo echo echo "Testing runtime env $runtime_env" From 79ffbb16c569857e90d7a7d85a8b9843788b5589 Mon Sep 17 00:00:00 2001 From: Jason Gladish Date: Tue, 11 Jul 2023 21:27:55 -0400 Subject: [PATCH 14/19] Add new API options Why is this change needed? -------------------------- We'd like to allow users to set the following options: - iframes - page_margin - pdf_forms How does it address the issue? ------------------------------ Add the options and regenerate the client. Any links to any relevant tickets, articles, or other resources? --------------------------------------------------------------- https://3.basecamp.com/3093825/buckets/29007795/todolists/5257298600 Did you complete all of the following? -------------------------------------- - Run test suite? - Add new tests? - Consider security implications and practices? --- .review/generated_files/docs/PrinceOptions.md | 3 + .../java/com/docraptor/PrinceOptionsTest.java | 24 ++++ api/openapi.yaml | 15 +++ docraptor.yaml | 10 ++ .../java/com/docraptor/PrinceOptions.java | 105 +++++++++++++++++- 5 files changed, 154 insertions(+), 3 deletions(-) diff --git a/.review/generated_files/docs/PrinceOptions.md b/.review/generated_files/docs/PrinceOptions.md index fbf7d2c..176719b 100644 --- a/.review/generated_files/docs/PrinceOptions.md +++ b/.review/generated_files/docs/PrinceOptions.md @@ -37,6 +37,9 @@ |**cssDpi** | **Integer** | Set the DPI when rendering CSS. Defaults to 96 but can be set with Prince 9.0 and up. | [optional] | |**profile** | **String** | In Prince 9.0 and up you can set the PDF profile. | [optional] | |**pdfTitle** | **String** | Specify the PDF title, part of the document's metadata. | [optional] | +|**iframes** | **Boolean** | Enable loading of iframes. | [optional] | +|**pageMargin** | **String** | Specify the page margin distance. | [optional] | +|**pdfForms** | **Boolean** | Make form fields editable by default. | [optional] | diff --git a/.review/generated_files/src/test/java/com/docraptor/PrinceOptionsTest.java b/.review/generated_files/src/test/java/com/docraptor/PrinceOptionsTest.java index f971a0d..979c6a6 100644 --- a/.review/generated_files/src/test/java/com/docraptor/PrinceOptionsTest.java +++ b/.review/generated_files/src/test/java/com/docraptor/PrinceOptionsTest.java @@ -279,4 +279,28 @@ public void pdfTitleTest() { // TODO: test pdfTitle } + /** + * Test the property 'iframes' + */ + @Test + public void iframesTest() { + // TODO: test iframes + } + + /** + * Test the property 'pageMargin' + */ + @Test + public void pageMarginTest() { + // TODO: test pageMargin + } + + /** + * Test the property 'pdfForms' + */ + @Test + public void pdfFormsTest() { + // TODO: test pdfForms + } + } diff --git a/api/openapi.yaml b/api/openapi.yaml index e2a7b54..0392ef3 100644 --- a/api/openapi.yaml +++ b/api/openapi.yaml @@ -384,12 +384,14 @@ components: owner_password: owner_password no_default_style: true debug: true + page_margin: page_margin css_dpi: 5 profile: profile http_timeout: 6 no_compress: true disallow_annotate: true version: version + pdf_forms: true javascript: true no_author_style: true key_bits: 1 @@ -398,6 +400,7 @@ components: no_xinclude: true disallow_print: true disallow_copy: true + iframes: true name: name tag: tag strict: none @@ -503,12 +506,14 @@ components: owner_password: owner_password no_default_style: true debug: true + page_margin: page_margin css_dpi: 5 profile: profile http_timeout: 6 no_compress: true disallow_annotate: true version: version + pdf_forms: true javascript: true no_author_style: true key_bits: 1 @@ -517,6 +522,7 @@ components: no_xinclude: true disallow_print: true disallow_copy: true + iframes: true properties: baseurl: description: Set the baseurl for assets. @@ -619,6 +625,15 @@ components: pdf_title: description: "Specify the PDF title, part of the document's metadata." type: string + iframes: + description: Enable loading of iframes. + type: boolean + page_margin: + description: Specify the page margin distance. + type: string + pdf_forms: + description: Make form fields editable by default. + type: boolean type: object AsyncDoc: example: diff --git a/docraptor.yaml b/docraptor.yaml index 6a8cc20..ce46cac 100644 --- a/docraptor.yaml +++ b/docraptor.yaml @@ -428,6 +428,16 @@ definitions: pdf_title: type: string description: Specify the PDF title, part of the document's metadata. + iframes: + type: boolean + description: Enable loading of iframes. + nullable: true + page_margin: + type: string + description: Specify the page margin distance. + pdf_forms: + type: boolean + description: Make form fields editable by default. AsyncDoc: type: object diff --git a/src/main/java/com/docraptor/PrinceOptions.java b/src/main/java/com/docraptor/PrinceOptions.java index 5f00264..0cc19f6 100644 --- a/src/main/java/com/docraptor/PrinceOptions.java +++ b/src/main/java/com/docraptor/PrinceOptions.java @@ -58,7 +58,10 @@ PrinceOptions.JSON_PROPERTY_JAVASCRIPT, PrinceOptions.JSON_PROPERTY_CSS_DPI, PrinceOptions.JSON_PROPERTY_PROFILE, - PrinceOptions.JSON_PROPERTY_PDF_TITLE + PrinceOptions.JSON_PROPERTY_PDF_TITLE, + PrinceOptions.JSON_PROPERTY_IFRAMES, + PrinceOptions.JSON_PROPERTY_PAGE_MARGIN, + PrinceOptions.JSON_PROPERTY_PDF_FORMS }) @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") public class PrinceOptions { @@ -189,6 +192,15 @@ public static InputEnum fromValue(String value) { public static final String JSON_PROPERTY_PDF_TITLE = "pdf_title"; private String pdfTitle; + public static final String JSON_PROPERTY_IFRAMES = "iframes"; + private Boolean iframes; + + public static final String JSON_PROPERTY_PAGE_MARGIN = "page_margin"; + private String pageMargin; + + public static final String JSON_PROPERTY_PDF_FORMS = "pdf_forms"; + private Boolean pdfForms; + public PrinceOptions() { } @@ -1002,6 +1014,87 @@ public void setPdfTitle(String pdfTitle) { } + public PrinceOptions iframes(Boolean iframes) { + + this.iframes = iframes; + return this; + } + + /** + * Enable loading of iframes. + * @return iframes + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "Enable loading of iframes.") + @JsonProperty(JSON_PROPERTY_IFRAMES) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Boolean getIframes() { + return iframes; + } + + + @JsonProperty(JSON_PROPERTY_IFRAMES) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setIframes(Boolean iframes) { + this.iframes = iframes; + } + + + public PrinceOptions pageMargin(String pageMargin) { + + this.pageMargin = pageMargin; + return this; + } + + /** + * Specify the page margin distance. + * @return pageMargin + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "Specify the page margin distance.") + @JsonProperty(JSON_PROPERTY_PAGE_MARGIN) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getPageMargin() { + return pageMargin; + } + + + @JsonProperty(JSON_PROPERTY_PAGE_MARGIN) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setPageMargin(String pageMargin) { + this.pageMargin = pageMargin; + } + + + public PrinceOptions pdfForms(Boolean pdfForms) { + + this.pdfForms = pdfForms; + return this; + } + + /** + * Make form fields editable by default. + * @return pdfForms + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "Make form fields editable by default.") + @JsonProperty(JSON_PROPERTY_PDF_FORMS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Boolean getPdfForms() { + return pdfForms; + } + + + @JsonProperty(JSON_PROPERTY_PDF_FORMS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setPdfForms(Boolean pdfForms) { + this.pdfForms = pdfForms; + } + + @Override public boolean equals(Object o) { if (this == o) { @@ -1040,12 +1133,15 @@ public boolean equals(Object o) { Objects.equals(this.javascript, princeOptions.javascript) && Objects.equals(this.cssDpi, princeOptions.cssDpi) && Objects.equals(this.profile, princeOptions.profile) && - Objects.equals(this.pdfTitle, princeOptions.pdfTitle); + Objects.equals(this.pdfTitle, princeOptions.pdfTitle) && + Objects.equals(this.iframes, princeOptions.iframes) && + Objects.equals(this.pageMargin, princeOptions.pageMargin) && + Objects.equals(this.pdfForms, princeOptions.pdfForms); } @Override public int hashCode() { - return Objects.hash(baseurl, noXinclude, noNetwork, noParallelDownloads, httpUser, httpPassword, httpProxy, httpTimeout, insecure, media, noAuthorStyle, noDefaultStyle, noEmbedFonts, noSubsetFonts, noCompress, encrypt, keyBits, userPassword, ownerPassword, disallowPrint, disallowCopy, disallowAnnotate, disallowModify, debug, input, version, javascript, cssDpi, profile, pdfTitle); + return Objects.hash(baseurl, noXinclude, noNetwork, noParallelDownloads, httpUser, httpPassword, httpProxy, httpTimeout, insecure, media, noAuthorStyle, noDefaultStyle, noEmbedFonts, noSubsetFonts, noCompress, encrypt, keyBits, userPassword, ownerPassword, disallowPrint, disallowCopy, disallowAnnotate, disallowModify, debug, input, version, javascript, cssDpi, profile, pdfTitle, iframes, pageMargin, pdfForms); } @Override @@ -1082,6 +1178,9 @@ public String toString() { sb.append(" cssDpi: ").append(toIndentedString(cssDpi)).append("\n"); sb.append(" profile: ").append(toIndentedString(profile)).append("\n"); sb.append(" pdfTitle: ").append(toIndentedString(pdfTitle)).append("\n"); + sb.append(" iframes: ").append(toIndentedString(iframes)).append("\n"); + sb.append(" pageMargin: ").append(toIndentedString(pageMargin)).append("\n"); + sb.append(" pdfForms: ").append(toIndentedString(pdfForms)).append("\n"); sb.append("}"); return sb.toString(); } From 7ad0379c680da0a7a5cd6ab91f7b8e93a03c506f Mon Sep 17 00:00:00 2001 From: Jason Gladish Date: Tue, 11 Jul 2023 21:28:40 -0400 Subject: [PATCH 15/19] Add tests for the new iframes option Why is this change needed? -------------------------- We want to have a basic check that this new works and continues to work in the future. How does it address the issue? ------------------------------ Add iframes tests. Any links to any relevant tickets, articles, or other resources? --------------------------------------------------------------- https://3.basecamp.com/3093825/buckets/29007795/todolists/5257298600 Did you complete all of the following? -------------------------------------- - Run test suite? - Add new tests? - Consider security implications and practices? --- script/inside_container/test | 3 ++ test/IframesDefault.java | 59 ++++++++++++++++++++++++++++++++++++ test/IframesFalse.java | 59 ++++++++++++++++++++++++++++++++++++ test/IframesTrue.java | 59 ++++++++++++++++++++++++++++++++++++ 4 files changed, 180 insertions(+) create mode 100644 test/IframesDefault.java create mode 100644 test/IframesFalse.java create mode 100644 test/IframesTrue.java diff --git a/script/inside_container/test b/script/inside_container/test index 840e4b6..89a762e 100755 --- a/script/inside_container/test +++ b/script/inside_container/test @@ -2,6 +2,9 @@ set -e cd "$(dirname "$0")/../.." +apt update +apt install poppler-utils -y + cd test # runs a test file with PASS/FAIL message diff --git a/test/IframesDefault.java b/test/IframesDefault.java new file mode 100644 index 0000000..9f0205b --- /dev/null +++ b/test/IframesDefault.java @@ -0,0 +1,59 @@ +import java.io.*; +import java.net.*; +import com.docraptor.*; + +public class IframesDefault { + public static void main(String[] args) throws Exception { + DocApi docraptor = new DocApi(); + ApiClient client = docraptor.getApiClient(); + client.setUsername("YOUR_API_KEY_HERE"); + // client.setDebugging(true); + + Doc doc = new Doc(); + doc.setName("java-sync.pdf"); + doc.setDocumentType(Doc.DocumentTypeEnum.PDF); + doc.setDocumentContent( + "" + + "

Baseline text

" + + "" + + "" + ); + doc.setTest(true); + // PrinceOptions prince_options = new PrinceOptions(); + // prince_options.setIframes(true); + // doc.setPrinceOptions(prince_options); + + byte data[] = docraptor.createDoc(doc); + + String output_file = System.getenv("TEST_OUTPUT_DIR") + + "/" + System.getenv("TEST_NAME") + "_csharp_" + + System.getenv("RUNTIME_ENV") + ".pdf"; + + FileOutputStream out = new FileOutputStream(output_file); + out.write(data); + out.close(); + + BufferedReader br = new BufferedReader(new FileReader(output_file)); + String line = br.readLine(); + if (!line.contains("%PDF-1.5")) { + throw new IllegalArgumentException("unexpected file header: " + line); + } + + String command = "pdftotext " + output_file + " -"; + + String[] commands = {"bash", "-c", command}; + Process p = Runtime.getRuntime().exec(commands); + p.waitFor(); + BufferedReader b = new BufferedReader(new InputStreamReader(p.getInputStream())); + String output = ""; + while ((line = b.readLine()) != null) { + output += line; + } + b.close(); + + if(!output.contains("Test")) { + throw new IllegalArgumentException("output should have contained iframe content: " + output); + } + + } +} diff --git a/test/IframesFalse.java b/test/IframesFalse.java new file mode 100644 index 0000000..20575e9 --- /dev/null +++ b/test/IframesFalse.java @@ -0,0 +1,59 @@ +import java.io.*; +import java.net.*; +import com.docraptor.*; + +public class IframesFalse { + public static void main(String[] args) throws Exception { + DocApi docraptor = new DocApi(); + ApiClient client = docraptor.getApiClient(); + client.setUsername("YOUR_API_KEY_HERE"); + // client.setDebugging(true); + + Doc doc = new Doc(); + doc.setName("java-sync.pdf"); + doc.setDocumentType(Doc.DocumentTypeEnum.PDF); + doc.setDocumentContent( + "" + + "

Baseline text

" + + "" + + "" + ); + doc.setTest(true); + PrinceOptions prince_options = new PrinceOptions(); + prince_options.setIframes(false); + doc.setPrinceOptions(prince_options); + + byte data[] = docraptor.createDoc(doc); + + String output_file = System.getenv("TEST_OUTPUT_DIR") + + "/" + System.getenv("TEST_NAME") + "_csharp_" + + System.getenv("RUNTIME_ENV") + ".pdf"; + + FileOutputStream out = new FileOutputStream(output_file); + out.write(data); + out.close(); + + BufferedReader br = new BufferedReader(new FileReader(output_file)); + String line = br.readLine(); + if (!line.contains("%PDF-1.5")) { + throw new IllegalArgumentException("unexpected file header: " + line); + } + + String command = "pdftotext " + output_file + " -"; + + String[] commands = {"bash", "-c", command}; + Process p = Runtime.getRuntime().exec(commands); + p.waitFor(); + BufferedReader b = new BufferedReader(new InputStreamReader(p.getInputStream())); + String output = ""; + while ((line = b.readLine()) != null) { + output += line; + } + b.close(); + + if(output.contains("Test")) { + throw new IllegalArgumentException("output should not have contained iframe content: " + output); + } + + } +} diff --git a/test/IframesTrue.java b/test/IframesTrue.java new file mode 100644 index 0000000..71fcea5 --- /dev/null +++ b/test/IframesTrue.java @@ -0,0 +1,59 @@ +import java.io.*; +import java.net.*; +import com.docraptor.*; + +public class IframesTrue { + public static void main(String[] args) throws Exception { + DocApi docraptor = new DocApi(); + ApiClient client = docraptor.getApiClient(); + client.setUsername("YOUR_API_KEY_HERE"); + // client.setDebugging(true); + + Doc doc = new Doc(); + doc.setName("java-sync.pdf"); + doc.setDocumentType(Doc.DocumentTypeEnum.PDF); + doc.setDocumentContent( + "" + + "

Baseline text

" + + "" + + "" + ); + doc.setTest(true); + PrinceOptions prince_options = new PrinceOptions(); + prince_options.setIframes(true); + doc.setPrinceOptions(prince_options); + + byte data[] = docraptor.createDoc(doc); + + String output_file = System.getenv("TEST_OUTPUT_DIR") + + "/" + System.getenv("TEST_NAME") + "_csharp_" + + System.getenv("RUNTIME_ENV") + ".pdf"; + + FileOutputStream out = new FileOutputStream(output_file); + out.write(data); + out.close(); + + BufferedReader br = new BufferedReader(new FileReader(output_file)); + String line = br.readLine(); + if (!line.contains("%PDF-1.5")) { + throw new IllegalArgumentException("unexpected file header: " + line); + } + + String command = "pdftotext " + output_file + " -"; + + String[] commands = {"bash", "-c", command}; + Process p = Runtime.getRuntime().exec(commands); + p.waitFor(); + BufferedReader b = new BufferedReader(new InputStreamReader(p.getInputStream())); + String output = ""; + while ((line = b.readLine()) != null) { + output += line; + } + b.close(); + + if(!output.contains("Test")) { + throw new IllegalArgumentException("output should have contained iframe content: " + output); + } + + } +} From c7039ea9ca215d198cc301e4aed012626be7eefd Mon Sep 17 00:00:00 2001 From: Jason Gladish Date: Fri, 14 Jul 2023 14:29:59 -0400 Subject: [PATCH 16/19] Draft v3.1.0 release Why is this change needed? -------------------------- We'd like to release a new version of the client library with support for new API options. How does it address the issue? ------------------------------ Bump the version number and update the changelog. Did you complete all of the following? -------------------------------------- - Run test suite? - Add new tests? - Consider security implications and practices? --- .review/generated_files/README.md | 6 +++--- CHANGELOG.md | 3 +++ README.md | 2 +- build.gradle | 2 +- generator-config.json | 2 +- pom.xml | 2 +- src/main/java/com/docraptor/ApiClient.java | 2 +- 7 files changed, 11 insertions(+), 8 deletions(-) diff --git a/.review/generated_files/README.md b/.review/generated_files/README.md index d393d3b..c436cda 100644 --- a/.review/generated_files/README.md +++ b/.review/generated_files/README.md @@ -40,7 +40,7 @@ Add this dependency to your project's POM: com.docraptor docraptor - 3.0.0 + 3.1.0 compile ``` @@ -56,7 +56,7 @@ Add this dependency to your project's build file: } dependencies { - implementation "com.docraptor:docraptor:3.0.0" + implementation "com.docraptor:docraptor:3.1.0" } ``` @@ -70,7 +70,7 @@ mvn clean package Then manually install the following JARs: -- `target/docraptor-3.0.0.jar` +- `target/docraptor-3.1.0.jar` - `target/lib/*.jar` ## Getting Started diff --git a/CHANGELOG.md b/CHANGELOG.md index 530f708..66f8820 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +### 3.1.0 [July 14, 2023] +* Add new API options + ### 3.0.0 [November 15, 2022] * Switch API host to more secure api.docraptor.com (dropping old TLS) * Switch from swagger to openapi-generator v6.0.1 (better maintained) diff --git a/README.md b/README.md index 3a1a8e2..512e55a 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ After the client library is installed/deployed, you can use it in your Maven pro com.docraptor docraptor - 3.0.0 + 3.1.0 ``` diff --git a/build.gradle b/build.gradle index 98a5920..83b2f92 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'idea' apply plugin: 'eclipse' group = 'com.docraptor' -version = '3.0.0' +version = '3.1.0' buildscript { repositories { diff --git a/generator-config.json b/generator-config.json index 6089c43..cb70d0c 100644 --- a/generator-config.json +++ b/generator-config.json @@ -4,7 +4,7 @@ "apiPackage": "com.docraptor", "groupId": "com.docraptor", "artifactId": "docraptor", - "artifactVersion": "3.0.0", + "artifactVersion": "3.1.0", "artifactUrl": "https://github.com/DocRaptor/docraptor-java", "artifactDescription": "A native client library for the DocRaptor HTML to PDF/XLS service.", "scmConnection": "scm:git:git@github.com:DocRaptor/docraptor-java.git", diff --git a/pom.xml b/pom.xml index f918a1c..f73481e 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ docraptor jar docraptor - 3.0.0 + 3.1.0 https://github.com/DocRaptor/docraptor-java A native client library for the DocRaptor HTML to PDF/XLS service. diff --git a/src/main/java/com/docraptor/ApiClient.java b/src/main/java/com/docraptor/ApiClient.java index d17cd02..2f4fedc 100644 --- a/src/main/java/com/docraptor/ApiClient.java +++ b/src/main/java/com/docraptor/ApiClient.java @@ -98,7 +98,7 @@ public ApiClient() { dateFormat = ApiClient.buildDefaultDateFormat(); // Set default User-Agent. - setUserAgent("OpenAPI-Generator/3.0.0/java"); + setUserAgent("OpenAPI-Generator/3.1.0/java"); // Setup authentications (key: authentication name, value: authentication). authentications = new HashMap(); From 1bb1b3fd82cb17c9052ef082429b6f06f280f519 Mon Sep 17 00:00:00 2001 From: Jason Gladish Date: Tue, 26 Sep 2023 16:04:39 -0400 Subject: [PATCH 17/19] Update changelog to highlight pdf_forms Why is this change needed? -------------------------- It's a cool feature and worth promoting. How does it address the issue? ------------------------------ Highlight that one of the new options allows enabling PDF forms. Any links to any relevant tickets, articles, or other resources? --------------------------------------------------------------- https://github.com/expectedbehavior/docraptor-csharp/pull/5#discussion_r1337695884 Did you complete all of the following? -------------------------------------- - Run test suite? - Add new tests? - Consider security implications and practices? --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66f8820..0fdfe43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ ### 3.1.0 [July 14, 2023] -* Add new API options +* Add new API options (including prince_options[pdf_forms] to enable PDF forms) ### 3.0.0 [November 15, 2022] * Switch API host to more secure api.docraptor.com (dropping old TLS) From a03589004d327138622032fa3dfcdc739acef80e Mon Sep 17 00:00:00 2001 From: Jason Gladish Date: Wed, 27 Sep 2023 17:14:11 -0400 Subject: [PATCH 18/19] Fix issues with release script Why is this change needed? -------------------------- Without these changes we get the following error: ``` gpg: connecting dirmngr at '/root/.gnupg/S.dirmngr' failed: IPC connect call failed gpg: error searching keyserver: No dirmngr gpg: keyserver search failed: No dirmngr ``` It seems to be because the sockets in the host's `~/.gnupg` directory are not accessible to the container. How does it address the issue? ------------------------------ We copy the contents of the host's `~/.gnupg` directory into the container's `~/.gnupg` directory during the release script run. This sets up the container's `~/.gnupg` directory with the same contents as the host's `~/.gnupg` directory excluding the sockets, which gnupg will setup itself when run inside the container. Did you complete all of the following? -------------------------------------- - Run test suite? - Add new tests? - Consider security implications and practices? --- .docker_mounts.list | 2 +- script/release | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.docker_mounts.list b/.docker_mounts.list index 7fb6f8d..e6d449e 100644 --- a/.docker_mounts.list +++ b/.docker_mounts.list @@ -1,4 +1,4 @@ # Specify mounts in `docker run --volume` format (source:target). Bash # expressions will be evaluated. # $(pwd)/tmp/cache_${image//:/_}:/app/tmp/cache -${HOME}/.gnupg/docraptor:/root/.gnupg +${HOME}/.gnupg/docraptor:/root/.gnupg_host_docraptor diff --git a/script/release b/script/release index ab2d035..3ffe7b8 100755 --- a/script/release +++ b/script/release @@ -35,6 +35,11 @@ cp -vb "$maven_settings_path" ~/.m2/"$(basename "$maven_settings_path")" echo "Moved." echo +echo "Setting up gnupg..." +mkdir -v ~/.gnupg +find ~/.gnupg_host_docraptor/ -maxdepth 1 -mindepth 1 -type d,f,l -exec cp -vr '{}' ~/.gnupg/ \; +chmod -R 700 ~/.gnupg/ + echo "Installing gpg-agent..." apt-get update DEBIAN_FRONTEND=noninteractive apt-get install -qq gpg-agent From 4d206daedb9746b331ba24f25c552adef831de4a Mon Sep 17 00:00:00 2001 From: Nathan Acuff Date: Tue, 2 Apr 2024 17:36:32 -0400 Subject: [PATCH 19/19] Introduce the userAgentToken parameter, which is currently not (yet) officially supported. It allows the user to pass a token which will then be used when retrieving any document content or resources from your servers. Why is this change needed? -------------------------- Many DocRaptor customers have security configurations that require workarounds to make docs that contain resources they do not want to expose to the open internet. This will enable firewall settings to filter based on user agent using a token that is passed to DocRaptor with each document. Any links to any relevant tickets, articles, or other resources? --------------------------------------------------------------- Any screenshots? ---------------- Did you complete all of the following? -------------------------------------- - Run test suite? - Add new tests? - Consider security implications and practices? Co-authored-by: Zach Hunt --- .review/generated_files/README.md | 6 +-- .review/generated_files/docs/Doc.md | 1 + .../src/test/java/com/docraptor/DocTest.java | 8 +++ CHANGELOG.md | 3 ++ README.md | 2 +- api/openapi.yaml | 5 ++ build.gradle | 2 +- docraptor.yaml | 3 ++ generator-config.json | 2 +- pom.xml | 2 +- src/main/java/com/docraptor/ApiClient.java | 2 +- src/main/java/com/docraptor/Doc.java | 39 ++++++++++++-- test/UserAgentTokenTest.java | 53 +++++++++++++++++++ 13 files changed, 117 insertions(+), 11 deletions(-) create mode 100644 test/UserAgentTokenTest.java diff --git a/.review/generated_files/README.md b/.review/generated_files/README.md index c436cda..edf800a 100644 --- a/.review/generated_files/README.md +++ b/.review/generated_files/README.md @@ -40,7 +40,7 @@ Add this dependency to your project's POM: com.docraptor docraptor - 3.1.0 + 3.2.0 compile ``` @@ -56,7 +56,7 @@ Add this dependency to your project's build file: } dependencies { - implementation "com.docraptor:docraptor:3.1.0" + implementation "com.docraptor:docraptor:3.2.0" } ``` @@ -70,7 +70,7 @@ mvn clean package Then manually install the following JARs: -- `target/docraptor-3.1.0.jar` +- `target/docraptor-3.2.0.jar` - `target/lib/*.jar` ## Getting Started diff --git a/.review/generated_files/docs/Doc.md b/.review/generated_files/docs/Doc.md index ed58936..529e54a 100644 --- a/.review/generated_files/docs/Doc.md +++ b/.review/generated_files/docs/Doc.md @@ -24,6 +24,7 @@ |**hostedDownloadLimit** | **Integer** | The number of times a hosted document can be downloaded. If no limit is specified, the document will be available for an unlimited number of downloads. | [optional] | |**hostedExpiresAt** | **String** | The date and time at which a hosted document will be removed and no longer available. Must be a properly formatted ISO 8601 datetime, like 1981-01-23T08:02:30-05:00. | [optional] | |**princeOptions** | [**PrinceOptions**](PrinceOptions.md) | | [optional] | +|**userAgentToken** | **String** | A token that will be added to the user agent for all requests made for document content while creating a PDF. | [optional] | diff --git a/.review/generated_files/src/test/java/com/docraptor/DocTest.java b/.review/generated_files/src/test/java/com/docraptor/DocTest.java index eef598c..6722034 100644 --- a/.review/generated_files/src/test/java/com/docraptor/DocTest.java +++ b/.review/generated_files/src/test/java/com/docraptor/DocTest.java @@ -176,4 +176,12 @@ public void princeOptionsTest() { // TODO: test princeOptions } + /** + * Test the property 'userAgentToken' + */ + @Test + public void userAgentTokenTest() { + // TODO: test userAgentToken + } + } diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fdfe43..c4f8d75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +### 3.2.0 [April 2, 2024] +* Add the new userAgentToken API option, to enable passing a key that will be passed back on resource requests + ### 3.1.0 [July 14, 2023] * Add new API options (including prince_options[pdf_forms] to enable PDF forms) diff --git a/README.md b/README.md index 512e55a..814e786 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ After the client library is installed/deployed, you can use it in your Maven pro com.docraptor docraptor - 3.1.0 + 3.2.0 ``` diff --git a/api/openapi.yaml b/api/openapi.yaml index 0392ef3..ce8aff4 100644 --- a/api/openapi.yaml +++ b/api/openapi.yaml @@ -401,6 +401,7 @@ components: disallow_print: true disallow_copy: true iframes: true + user_agent_token: user_agent_token name: name tag: tag strict: none @@ -483,6 +484,10 @@ components: type: string prince_options: $ref: '#/components/schemas/PrinceOptions' + user_agent_token: + description: A token that will be added to the user agent for all requests + made for document content while creating a PDF. + type: string required: - document_content - document_type diff --git a/build.gradle b/build.gradle index 83b2f92..9f90c24 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'idea' apply plugin: 'eclipse' group = 'com.docraptor' -version = '3.1.0' +version = '3.2.0' buildscript { repositories { diff --git a/docraptor.yaml b/docraptor.yaml index ce46cac..412a1cc 100644 --- a/docraptor.yaml +++ b/docraptor.yaml @@ -307,6 +307,9 @@ definitions: description: The date and time at which a hosted document will be removed and no longer available. Must be a properly formatted ISO 8601 datetime, like 1981-01-23T08:02:30-05:00. prince_options: $ref: '#/definitions/PrinceOptions' + user_agent_token: + type: string + description: A token that will be added to the user agent for all requests made for document content while creating a PDF. PrinceOptions: type: object diff --git a/generator-config.json b/generator-config.json index cb70d0c..eface31 100644 --- a/generator-config.json +++ b/generator-config.json @@ -4,7 +4,7 @@ "apiPackage": "com.docraptor", "groupId": "com.docraptor", "artifactId": "docraptor", - "artifactVersion": "3.1.0", + "artifactVersion": "3.2.0", "artifactUrl": "https://github.com/DocRaptor/docraptor-java", "artifactDescription": "A native client library for the DocRaptor HTML to PDF/XLS service.", "scmConnection": "scm:git:git@github.com:DocRaptor/docraptor-java.git", diff --git a/pom.xml b/pom.xml index f73481e..1c943bf 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ docraptor jar docraptor - 3.1.0 + 3.2.0 https://github.com/DocRaptor/docraptor-java A native client library for the DocRaptor HTML to PDF/XLS service. diff --git a/src/main/java/com/docraptor/ApiClient.java b/src/main/java/com/docraptor/ApiClient.java index 2f4fedc..4f099fe 100644 --- a/src/main/java/com/docraptor/ApiClient.java +++ b/src/main/java/com/docraptor/ApiClient.java @@ -98,7 +98,7 @@ public ApiClient() { dateFormat = ApiClient.buildDefaultDateFormat(); // Set default User-Agent. - setUserAgent("OpenAPI-Generator/3.1.0/java"); + setUserAgent("OpenAPI-Generator/3.2.0/java"); // Setup authentications (key: authentication name, value: authentication). authentications = new HashMap(); diff --git a/src/main/java/com/docraptor/Doc.java b/src/main/java/com/docraptor/Doc.java index 54aade9..b3a3480 100644 --- a/src/main/java/com/docraptor/Doc.java +++ b/src/main/java/com/docraptor/Doc.java @@ -46,7 +46,8 @@ Doc.JSON_PROPERTY_CALLBACK_URL, Doc.JSON_PROPERTY_HOSTED_DOWNLOAD_LIMIT, Doc.JSON_PROPERTY_HOSTED_EXPIRES_AT, - Doc.JSON_PROPERTY_PRINCE_OPTIONS + Doc.JSON_PROPERTY_PRINCE_OPTIONS, + Doc.JSON_PROPERTY_USER_AGENT_TOKEN }) @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") public class Doc { @@ -173,6 +174,9 @@ public static StrictEnum fromValue(String value) { public static final String JSON_PROPERTY_PRINCE_OPTIONS = "prince_options"; private PrinceOptions princeOptions; + public static final String JSON_PROPERTY_USER_AGENT_TOKEN = "user_agent_token"; + private String userAgentToken; + public Doc() { } @@ -635,6 +639,33 @@ public void setPrinceOptions(PrinceOptions princeOptions) { } + public Doc userAgentToken(String userAgentToken) { + + this.userAgentToken = userAgentToken; + return this; + } + + /** + * A token that will be added to the user agent for all requests made for document content while creating a PDF. + * @return userAgentToken + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "A token that will be added to the user agent for all requests made for document content while creating a PDF.") + @JsonProperty(JSON_PROPERTY_USER_AGENT_TOKEN) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getUserAgentToken() { + return userAgentToken; + } + + + @JsonProperty(JSON_PROPERTY_USER_AGENT_TOKEN) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setUserAgentToken(String userAgentToken) { + this.userAgentToken = userAgentToken; + } + + @Override public boolean equals(Object o) { if (this == o) { @@ -660,12 +691,13 @@ public boolean equals(Object o) { Objects.equals(this.callbackUrl, doc.callbackUrl) && Objects.equals(this.hostedDownloadLimit, doc.hostedDownloadLimit) && Objects.equals(this.hostedExpiresAt, doc.hostedExpiresAt) && - Objects.equals(this.princeOptions, doc.princeOptions); + Objects.equals(this.princeOptions, doc.princeOptions) && + Objects.equals(this.userAgentToken, doc.userAgentToken); } @Override public int hashCode() { - return Objects.hash(name, documentType, documentContent, documentUrl, test, pipeline, strict, ignoreResourceErrors, ignoreConsoleMessages, tag, help, javascript, referrer, callbackUrl, hostedDownloadLimit, hostedExpiresAt, princeOptions); + return Objects.hash(name, documentType, documentContent, documentUrl, test, pipeline, strict, ignoreResourceErrors, ignoreConsoleMessages, tag, help, javascript, referrer, callbackUrl, hostedDownloadLimit, hostedExpiresAt, princeOptions, userAgentToken); } @Override @@ -689,6 +721,7 @@ public String toString() { sb.append(" hostedDownloadLimit: ").append(toIndentedString(hostedDownloadLimit)).append("\n"); sb.append(" hostedExpiresAt: ").append(toIndentedString(hostedExpiresAt)).append("\n"); sb.append(" princeOptions: ").append(toIndentedString(princeOptions)).append("\n"); + sb.append(" userAgentToken: ").append(toIndentedString(userAgentToken)).append("\n"); sb.append("}"); return sb.toString(); } diff --git a/test/UserAgentTokenTest.java b/test/UserAgentTokenTest.java new file mode 100644 index 0000000..acee39d --- /dev/null +++ b/test/UserAgentTokenTest.java @@ -0,0 +1,53 @@ +import java.io.*; +import java.net.*; +import com.docraptor.*; + +public class UserAgentTokenTest { + public static void main(String[] args) throws Exception { + DocApi docraptor = new DocApi(); + ApiClient client = docraptor.getApiClient(); + client.setUsername("YOUR_API_KEY_HERE"); + // client.setDebugging(true); + + // Verify prince_options works by testing a url that will fail without + // prince_options[insecure]=true. + Doc doc = new Doc(); + doc.setName("java-ua-token.pdf"); + doc.setTest(true); + doc.setDocumentType(Doc.DocumentTypeEnum.PDF); + doc.setDocumentUrl("https://docraptor-test-harness.herokuapp.com/agent/agent_tester.html"); + doc.setUserAgentToken("SpecialToken Yay!"); + + byte data[] = docraptor.createDoc(doc); + + String output_file = System.getenv("TEST_OUTPUT_DIR") + + "/" + System.getenv("TEST_NAME") + "_csharp_" + + System.getenv("RUNTIME_ENV") + ".pdf"; + + FileOutputStream out = new FileOutputStream(output_file); + out.write(data); + out.close(); + + BufferedReader br = new BufferedReader(new FileReader(output_file)); + String line = br.readLine(); + if (!line.contains("%PDF-1.5")) { + throw new IllegalArgumentException("unexpected file header: " + line); + } + + String command = "pdftotext " + output_file + " -"; + + String[] commands = {"bash", "-c", command}; + Process p = Runtime.getRuntime().exec(commands); + p.waitFor(); + BufferedReader b = new BufferedReader(new InputStreamReader(p.getInputStream())); + String output = ""; + while ((line = b.readLine()) != null) { + output += line; + } + b.close(); + + if(!output.contains("SpecialToken Yay!")) { + throw new IllegalArgumentException("output should have contained user agent token content: " + output); + } + } +}