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 +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
|
-
[![
|
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) -
|
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
|