smartsheet 2.77.0 → 2.101.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +12 -12
  3. data/.rubocop.yml +4 -4
  4. data/.travis.yml +29 -15
  5. data/.yardopts +3 -3
  6. data/ADVANCED.md +78 -78
  7. data/CHANGELOG.md +133 -112
  8. data/Gemfile +6 -6
  9. data/LICENSE +202 -202
  10. data/README.md +248 -246
  11. data/Rakefile +29 -29
  12. data/bin/console +14 -14
  13. data/bin/setup +8 -8
  14. data/lib/smartsheet.rb +2 -2
  15. data/lib/smartsheet/api/body_builder.rb +25 -25
  16. data/lib/smartsheet/api/endpoint_spec.rb +54 -54
  17. data/lib/smartsheet/api/faraday_adapter/faraday_net_client.rb +45 -45
  18. data/lib/smartsheet/api/faraday_adapter/faraday_response.rb +70 -70
  19. data/lib/smartsheet/api/faraday_adapter/middleware/faraday_error_translator.rb +20 -20
  20. data/lib/smartsheet/api/faraday_adapter/middleware/response_parser.rb +25 -25
  21. data/lib/smartsheet/api/file_spec.rb +55 -55
  22. data/lib/smartsheet/api/header_builder.rb +96 -96
  23. data/lib/smartsheet/api/request.rb +42 -42
  24. data/lib/smartsheet/api/request_client.rb +43 -43
  25. data/lib/smartsheet/api/request_logger.rb +182 -182
  26. data/lib/smartsheet/api/request_spec.rb +57 -57
  27. data/lib/smartsheet/api/response_net_client_decorator.rb +54 -54
  28. data/lib/smartsheet/api/retry_logic.rb +40 -40
  29. data/lib/smartsheet/api/retry_net_client_decorator.rb +37 -37
  30. data/lib/smartsheet/api/url_builder.rb +25 -25
  31. data/lib/smartsheet/client.rb +193 -193
  32. data/lib/smartsheet/constants.rb +18 -18
  33. data/lib/smartsheet/endpoints/contacts/contacts.rb +30 -30
  34. data/lib/smartsheet/endpoints/events/events.rb +20 -20
  35. data/lib/smartsheet/endpoints/favorites/favorites.rb +159 -159
  36. data/lib/smartsheet/endpoints/folders/folders.rb +125 -125
  37. data/lib/smartsheet/endpoints/groups/groups.rb +83 -83
  38. data/lib/smartsheet/endpoints/home/home.rb +20 -20
  39. data/lib/smartsheet/endpoints/reports/reports.rb +100 -100
  40. data/lib/smartsheet/endpoints/reports/reports_share.rb +69 -69
  41. data/lib/smartsheet/endpoints/search/search.rb +30 -30
  42. data/lib/smartsheet/endpoints/server_info/server_info.rb +21 -21
  43. data/lib/smartsheet/endpoints/share/share.rb +58 -58
  44. data/lib/smartsheet/endpoints/sheets/automation_rules.rb +55 -55
  45. data/lib/smartsheet/endpoints/sheets/cells.rb +82 -82
  46. data/lib/smartsheet/endpoints/sheets/columns.rb +66 -66
  47. data/lib/smartsheet/endpoints/sheets/comments.rb +64 -64
  48. data/lib/smartsheet/endpoints/sheets/comments_attachments.rb +78 -78
  49. data/lib/smartsheet/endpoints/sheets/cross_sheet_references.rb +45 -45
  50. data/lib/smartsheet/endpoints/sheets/discussions.rb +84 -84
  51. data/lib/smartsheet/endpoints/sheets/discussions_attachments.rb +22 -22
  52. data/lib/smartsheet/endpoints/sheets/rows.rb +106 -106
  53. data/lib/smartsheet/endpoints/sheets/rows_attachments.rb +92 -92
  54. data/lib/smartsheet/endpoints/sheets/sheets.rb +514 -510
  55. data/lib/smartsheet/endpoints/sheets/sheets_attachments.rb +174 -174
  56. data/lib/smartsheet/endpoints/sheets/sheets_share.rb +69 -69
  57. data/lib/smartsheet/endpoints/sheets/sheets_summaries.rb +123 -0
  58. data/lib/smartsheet/endpoints/sights/sights.rb +101 -101
  59. data/lib/smartsheet/endpoints/sights/sights_share.rb +69 -69
  60. data/lib/smartsheet/endpoints/templates/templates.rb +29 -29
  61. data/lib/smartsheet/endpoints/token/token.rb +70 -66
  62. data/lib/smartsheet/endpoints/update_requests/sent_update_requests.rb +44 -44
  63. data/lib/smartsheet/endpoints/update_requests/update_requests.rb +74 -74
  64. data/lib/smartsheet/endpoints/users/alternate_emails.rb +79 -79
  65. data/lib/smartsheet/endpoints/users/users.rb +123 -77
  66. data/lib/smartsheet/endpoints/webhooks/webhooks.rb +71 -71
  67. data/lib/smartsheet/endpoints/workspaces/workspaces.rb +87 -87
  68. data/lib/smartsheet/endpoints/workspaces/workspaces_share.rb +70 -70
  69. data/lib/smartsheet/error.rb +69 -69
  70. data/lib/smartsheet/general_request.rb +74 -74
  71. data/lib/smartsheet/version.rb +5 -5
  72. data/smartsheet.gemspec +54 -54
  73. metadata +24 -12
