Skip to content

Commit 1a8baf1

Browse files
Merge pull request #98 from cronofy/add-client-secret-only-availability-auth
Add client secret only auth for availability
2 parents b8b441f + f490794 commit 1a8baf1

File tree

4 files changed

+162
-3
lines changed

4 files changed

+162
-3
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## [0.37.4]
2+
3+
* Support client_secret only clients being able to authorize `#availability` calls. [#97]
4+
15
## [0.37.3]
26

37
* 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]
@@ -192,6 +196,7 @@
192196
[0.37.1]: https://github.com/cronofy/cronofy-ruby/releases/tag/v0.37.1
193197
[0.37.2]: https://github.com/cronofy/cronofy-ruby/releases/tag/v0.37.2
194198
[0.37.3]: https://github.com/cronofy/cronofy-ruby/releases/tag/v0.37.3
199+
[0.37.4]: https://github.com/cronofy/cronofy-ruby/releases/tag/v0.37.4
195200

196201
[#13]: https://github.com/cronofy/cronofy-ruby/pull/13
197202
[#16]: https://github.com/cronofy/cronofy-ruby/pull/16
@@ -237,3 +242,4 @@
237242
[#90]: https://github.com/cronofy/cronofy-ruby/pull/90
238243
[#91]: https://github.com/cronofy/cronofy-ruby/pull/91
239244
[#95]: https://github.com/cronofy/cronofy-ruby/pull/95
245+
[#97]: https://github.com/cronofy/cronofy-ruby/pull/97

lib/cronofy/client.rb

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -844,7 +844,7 @@ def availability(options = {})
844844

845845
translate_available_periods(options[:query_periods] || options[:available_periods])
846846

847-
response = post("/v1/availability", options)
847+
response = availability_post("/v1/availability", options)
848848

849849
parse_collections(
850850
response,
@@ -889,7 +889,7 @@ def sequenced_availability(options = {})
889889

890890
translate_available_periods(options[:query_periods] || options[:available_periods])
891891

892-
response = post("/v1/sequenced_availability", options)
892+
response = availability_post("/v1/sequenced_availability", options)
893893
parse_collection(Sequence, "sequences", response)
894894
end
895895

@@ -1811,6 +1811,17 @@ def raw_post(url, body)
18111811
wrapped_request { @auth.api_client.request(:post, url, json_request_args(body)) }
18121812
end
18131813

1814+
# Availability Query could originally be authenticated via an access_token
1815+
# Whilst it should be authed via an API key now, we try access_token first
1816+
# for backward compatibility
1817+
def availability_post(url, body)
1818+
if @auth.access_token
1819+
post(url, body)
1820+
else
1821+
wrapped_request { api_key!.post(url, json_request_args(body)) }
1822+
end
1823+
end
1824+
18141825
def wrapped_request
18151826
yield
18161827
rescue OAuth2::Error => e

lib/cronofy/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
module Cronofy
2-
VERSION = "0.37.3".freeze
2+
VERSION = "0.37.4".freeze
33
end

spec/lib/cronofy/client_spec.rb

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,6 +1257,17 @@
12571257
let(:request_url) { 'https://api.cronofy.com/v1/availability' }
12581258
let(:request_headers) { json_request_headers }
12591259

1260+
let(:client_id) { 'example_id' }
1261+
let(:client_secret) { 'example_secret' }
1262+
let(:token) { client_secret }
1263+
1264+
let(:client) do
1265+
Cronofy::Client.new(
1266+
client_id: client_id,
1267+
client_secret: client_secret,
1268+
)
1269+
end
1270+
12601271
let(:request_body) do
12611272
{
12621273
"participants" => [
@@ -1770,6 +1781,87 @@
17701781
it_behaves_like 'a Cronofy request'
17711782
it_behaves_like 'a Cronofy request with mapped return value'
17721783
end
1784+
1785+
context "when trying to auth with only an access_token, as originally implemented" do
1786+
let(:access_token) { "access_token_123"}
1787+
let(:client) { Cronofy::Client.new(access_token: access_token) }
1788+
let(:request_headers) do
1789+
{
1790+
"Authorization" => "Bearer #{access_token}",
1791+
"User-Agent" => "Cronofy Ruby #{::Cronofy::VERSION}",
1792+
"Content-Type" => "application/json; charset=utf-8",
1793+
}
1794+
end
1795+
1796+
let(:participants) do
1797+
{ members: %w{acc_567236000909002 acc_678347111010113} }
1798+
end
1799+
1800+
let(:required_duration) { 60 }
1801+
1802+
let(:available_periods) do
1803+
[
1804+
{ start: Time.parse("2017-01-03T09:00:00Z"), end: Time.parse("2017-01-03T18:00:00Z") },
1805+
{ start: Time.parse("2017-01-04T09:00:00Z"), end: Time.parse("2017-01-04T18:00:00Z") },
1806+
]
1807+
end
1808+
1809+
it_behaves_like 'a Cronofy request'
1810+
it_behaves_like 'a Cronofy request with mapped return value'
1811+
end
1812+
1813+
context "when trying to auth with both a client_secret and access_token" do
1814+
let(:access_token) { "access_token_123" }
1815+
let(:client_secret) { "client_secret_456" }
1816+
let(:client) { Cronofy::Client.new(access_token: access_token, client_secret: client_secret) }
1817+
let(:request_headers) do
1818+
{
1819+
"Authorization" => "Bearer #{access_token}",
1820+
"User-Agent" => "Cronofy Ruby #{::Cronofy::VERSION}",
1821+
"Content-Type" => "application/json; charset=utf-8",
1822+
}
1823+
end
1824+
1825+
let(:participants) do
1826+
{ members: %w{acc_567236000909002 acc_678347111010113} }
1827+
end
1828+
1829+
let(:required_duration) { 60 }
1830+
1831+
let(:available_periods) do
1832+
[
1833+
{ start: Time.parse("2017-01-03T09:00:00Z"), end: Time.parse("2017-01-03T18:00:00Z") },
1834+
{ start: Time.parse("2017-01-04T09:00:00Z"), end: Time.parse("2017-01-04T18:00:00Z") },
1835+
]
1836+
end
1837+
1838+
describe "it prefers the access_token for backward compatibility" do
1839+
it_behaves_like 'a Cronofy request'
1840+
it_behaves_like 'a Cronofy request with mapped return value'
1841+
end
1842+
end
1843+
1844+
context "when trying to auth without a client_secret or access_token" do
1845+
let(:client) { Cronofy::Client.new }
1846+
1847+
let(:participants) do
1848+
{ members: %w{acc_567236000909002 acc_678347111010113} }
1849+
end
1850+
1851+
let(:required_duration) { 60 }
1852+
1853+
let(:available_periods) do
1854+
[
1855+
{ start: Time.parse("2017-01-03T09:00:00Z"), end: Time.parse("2017-01-03T18:00:00Z") },
1856+
{ start: Time.parse("2017-01-04T09:00:00Z"), end: Time.parse("2017-01-04T18:00:00Z") },
1857+
]
1858+
end
1859+
1860+
1861+
it "raises an API Key error" do
1862+
expect{ subject }.to raise_error(Cronofy::CredentialsMissingError)
1863+
end
1864+
end
17731865
end
17741866
end
17751867

@@ -1779,6 +1871,17 @@
17791871
let(:request_url) { 'https://api.cronofy.com/v1/sequenced_availability' }
17801872
let(:request_headers) { json_request_headers }
17811873

1874+
let(:client_id) { 'example_id' }
1875+
let(:client_secret) { 'example_secret' }
1876+
let(:token) { client_secret }
1877+
1878+
let(:client) do
1879+
Cronofy::Client.new(
1880+
client_id: client_id,
1881+
client_secret: client_secret,
1882+
)
1883+
end
1884+
17821885
let(:request_body) do
17831886
{
17841887
"sequence" => [
@@ -1937,6 +2040,45 @@
19372040
it_behaves_like 'a Cronofy request'
19382041
it_behaves_like 'a Cronofy request with mapped return value'
19392042
end
2043+
2044+
context "when trying to auth with access_token only" do
2045+
let(:access_token) { "access_token_123"}
2046+
let(:client) { Cronofy::Client.new(access_token: access_token) }
2047+
let(:request_headers) do
2048+
{
2049+
"Authorization" => "Bearer #{access_token}",
2050+
"User-Agent" => "Cronofy Ruby #{::Cronofy::VERSION}",
2051+
"Content-Type" => "application/json; charset=utf-8",
2052+
}
2053+
end
2054+
2055+
it_behaves_like 'a Cronofy request'
2056+
it_behaves_like 'a Cronofy request with mapped return value'
2057+
end
2058+
2059+
context "when trying to auth with both access_token and client_secret provided" do
2060+
let(:client_id) { 'example_id' }
2061+
let(:client_secret) { 'example_secret' }
2062+
let(:access_token) { "access_token_123"}
2063+
2064+
let(:client) do
2065+
Cronofy::Client.new(
2066+
client_id: client_id,
2067+
client_secret: client_secret,
2068+
access_token: access_token,
2069+
)
2070+
end
2071+
let(:request_headers) do
2072+
{
2073+
"Authorization" => "Bearer #{access_token}",
2074+
"User-Agent" => "Cronofy Ruby #{::Cronofy::VERSION}",
2075+
"Content-Type" => "application/json; charset=utf-8",
2076+
}
2077+
end
2078+
2079+
it_behaves_like 'a Cronofy request'
2080+
it_behaves_like 'a Cronofy request with mapped return value'
2081+
end
19402082
end
19412083
end
19422084

0 commit comments

Comments
 (0)