adobe_doc_api 0.1.3 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4e5a77582f1fc5d80a10d049be384c0abf2dbe2b4206522128e536a8787517de
4
- data.tar.gz: 5373eb84624217386db5663be8b8c829dcd9b98128a5a634c9467185ce3e6f3d
3
+ metadata.gz: 561ccbe710cbc9856655dc3d4235846dc2c55bacbc6d44794cc76282846b87b1
4
+ data.tar.gz: 7df931d666bb7cd7007b7c870504b996a77103e80a09ba5e97c21e9b96f8e8c8
5
5
  SHA512:
6
- metadata.gz: 9b0b0dd6eff1e19d986ef5e52e0b2409b88ecba9bac484948ed7366a485b062f94c7c11f81160735f714e08c5a24a38b6baca8cbebd15148c9562e8b360f7fdc
7
- data.tar.gz: aa00f4f6446199a46dab1b0101cbc3acd71ab44692375b83695e7062eccacab12b549298528a80f45e9c80b46ddc42217339a36d7d612aa91c39c3e86070d71c
6
+ metadata.gz: cc3925566f5027e07062cfd437d65898df2e688d33b39b6977bdf1d9954688e1d8677cb72d81b1ff4142082c022d258590166499380e37572af147da9c12cf85
7
+ data.tar.gz: 8500d15211572b7377e7e2710ca0d6c926555df58e3980972561f6b3843f483381d1d2fe70e69487c8f2edbe71a1953a8372b6f4eed38f872742871577dd9cb3
data/CHANGELOG.md CHANGED
@@ -1,4 +1,9 @@
1
- ## [Unreleased]
1
+ ## [0.2.1] - 2023-06-20
2
+ - Updates to Adobe PDF Services API
3
+ - Removed JWT token authentication
4
+
5
+ ## [0.1.4] - 2021-12-30
6
+ - Fix issue with parsing file boundary that included \r\n
2
7
 
3
8
  ## [0.1.3] - 2021-12-30
4
9
  - Added ability to configure AdobeDocApi to provide better customization
data/Gemfile.lock ADDED
@@ -0,0 +1,57 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ adobe_doc_api (0.2.0)
5
+ faraday (~> 1.8)
6
+ faraday_middleware (~> 1.2)
7
+ jwt (~> 2.3.0)
8
+ openssl (~> 2.2.1)
9
+
10
+ GEM
11
+ remote: https://rubygems.org/
12
+ specs:
13
+ faraday (1.10.3)
14
+ faraday-em_http (~> 1.0)
15
+ faraday-em_synchrony (~> 1.0)
16
+ faraday-excon (~> 1.1)
17
+ faraday-httpclient (~> 1.0)
18
+ faraday-multipart (~> 1.0)
19
+ faraday-net_http (~> 1.0)
20
+ faraday-net_http_persistent (~> 1.0)
21
+ faraday-patron (~> 1.0)
22
+ faraday-rack (~> 1.0)
23
+ faraday-retry (~> 1.0)
24
+ ruby2_keywords (>= 0.0.4)
25
+ faraday-em_http (1.0.0)
26
+ faraday-em_synchrony (1.0.0)
27
+ faraday-excon (1.1.0)
28
+ faraday-httpclient (1.0.1)
29
+ faraday-multipart (1.0.4)
30
+ multipart-post (~> 2)
31
+ faraday-net_http (1.0.1)
32
+ faraday-net_http_persistent (1.2.0)
33
+ faraday-patron (1.0.0)
34
+ faraday-rack (1.0.0)
35
+ faraday-retry (1.0.3)
36
+ faraday_middleware (1.2.0)
37
+ faraday (~> 1.0)
38
+ ipaddr (1.2.5)
39
+ jwt (2.3.0)
40
+ minitest (5.15.0)
41
+ multipart-post (2.3.0)
42
+ openssl (2.2.3)
43
+ ipaddr
44
+ rake (13.0.6)
45
+ ruby2_keywords (0.0.5)
46
+
47
+ PLATFORMS
48
+ x86_64-darwin-19
49
+ x86_64-linux
50
+
51
+ DEPENDENCIES
52
+ adobe_doc_api!
53
+ minitest (~> 5.0)
54
+ rake (~> 13.0)
55
+
56
+ BUNDLED WITH
57
+ 2.2.32
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # AdobeDocApi
2
2
 