@@ -1,44 +1,44 @@
1
- require 'smartsheet/version'
2
- require 'smartsheet/error'
3
-
4
- module Smartsheet
5
- module API
6
- # Composes {EndpointSpec endpoint specifications} and {RequestSpec request specifications} to
7
- # form a single {Request} that it submits to the provided client
8
- class RequestClient
9
- def initialize(
10
- token,
11
- client,
12
- base_url,
13
- app_user_agent: nil,
14
- assume_user: nil,
15
- logger: MuteRequestLogger.new
16
- )
17
- @token = token
18
- @client = client
19
- @app_user_agent = app_user_agent
20
- @assume_user = assume_user
21
- @logger = logger
22
- @base_url = base_url
23
- end
24
-
25
- def make_request(endpoint_spec, request_spec)
26
- request = Request.new(
27
- token,
28
- endpoint_spec,
29
- request_spec,
30
- base_url,
31
- app_user_agent: app_user_agent,
32
- assume_user: assume_user
33
- )
34
-
35
- logger.log_request(request)
36
- client.make_request(request)
37
- end
38
-
39
- private
40
-
41
- attr_reader :token, :client, :app_user_agent, :assume_user, :logger, :base_url
42
- end
43
- end
1
+ require 'smartsheet/version'
2
+ require 'smartsheet/error'
3
+
4
+ module Smartsheet
5
+ module API
6
+ # Composes {EndpointSpec endpoint specifications} and {RequestSpec request specifications} to
7
+ # form a single {Request} that it submits to the provided client
8
+ class RequestClient
9
+ def initialize(
10
+ token,
11
+ client,
12
+ base_url,
13
+ app_user_agent: nil,
14
+ assume_user: nil,
15
+ logger: MuteRequestLogger.new
16
+ )
17
+ @token = token
18
+ @client = client
19
+ @app_user_agent = app_user_agent
20
+ @assume_user = assume_user
21
+ @logger = logger
22
+ @base_url = base_url
23
+ end
24
+
25
+ def make_request(endpoint_spec, request_spec)
26
+ request = Request.new(
27
+ token,
28
+ endpoint_spec,
29
+ request_spec,
30
+ base_url,
31
+ app_user_agent: app_user_agent,
32
+ assume_user: assume_user
33
+ )
34
+
35
+ logger.log_request(request)
36
+ client.make_request(request)
37
+ end
38
+
39
+ private
40
+
41
+ attr_reader :token, :client, :app_user_agent, :assume_user, :logger, :base_url
42
+ end
43
+ end
44
44
  end
