pandexio 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,78 +1,78 @@
1
- #Pandexio SDK for Ruby
2
-
3
- ##Overview
4
- This Pandexio SDK enables Ruby server applications to easily generate signed requests that can be consumed by the Pandexio REST API (https://platform.pandexio.com) and the Pandexio Hosted Model (https://hosted.pandexio.com).
5
-
6
- ##Definitions
7
-
8
- ###Pandexio::Request
9
- - type - class
10
- - attributes:
11
- - method - required. The request HTTP verb (GET, POST, PUT, PATCH, DELETE).
12
- - path - required. The path part of the request URL (e.g., /v2/documents/a4df7a95-d1f6-4664-b208-74568990bd15).
13
- - query_parameters - optional. A hash containing the query parameters (e.g., { "coverSize" => "xl" }).
14
- - headers - required. A hash containing the headers (e.g., { "Host" => "platform.pandexio.com" }). Host header must be included.
15
- - payload - optional. UTF-8 encoded request body. Only applicable for POST, PUT, and PATCH requests.
16
-
17
- ###Pandexio::SigningOptions
18
- - type - class
19
- - attributes:
20
- - algorithm - required. The HMAC algorithm to use. Choose from any specified in
21
- - Pandexio::SigningAlgorithms::PDX_HMAC_MD5 - MD5 HMAC
22
- - Pandexio::SigningAlgorithms::PDX_HMAC_SHA1 - SHA1 HMAC
23
- - Pandexio::SigningAlgorithms::PDX_HMAC_SHA256 - SHA256 HMAC
24
- - Pandexio::SigningAlgorithms::PDX_HMAC_SHA384 - SHA384 HMAC
25
- - Pandexio::SigningAlgorithms::PDX_HMAC_SHA512 - SHA512 HMAC
26
- - mechanism - required. Specifies which signing mechanism to use. Signing mechanisms include:
27
- - Pandexio::SigningMechanisms::QUERY_STRING - Sign the request using query string parameters
28
- - Pandexio::SigningMechanisms::HEADER - Sign the request using headers
29
- - domain_id - required. Public API key.
30
- - domain_key - required. Shared secret API key used to generate HMAC signatures.
31
- - date - required. ISO8601 date/time when the request was made.
32
- - expires - required. Number of seconds before the request signature expires.
33
- - originator - required. The name of the application, feature, etc. making the request.
34
- - email_address - required. The email address of the user making the request.
35
- - display_name - required. The display name of the user making the request.
36
- - profile_image - optional. The profile image thumbnail, either data URL or HTTP URL of the user making the request.
37
-
38
- ###Pandexio::to_authorized_request
39
- - type - method
40
- - arguments
41
- - Pandexio::Request *normalized_request* - A non-signed request containing information about the request to be made.
42
- - Pandexio::SigningOptions *signing_options* - The details specifying how to sign the *normalized_request*
43
- - result
44
- - Pandexio::Request *authorized_request* - A signed request containing information about the request to be made as well as signing information as headers or query string parameters, depending on the *signing_options*.
45
-
46
- ##Signing a Request
47
- Take the following steps to create a signed Pandexio request.
48
-
49
- 1. Create an instance of Pandexio::Request containing details of the request to be made, the *normalized_request*.
50
- 2. Create an instance of Pandexio::SigningOptions. These *signing_options* specify the SDK will sign the request.
51
- 3. Call Pandexio::to_authorized_request, passing in the *normalized_request* and the *signing_options*.
52
- 4. Build an HTTP request using the Pandexio::Request, *authorized_request*, returned by Pandexio::to_authorized_request and make the HTTP request using the HTTP client of choice.
53
-
54
- ##All Together
55
- Here's an example showing the generation of a signed Pandexio request to retrieve an extra large document cover thumbnail for a given document:
56
-
57
- ```ruby
58
- require 'pandexio'
59
-
60
- normalized_request = Pandexio::Request.new(
61
- :method => "GET",
62
- :path => "/v2/documents/a4df7a95-d1f6-4664-b208-74568990bd15/cover",
63
- :query_parameters => { "coverSize" => "xl" },
64
- :headers => { "Host" => "platform.pandexio.com" })
65
-
66
- signing_options = Pandexio::SigningOptions.new(
67
- :algorithm => Pandexio::SigningAlgorithms::PDX_HMAC_SHA256,
68
- :mechanism => Pandexio::SigningMechanisms::QUERY_STRING,
69
- :domain_id => "1234567890",
70
- :domain_key => "asdfjklqwerzxcv",
71
- :date => Time.utc(2015, 6, 10, 13, 22, 46),
72
- :expires => 90,
73
- :originator => "Demo",
74
- :email_address => "terry@contoso.com",
75
- :display_name => "Terry Contoso")
76
-
77
- authorized_request = Pandexio::to_authorized_request(normalized_request, signing_options)
78
- ```
1
+ #Pandexio SDK for Ruby
2
+
3
+ ##Overview
4
+ This Pandexio SDK enables Ruby server applications to easily generate signed requests that can be consumed by the Pandexio REST API (https://platform.pandexio.com) and the Pandexio Hosted Model (https://hosted.pandexio.com).
5
+
6
+ ##Definitions
7
+
8
+ ###Pandexio::Request
9
+ - type - class
10
+ - attributes:
11
+ - method - required. The request HTTP verb (GET, POST, PUT, PATCH, DELETE).
12
+ - path - required. The path part of the request URL (e.g., /v2/documents/a4df7a95-d1f6-4664-b208-74568990bd15).
13
+ - query_parameters - optional. A hash containing the query parameters (e.g., { "coverSize" => "xl" }).
14
+ - headers - required. A hash containing the headers (e.g., { "Host" => "platform.pandexio.com" }). Host header must be included.
15
+ - payload - optional. UTF-8 encoded request body. Only applicable for POST, PUT, and PATCH requests.
16
+
17
+ ###Pandexio::SigningOptions
18
+ - type - class
19
+ - attributes:
20
+ - algorithm - required. The HMAC algorithm to use. Choose from any specified in
21
+ - Pandexio::SigningAlgorithms::PDX_HMAC_MD5 - MD5 HMAC
22
+ - Pandexio::SigningAlgorithms::PDX_HMAC_SHA1 - SHA1 HMAC
23
+ - Pandexio::SigningAlgorithms::PDX_HMAC_SHA256 - SHA256 HMAC
24
+ - Pandexio::SigningAlgorithms::PDX_HMAC_SHA384 - SHA384 HMAC
25
+ - Pandexio::SigningAlgorithms::PDX_HMAC_SHA512 - SHA512 HMAC
26
+ - mechanism - required. Specifies which signing mechanism to use. Signing mechanisms include:
27
+ - Pandexio::SigningMechanisms::QUERY_STRING - Sign the request using query string parameters
28
+ - Pandexio::SigningMechanisms::HEADER - Sign the request using headers
29
+ - domain_id - required. Public API key.
30
+ - domain_key - required. Shared secret API key used to generate HMAC signatures.
31
+ - date - required. ISO8601 date/time when the request was made.
32
+ - expires - required. Number of seconds before the request signature expires.
33
+ - originator - required. The name of the application, feature, etc. making the request.
34
+ - email_address - required. The email address of the user making the request.
35
+ - display_name - required. The display name of the user making the request.
36
+ - profile_image - optional. The profile image thumbnail, either data URL or HTTP URL of the user making the request.
37
+
38
+ ###Pandexio::to_authorized_request
39
+ - type - method
40
+ - arguments
41
+ - Pandexio::Request *normalized_request* - A non-signed request containing information about the request to be made.
42
+ - Pandexio::SigningOptions *signing_options* - The details specifying how to sign the *normalized_request*
43
+ - result
44
+ - Pandexio::Request *authorized_request* - A signed request containing information about the request to be made as well as signing information as headers or query string parameters, depending on the *signing_options*.
45
+
46
+ ##Signing a Request
47
+ Take the following steps to create a signed Pandexio request.
48
+
49
+ 1. Create an instance of Pandexio::Request containing details of the request to be made, the *normalized_request*.
50
+ 2. Create an instance of Pandexio::SigningOptions. These *signing_options* specify the SDK will sign the request.
51
+ 3. Call Pandexio::to_authorized_request, passing in the *normalized_request* and the *signing_options*.
52
+ 4. Build an HTTP request using the Pandexio::Request, *authorized_request*, returned by Pandexio::to_authorized_request and make the HTTP request using the HTTP client of choice.
53
+
54
+ ##All Together
55
+ Here's an example showing the generation of a signed Pandexio request to retrieve an extra large document cover thumbnail for a given document:
56
+
57
+ ```ruby
58
+ require 'pandexio'
59
+
60
+ normalized_request = Pandexio::Request.new(
61
+ :method => "GET",
62
+ :path => "/v2/documents/a4df7a95-d1f6-4664-b208-74568990bd15/cover",
63
+ :query_parameters => { "coverSize" => "xl" },
64
+ :headers => { "Host" => "platform.pandexio.com" })
65
+
66
+ signing_options = Pandexio::SigningOptions.new(
67
+ :algorithm => Pandexio::SigningAlgorithms::PDX_HMAC_SHA256,
68
+ :mechanism => Pandexio::SigningMechanisms::QUERY_STRING,
69
+ :domain_id => "1234567890",
70
+ :domain_key => "asdfjklqwerzxcv",
71
+ :date => Time.utc(2015, 6, 10, 13, 22, 46),
72
+ :expires => 90,
73
+ :originator => "Demo",
74
+ :email_address => "terry@contoso.com",
75
+ :display_name => "Terry Contoso")
76
+
77
+ authorized_request = Pandexio::to_authorized_request(normalized_request, signing_options)
78
+ ```
data/Rakefile CHANGED
@@ -1,9 +1,9 @@
1
- require 'rake/testtask'
2
-
3
- Rake::TestTask.new do |t|
4
- t.libs << 'test'
5
- t.verbose = true
6
- end
7
-
8
- desc "Run tests"
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new do |t|
4
+ t.libs << 'test'
5
+ t.verbose = true
6
+ end
7
+
8
+ desc "Run tests"
9
9
  task :default => :test
data/lib/pandexio.rb CHANGED
@@ -1,153 +1,151 @@
1
- require 'time'
2
- require 'stringio'
3
- require 'openssl'
4
- require_relative 'request.rb'
5
- require_relative 'signing_algorithms.rb'
6
- require_relative 'signing_attributes.rb'
7
- require_relative 'signing_mechanisms.rb'
8
- require_relative 'signing_options.rb'
9
-
10
- module Pandexio
11
-
12
- LINE_BREAK = "\r\n"
13
- private_constant :LINE_BREAK
14
-
15
- private
16
-
17
- def self.ordinal_key_value_sort(a, b)
18
-
19
- a_codepoints, b_codepoints = a[0].codepoints, b[0].codepoints
20
-
21
- max_i = [a_codepoints.size, b_codepoints.size].min
22
-
23
- for i in 0..max_i
24
- a_codepoint = a_codepoints[i]
25
- b_codepoint = b_codepoints[i]
26
- return -1 if a_codepoint < b_codepoint
27
- return 1 if a_codepoint > b_codepoint
28
- end
29
-
30
- return 0
31
-
32
- end
33
-
34
- def self.build_canonical_query_string(query_parameters)
35
-
36
- temp_query_parameters = query_parameters.dup
37
-
38
- query_sort = ->(a,b) { ordinal_key_value_sort(a, b) }
39
- temp_query_parameters = temp_query_parameters.sort(&query_sort)
40
-
41
- canonical_query_string = StringIO.new
42
-
43
- temp_query_parameters.each do |key, value|
44
- next if key == SigningAttributes::ALGORITHM || key == SigningAttributes::CREDENTIAL || key == SigningAttributes::SIGNED_HEADERS || key == SigningAttributes::SIGNATURE
45
- canonical_query_string << "&" if canonical_query_string.length > 0
46
- canonical_query_string << "#{key}=#{value}"
47
- end
48
-
49
- return canonical_query_string.string
50
-
51
- end
52
-
53
- def self.build_canonical_headers(headers)
54
-
55
- temp_headers = {}
56
-
57
- headers.each do |key, value|
58
- next if key == SigningAttributes::AUTHORIZATION
59
- temp_headers[key.downcase.strip] = value
60
- end
61
-
62
- header_sort = ->(a,b) { ordinal_key_value_sort(a, b) }
63
- temp_headers = temp_headers.sort(&header_sort)
64
-
65
- canonical_headers, signed_headers = StringIO.new, StringIO.new
66
-
67
- temp_headers.each do |key, value|
68
- next if key == SigningAttributes::AUTHORIZATION
69
- canonical_headers << LINE_BREAK if canonical_headers.length > 0
70
- canonical_headers << "#{key}:#{value}"
71
- signed_headers << ";" if signed_headers.length > 0
72
- signed_headers << "#{key}"
73
- end
74
-
75
- return canonical_headers.string, signed_headers.string
76
-
77
- end
78
-
79
- def self.build_canonical_payload(payload, digest)
80
- canonical_payload = digest.hexdigest(payload).encode('UTF-8')
81
- return canonical_payload;
82
- end
83
-
84
- def self.build_canonical_request(request, digest)
85
- canonical_query_string = build_canonical_query_string(request.query_parameters)
86
- canonical_headers, signed_headers = build_canonical_headers(request.headers)
87
- canonical_payload = build_canonical_payload(request.payload, digest)
88
- canonical_request = "#{request.method}#{LINE_BREAK}#{request.path}#{LINE_BREAK}#{canonical_query_string}#{LINE_BREAK}#{canonical_headers}#{LINE_BREAK}#{signed_headers}#{LINE_BREAK}#{canonical_payload}"
89
- return canonical_request, signed_headers
90
- end
91
-
92
- def self.build_string_to_sign(canonical_request, signing_options)
93
- signing_string = "#{signing_options.algorithm}#{LINE_BREAK}#{signing_options.date.iso8601}#{LINE_BREAK}#{canonical_request}".encode('UTF-8')
94
- return signing_string
95
- end
96
-
97
- def self.generate_signature(string_to_sign, signing_options, digest)
98
- return OpenSSL::HMAC.hexdigest(digest, signing_options.domain_key, string_to_sign)
99
- end
100
-
101
- public
102
-
103
- def self.to_authorized_request(normalized_request, signing_options)
104
-
105
- raise ArgumentError, 'normalized_request must be of type Pandexio::Request and cannot be nil' unless !normalized_request.nil? && normalized_request.is_a?(Request)
106
- raise ArgumentError, 'normalized_request.query_parameters must be of type Hash and cannot be nil' unless !normalized_request.query_parameters.nil? && normalized_request.query_parameters.is_a?(Hash)
107
- raise ArgumentError, 'normalized_request.headers must be of type Hash and cannot be nil' unless !normalized_request.headers.nil? && normalized_request.headers.is_a?(Hash)
108
-
109
- raise ArgumentError, 'signing_options must be of type Pandexio::SigningOptions cannot be nil' unless !signing_options.nil? && signing_options.is_a?(SigningOptions)
110
- raise ArgumentError, 'signing_options.domain_id must be of type String and cannot be nil or empty' unless !signing_options.domain_id.nil? && signing_options.domain_id.is_a?(String) && !signing_options.domain_id.empty?
111
- raise ArgumentError, 'signing_options.domain_key must be of type String and cannot be nil or empty' unless !signing_options.domain_key.nil? && signing_options.domain_key.is_a?(String) && !signing_options.domain_key.empty?
112
- raise ArgumentError, 'signing_options.algorithm must be of type String and cannot be nil or empty' unless SigningAlgorithms.is_v(signing_options.algorithm)
113
- raise ArgumentError, 'signing_options.mechanism must be a valid signing mechanism' unless SigningMechanisms.is_v(signing_options.mechanism)
114
- raise ArgumentError, 'signing_options.date must be of type Time and cannot be nil' unless !signing_options.date.nil? && signing_options.date.is_a?(Time)
115
- raise ArgumentError, 'signing_options.expires must be of type Fixnum and cannot be nil or empty' unless !signing_options.expires.nil? && signing_options.expires.is_a?(Fixnum) && signing_options.expires > 0
116
- raise ArgumentError, 'signing_options.originator must be of type String and cannot be nil or empty' unless !signing_options.originator.nil? && signing_options.originator.is_a?(String) && !signing_options.originator.empty?
117
- raise ArgumentError, 'signing_options.email_address must be of type String and cannot be nil or empty' unless !signing_options.email_address.nil? && signing_options.email_address.is_a?(String) && !signing_options.email_address.empty?
118
- raise ArgumentError, 'signing_options.display_name must be of type String and cannot be nil or empty' unless !signing_options.display_name.nil? && signing_options.display_name.is_a?(String) && !signing_options.display_name.empty?
119
-
120
- authorized_request = normalized_request.dup
121
-
122
- append = -> (p) do
123
- p[SigningAttributes::DATE] = signing_options.date.iso8601
124
- p[SigningAttributes::EXPIRES] = signing_options.expires
125
- p[SigningAttributes::ORIGINATOR] = signing_options.originator
126
- p[SigningAttributes::EMAIL_ADDRESS] = signing_options.email_address
127
- p[SigningAttributes::DISPLAY_NAME] = signing_options.display_name
128
- p[SigningAttributes::PROFILE_IMAGE] = signing_options.profile_image if !signing_options.profile_image.nil? && signing_options.profile_image.is_a?(String) && !signing_options.profile_image.empty?
129
- end
130
-
131
- append.call(
132
- signing_options.mechanism == SigningMechanisms::QUERY_STRING ? authorized_request.query_parameters :
133
- signing_options.mechanism == SigningMechanisms::HEADER ? authorized_request.headers : {})
134
-
135
- digest = SigningAlgorithms.to_d(signing_options.algorithm)
136
- canonical_request, signed_headers = build_canonical_request(authorized_request, digest)
137
- string_to_sign = build_string_to_sign(canonical_request, signing_options)
138
- signature = generate_signature(string_to_sign, signing_options, digest)
139
-
140
- if signing_options.mechanism == SigningMechanisms::QUERY_STRING
141
- authorized_request.query_parameters[SigningAttributes::ALGORITHM] = signing_options.algorithm
142
- authorized_request.query_parameters[SigningAttributes::CREDENTIAL] = signing_options.domain_id
143
- authorized_request.query_parameters[SigningAttributes::SIGNED_HEADERS] = signed_headers
144
- authorized_request.query_parameters[SigningAttributes::SIGNATURE] = signature
145
- elsif signing_options.mechanism == SigningMechanisms::HEADER
146
- authorized_request.headers[SigningAttributes::AUTHORIZATION] = "#{signing_options.algorithm} Credential=#{signing_options.domain_id}, SignedHeaders=#{signed_headers}, Signature=#{signature}"
147
- end
148
-
149
- return authorized_request
150
-
151
- end
152
-
1
+ require 'time'
2
+ require 'stringio'
3
+ require 'openssl'
4
+ require_relative 'request.rb'
5
+ require_relative 'signing_algorithms.rb'
6
+ require_relative 'signing_attributes.rb'
7
+ require_relative 'signing_mechanisms.rb'
8
+ require_relative 'signing_options.rb'
9
+
10
+ module Pandexio
11
+
12
+ LINE_BREAK = "\r\n"
13
+ private_constant :LINE_BREAK
14
+
15
+ private
16
+
17
+ def self.ordinal_key_value_sort(a, b)
18
+
19
+ a_codepoints, b_codepoints = a[0].codepoints.to_a, b[0].codepoints.to_a
20
+
21
+ max_i = [a_codepoints.size, b_codepoints.size].min
22
+
23
+ for i in 0..max_i
24
+ a_codepoint = a_codepoints[i]
25
+ b_codepoint = b_codepoints[i]
26
+ return -1 if a_codepoint < b_codepoint
27
+ return 1 if a_codepoint > b_codepoint
28
+ end
29
+
30
+ return 0
31
+
32
+ end
33
+
34
+ def self.build_canonical_query_string(query_parameters)
35
+
36
+ temp_query_parameters = query_parameters.dup
37
+
38
+ temp_query_parameters = temp_query_parameters.sort { |a, b| ordinal_key_value_sort(a, b) }
39
+
40
+ canonical_query_string = StringIO.new
41
+
42
+ temp_query_parameters.each do |key, value|
43
+ next if key == SigningAttributes::ALGORITHM || key == SigningAttributes::CREDENTIAL || key == SigningAttributes::SIGNED_HEADERS || key == SigningAttributes::SIGNATURE
44
+ canonical_query_string << "&" if canonical_query_string.length > 0
45
+ canonical_query_string << "#{key}=#{value}"
46
+ end
47
+
48
+ return canonical_query_string.string
49
+
50
+ end
51
+
52
+ def self.build_canonical_headers(headers)
53
+
54
+ temp_headers = {}
55
+
56
+ headers.each do |key, value|
57
+ next if key == SigningAttributes::AUTHORIZATION
58
+ temp_headers[key.downcase.strip] = value
59
+ end
60
+
61
+ temp_headers = temp_headers.sort { |a, b| ordinal_key_value_sort(a, b) }
62
+
63
+ canonical_headers, signed_headers = StringIO.new, StringIO.new
64
+
65
+ temp_headers.each do |key, value|
66
+ next if key == SigningAttributes::AUTHORIZATION
67
+ canonical_headers << LINE_BREAK if canonical_headers.length > 0
68
+ canonical_headers << "#{key}:#{value}"
69
+ signed_headers << ";" if signed_headers.length > 0
70
+ signed_headers << "#{key}"
71
+ end
72
+
73
+ return canonical_headers.string, signed_headers.string
74
+
75
+ end
76
+
77
+ def self.build_canonical_payload(payload, digest)
78
+ canonical_payload = digest.hexdigest(payload).encode('UTF-8')
79
+ return canonical_payload;
80
+ end
81
+
82
+ def self.build_canonical_request(request, digest)
83
+ canonical_query_string = build_canonical_query_string(request.query_parameters)
84
+ canonical_headers, signed_headers = build_canonical_headers(request.headers)
85
+ canonical_payload = build_canonical_payload(request.payload, digest)
86
+ canonical_request = "#{request.method}#{LINE_BREAK}#{request.path}#{LINE_BREAK}#{canonical_query_string}#{LINE_BREAK}#{canonical_headers}#{LINE_BREAK}#{signed_headers}#{LINE_BREAK}#{canonical_payload}"
87
+ return canonical_request, signed_headers
88
+ end
89
+
90
+ def self.build_string_to_sign(canonical_request, signing_options)
91
+ signing_string = "#{signing_options.algorithm}#{LINE_BREAK}#{signing_options.date.iso8601}#{LINE_BREAK}#{canonical_request}".encode('UTF-8')
92
+ return signing_string
93
+ end
94
+
95
+ def self.generate_signature(string_to_sign, signing_options, digest)
96
+ return OpenSSL::HMAC.hexdigest(digest, signing_options.domain_key, string_to_sign)
97
+ end
98
+
99
+ public
100
+
101
+ def self.to_authorized_request(normalized_request, signing_options)
102
+
103
+ raise ArgumentError, 'normalized_request must be of type Pandexio::Request and cannot be nil' unless !normalized_request.nil? && normalized_request.is_a?(Request)
104
+ raise ArgumentError, 'normalized_request.query_parameters must be of type Hash and cannot be nil' unless !normalized_request.query_parameters.nil? && normalized_request.query_parameters.is_a?(Hash)
105
+ raise ArgumentError, 'normalized_request.headers must be of type Hash and cannot be nil' unless !normalized_request.headers.nil? && normalized_request.headers.is_a?(Hash)
106
+
107
+ raise ArgumentError, 'signing_options must be of type Pandexio::SigningOptions cannot be nil' unless !signing_options.nil? && signing_options.is_a?(SigningOptions)
108
+ raise ArgumentError, 'signing_options.domain_id must be of type String and cannot be nil or empty' unless !signing_options.domain_id.nil? && signing_options.domain_id.is_a?(String) && !signing_options.domain_id.empty?
109
+ raise ArgumentError, 'signing_options.domain_key must be of type String and cannot be nil or empty' unless !signing_options.domain_key.nil? && signing_options.domain_key.is_a?(String) && !signing_options.domain_key.empty?
110
+ raise ArgumentError, 'signing_options.algorithm must be of type String and cannot be nil or empty' unless SigningAlgorithms.is_v(signing_options.algorithm)
111
+ raise ArgumentError, 'signing_options.mechanism must be a valid signing mechanism' unless SigningMechanisms.is_v(signing_options.mechanism)
112
+ raise ArgumentError, 'signing_options.date must be of type Time and cannot be nil' unless !signing_options.date.nil? && signing_options.date.is_a?(Time)
113
+ raise ArgumentError, 'signing_options.expires must be of type Fixnum and cannot be nil or empty' unless !signing_options.expires.nil? && signing_options.expires.is_a?(Fixnum) && signing_options.expires > 0
114
+ raise ArgumentError, 'signing_options.originator must be of type String and cannot be nil or empty' unless !signing_options.originator.nil? && signing_options.originator.is_a?(String) && !signing_options.originator.empty?
115
+ raise ArgumentError, 'signing_options.email_address must be of type String and cannot be nil or empty' unless !signing_options.email_address.nil? && signing_options.email_address.is_a?(String) && !signing_options.email_address.empty?
116
+ raise ArgumentError, 'signing_options.display_name must be of type String and cannot be nil or empty' unless !signing_options.display_name.nil? && signing_options.display_name.is_a?(String) && !signing_options.display_name.empty?
117
+
118
+ authorized_request = normalized_request.dup
119
+
120
+ append = lambda { |p|
121
+ p[SigningAttributes::DATE] = signing_options.date.iso8601
122
+ p[SigningAttributes::EXPIRES] = signing_options.expires
123
+ p[SigningAttributes::ORIGINATOR] = signing_options.originator
124
+ p[SigningAttributes::EMAIL_ADDRESS] = signing_options.email_address
125
+ p[SigningAttributes::DISPLAY_NAME] = signing_options.display_name
126
+ p[SigningAttributes::PROFILE_IMAGE] = signing_options.profile_image if !signing_options.profile_image.nil? && signing_options.profile_image.is_a?(String) && !signing_options.profile_image.empty?
127
+ }
128
+
129
+ append.call(
130
+ signing_options.mechanism == SigningMechanisms::QUERY_STRING ? authorized_request.query_parameters :
131
+ signing_options.mechanism == SigningMechanisms::HEADER ? authorized_request.headers : {})
132
+
133
+ digest = SigningAlgorithms.to_d(signing_options.algorithm)
134
+ canonical_request, signed_headers = build_canonical_request(authorized_request, digest)
135
+ string_to_sign = build_string_to_sign(canonical_request, signing_options)
136
+ signature = generate_signature(string_to_sign, signing_options, digest)
137
+
138
+ if signing_options.mechanism == SigningMechanisms::QUERY_STRING
139
+ authorized_request.query_parameters[SigningAttributes::ALGORITHM] = signing_options.algorithm
140
+ authorized_request.query_parameters[SigningAttributes::CREDENTIAL] = signing_options.domain_id
141
+ authorized_request.query_parameters[SigningAttributes::SIGNED_HEADERS] = signed_headers
142
+ authorized_request.query_parameters[SigningAttributes::SIGNATURE] = signature
143
+ elsif signing_options.mechanism == SigningMechanisms::HEADER
144
+ authorized_request.headers[SigningAttributes::AUTHORIZATION] = "#{signing_options.algorithm} Credential=#{signing_options.domain_id}, SignedHeaders=#{signed_headers}, Signature=#{signature}"
145
+ end
146
+
147
+ return authorized_request
148
+
149
+ end
150
+
153
151
  end