3
- This is still a work in progress. Use at your own risk.
3
+ This is still a work in progress and breaking changes may be made, but I will do my best to update the README when features have been changed.
4
4
 
5
5
  ## Installation
6
6
 
@@ -18,35 +18,46 @@ Or install it yourself as:
18
18
 
19
19
  $ gem install adobe_doc_api
20
20
 
21
- ## Configuration
22
- * Configuration can be overridden if you need by passing the values to AdobeDocApi::Client.new
21
+ ## Configuration
23
22
  ```ruby
24
23
  AdobeDocApi.configure do |config|
25
- config.client_id = nil
26
- config.client_secret = nil
27
- config.org_id = nil
28
- config.tech_account_id = nil
29
- config.private_key_path = nil
24
+ config.client_id = nil
25
+ config.client_secret = nil
26
+ config.org_id = nil
27
+ config.tech_account_id = nil
28
+ config.private_key_path = nil
29
+ end
30
+ ```
31
+ ### Recommended configuration if using Rails 6+
32
+ ```ruby
33
+ AdobeDocApi.configure do |config|
34
+ config.client_id = Rails.application.credentials.dig(:adobe_doc, :client_id)
35
+ config.client_secret = Rails.application.credentials.dig(:adobe_doc, :client_secret)
36
+ config.org_id = Rails.application.credentials.dig(:adobe_doc, :org_id)
37
+ config.tech_account_id = Rails.application.credentials.dig(:adobe_doc, :tech_account_id)
38
+ config.private_key_path = Rails.application.credentials.dig(:adobe_doc, :private_key_path)
30
39
  end
31
40
  ```
32
-
33
41
  ## Usage
34
42
 
35
43
  ```ruby
36
- key_path = "../full_path_to/private.key"
37
44
  template_path = "../full_path_to/disclosure.docx"
38
45
  output_path = "../full_path_to_output/output.docx"
39
46
  json_data = { 'DocTag': 'Value', 'DocTag2': 'Value2'}
40
47
 
41
48
  client = AdobeDocApi::Client.new
42
-
43
- # Without configuration you must pass these values
44
- # client = AdobeDocApi::Client.new(private_key: key_path, client_id: ENV['adobe_client_id'], client_secret: ENV['adobe_client_secret']org_id: ENV['adobe_org_id'], tech_account_id: ENV['adobe_tech_account_id'], access_token: nil)
45
-
46
49
  client.submit(json: json_data, template: template_path, output: output_path)
47
50
  # returns true or false if file was saved to output_path
48
51
  ```
49
-
52
+ ### Usage without configuration
53
+ ```ruby
54
+ client = AdobeDocApi::Client.new(private_key: key_path,
55
+ client_id: adobe_client_id,
56
+ client_secret: adobe_client_secret,
57
+ org_id: adobe_org_id,
58
+ tech_account_id: adobe_tech_account_id,
59
+ access_token: nil)
60
+ ```
50
61
  ## Todo
51
62
  - [x] Add multipart parsing to improve saving the file from the response
52
63
  - [ ] Add documentation
@@ -24,78 +24,85 @@ module AdobeDocApi
24
24
  end
25
25
 
26
26
  def get_access_token(private_key)
