cronofy 0.36.0 → 0.37.3
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +30 -0
- data/README.md +18 -8
- data/cronofy.gemspec +2 -2
- data/lib/cronofy.rb +27 -11
- data/lib/cronofy/auth.rb +37 -7
- data/lib/cronofy/client.rb +31 -14
- data/lib/cronofy/version.rb +1 -1
- data/spec/lib/cronofy/auth_spec.rb +92 -12
- data/spec/lib/cronofy/client_spec.rb +126 -6
- metadata +20 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f398fb44b861ba5df84e244632877a53b050f584c08d15a815cb0e4abaae13bc
|
4
|
+
data.tar.gz: 8cea161bbef6df1b41a3ff52b29984c9ccd3f713abe279a7137e1e0be89cd7d7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
[](https://github.com/cronofy/cronofy-ruby/actions/workflows/ci.yml)
|
4
4
|
[](http://badge.fury.io/rb/cronofy)
|
5
5
|
|
6
|
-
[Cronofy](https://www.cronofy.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 [
|
27
|
-
to
|
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
|
-
|
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 -
|
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
|
-
|
16
|
+
default_data_center
|
17
17
|
end
|
18
18
|
|
19
19
|
def self.default_data_centre=(value)
|
20
|
-
|
20
|
+
default_data_center= value
|
21
21
|
end
|
22
22
|
|
23
|
-
def self.
|
24
|
-
|
25
|
-
|
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'] ||
|
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
|
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(
|
50
|
-
if
|
51
|
-
|
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'] ||
|
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
|
-
|
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(
|
20
|
-
@api_client = OAuth2::Client.new(client_id, client_secret, site: ::Cronofy.api_url(
|
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")
|
data/lib/cronofy/client.rb
CHANGED
@@ -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
|
-
# :
|
31
|
-
#
|
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
|
-
@
|
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
|
-
|
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
|
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
|
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
|
-
|
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
|
-
# :
|
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
|
-
#
|
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
|
-
#
|
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(@
|
1901
|
+
::Cronofy.api_url(@data_center)
|
1885
1902
|
end
|
1886
1903
|
end
|
1887
1904
|
|
data/lib/cronofy/version.rb
CHANGED
@@ -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(:
|
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
|
-
|
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
|
160
|
-
let(:
|
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(:
|
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
|
-
|
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(:
|
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
|
-
|
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
|
312
|
-
let(:
|
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
|
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
|
-
|
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 "
|
2329
|
-
let(:
|
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:
|
2401
|
+
data_centre: data_center,
|
2338
2402
|
)
|
2339
2403
|
end
|
2340
2404
|
|
2341
2405
|
describe "Userinfo" do
|
2342
|
-
let(:request_url) { "https://api-#{
|
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.
|
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.
|
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.
|
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:
|
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: '
|
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: '
|
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.
|
159
|
+
rubygems_version: 3.2.20
|
160
160
|
signing_key:
|
161
161
|
specification_version: 4
|
162
|
-
summary: Cronofy -
|
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
|