cronofy 0.36.0 → 0.37.3

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: e085c07872654ff1e239fcdce81beeb212856ce2ff7d9c3168e71c3f2778e6d5
4
- data.tar.gz: 0ce2421b8e0aa2b39c76a72eaeeddd4a474573690a6d3ccdf437c1d57dbf0028
3
+ metadata.gz: f398fb44b861ba5df84e244632877a53b050f584c08d15a815cb0e4abaae13bc
4
+ data.tar.gz: 8cea161bbef6df1b41a3ff52b29984c9ccd3f713abe279a7137e1e0be89cd7d7
5
5
  SHA512:
6
- metadata.gz: 8df4506dfe09d4454c8901e312dbda5d03a27d1ec8a0cb28506327f8802a691fa5abf00abd8028ee6f04d9c09eae73f3a0ea417409e7164b2fa1e0e4530bb2a3
7
- data.tar.gz: fe07ce98f72073fa8c0254510a089fbf04d37d5da2a12b7c12d1de77e19e1666c394d14aca6d32d96ad2ee7093b1e276ad5571f0ffcfd615a4d269e70031e07b
6
+ metadata.gz: 5961670573669f876d06f772a1c96175ac2e37a06fb3b3c6a1c677da86f5cbcb50820aa1e71897b7e8379ec556b55f9b56751efb51037d2f642284e72f0f07ed
7
+ data.tar.gz: 7bf5e28b6786f2fee081d09562e9e2dd57a90652994d1755a13b76c9ad9484cb50ef9dce1784fd6921372a3f6b5b29888c2274e99ed13bdb196aa42036133233
data/CHANGELOG.md CHANGED
@@ -1,3 +1,23 @@
1
+ ## [0.37.3]
2
+
3
+ * Support `hmac_valid` as well as the original `hmac_match` for Client to verify a HMAC from a push notification using the client's secret.[#95]
4
+
5
+ ## [0.37.2]
6
+
7
+ * Support `query_periods` as well as the original `available_periods` for Availability Query and Sequenced Availability [#91]
8
+
9
+ ## [0.37.1]
10
+
11
+ * Rename `data_centre` to `data_centre` (with aliases for backwards compatibility) [#90]
12
+
13
+ ## [0.37.0]
14
+
15
+ * Add `revoke_by_token` and `revoke_by_sub` to the Client [#86]
16
+
17
+ ## [0.36.1]
18
+
19
+ * Loosen the version requirement on Hashie to allow 4.X
20
+
1
21
  ## [0.36.0]
2
22
 
3
23
  * Add support for Available Periods [#81]
@@ -167,6 +187,11 @@
167
187
  [0.34.0]: https://github.com/cronofy/cronofy-ruby/releases/tag/v0.34.0
168
188
  [0.35.0]: https://github.com/cronofy/cronofy-ruby/releases/tag/v0.35.0
169
189
  [0.36.0]: https://github.com/cronofy/cronofy-ruby/releases/tag/v0.36.0
190
+ [0.36.1]: https://github.com/cronofy/cronofy-ruby/releases/tag/v0.36.1
191
+ [0.37.0]: https://github.com/cronofy/cronofy-ruby/releases/tag/v0.37.0
192
+ [0.37.1]: https://github.com/cronofy/cronofy-ruby/releases/tag/v0.37.1
193
+ [0.37.2]: https://github.com/cronofy/cronofy-ruby/releases/tag/v0.37.2
194
+ [0.37.3]: https://github.com/cronofy/cronofy-ruby/releases/tag/v0.37.3
170
195
 
171
196
  [#13]: https://github.com/cronofy/cronofy-ruby/pull/13
172
197
  [#16]: https://github.com/cronofy/cronofy-ruby/pull/16
@@ -207,3 +232,8 @@
207
232
  [#75]: https://github.com/cronofy/cronofy-ruby/pull/75
208
233
  [#77]: https://github.com/cronofy/cronofy-ruby/pull/77
209
234
  [#81]: https://github.com/cronofy/cronofy-ruby/pull/81
235
+ [#85]: https://github.com/cronofy/cronofy-ruby/pull/85
236
+ [#86]: https://github.com/cronofy/cronofy-ruby/pull/86
237
+ [#90]: https://github.com/cronofy/cronofy-ruby/pull/90
238
+ [#91]: https://github.com/cronofy/cronofy-ruby/pull/91
239
+ [#95]: https://github.com/cronofy/cronofy-ruby/pull/95
data/README.md CHANGED
@@ -1,9 +1,9 @@
1
1
  # Cronofy
2
2
 
3
- [![Build Status](https://travis-ci.org/cronofy/cronofy-ruby.svg?branch=master)](https://travis-ci.org/cronofy/cronofy-ruby)
3
+ [![ruby CI](https://github.com/cronofy/cronofy-ruby/actions/workflows/ci.yml/badge.svg)](https://github.com/cronofy/cronofy-ruby/actions/workflows/ci.yml)
4
4
  [![Gem Version](https://badge.fury.io/rb/cronofy.svg)](http://badge.fury.io/rb/cronofy)
5
5
 
6
- [Cronofy](https://www.cronofy.com) - one API for all the calendars (Google, iCloud, Exchange, Office 365, Outlook.com)
6
+ [Cronofy](https://www.cronofy.com) - the scheduling platform for business
7
7
 
8
8
  ## Installation
9
9
 
@@ -23,22 +23,21 @@ bundle install
23
23
 
24
24
  In order to use the Cronofy API you will need to [create a developer account](https://app.cronofy.com/sign_up/new).
25
25
 
26
- From there you can [use your Calendar Sandbox](https://app.cronofy.com/oauth/sandbox)
27
- to access your own calendars, or you can [create an OAuth application](https://app.cronofy.com/oauth/applications/new)
28
- to obtain an OAuth `client_id` and `client_secret` to be able to use the full
29
- API.
26
+ From there you can [create an OAuth application](https://app.cronofy.com/oauth/applications/new)
27
+ to obtain an OAuth `client_id` and `client_secret` to be able to use the full API.
30
28
 
31
29
  ## Creating a client
32
30
 
33
31
  To make calls to the Cronofy API you must create a `Cronofy::Client`. This takes
34
- four keyword arguments, all of which are optional:
32
+ five keyword arguments, all of which are optional:
35
33
 
36
34
  ```ruby
37
35
  cronofy = Cronofy::Client.new(
38
36
  client_id: 'CLIENT_ID',
39
37
  client_secret: 'CLIENT_SECRET',
40
38
  access_token: 'ACCESS_TOKEN',
41
- refresh_token: 'REFRESH_TOKEN'
39
+ refresh_token: 'REFRESH_TOKEN',
40
+ data_center: :de
42
41
  )
43
42
  ```
44
43
 
@@ -53,6 +52,8 @@ If `client_id` and `client_secret` are not specified explicitly the values from
53
52
  the environment variables `CRONOFY_CLIENT_ID` and `CRONOFY_CLIENT_SECRET` will
54
53
  be used if present.
55
54
 
55
+ `data_center` is the two-letter designation for the data center you want to operate against - for example `:de` for Germany, or `:au` for Australia. When omitted, this defaults to the US data center.
56
+
56
57
  ## Authorization
57
58
 
58
59
  [API documentation](https://www.cronofy.com/developers/api/#authorization)
@@ -133,6 +134,15 @@ To delete an event from user's calendar:
133
134
  cronofy.delete_event(calendar_id, 'uniq-id')
134
135
  ```
135
136
 
137
+ ## A feature I want is not in the SDK, how do I get it?
138
+
139
+ We add features to this SDK as they are requested, to focus on developing the Cronofy API.
140
+
141
+ If you're comfortable contributing support for an endpoint or attribute, then we love to receive pull requests!
142
+ Please create a PR mentioning the feature/API endpoint you’ve added and we’ll review it as soon as we can.
143
+
144
+ If you would like to request a feature is added by our team then please let us know by getting in touch via [support@cronofy.com](mailto:support@cronofy.com).
145
+
136
146
  ## Links
137
147
 
138
148
  * [API documentation](https://www.cronofy.com/developers/api)
data/cronofy.gemspec CHANGED
@@ -5,7 +5,7 @@ Gem::Specification.new do |spec|
5
5
  spec.version = Cronofy::VERSION
6
6
  spec.authors = ["Sergii Paryzhskyi", "Garry Shutler"]
7
7
  spec.email = ["parizhskiy@gmail.com", "garry@cronofy.com"]
8
- spec.summary = %q{Cronofy - one API for all the calendars}
8
+ spec.summary = %q{Cronofy - the scheduling platform for business}
9
9
  spec.description = %q{Ruby wrapper for Cronofy's unified calendar API}
10
10
  spec.homepage = "https://github.com/cronofy/cronofy-ruby"
11
11
  spec.license = "MIT"
@@ -17,8 +17,8 @@ Gem::Specification.new do |spec|
17
17
  spec.files += Dir['spec/**/*.rb']
18
18
  spec.test_files = Dir['spec/**/*.rb']
19
19
 
20
+ spec.add_runtime_dependency "hashie", ">= 2.1", "< 5"
20
21
  spec.add_runtime_dependency "oauth2", "~> 1.0"
21
- spec.add_runtime_dependency "hashie", ">= 2.1", "< 4"
22
22
 
23
23
  spec.add_development_dependency "bundler", ">= 1.6", "< 3"
24
24
  spec.add_development_dependency "rake", "~> 10.0"
data/lib/cronofy.rb CHANGED
@@ -13,18 +13,26 @@ require 'openssl'
13
13
 
14
14
  module Cronofy
15
15
  def self.default_data_centre
16
- @default_data_centre || ENV['CRONOFY_DATA_CENTRE']
16
+ default_data_center
17
17
  end
18
18
 
19
19
  def self.default_data_centre=(value)
20
- @default_data_centre = value
20
+ default_data_center= value
21
21
  end
22
22
 
23
- def self.api_url(data_centre_override)
24
- if data_centre_override
25
- api_url_for_data_centre(data_centre_override)
23
+ def self.default_data_center
24
+ @default_data_center || ENV['CRONOFY_DATA_CENTER'] || ENV['CRONOFY_DATA_CENTRE']
25
+ end
26
+
27
+ def self.default_data_center=(value)
28
+ @default_data_center = value
29
+ end
30
+
31
+ def self.api_url(data_center_override)
32
+ if data_center_override
33
+ api_url_for_data_center(data_center_override)
26
34
  else
27
- ENV['CRONOFY_API_URL'] || api_url_for_data_centre(default_data_centre)
35
+ ENV['CRONOFY_API_URL'] || api_url_for_data_center(default_data_center)
28
36
  end
29
37
  end
30
38
 
@@ -32,7 +40,11 @@ module Cronofy
32
40
  @api_url = value
33
41
  end
34
42
 
35
- def self.api_url_for_data_centre(dc)
43
+ def self.api_url_for_data_centre
44
+ api_url_for_data_center
45
+ end
46
+
47
+ def self.api_url_for_data_center(dc)
36
48
  @api_urls ||= Hash.new do |hash, key|
37
49
  if key.nil? || key.to_sym == :us
38
50
  url = "https://api.cronofy.com"
@@ -46,11 +58,11 @@ module Cronofy
46
58
  @api_urls[dc]
47
59
  end
48
60
 
49
- def self.app_url(data_centre_override)
50
- if data_centre_override
51
- app_url_for_data_centre(data_centre_override)
61
+ def self.app_url(data_center_override)
62
+ if data_center_override
63
+ app_url_for_data_center(data_center_override)
52
64
  else
53
- ENV['CRONOFY_APP_URL'] || app_url_for_data_centre(default_data_centre)
65
+ ENV['CRONOFY_APP_URL'] || app_url_for_data_center(default_data_center)
54
66
  end
55
67
  end
56
68
 
@@ -59,6 +71,10 @@ module Cronofy
59
71
  end
60
72
 
61
73
  def self.app_url_for_data_centre(dc)
74
+ app_url_for_data_center(dc)
75
+ end
76
+
77
+ def self.app_url_for_data_center(dc)
62
78
  @app_urls ||= Hash.new do |hash, key|
63
79
  if key.nil? || key.to_sym == :us
64
80
  url = "https://app.cronofy.com"
data/lib/cronofy/auth.rb CHANGED
@@ -11,13 +11,13 @@ module Cronofy
11
11
  access_token = options[:access_token]
12
12
  client_id = options[:client_id]
13
13
  client_secret = options[:client_secret]
14
- data_centre = options[:data_centre]
14
+ data_center = options[:data_center]
15
15
  refresh_token = options[:refresh_token]
16
16
 
17
17
  @client_credentials_missing = blank?(client_id) || blank?(client_secret)
18
18
 
19
- @auth_client = OAuth2::Client.new(client_id, client_secret, site: ::Cronofy.app_url(data_centre), connection_opts: { headers: { "User-Agent" => "Cronofy Ruby #{::Cronofy::VERSION}" } })
20
- @api_client = OAuth2::Client.new(client_id, client_secret, site: ::Cronofy.api_url(data_centre), connection_opts: { headers: { "User-Agent" => "Cronofy Ruby #{::Cronofy::VERSION}" } })
19
+ @auth_client = OAuth2::Client.new(client_id, client_secret, site: ::Cronofy.app_url(data_center), connection_opts: { headers: { "User-Agent" => "Cronofy Ruby #{::Cronofy::VERSION}" } })
20
+ @api_client = OAuth2::Client.new(client_id, client_secret, site: ::Cronofy.api_url(data_center), connection_opts: { headers: { "User-Agent" => "Cronofy Ruby #{::Cronofy::VERSION}" } })
21
21
 
22
22
  set_access_token(access_token, refresh_token) if access_token || refresh_token
23
23
  set_api_key(client_secret) if client_secret
@@ -118,20 +118,50 @@ module Cronofy
118
118
  def revoke!
119
119
  raise CredentialsMissingError.new("No credentials to revoke") unless access_token
120
120
 
121
+ token = access_token.refresh_token || access_token.token
122
+ revoke_by_token(token)
123
+ @access_token = nil
124
+ end
125
+
126
+ # Internal: Revokes an authorization by the sub
127
+ #
128
+ # Returns nothing.
129
+ #
130
+ # Raises Cronofy::CredentialsMissingError if no credentials available.
131
+ def revoke_by_sub(sub)
132
+ do_revoke(sub: sub)
133
+ end
134
+
135
+ # Internal: Revokes an authorization via the token
136
+ #
137
+ # Returns nothing.
138
+ #
139
+ # Raises Cronofy::CredentialsMissingError if no credentials available.
140
+ def revoke_by_token(token)
141
+ do_revoke(token: token)
142
+ end
143
+
144
+ private
145
+
146
+ def do_revoke(token: nil, sub: nil)
147
+ raise CredentialsMissingError.new("No credentials to revoke") unless token || sub
148
+
121
149
  do_request do
122
150
  body = {
123
151
  client_id: @api_client.id,
124
152
  client_secret: @api_client.secret,
125
- token: access_token.refresh_token || access_token.token,
126
153
  }
127
154
 
155
+ if token
156
+ body.merge!(token: token)
157
+ else
158
+ body.merge!(sub: sub)
159
+ end
160
+
128
161
  @api_client.request(:post, "/oauth/token/revoke", body: body)
129
- @access_token = nil
130
162
  end
131
163
  end
132
164
 
133
- private
134
-
135
165
  def do_request(&block)
136
166
  if @client_credentials_missing
137
167
  raise CredentialsMissingError.new("OAuth client_id and client_secret must be set")
@@ -27,22 +27,22 @@ module Cronofy
27
27
  # ENV["CRONOFY_CLIENT_SECRET"]).
28
28
  # :refresh_token - An existing refresh token String for the user's
29
29
  # account (optional).
30
- # :data_centre - An identifier to override the default data
31
- # centre (optional).
30
+ # :data_center - An identifier to override the default data
31
+ # center (optional).
32
32
  def initialize(options = {})
33
33
  access_token = options[:access_token]
34
34
  refresh_token = options[:refresh_token]
35
35
 
36
36
  @client_id = options.fetch(:client_id, ENV["CRONOFY_CLIENT_ID"])
37
37
  @client_secret = options.fetch(:client_secret, ENV["CRONOFY_CLIENT_SECRET"])
38
- @data_centre = options[:data_centre]
38
+ @data_center = options[:data_center] || options[:data_centre]
39
39
 
40
40
  @auth = Auth.new(
41
41
  client_id: @client_id,
42
42
  client_secret: @client_secret,
43
43
  access_token: access_token,
44
44
  refresh_token: refresh_token,
45
- data_centre: @data_centre,
45
+ data_center: @data_center
46
46
  )
47
47
  end
48
48
 
@@ -471,24 +471,33 @@ module Cronofy
471
471
  parse_json(Channel, "channel", response)
472
472
  end
473
473
 
474
+ # DEPRECATED: Please use hmac_valid instead.
475
+ def hmac_match?(args)
476
+ warn "[DEPRECATION] `hmac_match?` is deprecated. Please use `hmac_valid?` instead."
477
+ hmac_valid?(args)
478
+ end
479
+
474
480
  # Public: Verifies a HMAC from a push notification using the client secret.
475
481
  #
476
482
  # args - A Hash containing the details of the push notification:
477
483
  # :body - A String of the body of the notification.
478
- # :hmac - A String of the HMAC of the notification taken from the
484
+ # :hmac - A String containing comma-separated values describing HMACs of the notification taken from the
479
485
  # Cronofy-HMAC-SHA256 header.
480
486
  #
481
- # Returns true if the HMAC provided matches the one calculated using the
487
+ # Returns true if one of the HMAC provided matches the one calculated using the
482
488
  # client secret, otherwise false.
483
- def hmac_match?(args)
489
+ def hmac_valid?(args)
484
490
  body = args[:body]
485
491
  hmac = args[:hmac]
486
492
 
493
+ return false if hmac.nil? || hmac.empty?
494
+
487
495
  sha256 = OpenSSL::Digest.new('sha256')
488
496
  digest = OpenSSL::HMAC.digest(sha256, @client_secret, body)
489
497
  calculated = Base64.encode64(digest).strip
490
498
 
491
- calculated == hmac
499
+ hmac_list = hmac.split(',')
500
+ hmac_list.include?(calculated)
492
501
  end
493
502
 
494
503
  # Public: Lists all the notification channels for the account.
@@ -737,6 +746,14 @@ module Cronofy
737
746
  @auth.revoke!
738
747
  end
739
748
 
749
+ def revoke_by_sub(sub)
750
+ @auth.revoke_by_sub(sub)
751
+ end
752
+
753
+ def revoke_by_token(token)
754
+ @auth.revoke_by_token(token)
755
+ end
756
+
740
757
  # Public: Requests elevated permissions for a set of calendars.
741
758
  #
742
759
  # args - A Hash of options used to initialize the request (default: {}):
@@ -795,7 +812,7 @@ module Cronofy
795
812
  # for a single participant group.
796
813
  # :required_duration - An Integer representing the minimum number
797
814
  # of minutes of availability required.
798
- # :available_periods - An Array of available time periods Hashes,
815
+ # :query_periods - An Array of available time periods Hashes,
799
816
  # each must specify a start and end Time.
800
817
  # :start_interval - An Integer representing the start interval
801
818
  # of minutes for the availability query.
@@ -825,7 +842,7 @@ module Cronofy
825
842
  options[:buffer] = map_availability_buffer(buffer)
826
843
  end
827
844
 
828
- translate_available_periods(options[:available_periods])
845
+ translate_available_periods(options[:query_periods] || options[:available_periods])
829
846
 
830
847
  response = post("/v1/availability", options)
831
848
 
@@ -839,7 +856,7 @@ module Cronofy
839
856
  # Public: Performs an sequenced availability query.
840
857
  #
841
858
  # options - The Hash options used to refine the selection (default: {}):
842
- # :sequence - An Array of sequence defintions containing
859
+ # :sequence - An Array of sequence defintions containing
843
860
  # a Hash of:
844
861
  # :sequence_id - A String to uniquely identify this part
845
862
  # of the proposed sequence.
@@ -853,7 +870,7 @@ module Cronofy
853
870
  # of minutes for the availability query.
854
871
  # :buffer - An Hash containing the buffer to apply to
855
872
  # the availability query.
856
- # :available_periods - An Array of available time periods Hashes,
873
+ # :query_periods - An Array of available time periods Hashes,
857
874
  # each must specify a start and end Time.
858
875
  #
859
876
  # Returns an Array of Sequences.
@@ -870,7 +887,7 @@ module Cronofy
870
887
  def sequenced_availability(options = {})
871
888
  options[:sequence] = map_availability_sequence(options[:sequence])
872
889
 
873
- translate_available_periods(options[:available_periods])
890
+ translate_available_periods(options[:query_periods] || options[:available_periods])
874
891
 
875
892
  response = post("/v1/sequenced_availability", options)
876
893
  parse_collection(Sequence, "sequences", response)
@@ -1881,7 +1898,7 @@ module Cronofy
1881
1898
  end
1882
1899
 
1883
1900
  def api_url
1884
- ::Cronofy.api_url(@data_centre)
1901
+ ::Cronofy.api_url(@data_center)
1885
1902
  end
1886
1903
  end
1887
1904
 
@@ -1,3 +1,3 @@
1
1
  module Cronofy
2
- VERSION = "0.36.0".freeze
2
+ VERSION = "0.37.3".freeze
3
3
  end
@@ -92,7 +92,7 @@ describe Cronofy::Auth do
92
92
  let(:scheme) { 'https' }
93
93
  let(:host) { 'app.cronofy.com' }
94
94
  let(:path) { '/oauth/authorize' }
95
- let(:data_centre_override) { nil }
95
+ let(:data_center_override) { nil }
96
96
  let(:default_params) do
97
97
  {
98
98
  'client_id' => client_id,
@@ -106,7 +106,7 @@ describe Cronofy::Auth do
106
106
  Cronofy::Auth.new(
107
107
  client_id: client_id,
108
108
  client_secret: client_secret,
109
- data_centre: data_centre_override,
109
+ data_center: data_center_override,
110
110
  )
111
111
  end
112
112
 
@@ -156,8 +156,8 @@ describe Cronofy::Auth do
156
156
  it_behaves_like 'a user auth link provider'
157
157
  end
158
158
 
159
- context 'when data centre overridden' do
160
- let(:data_centre_override) { :de }
159
+ context 'when data center overridden' do
160
+ let(:data_center_override) { :de }
161
161
  let(:host) { 'app-de.cronofy.com' }
162
162
  let(:params) { default_params }
163
163
 
@@ -204,13 +204,13 @@ describe Cronofy::Auth do
204
204
  end
205
205
 
206
206
  describe '#get_token_from_code' do
207
- let(:data_centre_override) { nil }
207
+ let(:data_center_override) { nil }
208
208
 
209
209
  subject do
210
210
  Cronofy::Auth.new(
211
211
  client_id: client_id,
212
212
  client_secret: client_secret,
213
- data_centre: data_centre_override,
213
+ data_center: data_center_override,
214
214
  ).get_token_from_code(code, redirect_uri)
215
215
  end
216
216
 
@@ -236,7 +236,7 @@ describe Cronofy::Auth do
236
236
  end
237
237
 
238
238
  describe '#application_calendar' do
239
- let(:data_centre_override) { nil }
239
+ let(:data_center_override) { nil }
240
240
 
241
241
  let(:application_calendar_id) { "my-application-calendar" }
242
242
  let(:cronofy_application_calendar_id) { "apc_54475485743" }
@@ -273,7 +273,7 @@ describe Cronofy::Auth do
273
273
  Cronofy::Auth.new(
274
274
  client_id: client_id,
275
275
  client_secret: client_secret,
276
- data_centre: data_centre_override,
276
+ data_center: data_center_override,
277
277
  ).application_calendar(application_calendar_id)
278
278
  end
279
279
 
@@ -308,8 +308,8 @@ describe Cronofy::Auth do
308
308
  end
309
309
  end
310
310
 
311
- context "with data centre overridden" do
312
- let(:data_centre_override) { :de }
311
+ context "with data center overridden" do
312
+ let(:data_center_override) { :de }
313
313
  let(:api_token_url) { "https://api-de.cronofy.com/oauth/token" }
314
314
  let(:app_token_url) { "https://app-de.cronofy.com/oauth/token" }
315
315
 
@@ -372,14 +372,14 @@ describe Cronofy::Auth do
372
372
  it_behaves_like 'an authorization request'
373
373
  end
374
374
 
375
- context "with data centre overridden" do
375
+ context "with data center overridden" do
376
376
  subject do
377
377
  Cronofy::Auth.new(
378
378
  client_id: client_id,
379
379
  client_secret: client_secret,
380
380
  access_token: access_token,
381
381
  refresh_token: refresh_token,
382
- data_centre: :de,
382
+ data_center: :de,
383
383
  ).refresh!
384
384
  end
385
385
 
@@ -476,4 +476,84 @@ describe Cronofy::Auth do
476
476
  end
477
477
  end
478
478
  end
479
+
480
+ describe "#revoke_by_sub" do
481
+ let(:auth) do
482
+ Cronofy::Auth.new(
483
+ client_id: client_id,
484
+ client_secret: client_secret,
485
+ access_token: access_token,
486
+ refresh_token: refresh_token,
487
+ )
488
+ end
489
+
490
+ let!(:revocation_request) do
491
+ stub_request(:post, "https://api.cronofy.com/oauth/token/revoke")
492
+ .with(
493
+ body: {
494
+ client_id: client_id,
495
+ client_secret: client_secret,
496
+ sub: sub,
497
+ },
498
+ headers: {
499
+ 'Content-Type' => 'application/x-www-form-urlencoded',
500
+ 'User-Agent' => "Cronofy Ruby #{Cronofy::VERSION}",
501
+ }
502
+ ).to_return(status: response_status)
503
+ end
504
+
505
+ let(:sub) { "random_sub_value" }
506
+
507
+ before do
508
+ auth.revoke_by_sub(sub)
509
+ end
510
+
511
+ it "does not unset the access token for the current auth" do
512
+ expect(auth.access_token).not_to be_nil
513
+ end
514
+
515
+ it "makes the revocation request" do
516
+ expect(revocation_request).to have_been_requested
517
+ end
518
+ end
519
+
520
+ describe "#revoke_by_token" do
521
+ let(:auth) do
522
+ Cronofy::Auth.new(
523
+ client_id: client_id,
524
+ client_secret: client_secret,
525
+ access_token: access_token,
526
+ refresh_token: refresh_token,
527
+ )
528
+ end
529
+
530
+ let!(:revocation_request) do
531
+ stub_request(:post, "https://api.cronofy.com/oauth/token/revoke")
532
+ .with(
533
+ body: {
534
+ client_id: client_id,
535
+ client_secret: client_secret,
536
+ token: token,
537
+ },
538
+ headers: {
539
+ 'Content-Type' => 'application/x-www-form-urlencoded',
540
+ 'User-Agent' => "Cronofy Ruby #{Cronofy::VERSION}",
541
+ }
542
+ ).to_return(status: response_status)
543
+ end
544
+
545
+ let(:token) { "random_token_value" }
546
+
547
+ before do
548
+ auth.revoke_by_token(token)
549
+ end
550
+
551
+ it "does not unset the access token for the current auth" do
552
+ expect(auth.access_token).not_to be_nil
553
+ end
554
+
555
+ it "makes the revocation request" do
556
+ expect(revocation_request).to have_been_requested
557
+ end
558
+ end
479
559
  end
@@ -266,6 +266,7 @@ describe Cronofy::Client do
266
266
  ],
267
267
  }
268
268
  end
269
+
269
270
  let(:request_body) do
270
271
  {
271
272
  :event_id => "qTtZdczOccgaPncGJaCiLg",
@@ -1718,6 +1719,57 @@ describe Cronofy::Client do
1718
1719
  it_behaves_like 'a Cronofy request'
1719
1720
  it_behaves_like 'a Cronofy request with mapped return value'
1720
1721
  end
1722
+
1723
+ context "when given query_periods instead of available_periods" do
1724
+ let(:participants) do
1725
+ { members: %w{acc_567236000909002 acc_678347111010113} }
1726
+ end
1727
+
1728
+ let(:required_duration) { 60 }
1729
+
1730
+ let(:query_periods) do
1731
+ [
1732
+ { start: Time.parse("2017-01-03T09:00:00Z"), end: Time.parse("2017-01-03T18:00:00Z") },
1733
+ { start: Time.parse("2017-01-04T09:00:00Z"), end: Time.parse("2017-01-04T18:00:00Z") },
1734
+ ]
1735
+ end
1736
+
1737
+ let(:request_body) do
1738
+ {
1739
+ "participants" => [
1740
+ {
1741
+ "members" => [
1742
+ { "sub" => "acc_567236000909002" },
1743
+ { "sub" => "acc_678347111010113" }
1744
+ ],
1745
+ "required" => "all"
1746
+ }
1747
+ ],
1748
+ "query_periods" => [
1749
+ {
1750
+ "start" => "2017-01-03T09:00:00Z",
1751
+ "end" => "2017-01-03T18:00:00Z"
1752
+ },
1753
+ {
1754
+ "start" => "2017-01-04T09:00:00Z",
1755
+ "end" => "2017-01-04T18:00:00Z"
1756
+ }
1757
+ ],
1758
+ "required_duration" => { "minutes" => 60 },
1759
+ }
1760
+ end
1761
+
1762
+ subject do
1763
+ client.availability(
1764
+ participants: participants,
1765
+ required_duration: required_duration,
1766
+ query_periods: query_periods
1767
+ )
1768
+ end
1769
+
1770
+ it_behaves_like 'a Cronofy request'
1771
+ it_behaves_like 'a Cronofy request with mapped return value'
1772
+ end
1721
1773
  end
1722
1774
  end
1723
1775
 
@@ -1873,6 +1925,18 @@ describe Cronofy::Client do
1873
1925
 
1874
1926
  it_behaves_like 'a Cronofy request'
1875
1927
  it_behaves_like 'a Cronofy request with mapped return value'
1928
+
1929
+ context "when passing query_periods instead" do
1930
+ before do
1931
+ args[:query_periods] = args[:available_periods]
1932
+ args.delete(:available_periods)
1933
+ request_body["query_periods"] = request_body["available_periods"]
1934
+ request_body.delete("available_periods")
1935
+ end
1936
+
1937
+ it_behaves_like 'a Cronofy request'
1938
+ it_behaves_like 'a Cronofy request with mapped return value'
1939
+ end
1876
1940
  end
1877
1941
  end
1878
1942
 
@@ -2325,8 +2389,8 @@ describe Cronofy::Client do
2325
2389
 
2326
2390
  end
2327
2391
 
2328
- describe "Specified data centre" do
2329
- let(:data_centre) { :de }
2392
+ describe "specifying data_centre" do
2393
+ let(:data_center) { :de }
2330
2394
 
2331
2395
  let(:client) do
2332
2396
  Cronofy::Client.new(
@@ -2334,12 +2398,52 @@ describe Cronofy::Client do
2334
2398
  client_secret: 'client_secret_456',
2335
2399
  access_token: token,
2336
2400
  refresh_token: 'refresh_token_456',
2337
- data_centre: data_centre,
2401
+ data_centre: data_center,
2338
2402
  )
2339
2403
  end
2340
2404
 
2341
2405
  describe "Userinfo" do
2342
- let(:request_url) { "https://api-#{data_centre}.cronofy.com/v1/userinfo" }
2406
+ let(:request_url) { "https://api-#{data_center}.cronofy.com/v1/userinfo" }
2407
+
2408
+ describe "#userinfo" do
2409
+ let(:method) { :get }
2410
+
2411
+ let(:correct_response_code) { 200 }
2412
+ let(:correct_response_body) do
2413
+ {
2414
+ "sub" => "ser_5700a00eb0ccd07000000000",
2415
+ "cronofy.type" => "service_account",
2416
+ "cronofy.service_account.domain" => "example.com"
2417
+ }
2418
+ end
2419
+
2420
+ let(:correct_mapped_result) do
2421
+ Cronofy::UserInfo.new(correct_response_body)
2422
+ end
2423
+
2424
+ subject { client.userinfo }
2425
+
2426
+ it_behaves_like "a Cronofy request"
2427
+ it_behaves_like "a Cronofy request with mapped return value"
2428
+ end
2429
+ end
2430
+ end
2431
+
2432
+ describe "specifying data_center" do
2433
+ let(:data_center) { :au }
2434
+
2435
+ let(:client) do
2436
+ Cronofy::Client.new(
2437
+ client_id: 'client_id_123',
2438
+ client_secret: 'client_secret_456',
2439
+ access_token: token,
2440
+ refresh_token: 'refresh_token_456',
2441
+ data_center: data_center,
2442
+ )
2443
+ end
2444
+
2445
+ describe "Userinfo" do
2446
+ let(:request_url) { "https://api-#{data_center}.cronofy.com/v1/userinfo" }
2343
2447
 
2344
2448
  describe "#userinfo" do
2345
2449
  let(:method) { :get }
@@ -2377,11 +2481,27 @@ describe Cronofy::Client do
2377
2481
  let(:body) { "{\"example\":\"well-known\"}" }
2378
2482
 
2379
2483
  it "verifies the correct HMAC" do
2380
- expect(client.hmac_match?(body: body, hmac: "6r2/HjBkqymGegX0wOfifieeUXbbHwtV/LohHS+jv6c=")).to be true
2484
+ expect(client.hmac_valid?(body: body, hmac: "6r2/HjBkqymGegX0wOfifieeUXbbHwtV/LohHS+jv6c=")).to be true
2381
2485
  end
2382
2486
 
2383
2487
  it "rejects an incorrect HMAC" do
2384
- expect(client.hmac_match?(body: body, hmac: "something-else")).to be false
2488
+ expect(client.hmac_valid?(body: body, hmac: "something-else")).to be false
2489
+ end
2490
+
2491
+ it "verifies the correct HMAC when one of the multiple HMACs splitted by ',' match" do
2492
+ expect(client.hmac_valid?(body: body, hmac: "6r2/HjBkqymGegX0wOfifieeUXbbHwtV/LohHS+jv6c=,something-else")).to be true
2493
+ end
2494
+
2495
+ it "rejects incorrect when multiple HMACs splitted by ',' don't match" do
2496
+ expect(client.hmac_valid?(body: body, hmac: "something-else,something-else2")).to be false
2497
+ end
2498
+
2499
+ it "rejects if empty HMAC" do
2500
+ expect(client.hmac_valid?(body: body, hmac: "")).to be false
2501
+ end
2502
+
2503
+ it "rejects if nil HMAC" do
2504
+ expect(client.hmac_valid?(body: body, hmac: nil)).to be false
2385
2505
  end
2386
2506
  end
2387
2507
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cronofy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.36.0
4
+ version: 0.37.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sergii Paryzhskyi
@@ -9,22 +9,8 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-09-23 00:00:00.000000000 Z
12
+ date: 2021-07-02 00:00:00.000000000 Z
13
13
  dependencies:
14
- - !ruby/object:Gem::Dependency
15
- name: oauth2
16
- requirement: !ruby/object:Gem::Requirement
17
- requirements:
18
- - - "~>"
19
- - !ruby/object:Gem::Version
20
- version: '1.0'
21
- type: :runtime
22
- prerelease: false
23
- version_requirements: !ruby/object:Gem::Requirement
24
- requirements:
25
- - - "~>"
26
- - !ruby/object:Gem::Version
27
- version: '1.0'
28
14
  - !ruby/object:Gem::Dependency
29
15
  name: hashie
30
16
  requirement: !ruby/object:Gem::Requirement
@@ -34,7 +20,7 @@ dependencies:
34
20
  version: '2.1'
35
21
  - - "<"
36
22
  - !ruby/object:Gem::Version
37
- version: '4'
23
+ version: '5'
38
24
  type: :runtime
39
25
  prerelease: false
40
26
  version_requirements: !ruby/object:Gem::Requirement
@@ -44,7 +30,21 @@ dependencies:
44
30
  version: '2.1'
45
31
  - - "<"
46
32
  - !ruby/object:Gem::Version
47
- version: '4'
33
+ version: '5'
34
+ - !ruby/object:Gem::Dependency
35
+ name: oauth2
36
+ requirement: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.0'
41
+ type: :runtime
42
+ prerelease: false
43
+ version_requirements: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.0'
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: bundler
50
50
  requirement: !ruby/object:Gem::Requirement
@@ -156,10 +156,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
156
156
  - !ruby/object:Gem::Version
157
157
  version: '0'
158
158
  requirements: []
159
- rubygems_version: 3.1.2
159
+ rubygems_version: 3.2.20
160
160
  signing_key:
161
161
  specification_version: 4
162
- summary: Cronofy - one API for all the calendars
162
+ summary: Cronofy - the scheduling platform for business
163
163
  test_files:
164
164
  - spec/spec_helper.rb
165
165
  - spec/response_parser_spec.rb