booqable 1.0.0
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 +7 -0
- data/.rspec +2 -0
- data/.rubocop.yml +11 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/LICENSE.txt +21 -0
- data/README.md +403 -0
- data/Rakefile +12 -0
- data/lib/booqable/auth.rb +114 -0
- data/lib/booqable/client.rb +81 -0
- data/lib/booqable/configurable.rb +143 -0
- data/lib/booqable/default.rb +215 -0
- data/lib/booqable/error.rb +428 -0
- data/lib/booqable/http.rb +383 -0
- data/lib/booqable/json_api_serializer.rb +266 -0
- data/lib/booqable/middleware/auth/api_key.rb +46 -0
- data/lib/booqable/middleware/auth/oauth.rb +88 -0
- data/lib/booqable/middleware/auth/single_use.rb +157 -0
- data/lib/booqable/middleware/base.rb +7 -0
- data/lib/booqable/middleware/raise_error.rb +29 -0
- data/lib/booqable/oauth_client.rb +72 -0
- data/lib/booqable/rate_limit.rb +51 -0
- data/lib/booqable/resource_proxy.rb +149 -0
- data/lib/booqable/resources.json +74 -0
- data/lib/booqable/resources.rb +68 -0
- data/lib/booqable/version.rb +5 -0
- data/lib/booqable.rb +85 -0
- data/sig/booqable.rbs +324 -0
- metadata +174 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
module Booqable
|
|
2
|
+
# Authentication methods for {Booqable::Client}
|
|
3
|
+
#
|
|
4
|
+
# Provides authentication support for multiple methods including OAuth2,
|
|
5
|
+
# API keys, and single-use tokens. The module automatically detects which
|
|
6
|
+
# authentication method to use based on the configured credentials.
|
|
7
|
+
#
|
|
8
|
+
# @example OAuth authentication
|
|
9
|
+
# client = Booqable::Client.new(
|
|
10
|
+
# client_id: "your_client_id",
|
|
11
|
+
# client_secret: "your_client_secret"
|
|
12
|
+
# )
|
|
13
|
+
# client.authenticate_with_code("auth_code_from_callback")
|
|
14
|
+
#
|
|
15
|
+
# @example API key authentication
|
|
16
|
+
# client = Booqable::Client.new(api_key: "your_api_key")
|
|
17
|
+
# # Authentication is automatic with API requests
|
|
18
|
+
#
|
|
19
|
+
# @example Single-use token authentication
|
|
20
|
+
# client = Booqable::Client.new(
|
|
21
|
+
# single_use_token: "your_token",
|
|
22
|
+
# single_use_token_algorithm: "HS256",
|
|
23
|
+
# single_use_token_secret: "your_secret"
|
|
24
|
+
# )
|
|
25
|
+
module Auth
|
|
26
|
+
# Complete OAuth authentication flow with authorization code
|
|
27
|
+
#
|
|
28
|
+
# Exchanges an authorization code for an access token and stores it
|
|
29
|
+
# using the configured write_token proc. This method should be called
|
|
30
|
+
# after the user has been redirected back from the OAuth provider.
|
|
31
|
+
#
|
|
32
|
+
# @param code [String] Authorization code from OAuth callback
|
|
33
|
+
# @return [void]
|
|
34
|
+
# @raise [OAuth2::Error] If the authorization code is invalid or expired
|
|
35
|
+
#
|
|
36
|
+
# @example
|
|
37
|
+
# # In your OAuth callback handler
|
|
38
|
+
# client.authenticate_with_code(params[:code])
|
|
39
|
+
def authenticate_with_code(code)
|
|
40
|
+
token = oauth_client.get_token_from_code(code)
|
|
41
|
+
@write_token.call(token.to_hash)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Inject appropriate authentication middleware into the request stack
|
|
45
|
+
#
|
|
46
|
+
# Automatically detects which authentication method is configured and
|
|
47
|
+
# injects the corresponding middleware. Multiple authentication methods
|
|
48
|
+
# can be configured, with OAuth taking precedence over API keys.
|
|
49
|
+
#
|
|
50
|
+
# @param builder [Faraday::Builder] The middleware builder to configure
|
|
51
|
+
# @return [void]
|
|
52
|
+
# @api private
|
|
53
|
+
def inject_auth_middleware(builder)
|
|
54
|
+
builder.use Booqable::Middleware::Auth::OAuth, {
|
|
55
|
+
client_id: client_id,
|
|
56
|
+
client_secret: client_secret,
|
|
57
|
+
api_endpoint: api_endpoint,
|
|
58
|
+
redirect_uri: redirect_uri,
|
|
59
|
+
read_token: read_token,
|
|
60
|
+
write_token: write_token
|
|
61
|
+
} if oauth_authenticated?
|
|
62
|
+
|
|
63
|
+
builder.use Booqable::Middleware::Auth::ApiKey, {
|
|
64
|
+
api_key: api_key
|
|
65
|
+
} if api_key_authenticated?
|
|
66
|
+
|
|
67
|
+
builder.use Booqable::Middleware::Auth::SingleUse, {
|
|
68
|
+
single_use_token: single_use_token,
|
|
69
|
+
single_use_token_algorithm: single_use_token_algorithm,
|
|
70
|
+
single_use_token_private_key: single_use_token_private_key || single_use_token_secret,
|
|
71
|
+
single_use_token_expiration_period: single_use_token_expiration_period,
|
|
72
|
+
single_use_token_company_id: single_use_token_company_id,
|
|
73
|
+
single_use_token_user_id: single_use_token_user_id,
|
|
74
|
+
api_endpoint: api_endpoint
|
|
75
|
+
} if single_use_token_authenticated?
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Get or create the OAuth client
|
|
79
|
+
#
|
|
80
|
+
# Returns a memoized OAuth client instance configured with the current
|
|
81
|
+
# client credentials. Returns nil if OAuth is not configured.
|
|
82
|
+
#
|
|
83
|
+
# @return [OAuthClient, nil] OAuth client instance or nil if not configured
|
|
84
|
+
def oauth_client
|
|
85
|
+
@oauth_client ||= OAuthClient.new(
|
|
86
|
+
api_endpoint: api_endpoint,
|
|
87
|
+
client_id: @client_id,
|
|
88
|
+
client_secret: @client_secret,
|
|
89
|
+
redirect_uri: @redirect_uri
|
|
90
|
+
) if oauth_authenticated?
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Check if OAuth authentication is configured
|
|
94
|
+
#
|
|
95
|
+
# @return [Boolean] true if both client_id and client_secret are present
|
|
96
|
+
def oauth_authenticated?
|
|
97
|
+
!!@client_id && !!@client_secret
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Check if API key authentication is configured
|
|
101
|
+
#
|
|
102
|
+
# @return [Boolean] true if api_key is present
|
|
103
|
+
def api_key_authenticated?
|
|
104
|
+
!!@api_key
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Check if single-use token authentication is configured
|
|
108
|
+
#
|
|
109
|
+
# @return [Boolean] true if single_use_token is present
|
|
110
|
+
def single_use_token_authenticated?
|
|
111
|
+
!!@single_use_token
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Booqable
|
|
4
|
+
# Client for the Booqable API
|
|
5
|
+
#
|
|
6
|
+
# Provides a Ruby interface to interact with the Booqable rental management API.
|
|
7
|
+
# The client can be configured with various authentication methods including
|
|
8
|
+
# API keys, OAuth, and single-use tokens.
|
|
9
|
+
#
|
|
10
|
+
# @example Initialize with API key
|
|
11
|
+
# client = Booqable::Client.new(
|
|
12
|
+
# api_key: "your_api_key",
|
|
13
|
+
# company_id: "your_company_id"
|
|
14
|
+
# )
|
|
15
|
+
#
|
|
16
|
+
# @example Initialize with OAuth
|
|
17
|
+
# client = Booqable::Client.new(
|
|
18
|
+
# client_id: "your_client_id",
|
|
19
|
+
# client_secret: "your_client_secret",
|
|
20
|
+
# company_id: "your_company_id"
|
|
21
|
+
# )
|
|
22
|
+
#
|
|
23
|
+
# @see https://developers.booqable.com/
|
|
24
|
+
class Client
|
|
25
|
+
include Booqable::Configurable
|
|
26
|
+
include Booqable::Resources
|
|
27
|
+
include Booqable::Auth
|
|
28
|
+
include Booqable::HTTP
|
|
29
|
+
|
|
30
|
+
# List of configuration keys that contain sensitive information
|
|
31
|
+
# and should be masked in inspect output
|
|
32
|
+
SECRETS = %w[
|
|
33
|
+
client_secret
|
|
34
|
+
client_id
|
|
35
|
+
api_key
|
|
36
|
+
single_use_token
|
|
37
|
+
single_use_token_private_key
|
|
38
|
+
single_use_token_secret
|
|
39
|
+
refresh_token
|
|
40
|
+
access_token
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
# Initialize a new Client
|
|
44
|
+
#
|
|
45
|
+
# @param options [Hash] Configuration options for the client
|
|
46
|
+
# @see Booqable::Configurable For a complete list of supported configuration options
|
|
47
|
+
def initialize(options = {})
|
|
48
|
+
# Use options passed in, but fall back to module defaults
|
|
49
|
+
#
|
|
50
|
+
# This may look like a `.keys.each` which should be replaced with `#each_key`, but
|
|
51
|
+
# this doesn't actually work, since `#keys` is just a method we've defined ourselves.
|
|
52
|
+
# The class doesn't fulfill the whole `Enumerable` contract.
|
|
53
|
+
Booqable::Configurable.keys.each do |key|
|
|
54
|
+
value = options[key].nil? ? Booqable.instance_variable_get(:"@#{key}") : options[key]
|
|
55
|
+
instance_variable_set(:"@#{key}", value)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# String representation of the client with sensitive information masked
|
|
60
|
+
#
|
|
61
|
+
# Overrides the default inspect method to hide sensitive configuration
|
|
62
|
+
# values like API keys, client secrets, and tokens by replacing them
|
|
63
|
+
# with asterisks.
|
|
64
|
+
#
|
|
65
|
+
# @return [String] String representation with secrets masked
|
|
66
|
+
# @example
|
|
67
|
+
# client = Booqable::Client.new(api_key: "secret123")
|
|
68
|
+
# client.inspect #=> "#<Booqable::Client:0x... @api_key=\"*********\">"
|
|
69
|
+
def inspect
|
|
70
|
+
inspected = super
|
|
71
|
+
|
|
72
|
+
secrets = SECRETS.map { |secret| instance_variable_get("@#{secret}") }
|
|
73
|
+
|
|
74
|
+
inspected.gsub!(/"(#{secrets.join("|")})"/) do |match|
|
|
75
|
+
match.gsub!(/./, "*")
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
inspected
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Booqable
|
|
4
|
+
# Configuration options for {Client}, defaulting to values
|
|
5
|
+
# in {Default}
|
|
6
|
+
module Configurable
|
|
7
|
+
# @!attribute api_endpoint
|
|
8
|
+
# @return [String] Base URL for API requests. default: https://company.booqable.com/api/4
|
|
9
|
+
# @!attribute auto_paginate
|
|
10
|
+
# @return [Boolean] Auto fetch next page of results until rate limit reached
|
|
11
|
+
# @!attribute client_id
|
|
12
|
+
# @return [String] Configure OAuth app key
|
|
13
|
+
# @!attribute [w] client_secret
|
|
14
|
+
# @return [String] Configure OAuth app secret
|
|
15
|
+
# @!attribute default_media_type
|
|
16
|
+
# @return [String] Configure preferred media type (for API versioning, for example)
|
|
17
|
+
# @!attribute connection_options
|
|
18
|
+
# @see https://github.com/lostisland/faraday
|
|
19
|
+
# @return [Hash] Configure connection options for Faraday
|
|
20
|
+
# @!attribute middleware
|
|
21
|
+
# @see https://github.com/lostisland/faraday
|
|
22
|
+
# @return [Faraday::Builder or Faraday::RackBuilder] Configure middleware for Faraday
|
|
23
|
+
# @!attribute per_page
|
|
24
|
+
# @return [String] Configure page size for paginated results. API default: 25
|
|
25
|
+
# @!attribute proxy
|
|
26
|
+
# @see https://github.com/lostisland/faraday
|
|
27
|
+
# @return [String] URI for proxy server
|
|
28
|
+
# @!attribute ssl_verify_mode
|
|
29
|
+
# @see https://github.com/lostisland/faraday
|
|
30
|
+
# @return [String] SSL verify mode for ssl connections
|
|
31
|
+
# @!attribute user_agent
|
|
32
|
+
# @return [String] Configure User-Agent header for requests.
|
|
33
|
+
|
|
34
|
+
attr_accessor :api_domain,
|
|
35
|
+
:api_endpoint,
|
|
36
|
+
:api_key,
|
|
37
|
+
:api_version,
|
|
38
|
+
:auto_paginate,
|
|
39
|
+
:client_id,
|
|
40
|
+
:client_secret,
|
|
41
|
+
:company_id,
|
|
42
|
+
:connection_options,
|
|
43
|
+
:debug,
|
|
44
|
+
:default_media_type,
|
|
45
|
+
:middleware,
|
|
46
|
+
:no_retries,
|
|
47
|
+
:per_page,
|
|
48
|
+
:proxy,
|
|
49
|
+
:read_token,
|
|
50
|
+
:redirect_uri,
|
|
51
|
+
:single_use_token,
|
|
52
|
+
:single_use_token_algorithm,
|
|
53
|
+
:single_use_token_company_id,
|
|
54
|
+
:single_use_token_expiration_period,
|
|
55
|
+
:single_use_token_private_key,
|
|
56
|
+
:single_use_token_secret,
|
|
57
|
+
:single_use_token_user_id,
|
|
58
|
+
:ssl_verify_mode,
|
|
59
|
+
:user_agent,
|
|
60
|
+
:write_token
|
|
61
|
+
|
|
62
|
+
class << self
|
|
63
|
+
# List of configurable keys for {Booqable::Client}
|
|
64
|
+
# @return [Array] of option keys
|
|
65
|
+
def keys
|
|
66
|
+
@keys ||= %i[
|
|
67
|
+
api_domain
|
|
68
|
+
api_endpoint
|
|
69
|
+
api_key
|
|
70
|
+
api_version
|
|
71
|
+
auto_paginate
|
|
72
|
+
client_id
|
|
73
|
+
client_secret
|
|
74
|
+
company_id
|
|
75
|
+
connection_options
|
|
76
|
+
debug
|
|
77
|
+
default_media_type
|
|
78
|
+
middleware
|
|
79
|
+
no_retries
|
|
80
|
+
per_page
|
|
81
|
+
proxy
|
|
82
|
+
read_token
|
|
83
|
+
redirect_uri
|
|
84
|
+
single_use_token
|
|
85
|
+
single_use_token_algorithm
|
|
86
|
+
single_use_token_company_id
|
|
87
|
+
single_use_token_expiration_period
|
|
88
|
+
single_use_token_private_key
|
|
89
|
+
single_use_token_secret
|
|
90
|
+
single_use_token_user_id
|
|
91
|
+
ssl_verify_mode
|
|
92
|
+
user_agent
|
|
93
|
+
write_token
|
|
94
|
+
]
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Set configuration options using a block
|
|
99
|
+
def configure
|
|
100
|
+
yield self
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Reset configuration options to default values
|
|
104
|
+
def reset!
|
|
105
|
+
# rubocop:disable Style/HashEachMethods
|
|
106
|
+
#
|
|
107
|
+
# This may look like a `.keys.each` which should be replaced with `#each_key`, but
|
|
108
|
+
# this doesn't actually work, since `#keys` is just a method we've defined ourselves.
|
|
109
|
+
# The class doesn't fulfill the whole `Enumerable` contract.
|
|
110
|
+
Booqable::Configurable.keys.each do |key|
|
|
111
|
+
# rubocop:enable Style/HashEachMethods
|
|
112
|
+
instance_variable_set(:"@#{key}", Booqable::Default.options[key])
|
|
113
|
+
end
|
|
114
|
+
self
|
|
115
|
+
end
|
|
116
|
+
alias setup reset!
|
|
117
|
+
|
|
118
|
+
# Compares client options to a Hash of requested options
|
|
119
|
+
#
|
|
120
|
+
# @param opts [Hash] Options to compare with current client options
|
|
121
|
+
# @return [Boolean]
|
|
122
|
+
def same_options?(opts)
|
|
123
|
+
opts.hash == options.hash
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Whether to print debug information
|
|
127
|
+
#
|
|
128
|
+
# @return [Boolean] true if debug mode is enabled, false otherwise
|
|
129
|
+
def debug?
|
|
130
|
+
@debug || false
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
private
|
|
134
|
+
|
|
135
|
+
def api_protocol
|
|
136
|
+
@api_domain == "booqable.com" ? "https" : "http"
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def options
|
|
140
|
+
Booqable::Configurable.keys.to_h { |key| [ key, instance_variable_get(:"@#{key}") ] }
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
|
|
2
|
+
module Booqable
|
|
3
|
+
# Default configuration options for {Client}
|
|
4
|
+
#
|
|
5
|
+
# Provides default values for all configuration options, with support for
|
|
6
|
+
# environment variable overrides. All defaults can be overridden by setting
|
|
7
|
+
# the appropriate environment variables.
|
|
8
|
+
#
|
|
9
|
+
# @example Environment variable configuration
|
|
10
|
+
# ENV["BOOQABLE_API_KEY"] = "your_api_key"
|
|
11
|
+
# ENV["BOOQABLE_COMPANY_ID"] = "your_company_id"
|
|
12
|
+
# ENV["BOOQABLE_PER_PAGE"] = "50"
|
|
13
|
+
module Default
|
|
14
|
+
# Default User Agent header string
|
|
15
|
+
USER_AGENT = "Booqable Ruby Gem #{Booqable::VERSION}"
|
|
16
|
+
|
|
17
|
+
# Default media type (json:api) for requests
|
|
18
|
+
MEDIA_TYPE = "application/vnd.api+json"
|
|
19
|
+
|
|
20
|
+
# Default retry options for Faraday::Retry middleware
|
|
21
|
+
RETRY_OPTIONS = {
|
|
22
|
+
exceptions: Faraday::Retry::Middleware::DEFAULT_EXCEPTIONS + [ Booqable::ServerError ],
|
|
23
|
+
max: 2, # maximum number of retries (total of 3 attempts including the first)
|
|
24
|
+
interval: 2, # seconds to wait before retrying
|
|
25
|
+
interval_randomness: 0.5, # randomize the interval by this amount
|
|
26
|
+
backoff_factor: 2 # multiply the interval by this factor on each retry
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
# Basic middleware stack for Faraday::Connection (without authentication middleware)
|
|
30
|
+
MIDDLEWARE = Faraday::RackBuilder.new do |builder|
|
|
31
|
+
# Retry middleware
|
|
32
|
+
builder.use Faraday::Retry::Middleware, RETRY_OPTIONS
|
|
33
|
+
# Error handling middleware
|
|
34
|
+
builder.use Booqable::Middleware::RaiseError
|
|
35
|
+
|
|
36
|
+
builder.adapter Faraday.default_adapter
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
class << self
|
|
40
|
+
# Configuration options
|
|
41
|
+
# @return [Hash]
|
|
42
|
+
def options
|
|
43
|
+
Booqable::Configurable.keys.to_h { |key| [ key, send(key) ] }
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Default API endpoint from ENV
|
|
47
|
+
# @return [String]
|
|
48
|
+
def api_domain
|
|
49
|
+
ENV.fetch("BOOQABLE_API_DOMAIN", "booqable.com")
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Default API version from ENV
|
|
53
|
+
# @return [Integer] API version number
|
|
54
|
+
def api_version
|
|
55
|
+
ENV.fetch("BOOQABLE_API_VERSION", 4)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Default API endpoint from ENV
|
|
59
|
+
# @return [String, nil] Full API endpoint URL or nil to construct from domain
|
|
60
|
+
def api_endpoint
|
|
61
|
+
ENV.fetch("BOOQABLE_API_ENDPOINT", nil)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Default pagination preference from ENV
|
|
65
|
+
# @return [String]
|
|
66
|
+
def auto_paginate
|
|
67
|
+
ENV.fetch("BOOQABLE_AUTO_PAGINATE", nil)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Default OAuth app key from ENV
|
|
71
|
+
# @return [String]
|
|
72
|
+
def client_id
|
|
73
|
+
ENV.fetch("BOOQABLE_CLIENT_ID", nil)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Default OAuth app secret from ENV
|
|
77
|
+
# @return [String]
|
|
78
|
+
def client_secret
|
|
79
|
+
ENV.fetch("BOOQABLE_CLIENT_SECRET", nil)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Default company ID from ENV
|
|
83
|
+
# @return [String, nil] Company identifier
|
|
84
|
+
def company_id
|
|
85
|
+
ENV.fetch("BOOQABLE_COMPANY_ID", nil)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Default redirect URI for OAuth from ENV
|
|
89
|
+
# @return [String]
|
|
90
|
+
def redirect_uri
|
|
91
|
+
ENV.fetch("BOOQABLE_REDIRECT_URI", nil)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Default options for Faraday::Connection
|
|
95
|
+
# @return [Hash]
|
|
96
|
+
def connection_options
|
|
97
|
+
nil
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Default media type from ENV or {MEDIA_TYPE}
|
|
101
|
+
# @return [String]
|
|
102
|
+
def default_media_type
|
|
103
|
+
ENV.fetch("BOOQABLE_DEFAULT_MEDIA_TYPE") { MEDIA_TYPE }
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Default middleware stack for Faraday::Connection
|
|
107
|
+
# from {MIDDLEWARE}
|
|
108
|
+
# @return [Faraday::RackBuilder or Faraday::Builder]
|
|
109
|
+
def middleware
|
|
110
|
+
MIDDLEWARE
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# Default pagination page size from ENV
|
|
114
|
+
# @return [Integer] Page size
|
|
115
|
+
def per_page
|
|
116
|
+
page_size = ENV.fetch("BOOQABLE_PER_PAGE", 25)
|
|
117
|
+
|
|
118
|
+
page_size&.to_i
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Default proxy server URI for Faraday connection from ENV
|
|
122
|
+
# @return [String]
|
|
123
|
+
def proxy
|
|
124
|
+
ENV.fetch("BOOQABLE_PROXY", nil)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# Default SSL verify mode from ENV
|
|
128
|
+
# @return [Integer]
|
|
129
|
+
def ssl_verify_mode
|
|
130
|
+
# 0 is OpenSSL::SSL::VERIFY_NONE
|
|
131
|
+
# 1 is OpenSSL::SSL::SSL_VERIFY_PEER
|
|
132
|
+
# the standard default for SSL is SSL_VERIFY_PEER which requires a server certificate check on the client
|
|
133
|
+
ENV.fetch("BOOQABLE_SSL_VERIFY_MODE", 1).to_i
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Default User-Agent header string from ENV or {USER_AGENT}
|
|
137
|
+
# @return [String]
|
|
138
|
+
def user_agent
|
|
139
|
+
ENV.fetch("BOOQABLE_USER_AGENT") { USER_AGENT }
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# Default OAuth token reader
|
|
143
|
+
# @return [Proc] Empty proc that returns nothing
|
|
144
|
+
def read_token
|
|
145
|
+
Proc.new { }
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
# Default OAuth token writer
|
|
149
|
+
# @return [Proc] Empty proc that does nothing
|
|
150
|
+
def write_token
|
|
151
|
+
Proc.new { }
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# Default API key from ENV
|
|
155
|
+
# @return [String, nil] API key for authentication
|
|
156
|
+
def api_key
|
|
157
|
+
ENV.fetch("BOOQABLE_API_KEY", nil)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# Default single use token from ENV
|
|
161
|
+
# @return [String, nil] Single use token for authentication
|
|
162
|
+
def single_use_token
|
|
163
|
+
ENV.fetch("BOOQABLE_SINGLE_USE_TOKEN", nil)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# Default single use token algorithm from ENV
|
|
167
|
+
# @return [String, nil] Algorithm for single use token (e.g., "HS256", "RS256")
|
|
168
|
+
def single_use_token_algorithm
|
|
169
|
+
ENV.fetch("BOOQABLE_SINGLE_USE_TOKEN_ALGORITHM", nil)
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# Default single use token secret from ENV
|
|
173
|
+
# @return [String, nil] Secret for HMAC single use token signing
|
|
174
|
+
def single_use_token_secret
|
|
175
|
+
ENV.fetch("BOOQABLE_SINGLE_USE_TOKEN_SECRET", nil)
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# Default single use token private key from ENV
|
|
179
|
+
# @return [String, nil] Private key for RSA/ECDSA single use token signing
|
|
180
|
+
def single_use_token_private_key
|
|
181
|
+
ENV.fetch("BOOQABLE_SINGLE_USE_TOKEN_PRIVATE_KEY", nil)
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
# Default single use token expiration period from ENV
|
|
185
|
+
# @return [Integer] Token expiration period in seconds
|
|
186
|
+
def single_use_token_expiration_period
|
|
187
|
+
ENV.fetch("BOOQABLE_SINGLE_USE_TOKEN_EXPIRATION_PERIOD") { 10 * 60 }.to_i # default to 10 minutes
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# Default single use token company ID from ENV
|
|
191
|
+
# @return [String, nil] Company ID for single use token
|
|
192
|
+
def single_use_token_company_id
|
|
193
|
+
ENV.fetch("BOOQABLE_SINGLE_USE_TOKEN_COMPANY_ID", nil)
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# Default single use token user ID from ENV
|
|
197
|
+
# @return [String, nil] User ID for single use token
|
|
198
|
+
def single_use_token_user_id
|
|
199
|
+
ENV.fetch("BOOQABLE_SINGLE_USE_TOKEN_USER_ID", nil)
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
# Default debug mode setting
|
|
203
|
+
# @return [Boolean] Whether debug mode is enabled
|
|
204
|
+
def debug
|
|
205
|
+
false
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
# Default retry setting
|
|
209
|
+
# @return [Boolean] Whether to disable retries
|
|
210
|
+
def no_retries
|
|
211
|
+
false
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
end
|