fmrest-core 0.18.0.rc3 → 0.20.0.rc1
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 +11 -0
- data/README.md +62 -91
- data/lib/fmrest/connection_settings.rb +6 -1
- data/lib/fmrest/token_store/memory.rb +4 -4
- data/lib/fmrest/token_store/null.rb +4 -13
- data/lib/fmrest/token_store/short_memory.rb +29 -0
- data/lib/fmrest/token_store.rb +24 -0
- data/lib/fmrest/v1/connection.rb +22 -3
- data/lib/fmrest/v1/raise_errors.rb +11 -0
- data/lib/fmrest/v1/token_session.rb +6 -19
- data/lib/fmrest/v1/type_coercer.rb +1 -1
- data/lib/fmrest/version.rb +1 -1
- data/lib/fmrest.rb +7 -0
- metadata +5 -5
- data/lib/fmrest-spyke.rb +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e65b80ac2c60bb8c3ba6c356c55c720dec5ed59ee8afdb94e18c025bf327a3fe
|
4
|
+
data.tar.gz: c144aaafd1b237bd67fdbd90a99423dae90638555703dd4b6b2eb05dbc7f687e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ff81e141c358ae0f4c95d1d4b82a58b717caa550239b358345d6fcc0a1c3e9af1df3dee9e5c014e2163a67a73fbf83ab4d2bd1df674a0e16261f3c57c3e6a826
|
7
|
+
data.tar.gz: 0ed42801b904cc7967dab1c5990aa8389d07727b7a5d3234db6efb40b61d5c3312fbe1e45522bb05058fefc237571456546c209b3f8f752ff0c4a9026770f181
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
## Changelog
|
2
2
|
|
3
|
+
### 0.20.0
|
4
|
+
|
5
|
+
* Forward proxy options to AWS Client when using `fmrest-cloud` gem
|
6
|
+
|
7
|
+
### 0.19.0
|
8
|
+
|
9
|
+
* Added native support for FileMaker Cloud through the `fmrest-cloud` gem
|
10
|
+
|
3
11
|
### 0.18.0
|
4
12
|
|
5
13
|
* Better support for portals with mismatching field qualifiers
|
@@ -7,6 +15,9 @@
|
|
7
15
|
* Defining an attribute on a model that would collide with an existing method
|
8
16
|
now raises an error
|
9
17
|
* Cleared Faraday deprecation messages on authentication methods
|
18
|
+
* Handle FileMaker Cloud case where HTTP 401 Unauthorized with content-type
|
19
|
+
text/html is returned after token expiry
|
20
|
+
* Add retry option to Rescuable mixin
|
10
21
|
* Added fmrest-ruby/VERSION to User-Agent headers
|
11
22
|
|
12
23
|
### 0.17.1
|
data/README.md
CHANGED
@@ -5,14 +5,27 @@
|
|
5
5
|
[](https://rubydoc.info/github/beezwax/fmrest-ruby)
|
6
6
|
|
7
7
|
A Ruby client for
|
8
|
-
[FileMaker
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
8
|
+
[FileMaker's Data API](https://help.claris.com/en/data-api-guide)
|
9
|
+
with ActiveRecord-ish ORM features.
|
10
|
+
|
11
|
+
While pretty feature-rich, fmrest-ruby doesn't yet support 100% of FileMaker
|
12
|
+
19's Data API features. See the [implementation completeness
|
13
|
+
table](#api-implementation-completeness-table) to check if a feature you need
|
14
|
+
is natively supported by the gem.
|
15
|
+
|
16
|
+
## Contents
|
17
|
+
|
18
|
+
* [Gems](#gems)
|
19
|
+
* [Installation](#installation)
|
20
|
+
* [Simple example](#simple-example)
|
21
|
+
* [Connection settings](#connection-settings)
|
22
|
+
* [Session token store](#session-token-store)
|
23
|
+
* [Date fields and timezones](#date-fields-and-timezones)
|
24
|
+
* [ActiveRecord-like ORM (fmrest-spyke)](#activerecord-like-orm-fmrest-spyke)
|
25
|
+
* [Logging](#logging)
|
26
|
+
* [Gotchas](#gotchas)
|
27
|
+
* [API implementation completeness table](#api-implementation-completeness-table)
|
28
|
+
* [Supported Ruby versions](#supported-ruby-versions)
|
16
29
|
|
17
30
|
## Gems
|
18
31
|
|
@@ -20,28 +33,26 @@ The `fmrest` gem is a wrapper for two other gems:
|
|
20
33
|
|
21
34
|
* `fmrest-spyke`, providing an ActiveRecord-like ORM library built on top
|
22
35
|
of `fmrest-core` and [Spyke](https://github.com/balvig/spyke).
|
23
|
-
* `fmrest-core`, providing the core
|
36
|
+
* `fmrest-core`, providing the core
|
37
|
+
[Faraday](https://github.com/lostisland/faraday) connection builder, session
|
24
38
|
management, and other core utilities.
|
25
39
|
|
40
|
+
In addition, the optional `fmrest-cloud` gem adds support for FileMaker Cloud.
|
41
|
+
See the [main document on connecting to FileMaker
|
42
|
+
Cloud](docs/FileMakerCloud.md).
|
43
|
+
|
26
44
|
## Installation
|
27
45
|
|
28
|
-
|
46
|
+
In your Gemfile:
|
29
47
|
|
30
48
|
```ruby
|
31
49
|
gem 'fmrest'
|
32
|
-
```
|
33
|
-
|
34
|
-
Or if you just want to use the Faraday connection without the ORM features:
|
35
50
|
|
36
|
-
|
37
|
-
gem 'fmrest-
|
51
|
+
# Optional: if your files are hosted on FileMaker Cloud
|
52
|
+
gem 'fmrest-cloud'
|
38
53
|
```
|
39
54
|
|
40
|
-
## Simple
|
41
|
-
|
42
|
-
### ORM example
|
43
|
-
|
44
|
-
Most people would want to use the ORM features:
|
55
|
+
## Simple example
|
45
56
|
|
46
57
|
```ruby
|
47
58
|
# A Layout model connecting to the "Honeybees Web" FileMaker layout
|
@@ -90,32 +101,9 @@ bee.tasks.build(urgency: "Today")
|
|
90
101
|
bee.save
|
91
102
|
```
|
92
103
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
Data API interaction and just want a lightweight solution) you can simply use
|
97
|
-
the Faraday connection provided by `fmrest-core`:
|
98
|
-
|
99
|
-
```ruby
|
100
|
-
connection = FmRest::V1.build_connection(
|
101
|
-
host: "…",
|
102
|
-
database: "…",
|
103
|
-
username: "…",
|
104
|
-
password: "…"
|
105
|
-
)
|
106
|
-
|
107
|
-
# Get all records (as parsed JSON)
|
108
|
-
connection.get("layouts/FancyLayout/records")
|
109
|
-
|
110
|
-
# Create new record
|
111
|
-
connection.post do |req|
|
112
|
-
req.url "layouts/FancyLayout/records"
|
113
|
-
|
114
|
-
# You can just pass a hash for the JSON body
|
115
|
-
req.body = { … }
|
116
|
-
end
|
117
|
-
```
|
118
|
-
|
104
|
+
In case you don't want the ORM features (i.e. you only need authentication and
|
105
|
+
JSON parsing, and are comfortable writing the API requests manually without the
|
106
|
+
ORM overhead) you can use the Faraday connection provided by `fmrest-core`.
|
119
107
|
See the [main document on using the base
|
120
108
|
connection](docs/BaseConnectionUsage.md) for more.
|
121
109
|
|
@@ -125,10 +113,6 @@ The minimum required connection settings are `:host`, `:database`, `:username`
|
|
125
113
|
and `:password`, but fmrest-ruby has many other options you can pass when
|
126
114
|
setting up a connection (see [full list](#full-list-of-available-options) below).
|
127
115
|
|
128
|
-
If you're using FileMaker Cloud you may need to pass `:fmid_token` instead
|
129
|
-
of the regular `:username` and `:password`. See the [main document on
|
130
|
-
connecting to FileMaker Cloud](docs/FileMakerCloud.md) for more info.
|
131
|
-
|
132
116
|
`:ssl` and `:proxy` are forwarded to the underlying
|
133
117
|
[Faraday](https://github.com/lostisland/faraday) connection. You can use this
|
134
118
|
to, for instance, disable SSL verification:
|
@@ -153,9 +137,8 @@ Option | Description | Format
|
|
153
137
|
`:username` | A Data API-ready account | String | None
|
154
138
|
`:password` | Your password | String | None
|
155
139
|
`:account_name` | Alias of `:username` | String | None
|
156
|
-
`:fmid_token` | Claris ID token (only needed for FileMaker Cloud) | String | None
|
157
140
|
`:ssl` | SSL options to be forwarded to Faraday | Faraday SSL options | None
|
158
|
-
`:proxy` | Proxy
|
141
|
+
`:proxy` | Proxy URI e.g. `http://username:password@proxy.host:5000` | String / URI | None
|
159
142
|
`:log` | Log JSON responses to STDOUT | Boolean | `false`
|
160
143
|
`:log_level` | Which log level to log into | Values accepted by `Logger#level=` | `:debug`
|
161
144
|
`:coerce_dates` | See section on [date fields](#date-fields-and-timezones) | Boolean \| `:hybrid` \| `:full` | `false`
|
@@ -165,6 +148,11 @@ Option | Description | Format
|
|
165
148
|
`:timezone` | The timezone for the FM server | `:local` \| `:utc` \| `nil` | `nil`
|
166
149
|
`:autologin` | Whether to automatically start Data API sessions | Boolean | `true`
|
167
150
|
`:token` | Used to manually provide a session token (e.g. if `:autologin` is `false`) | String | None
|
151
|
+
`:fmid_token` | Claris ID token (only needed if manually obtaining the token) | String | None
|
152
|
+
`:cloud` | Specifies whether the host is using FileMaker Cloud | `:auto` \| Boolean | `:auto`
|
153
|
+
`:cognito_client_id`| Overwrites the hardcoded FileMaker Cloud Cognito Client ID | String | None
|
154
|
+
`:cognito_pool_id` | Overwrites the hardcoded FileMaker Cloud Cognito Pool ID | String | None
|
155
|
+
`:aws_region` | Overwrites the hardcoded FileMaker Cloud AWS Region | String | None
|
168
156
|
|
169
157
|
### Default connection settings
|
170
158
|
|
@@ -207,7 +195,7 @@ See the [main document on date fields](docs/DateFields.md) for more info.
|
|
207
195
|
## ActiveRecord-like ORM (fmrest-spyke)
|
208
196
|
|
209
197
|
[Spyke](https://github.com/balvig/spyke) is an ActiveRecord-like gem for
|
210
|
-
building REST ORM models. fmrest-ruby
|
198
|
+
building REST ORM models. fmrest-ruby uses it to build its ORM features,
|
211
199
|
bundled in the `fmrest-spyke` gem (already included if you're using the
|
212
200
|
`fmrest` gem).
|
213
201
|
|
@@ -265,39 +253,33 @@ class Honeybee < FmRest::Layout
|
|
265
253
|
end
|
266
254
|
```
|
267
255
|
|
268
|
-
|
269
|
-
connection settings, so you don't have to worry about setting that up.
|
270
|
-
|
271
|
-
Note that these settings are inheritable, so you could create a base class that
|
256
|
+
These settings are class-inheritable, so you could create a base class that
|
272
257
|
does the initial connection setup and then inherit from it in models using that
|
273
258
|
same connection. E.g.:
|
274
259
|
|
275
260
|
```ruby
|
276
|
-
class
|
261
|
+
class ApplicationFmLayout < FmRest::Layout
|
277
262
|
self.fmrest_config = { host: "…", database: "…", … }
|
278
263
|
end
|
279
264
|
|
280
|
-
class Honeybee <
|
281
|
-
# This model will use the same connection as
|
265
|
+
class Honeybee < ApplicationFmLayout
|
266
|
+
# This model will use the same connection as ApplicationFmLayout
|
282
267
|
end
|
283
268
|
```
|
284
269
|
|
285
|
-
|
270
|
+
If `fmrest_config` is not set, your model will try to use
|
286
271
|
`FmRest.default_connection_settings` instead.
|
287
272
|
|
288
273
|
#### Connection settings overlays
|
289
274
|
|
290
275
|
There may be cases where you want to use a different set of connection settings
|
291
|
-
depending on context,
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
the model in one context would also change it in all other contexts, leading to
|
296
|
-
security issues.
|
276
|
+
depending on context. For example, if you want to use username and password
|
277
|
+
provided by the user in a web application. Since `.fmrest_config` is set at the
|
278
|
+
class level, changing the username/password for the model in one context would
|
279
|
+
also change it in all other contexts, leading to security issues.
|
297
280
|
|
298
|
-
To solve this scenario, fmrest-ruby provides a way of defining thread-local
|
299
|
-
reversible connection settings overlays through
|
300
|
-
`.fmrest_config_overlay=`.
|
281
|
+
To solve this scenario, fmrest-ruby provides a way of defining thread-local,
|
282
|
+
reversible connection settings overlays through `.fmrest_config_overlay=`.
|
301
283
|
|
302
284
|
See the [main document on connection setting overlays](docs/ConfigOverlays.md)
|
303
285
|
for details on how it works.
|
@@ -461,12 +443,10 @@ for details.
|
|
461
443
|
|
462
444
|
### Rescuable mixin
|
463
445
|
|
464
|
-
Sometimes you may want to handle Data API errors at the model level. For
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
`Rescuable` that provides convenience macros for that. If you've used Ruby on
|
469
|
-
Rails you may be familiar with its syntax from controllers. E.g.
|
446
|
+
Sometimes you may want to handle Data API errors at the model level. For such
|
447
|
+
cases fmrest-ruby provides an off-by-default mixin called `Rescuable` that
|
448
|
+
provides convenience macros for that. If you've used Ruby on Rails you may be
|
449
|
+
familiar with its syntax from controllers. E.g.
|
470
450
|
|
471
451
|
```ruby
|
472
452
|
class BeeBase < FmRest::Layout
|
@@ -474,9 +454,6 @@ class BeeBase < FmRest::Layout
|
|
474
454
|
|
475
455
|
rescue_from FmRest::APIError::SystemError, with: :notify_admin_of_system_error
|
476
456
|
|
477
|
-
# Shorthand for rescue_with FmRest::APIError::AccountError, ...
|
478
|
-
rescue_account_error { ClarisIDTokenManager.expire_token }
|
479
|
-
|
480
457
|
def self.notify_admin_of_system_error(e)
|
481
458
|
# Shoot an email to the FM admin...
|
482
459
|
end
|
@@ -549,14 +526,14 @@ Read about unexpected scenarios in the [gotchas doc](docs/Gotchas.md).
|
|
549
526
|
|
550
527
|
## API implementation completeness table
|
551
528
|
|
552
|
-
FM Data API reference: https://
|
529
|
+
FM Data API reference: https://help.claris.com/en/data-api-guide/
|
553
530
|
|
554
|
-
| FM
|
531
|
+
| FM 19 Data API feature | Supported by basic connection | Supported by FmRest::Layout |
|
555
532
|
|-------------------------------------|-------------------------------|-----------------------------|
|
556
533
|
| Log in using HTTP Basic Auth | Yes | Yes |
|
557
534
|
| Log in using OAuth | No | No |
|
558
535
|
| Log in to an external data source | No | No |
|
559
|
-
| Log in using Claris ID account
|
536
|
+
| Log in using Claris ID account (FileMaker Cloud) | Yes | Yes |
|
560
537
|
| Log out | Yes | Yes |
|
561
538
|
| Get product information | Manual* | No |
|
562
539
|
| Get database names | Manual* | No |
|
@@ -592,9 +569,9 @@ the following Ruby implementations:
|
|
592
569
|
## Gem development
|
593
570
|
|
594
571
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
595
|
-
`
|
596
|
-
prompt that will allow you to experiment (it will auto-load all
|
597
|
-
spec/fixtures).
|
572
|
+
`bundle exec rspec` to run the specs. You can also run `bin/console` for an
|
573
|
+
interactive prompt that will allow you to experiment (it will auto-load all
|
574
|
+
fixtures in spec/fixtures).
|
598
575
|
|
599
576
|
To install all gems onto your local machine, run
|
600
577
|
`bundle exec rake all:install`. To release a new version, update the version
|
@@ -602,12 +579,6 @@ number in `lib/fmrest/version.rb`, and then run `bundle exec rake all:release`,
|
|
602
579
|
which will create a git tag for the version, push git commits and tags, and
|
603
580
|
push the `.gem` files to [rubygems.org](https://rubygems.org).
|
604
581
|
|
605
|
-
## License
|
606
|
-
|
607
|
-
The gem is available as open source under the terms of the
|
608
|
-
[MIT License](https://opensource.org/licenses/MIT).
|
609
|
-
See [LICENSE.txt](LICENSE.txt).
|
610
|
-
|
611
582
|
## Disclaimer
|
612
583
|
|
613
584
|
This project is not sponsored by or otherwise affiliated with Claris
|
@@ -31,6 +31,10 @@ module FmRest
|
|
31
31
|
timestamp_format
|
32
32
|
time_format
|
33
33
|
timezone
|
34
|
+
cognito_client_id
|
35
|
+
cognito_pool_id
|
36
|
+
aws_region
|
37
|
+
cloud
|
34
38
|
).freeze
|
35
39
|
|
36
40
|
# NOTE: password intentionally left non-required since it's only really
|
@@ -51,7 +55,8 @@ module FmRest
|
|
51
55
|
date_format: DEFAULT_DATE_FORMAT,
|
52
56
|
time_format: DEFAULT_TIME_FORMAT,
|
53
57
|
timestamp_format: DEFAULT_TIMESTAMP_FORMAT,
|
54
|
-
coerce_dates: false
|
58
|
+
coerce_dates: false,
|
59
|
+
cloud: :auto,
|
55
60
|
}.freeze
|
56
61
|
|
57
62
|
def self.wrap(settings, skip_validation: false)
|
@@ -7,19 +7,19 @@ module FmRest
|
|
7
7
|
class Memory < Base
|
8
8
|
def initialize(*args)
|
9
9
|
super
|
10
|
-
|
10
|
+
@@tokens ||= {}
|
11
11
|
end
|
12
12
|
|
13
13
|
def delete(key)
|
14
|
-
|
14
|
+
@@tokens.delete(key)
|
15
15
|
end
|
16
16
|
|
17
17
|
def load(key)
|
18
|
-
|
18
|
+
@@tokens[key]
|
19
19
|
end
|
20
20
|
|
21
21
|
def store(key, value)
|
22
|
-
|
22
|
+
@@tokens[key] = value
|
23
23
|
end
|
24
24
|
end
|
25
25
|
end
|
@@ -1,20 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "singleton"
|
4
|
-
|
5
3
|
module FmRest
|
6
4
|
module TokenStore
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
def
|
11
|
-
end
|
12
|
-
|
13
|
-
def load(key)
|
14
|
-
end
|
15
|
-
|
16
|
-
def store(key, value)
|
17
|
-
end
|
5
|
+
class Null < Base
|
6
|
+
def delete(key); end
|
7
|
+
def load(key); end
|
8
|
+
def store(key, value); end
|
18
9
|
end
|
19
10
|
end
|
20
11
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "fmrest/token_store/base"
|
4
|
+
|
5
|
+
module FmRest
|
6
|
+
module TokenStore
|
7
|
+
# Similar to Memory token store, but using instance vars instead of class
|
8
|
+
# vars. Mainly useful for specs, where we want to scope token persistance
|
9
|
+
# to a spec's context only
|
10
|
+
class ShortMemory < Base
|
11
|
+
def initialize(*args)
|
12
|
+
super
|
13
|
+
@tokens ||= {}
|
14
|
+
end
|
15
|
+
|
16
|
+
def delete(key)
|
17
|
+
@tokens.delete(key)
|
18
|
+
end
|
19
|
+
|
20
|
+
def load(key)
|
21
|
+
@tokens[key]
|
22
|
+
end
|
23
|
+
|
24
|
+
def store(key, value)
|
25
|
+
@tokens[key] = value
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/fmrest/token_store.rb
CHANGED
@@ -8,5 +8,29 @@ module FmRest
|
|
8
8
|
autoload :ActiveRecord, "fmrest/token_store/active_record"
|
9
9
|
autoload :Moneta, "fmrest/token_store/moneta"
|
10
10
|
autoload :Redis, "fmrest/token_store/redis"
|
11
|
+
autoload :ShortMemory, "fmrest/token_store/short_memory"
|
12
|
+
|
13
|
+
TOKEN_STORE_INTERFACE = [:load, :store, :delete].freeze
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def token_store
|
18
|
+
@token_store ||=
|
19
|
+
if TOKEN_STORE_INTERFACE.all? { |method| token_store_option.respond_to?(method) }
|
20
|
+
token_store_option
|
21
|
+
elsif token_store_option.kind_of?(Class)
|
22
|
+
if token_store_option.respond_to?(:instance)
|
23
|
+
token_store_option.instance
|
24
|
+
else
|
25
|
+
token_store_option.new
|
26
|
+
end
|
27
|
+
else
|
28
|
+
FmRest::TokenStore::Memory.new
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def token_store_option
|
33
|
+
raise NotImplementedError
|
34
|
+
end
|
11
35
|
end
|
12
36
|
end
|
data/lib/fmrest/v1/connection.rb
CHANGED
@@ -12,6 +12,8 @@ module FmRest
|
|
12
12
|
AUTH_CONNECTION_HEADERS = DEFAULT_HEADERS.merge("Content-Type" => "application/json").freeze
|
13
13
|
CLARIS_ID_HTTP_AUTH_TYPE = "FMID"
|
14
14
|
|
15
|
+
FILEMAKER_CLOUD_HOST_MATCHER = /\.filemaker-cloud\.com\Z/.freeze
|
16
|
+
|
15
17
|
# Builds a complete DAPI Faraday connection with middleware already
|
16
18
|
# configured to handle authentication, JSON parsing, logging and DAPI
|
17
19
|
# error handling. A block can be optionally given for additional
|
@@ -39,7 +41,7 @@ module FmRest
|
|
39
41
|
yield conn, settings
|
40
42
|
else
|
41
43
|
conn.use TypeCoercer, settings
|
42
|
-
conn.response :json
|
44
|
+
conn.response :json, content_type: /\bjson$/
|
43
45
|
end
|
44
46
|
|
45
47
|
if settings.log
|
@@ -57,11 +59,18 @@ module FmRest
|
|
57
59
|
def auth_connection(settings = FmRest.default_connection_settings)
|
58
60
|
settings = ConnectionSettings.wrap(settings)
|
59
61
|
|
62
|
+
if is_cloud_host = cloud_host?(settings)
|
63
|
+
FmRest.require_cloud_support
|
64
|
+
end
|
65
|
+
|
60
66
|
base_connection(settings, headers: AUTH_CONNECTION_HEADERS) do |conn|
|
67
|
+
conn.use Cloud::AuthErrorHandler, settings if is_cloud_host
|
61
68
|
conn.use RaiseErrors
|
62
69
|
|
63
70
|
if settings.fmid_token?
|
64
|
-
conn.request :authorization, CLARIS_ID_HTTP_AUTH_TYPE, settings.fmid_token
|
71
|
+
conn.request :authorization, CLARIS_ID_HTTP_AUTH_TYPE, -> { settings.fmid_token }
|
72
|
+
elsif is_cloud_host
|
73
|
+
conn.request :authorization, CLARIS_ID_HTTP_AUTH_TYPE, -> { Cloud::ClarisIdTokenManager.new(settings).fetch_token }
|
65
74
|
else
|
66
75
|
conn.request :basic_auth, settings.username!, settings.password!
|
67
76
|
end
|
@@ -70,7 +79,7 @@ module FmRest
|
|
70
79
|
conn.response :logger, FmRest.logger, bodies: true, headers: true, log_level: settings.log_level
|
71
80
|
end
|
72
81
|
|
73
|
-
conn.response :json
|
82
|
+
conn.response :json, content_type: /\bjson$/
|
74
83
|
conn.adapter Faraday.default_adapter
|
75
84
|
end
|
76
85
|
end
|
@@ -117,6 +126,16 @@ module FmRest
|
|
117
126
|
&block
|
118
127
|
)
|
119
128
|
end
|
129
|
+
|
130
|
+
private
|
131
|
+
|
132
|
+
def cloud_host?(settings)
|
133
|
+
if settings.cloud == :auto
|
134
|
+
return FILEMAKER_CLOUD_HOST_MATCHER =~ settings.host
|
135
|
+
end
|
136
|
+
|
137
|
+
settings.cloud
|
138
|
+
end
|
120
139
|
end
|
121
140
|
end
|
122
141
|
end
|
@@ -27,6 +27,17 @@ module FmRest
|
|
27
27
|
}.freeze
|
28
28
|
|
29
29
|
def on_complete(env)
|
30
|
+
# Sometimes, especially when using FileMaker Cloud, a failed
|
31
|
+
# authorization request will return a 401 (Unauthorized) with text/html
|
32
|
+
# content-type instead of the regular JSON, so we need to catch it
|
33
|
+
# manually here, emulating a regular account error
|
34
|
+
if !(/\bjson$/ === env.response_headers["content-type"]) && env.status == 401
|
35
|
+
raise FmRest::APIError::AccountError.new(212, "Authentication failed (HTTP 401: Unauthorized)")
|
36
|
+
end
|
37
|
+
|
38
|
+
# From this point on we want JSON
|
39
|
+
return unless env.body.is_a?(Hash)
|
40
|
+
|
30
41
|
# Sniff for either straight JSON parsing or Spyke's format
|
31
42
|
if env.body[:metadata] && env.body[:metadata][:messages]
|
32
43
|
check_errors(env.body[:metadata][:messages])
|
@@ -7,10 +7,11 @@ module FmRest
|
|
7
7
|
# FM Data API authentication middleware using the credentials strategy
|
8
8
|
#
|
9
9
|
class TokenSession < Faraday::Middleware
|
10
|
+
include TokenStore
|
11
|
+
|
10
12
|
class NoSessionTokenSet < FmRest::Error; end
|
11
13
|
|
12
14
|
HEADER_KEY = "Authorization"
|
13
|
-
TOKEN_STORE_INTERFACE = [:load, :store, :delete].freeze
|
14
15
|
LOGOUT_PATH_MATCHER = %r{\A(#{FmRest::V1::Connection::DATABASES_PATH}/[^/]+/sessions/)[^/]+\Z}.freeze
|
15
16
|
|
16
17
|
# @param app [#call]
|
@@ -110,29 +111,15 @@ module FmRest
|
|
110
111
|
end
|
111
112
|
end
|
112
113
|
|
113
|
-
def token_store
|
114
|
-
@token_store ||=
|
115
|
-
begin
|
116
|
-
if TOKEN_STORE_INTERFACE.all? { |method| token_store_option.respond_to?(method) }
|
117
|
-
token_store_option
|
118
|
-
elsif token_store_option.kind_of?(Class)
|
119
|
-
if token_store_option.respond_to?(:instance)
|
120
|
-
token_store_option.instance
|
121
|
-
else
|
122
|
-
token_store_option.new
|
123
|
-
end
|
124
|
-
else
|
125
|
-
FmRest::TokenStore::Memory.new
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
114
|
def token_store_option
|
131
115
|
@settings.token_store || FmRest.token_store
|
132
116
|
end
|
133
117
|
|
134
118
|
def auth_connection
|
135
|
-
|
119
|
+
# NOTE: this is purposely not memoized so that settings can be
|
120
|
+
# refreshed (since proc-based settings will not be automatically
|
121
|
+
# re-eval'd, for example for fmid_token-based auth)
|
122
|
+
V1.auth_connection(@settings)
|
136
123
|
end
|
137
124
|
end
|
138
125
|
end
|
data/lib/fmrest/version.rb
CHANGED
data/lib/fmrest.rb
CHANGED
@@ -59,5 +59,12 @@ module FmRest
|
|
59
59
|
require "fmrest/spyke"
|
60
60
|
self.Layout(*_)
|
61
61
|
end
|
62
|
+
|
63
|
+
def require_cloud_support
|
64
|
+
require "fmrest/cloud"
|
65
|
+
rescue LoadError => e
|
66
|
+
e.message << " (Did you include fmrest-cloud in your Gemfile?)" unless e.message.frozen?
|
67
|
+
raise e
|
68
|
+
end
|
62
69
|
end
|
63
70
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fmrest-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.20.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pedro Carbajal
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-10-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -16,7 +16,7 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 1.8.0
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
22
|
version: '2.0'
|
@@ -26,7 +26,7 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
29
|
+
version: 1.8.0
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: '2.0'
|
@@ -64,7 +64,6 @@ files:
|
|
64
64
|
- LICENSE.txt
|
65
65
|
- README.md
|
66
66
|
- lib/fmrest-core.rb
|
67
|
-
- lib/fmrest-spyke.rb
|
68
67
|
- lib/fmrest.rb
|
69
68
|
- lib/fmrest/connection_settings.rb
|
70
69
|
- lib/fmrest/errors.rb
|
@@ -76,6 +75,7 @@ files:
|
|
76
75
|
- lib/fmrest/token_store/moneta.rb
|
77
76
|
- lib/fmrest/token_store/null.rb
|
78
77
|
- lib/fmrest/token_store/redis.rb
|
78
|
+
- lib/fmrest/token_store/short_memory.rb
|
79
79
|
- lib/fmrest/v1.rb
|
80
80
|
- lib/fmrest/v1/auth.rb
|
81
81
|
- lib/fmrest/v1/connection.rb
|
data/lib/fmrest-spyke.rb
DELETED