27
- jwt_payload = {
28
- "iss" => @org_id,
29
- "sub" => @tech_account_id,
30
- "https://ims-na1.adobelogin.com/s/ent_documentcloud_sdk" => true,
31
- "aud" => "https://ims-na1.adobelogin.com/c/#{@client_id}",
32
- "exp" => (Time.now.utc + 60).to_i
33
- }
34
-
35
- rsa_private = OpenSSL::PKey::RSA.new File.read(private_key)
36
-
37
- jwt_token = JWT.encode jwt_payload, rsa_private, "RS256"
38
-
27
+ # TODO: JWT token deprecated and will stop working Jan 1, 2024.
28
+ # jwt_payload = {
29
+ # "iss" => @org_id,
30
+ # "sub" => @tech_account_id,
31
+ # "https://ims-na1.adobelogin.com/s/ent_documentcloud_sdk" => true,
32
+ # "aud" => "https://ims-na1.adobelogin.com/c/#{@client_id}",
33
+ # "exp" => (Time.now.utc + 60).to_i
34
+ # }
35
+ #
36
+ # rsa_private = OpenSSL::PKey::RSA.new File.read(private_key)
37
+ #
38
+ # jwt_token = JWT.encode jwt_payload, rsa_private, "RS256"
39
+ #
39
40
  connection = Faraday.new do |conn|
40
41
  conn.response :json, content_type: "application/json"
41
42
  end
42
- response = connection.post JWT_URL do |req|
43
+ # response = connection.post JWT_URL do |req|
44
+ # req.params["client_id"] = @client_id
45
+ # req.params["client_secret"] = @client_secret
46
+ # req.params["jwt_token"] = jwt_token
47
+ # end
48
+ scopes = "openid, DCAPI, AdobeID"
49
+
50
+ response = connection.post "https://ims-na1.adobelogin.com/ims/token/v3" do |req|
43
51
  req.params["client_id"] = @client_id
44
- req.params["client_secret"] = @client_secret
45
- req.params["jwt_token"] = jwt_token
52
+ req.body = "client_secret=#{@client_secret}&grant_type=client_credentials&scope=#{scopes}"
46
53
  end
47
-
48
54
  return response.body["access_token"]
49
55
  end
50
56
 