@@ -1,183 +1,183 @@
1
- require 'logger'
2
-
3
- module Smartsheet
4
- module API
5
- # Censors strings and hash values for select blacklisted keys
6
- class Censor
7
- EXPOSED_CHARS = 4
8
- KEY_TO_STRING = ->(k){ k.to_s }
9
- KEY_TO_DOWNCASE_STRING = ->(k){ k.to_s.downcase }
10
-
11
- def initialize(*blacklist)
12
- @blacklist = Set.new(blacklist)
13
- end
14
-
15
- def censor_hash(h, case_insensitive: false)
16
- if case_insensitive
17
- _censor_hash(h, KEY_TO_DOWNCASE_STRING, downcased_blacklist)
18
- else
19
- _censor_hash(h, KEY_TO_STRING, blacklist)
20
- end
21
- end
22
-
23
- def censor(str)
24
- total_length = str.length
25
- censored_length = [total_length - EXPOSED_CHARS, 0].max
26
- ('*' * censored_length) + str[censored_length...total_length]
27
- end
28
-
29
- private
30
-
31
- def _censor_hash(h, key_transform, cased_blacklist)
32
- h.collect do |(k, v)|
33
- new_v =
34
- cased_blacklist.include?(key_transform.call(k)) ?
35
- censor(v) :
36
- v
37
-
38
- [k, new_v]
39
- end.to_h
40
- end
41
-
42
- def downcased_blacklist
43
- blacklist.collect { |x| x.downcase }
44
- end
45
-
46
- attr_reader :blacklist
47
- end
48
-
49
- # Logs request and response information, while censoring OAuth-relevant keys
50
- class RequestLogger
51
- QUERY_PARAM_CENSOR = Censor.new 'code', 'client_id', 'hash', 'refresh_token'
52
- HEADER_CENSOR = Censor.new 'authorization'
53
- PAYLOAD_CENSOR = Censor.new 'access_token', 'refresh_token'
54
-
55
- TRUNCATED_BODY_LENGTH = 1024
56
-
57
- def initialize(logger, log_full_body:)
58
- @logger = logger
59
- @log_full_body = log_full_body
60
- end
61
-
62
- def log_request(request)
63
- log_request_basics(Logger::INFO, request)
64
- log_headers('Request', request)
65
- log_body('Request', request.body)
66
- end
67
-
68
- def log_retry_attempt(request, response, attempt_num)
69
- logger.warn { "Request attempt #{attempt_num} failed" }
70
- log_request_basics(Logger::WARN, request)
71
- log_api_error(Logger::WARN, response)
72
- end
73
-
74
- def log_retry_failure(num_tries)
75
- try_word = num_tries == 1 ? 'try' : 'tries'
76
- logger.error { "Request failed after #{num_tries} #{try_word}" }
77
- end
78
-
79
- def log_successful_response(response)
80
- log_status(Logger::INFO, response)
81
- log_headers('Response', response)
82
- log_body('Response', response.result)
83
- end
84
-
85
- def log_api_error_response(request, error)
86
- log_request_basics(Logger::ERROR, request)
87
- log_api_error(Logger::ERROR, error)
88
- end
89
-
90
- def log_http_error_response(request, error)
91
- log_request_basics(Logger::ERROR, request)
92
- log_http_error(Logger::ERROR, error)
93
- end
94
-
95
- private
96
-
97
- attr_reader :logger, :log_full_body
98
-
99
- def log_request_basics(level, request)
100
- logger.log(level) { "Request: #{request.method.upcase} #{build_logging_url(request)}" }
101
- end
102
-
103
- def build_logging_url(request)
104
- query_params = QUERY_PARAM_CENSOR.censor_hash(request.params)
105
- query_param_str =
106
- if query_params.empty?
107
- ''
108
- else
109
- '?' + query_params.collect { |(k, v)| "#{k}=#{v}" }.join('&') # TODO: URI Encoding
110
- end
111
- request.url + query_param_str
112
- end
113
-
114
- def log_api_error(level, response)
115
- log_status(level, response)
116
- logger.log(level) do
117
- "#{response.error_code}: #{response.message} - Ref ID: #{response.ref_id}"
118
- end
119
- log_headers('Response', response)
120
- end
121
-
122
- def log_http_error(level, response)
123
- log_status(level, response)
124
- log_headers('Response', response)
125
- end
126
-
127
- def log_status(level, response)
128
- logger.log(level) { "Response: #{response.status_code} #{response.reason_phrase}" }
129
- end
130
-
131
- def log_headers(context, req_or_resp)
132
- censored_hash = HEADER_CENSOR.censor_hash(req_or_resp.headers, case_insensitive: true)
133
- logger.debug { "#{context} Headers: #{censored_hash}" }
134
- end
135
-
136
- def log_body(context, body)
137
- return unless body
138
-
139
- body_str =
140
- if body.is_a? String
141
- body
142
- elsif body.is_a? Hash
143
- PAYLOAD_CENSOR.censor_hash(body).to_s
144
- else
145
- '<Binary body>'
146
- end
147
-
148
- body_str = truncate_body(body_str) unless log_full_body
149
-
150
- logger.debug "#{context} Body: #{body_str}"
151
- end
152
-
153
- def truncate_body(body_str)
154
- if body_str.length > TRUNCATED_BODY_LENGTH
155
- body_str[0...TRUNCATED_BODY_LENGTH] + '...'
156
- else
157
- body_str
158
- end
159
- end
160
- end
161
-
162
- # Stubs all request logging methods by doing nothing (see {RequestLogger})
163
- class MuteRequestLogger
164
- def log_request(request)
165
- end
166
-
167
- def log_retry_attempt(request, response, attempt_num)
168
- end
169
-
170
- def log_retry_failure(num_retries)
171
- end
172
-
173
- def log_successful_response(response)
174
- end
175
-
176
- def log_api_error_response(request, error)
177
- end
178
-
179
- def log_http_error_response(request, error)
180
- end
181
- end
182
- end
1
+ require 'logger'
2
+
3
+ module Smartsheet
4
+ module API
5
+ # Censors strings and hash values for select blacklisted keys
6
+ class Censor
7
+ EXPOSED_CHARS = 4
8
+ KEY_TO_STRING = ->(k){ k.to_s }
9
+ KEY_TO_DOWNCASE_STRING = ->(k){ k.to_s.downcase }
10
+
11
+ def initialize(*blacklist)
12
+ @blacklist = Set.new(blacklist)
13
+ end
14
+
15
+ def censor_hash(h, case_insensitive: false)
16
+ if case_insensitive
17
+ _censor_hash(h, KEY_TO_DOWNCASE_STRING, downcased_blacklist)
18
+ else
19
+ _censor_hash(h, KEY_TO_STRING, blacklist)
20
+ end
21
+ end
22
+
23
+ def censor(str)
24
+ total_length = str.length
25
+ censored_length = [total_length - EXPOSED_CHARS, 0].max
26
+ ('*' * censored_length) + str[censored_length...total_length]
27
+ end
28
+
29
+ private
30
+
31
+ def _censor_hash(h, key_transform, cased_blacklist)
32
+ h.collect do |(k, v)|
33
+ new_v =
34
+ cased_blacklist.include?(key_transform.call(k)) ?
35
+ censor(v) :
36
+ v
37
+
38
+ [k, new_v]
39
+ end.to_h
40
+ end
41
+
42
+ def downcased_blacklist
43
+ blacklist.collect { |x| x.downcase }
44
+ end
45
+
46
+ attr_reader :blacklist
47
+ end
48
+
49
+ # Logs request and response information, while censoring OAuth-relevant keys
50
+ class RequestLogger
51
+ QUERY_PARAM_CENSOR = Censor.new 'code', 'client_id', 'hash', 'refresh_token'
52
+ HEADER_CENSOR = Censor.new 'authorization'
53
+ PAYLOAD_CENSOR = Censor.new 'access_token', 'refresh_token'
54
+
55
+ TRUNCATED_BODY_LENGTH = 1024
56
+
57
+ def initialize(logger, log_full_body:)
58
+ @logger = logger
59
+ @log_full_body = log_full_body
60
+ end
61
+
62
+ def log_request(request)
63
+ log_request_basics(Logger::INFO, request)
64
+ log_headers('Request', request)
65
+ log_body('Request', request.body)
66
+ end
67
+
68
+ def log_retry_attempt(request, response, attempt_num)
69
+ logger.warn { "Request attempt #{attempt_num} failed" }
70
+ log_request_basics(Logger::WARN, request)
71
+ log_api_error(Logger::WARN, response)
72
+ end
73
+
74
+ def log_retry_failure(num_tries)
75
+ try_word = num_tries == 1 ? 'try' : 'tries'
76
+ logger.error { "Request failed after #{num_tries} #{try_word}" }
77
+ end
78
+
79
+ def log_successful_response(response)
80
+ log_status(Logger::INFO, response)
81
+ log_headers('Response', response)
82
+ log_body('Response', response.result)
83
+ end
84
+
85
+ def log_api_error_response(request, error)
86
+ log_request_basics(Logger::ERROR, request)
87
+ log_api_error(Logger::ERROR, error)
88
+ end
89
+
90
+ def log_http_error_response(request, error)
91
+ log_request_basics(Logger::ERROR, request)
92
+ log_http_error(Logger::ERROR, error)
93
+ end
94
+
95
+ private
96
+
97
+ attr_reader :logger, :log_full_body
98
+
99
+ def log_request_basics(level, request)
100
+ logger.log(level) { "Request: #{request.method.upcase} #{build_logging_url(request)}" }
101
+ end
102
+
103
+ def build_logging_url(request)
104
+ query_params = QUERY_PARAM_CENSOR.censor_hash(request.params)
105
+ query_param_str =
106
+ if query_params.empty?
107
+ ''
108
+ else
109
+ '?' + query_params.collect { |(k, v)| "#{k}=#{v}" }.join('&') # TODO: URI Encoding
110
+ end
111
+ request.url + query_param_str
112
+ end
113
+
114
+ def log_api_error(level, response)
115
+ log_status(level, response)
116
+ logger.log(level) do
117
+ "#{response.error_code}: #{response.message} - Ref ID: #{response.ref_id}"
118
+ end
119
+ log_headers('Response', response)
120
+ end
121
+
122
+ def log_http_error(level, response)
123
+ log_status(level, response)
124
+ log_headers('Response', response)
125
+ end
126
+
127
+ def log_status(level, response)
128
+ logger.log(level) { "Response: #{response.status_code} #{response.reason_phrase}" }
129
+ end
130
+
131
+ def log_headers(context, req_or_resp)
132
+ censored_hash = HEADER_CENSOR.censor_hash(req_or_resp.headers, case_insensitive: true)
133
+ logger.debug { "#{context} Headers: #{censored_hash}" }
134
+ end
135
+
136
+ def log_body(context, body)
137
+ return unless body
138
+
139
+ body_str =
140
+ if body.is_a? String
141
+ body
142
+ elsif body.is_a? Hash
143
+ PAYLOAD_CENSOR.censor_hash(body).to_s
144
+ else
145
+ '<Binary body>'
146
+ end
147
+
148
+ body_str = truncate_body(body_str) unless log_full_body
149
+
150
+ logger.debug "#{context} Body: #{body_str}"
151
+ end
152
+
153
+ def truncate_body(body_str)
154
+ if body_str.length > TRUNCATED_BODY_LENGTH
155
+ body_str[0...TRUNCATED_BODY_LENGTH] + '...'
156
+ else
157
+ body_str
158
+ end
159
+ end
160
+ end
161
+
162
+ # Stubs all request logging methods by doing nothing (see {RequestLogger})
163
+ class MuteRequestLogger
164
+ def log_request(request)
165
+ end
166
+
167
+ def log_retry_attempt(request, response, attempt_num)
168
+ end
169
+
170
+ def log_retry_failure(num_retries)
171
+ end
172
+
173
+ def log_successful_response(response)
174
+ end
175
+
176
+ def log_api_error_response(request, error)
177
+ end
178
+
179
+ def log_http_error_response(request, error)
180
+ end
181
+ end
182
+ end
183
183
  end