57
+ def get_asset_id
58
+ # Create new asset ID to get upload pre-signed Uri
59
+ connection = Faraday.new do |conn|
60
+ conn.request :authorization, "Bearer", @access_token
61
+ conn.headers["x-api-key"] = @client_id
62
+ conn.headers["Content-Type"] = ""
63
+ conn.response :json, content_type: "application/json"
64
+ end
65
+ response = connection.post "https://pdf-services.adobe.io/assets" do |req|
66
+ req.body = {mediaType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"}.to_json
67
+ req.headers["Content-Type"] = "application/json"
68
+ end
69
+ # Return pre-signed uploadUri and assedID
70
+ return response.body["assetID"], response.body["uploadUri"]
71
+ end
72
+
51
73
  def submit(json:, template:, output:)
52
- @output = output
53
- output_format = /docx/.match?(File.extname(@output)) ? "application/vnd.openxmlformats-officedocument.wordprocessingml.document" : "application/pdf"
74
+ asset_id, upload_uri = get_asset_id
54
75
 
76
+ # Upload template to asset created earlier.
77
+ response = Faraday.put upload_uri do |req|
78
+ req.headers["Content-Type"] = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
79
+ req.body = File.binread(template)
80
+ end
81
+ raise("Failed to upload template.") if response.status.to_i != 200
82
+
83
+ # Post JSON Data for Merge to documentGeneration
55
84
  content_request = {
56
- "cpf:engine": {
57
- "repo:assetId": "urn:aaid:cpf:Service-52d5db6097ed436ebb96f13a4c7bf8fb"
58
- },
59
- "cpf:inputs": {
60
- documentIn: {
61
- "dc:format": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
62
- "cpf:location": "InputFile0"
63
- },
64
- params: {
65
- "cpf:inline": {
66
- outputFormat: File.extname(@output).delete("."),
67
- jsonDataForMerge: json
68
- }
69
- }
70
- },
71
- "cpf:outputs": {
72
- documentOut: {
73
- "dc:format": output_format.to_s,
74
- "cpf:location": "multipartLabel"
75
- }
76
- }
85
+ assetID: asset_id,
86
+ outputFormat: File.extname(output).delete("."),
87
+ jsonDataForMerge: json
77
88
  }.to_json
78
-
79
- connection = Faraday.new API_ENDPOINT_URL do |conn|
89
+ payload = content_request
90
+ connection = Faraday.new do |conn|
80
91
  conn.request :authorization, "Bearer", @access_token
81
92
  conn.headers["x-api-key"] = @client_id
82
- conn.request :multipart
83
- conn.request :url_encoded
84
- conn.response :json, content_type: "application/json"
85
93
  end
86
-
87
- payload = {"contentAnalyzerRequests" => content_request}
88
- payload[:InputFile0] = Faraday::FilePart.new(template, "application/vnd.openxmlformats-officedocument.wordprocessingml.document")
89
- res = connection.post("/ops/:create", payload)
90
- status_code = res.body["cpf:status"]["status"].to_i
91
- @location_url = res.headers["location"]
92
- raise Error.new(status_code: status_code, msg: res.body["cpf:status"]) unless status_code == 202
93
- poll_for_file(@location_url)
94
+ res = connection.post "https://pdf-services-ue1.adobe.io/operation/documentgeneration" do |req|
95
+ req.body = payload
96
+ req.headers["Content-Type"] = "application/json"
97
+ end
98
+ # TODO need to check status of response
99
+ # Begin polling for status of file
100
+ poll_for_file(res.headers["location"], output)
94
101
  end
95
102
 
96
103
  private
97
104
 
98
- def poll_for_file(url)
105
+ def poll_for_file(url, output)
99
106
  connection = Faraday.new do |conn|
100
107
  conn.request :authorization, "Bearer", @access_token
101
108
  conn.headers["x-api-key"] = @client_id
@@ -105,11 +112,11 @@ module AdobeDocApi
105
112
  sleep(6)
106
113
  response = connection.get(url)
107
114
  counter += 1
108
- if response.body.include?('"cpf:status":{"completed":true,"type":"","status":200}')
109
- @raw_response = response
110
- return write_to_file(response.body)
115
+ if JSON.parse(response.body)["status"] == "done"
116
+ file_response = Faraday.get JSON.parse(response.body)["asset"]["downloadUri"]
117
+ return true if File.open(output, "wb") { |f| f.write file_response.body}
111
118
  else
112
- status = JSON.parse(response.body)["cpf:status"]
119
+ status = JSON.parse(response.body)["status"]
113
120
  raise Error.new(status_code: status["status"], msg: status) if status["status"] != 202
114
121
  end
115
122
  break if counter > 10
@@ -119,21 +126,5 @@ module AdobeDocApi
119
126
  end
120
127
  end
121
128
 
122
- def write_to_file(response_body)
123
- line_index = []
124
- lines = response_body.split("\r\n")
125
- lines.each_with_index do |line, i|
126
- next if line.include?("--Boundary_") || line.match?(/^Content-(Type|Disposition):/) || line.empty? || JSON.parse(line.force_encoding("UTF-8").to_s)
127
- rescue
128
- line_index << i
129
- end
130
- if line_index.length == 1
131
- File.open(@output, "wb") { |f| f.write lines.at(line_index[0])}
132
- true
133
- else
134
- false
135
- end
136
- end
137
-
138
129
  end
139
130
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AdobeDocApi
4
- VERSION = "0.1.3"
4
+ VERSION = "0.2.1"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: adobe_doc_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Sonnier
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-12-30 00:00:00.000000000 Z
11
+ date: 2023-06-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -76,6 +76,7 @@ files:
76
76
  - CHANGELOG.md
77
77
  - CODE_OF_CONDUCT.md
78
78
  - Gemfile
79
+ - Gemfile.lock
79
80
  - LICENSE.txt
80
81
  - README.md
81
82
  - Rakefile