onelogin 1.8.0 → 1.9.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 +4 -4
- data/README.md +29 -0
- data/lib/onelogin/api/client.rb +79 -17
- data/lib/onelogin/api/cursor.rb +41 -1
- data/lib/onelogin/api/models/app.rb +8 -1
- data/lib/onelogin/api/models/user.rb +2 -1
- data/lib/onelogin/api/util/constants.rb +18 -0
- data/lib/onelogin/api/util/parser.rb +6 -2
- data/lib/onelogin/api/util/url_builder.rb +25 -1
- data/lib/onelogin/version.rb +1 -1
- metadata +3 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '0887ddcbf97b6c873d5547842d27822f35b7e4eeefa4c78285ed2828c0cf546b'
|
|
4
|
+
data.tar.gz: 5a59b6e4c2ff4605775a8473931ed82183d9f434d455a559214828cd612c1988
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 01b0e196b7f431a2d6e04a1b64757a4b0224b0a5b34e3b17ee6c829f642e6b321305d6ebe15dee6dae44fd15b92f64555927522994c469f7f8ba2a1964ccfb10
|
|
7
|
+
data.tar.gz: 2595a8b6f36f9a446e991baa18b66e37c9f2ac21687a43d7ca6f0c1dfa1b5c515a7edf8c9d57f3e64874d7690d79d807af31c3f689842fc21fda936bd8fd2b52
|
data/README.md
CHANGED
|
@@ -59,6 +59,7 @@ If you don't have an account you can [sign up for a free developer account here]
|
|
|
59
59
|
|max_results| Optional: Defaults to 1000 |
|
|
60
60
|
|timeout| Optional: Defaults to 60 (requires httparty > 0.16.2) |
|
|
61
61
|
|token_expiration_buffer| Optional: Non-negative number of seconds before token expiration to trigger a refresh. Set to `0` to disable. Defaults to 30 |
|
|
62
|
+
|api_version| Optional: `1` or `2`. Calls that API version from every method that supports it. See [API versions](#api-versions) |
|
|
62
63
|
|
|
63
64
|
```ruby
|
|
64
65
|
require 'onelogin'
|
|
@@ -158,6 +159,34 @@ client = OneLogin::Api::Client.new(
|
|
|
158
159
|
client.get_events.map {|event| event.id}
|
|
159
160
|
```
|
|
160
161
|
|
|
162
|
+
### API versions
|
|
163
|
+
|
|
164
|
+
Each method calls one version of the OneLogin API by default, and that default
|
|
165
|
+
doesn't change. Pass `api_version: 2` to move the methods below to API v2:
|
|
166
|
+
|
|
167
|
+
```ruby
|
|
168
|
+
client = OneLogin::Api::Client.new(
|
|
169
|
+
client_id: '',
|
|
170
|
+
client_secret:'',
|
|
171
|
+
api_version: 2
|
|
172
|
+
)
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
`get_users`, `get_user`, `get_user_apps`, `create_user`, `update_user`,
|
|
176
|
+
`delete_user`, `get_roles` and `get_role` support both versions. Every other method
|
|
177
|
+
keeps its default version, whatever `api_version` says.
|
|
178
|
+
`OneLogin::Api::Client::API_VERSIONS` lists the versions each method supports.
|
|
179
|
+
|
|
180
|
+
Under v2 they return the same models, filled from v2's responses. Two differences
|
|
181
|
+
show through:
|
|
182
|
+
|
|
183
|
+
- v2 lists fewer fields per user than v1. Under v2, `get_users` leaves `role_ids`
|
|
184
|
+
and `custom_attributes` empty, for example. `get_user` fills them.
|
|
185
|
+
- `App#login_id` from `get_user_apps` is the login's numeric id in v2, where v1
|
|
186
|
+
gives the username used to sign in. v2 fills the `provisioning_enabled`,
|
|
187
|
+
`provisioning_state` and `provisioning_status` fields rather than `provisioned`
|
|
188
|
+
and `personal`.
|
|
189
|
+
|
|
161
190
|
|
|
162
191
|
|
|
163
192
|
### Available Methods
|
data/lib/onelogin/api/client.rb
CHANGED
|
@@ -21,6 +21,7 @@ module OneLogin
|
|
|
21
21
|
|
|
22
22
|
attr_accessor :client_id, :client_secret, :region
|
|
23
23
|
attr_accessor :user_agent, :error, :error_description, :error_attribute
|
|
24
|
+
attr_reader :api_version
|
|
24
25
|
|
|
25
26
|
NOKOGIRI_OPTIONS = Nokogiri::XML::ParseOptions::STRICT |
|
|
26
27
|
Nokogiri::XML::ParseOptions::NONET
|
|
@@ -32,6 +33,9 @@ module OneLogin
|
|
|
32
33
|
#
|
|
33
34
|
# @param config [Hash] Client Id, Client Secret and Region
|
|
34
35
|
#
|
|
36
|
+
# Pass api_version to call that API version from every method that
|
|
37
|
+
# supports it (see API_VERSIONS). Other methods keep their default.
|
|
38
|
+
#
|
|
35
39
|
def initialize(config)
|
|
36
40
|
options = Hash[config.map { |(k, v)| [k.to_sym, v] }]
|
|
37
41
|
|
|
@@ -40,6 +44,7 @@ module OneLogin
|
|
|
40
44
|
@region = options[:region] || 'us'
|
|
41
45
|
@max_results = options[:max_results] || 1000
|
|
42
46
|
@token_expiration_buffer = normalize_expiration_buffer(options[:token_expiration_buffer])
|
|
47
|
+
@api_version = normalize_api_version(options[:api_version])
|
|
43
48
|
|
|
44
49
|
if options[:timeout] and defined? self.class.default_timeout
|
|
45
50
|
self.class.default_timeout options[:timeout]
|
|
@@ -105,6 +110,40 @@ module OneLogin
|
|
|
105
110
|
end
|
|
106
111
|
private :normalize_expiration_buffer
|
|
107
112
|
|
|
113
|
+
# Coerce the configured API version into one the SDK can call.
|
|
114
|
+
#
|
|
115
|
+
# nil leaves every method on its default version. Anything else must be a
|
|
116
|
+
# version at least one method supports, so a typo fails here instead of
|
|
117
|
+
# quietly calling the defaults. Only Integers and Strings convert:
|
|
118
|
+
# Integer() would truncate 1.9 to 1.
|
|
119
|
+
#
|
|
120
|
+
def normalize_api_version(value)
|
|
121
|
+
return nil if value.nil?
|
|
122
|
+
|
|
123
|
+
version = begin
|
|
124
|
+
Integer(value) if value.is_a?(Integer) || value.is_a?(String)
|
|
125
|
+
rescue ArgumentError
|
|
126
|
+
nil
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
supported = API_VERSIONS.values.flatten.uniq.sort
|
|
130
|
+
unless supported.include?(version)
|
|
131
|
+
raise ArgumentError, "api_version must be one of #{supported.join(', ')}, got #{value.inspect}"
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
version
|
|
135
|
+
end
|
|
136
|
+
private :normalize_api_version
|
|
137
|
+
|
|
138
|
+
# The API version a method calls: the configured api_version when the
|
|
139
|
+
# method supports it, otherwise the method's default.
|
|
140
|
+
#
|
|
141
|
+
def api_version_for(method)
|
|
142
|
+
versions = API_VERSIONS.fetch(method)
|
|
143
|
+
versions.include?(@api_version) ? @api_version : versions.first
|
|
144
|
+
end
|
|
145
|
+
private :api_version_for
|
|
146
|
+
|
|
108
147
|
# Clean any previous error registered at the client.
|
|
109
148
|
#
|
|
110
149
|
def clean_error
|
|
@@ -395,14 +434,16 @@ module OneLogin
|
|
|
395
434
|
prepare_token
|
|
396
435
|
|
|
397
436
|
begin
|
|
437
|
+
version = api_version_for(:get_users)
|
|
398
438
|
options = {
|
|
399
439
|
model: OneLogin::Api::Models::User,
|
|
400
440
|
headers: authorized_headers,
|
|
401
441
|
max_results: @max_results,
|
|
402
|
-
params: params
|
|
442
|
+
params: params,
|
|
443
|
+
api_version: version
|
|
403
444
|
}
|
|
404
445
|
|
|
405
|
-
return Cursor.new(self, url_for(GET_USERS_URL), options)
|
|
446
|
+
return Cursor.new(self, url_for(GET_USERS_URL, version: version), options)
|
|
406
447
|
|
|
407
448
|
rescue Exception => e
|
|
408
449
|
@error = '500'
|
|
@@ -431,7 +472,8 @@ module OneLogin
|
|
|
431
472
|
return
|
|
432
473
|
end
|
|
433
474
|
|
|
434
|
-
|
|
475
|
+
version = api_version_for(:get_user)
|
|
476
|
+
url = url_for(GET_USER_URL, user_id, version: version)
|
|
435
477
|
|
|
436
478
|
response = self.class.get(
|
|
437
479
|
url,
|
|
@@ -440,7 +482,9 @@ module OneLogin
|
|
|
440
482
|
|
|
441
483
|
if response.code == 200
|
|
442
484
|
json_data = JSON.parse(response.body)
|
|
443
|
-
if
|
|
485
|
+
if version == 2
|
|
486
|
+
return OneLogin::Api::Models::User.new(json_data) if json_data.is_a?(Hash)
|
|
487
|
+
elsif json_data && json_data['data']
|
|
444
488
|
return OneLogin::Api::Models::User.new(json_data['data'][0])
|
|
445
489
|
end
|
|
446
490
|
else
|
|
@@ -474,13 +518,15 @@ module OneLogin
|
|
|
474
518
|
return
|
|
475
519
|
end
|
|
476
520
|
|
|
521
|
+
version = api_version_for(:get_user_apps)
|
|
477
522
|
options = {
|
|
478
523
|
model: OneLogin::Api::Models::App,
|
|
479
524
|
headers: authorized_headers,
|
|
480
|
-
max_results: @max_results
|
|
525
|
+
max_results: @max_results,
|
|
526
|
+
api_version: version
|
|
481
527
|
}
|
|
482
528
|
|
|
483
|
-
return Cursor.new(self, url_for(GET_APPS_FOR_USER_URL, user_id), options)
|
|
529
|
+
return Cursor.new(self, url_for(GET_APPS_FOR_USER_URL, user_id, version: version), options)
|
|
484
530
|
|
|
485
531
|
rescue Exception => e
|
|
486
532
|
@error = '500'
|
|
@@ -588,7 +634,8 @@ module OneLogin
|
|
|
588
634
|
prepare_token
|
|
589
635
|
|
|
590
636
|
begin
|
|
591
|
-
|
|
637
|
+
version = api_version_for(:create_user)
|
|
638
|
+
url = url_for(CREATE_USER_URL, version: version)
|
|
592
639
|
|
|
593
640
|
response = self.class.post(
|
|
594
641
|
url,
|
|
@@ -596,9 +643,12 @@ module OneLogin
|
|
|
596
643
|
body: user_params.to_json
|
|
597
644
|
)
|
|
598
645
|
|
|
599
|
-
|
|
646
|
+
# v1 answers a create with 200, v2 with 201 Created.
|
|
647
|
+
if response.code == (version == 2 ? 201 : 200)
|
|
600
648
|
json_data = JSON.parse(response.body)
|
|
601
|
-
if
|
|
649
|
+
if version == 2
|
|
650
|
+
return OneLogin::Api::Models::User.new(json_data) if json_data.is_a?(Hash)
|
|
651
|
+
elsif json_data && json_data['data']
|
|
602
652
|
return OneLogin::Api::Models::User.new(json_data['data'][0])
|
|
603
653
|
end
|
|
604
654
|
else
|
|
@@ -639,7 +689,8 @@ module OneLogin
|
|
|
639
689
|
return
|
|
640
690
|
end
|
|
641
691
|
|
|
642
|
-
|
|
692
|
+
version = api_version_for(:update_user)
|
|
693
|
+
url = url_for(UPDATE_USER_URL, user_id, version: version)
|
|
643
694
|
|
|
644
695
|
response = self.class.put(
|
|
645
696
|
url,
|
|
@@ -649,7 +700,9 @@ module OneLogin
|
|
|
649
700
|
|
|
650
701
|
if response.code == 200
|
|
651
702
|
json_data = JSON.parse(response.body)
|
|
652
|
-
if
|
|
703
|
+
if version == 2
|
|
704
|
+
return OneLogin::Api::Models::User.new(json_data) if json_data.is_a?(Hash)
|
|
705
|
+
elsif json_data && json_data['data']
|
|
653
706
|
return OneLogin::Api::Models::User.new(json_data['data'][0])
|
|
654
707
|
end
|
|
655
708
|
else
|
|
@@ -1069,14 +1122,18 @@ module OneLogin
|
|
|
1069
1122
|
return
|
|
1070
1123
|
end
|
|
1071
1124
|
|
|
1072
|
-
|
|
1125
|
+
version = api_version_for(:delete_user)
|
|
1126
|
+
url = url_for(DELETE_USER_URL, user_id, version: version)
|
|
1073
1127
|
|
|
1074
1128
|
response = self.class.delete(
|
|
1075
1129
|
url,
|
|
1076
1130
|
headers: authorized_headers
|
|
1077
1131
|
)
|
|
1078
1132
|
|
|
1079
|
-
|
|
1133
|
+
# v2 confirms a delete with an empty 204 rather than a status body.
|
|
1134
|
+
if version == 2 && response.code == 204
|
|
1135
|
+
return true
|
|
1136
|
+
elsif version == 1 && response.code == 200
|
|
1080
1137
|
return handle_operation_response(response)
|
|
1081
1138
|
else
|
|
1082
1139
|
@error = response.code.to_s
|
|
@@ -1621,14 +1678,16 @@ module OneLogin
|
|
|
1621
1678
|
prepare_token
|
|
1622
1679
|
|
|
1623
1680
|
begin
|
|
1681
|
+
version = api_version_for(:get_roles)
|
|
1624
1682
|
options = {
|
|
1625
1683
|
model: OneLogin::Api::Models::Role,
|
|
1626
1684
|
headers: authorized_headers,
|
|
1627
1685
|
max_results: @max_results,
|
|
1628
|
-
params: params
|
|
1686
|
+
params: params,
|
|
1687
|
+
api_version: version
|
|
1629
1688
|
}
|
|
1630
1689
|
|
|
1631
|
-
return Cursor.new(self, url_for(GET_ROLES_URL), options)
|
|
1690
|
+
return Cursor.new(self, url_for(GET_ROLES_URL, version: version), options)
|
|
1632
1691
|
|
|
1633
1692
|
rescue Exception => e
|
|
1634
1693
|
@error = '500'
|
|
@@ -1657,7 +1716,8 @@ module OneLogin
|
|
|
1657
1716
|
return
|
|
1658
1717
|
end
|
|
1659
1718
|
|
|
1660
|
-
|
|
1719
|
+
version = api_version_for(:get_role)
|
|
1720
|
+
url = url_for(GET_ROLE_URL, role_id, version: version)
|
|
1661
1721
|
|
|
1662
1722
|
response = self.class.get(
|
|
1663
1723
|
url,
|
|
@@ -1666,7 +1726,9 @@ module OneLogin
|
|
|
1666
1726
|
|
|
1667
1727
|
if response.code == 200
|
|
1668
1728
|
json_data = JSON.parse(response.body)
|
|
1669
|
-
if
|
|
1729
|
+
if version == 2
|
|
1730
|
+
return OneLogin::Api::Models::Role.new(json_data) if json_data.is_a?(Hash)
|
|
1731
|
+
elsif json_data && json_data['data']
|
|
1670
1732
|
return OneLogin::Api::Models::Role.new(json_data['data'][0])
|
|
1671
1733
|
end
|
|
1672
1734
|
else
|
data/lib/onelogin/api/cursor.rb
CHANGED
|
@@ -25,6 +25,7 @@ class Cursor
|
|
|
25
25
|
@params = options[:params] || {}
|
|
26
26
|
@max_results = options[:max_results]
|
|
27
27
|
@container = options[:container] || 'data'
|
|
28
|
+
@api_version = options[:api_version]
|
|
28
29
|
|
|
29
30
|
@collection = []
|
|
30
31
|
@after_cursor = options.fetch(:after_cursor, nil)
|
|
@@ -53,12 +54,14 @@ class Cursor
|
|
|
53
54
|
private
|
|
54
55
|
|
|
55
56
|
def fetch_next_page
|
|
57
|
+
return fetch_next_v2_page if @api_version == 2
|
|
58
|
+
|
|
56
59
|
@params = @params.merge(after_cursor: @after_cursor) if @after_cursor
|
|
57
60
|
@client.prepare_token
|
|
58
61
|
|
|
59
62
|
response = @client.class.get(
|
|
60
63
|
@url,
|
|
61
|
-
headers:
|
|
64
|
+
headers: request_headers,
|
|
62
65
|
query: @params
|
|
63
66
|
)
|
|
64
67
|
|
|
@@ -91,6 +94,43 @@ class Cursor
|
|
|
91
94
|
end
|
|
92
95
|
end
|
|
93
96
|
|
|
97
|
+
# v2 returns a bare array and puts the next page's cursor in the After-Cursor
|
|
98
|
+
# header, which is absent on the last page. The cursor already encodes the
|
|
99
|
+
# filters and page size, and the API rejects a cursor sent alongside limit or
|
|
100
|
+
# page, so follow-up requests send the cursor alone.
|
|
101
|
+
def fetch_next_v2_page
|
|
102
|
+
@client.prepare_token
|
|
103
|
+
|
|
104
|
+
response = @client.class.get(
|
|
105
|
+
@url,
|
|
106
|
+
headers: request_headers,
|
|
107
|
+
query: @after_cursor ? { cursor: @after_cursor } : @params
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
results = response.parsed_response
|
|
111
|
+
|
|
112
|
+
unless response.code == 200 && results.is_a?(Array)
|
|
113
|
+
message = results.is_a?(Hash) ? extract_error_message_from_response(response) : "Response could not be parsed"
|
|
114
|
+
raise OneLogin::Api::ApiException.new(message, response.code)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
@collection += if results_remaining < results.size
|
|
118
|
+
results.slice(0, results_remaining)
|
|
119
|
+
else
|
|
120
|
+
results
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
@after_cursor = response.headers['after-cursor']
|
|
124
|
+
@last_cursor_empty = @after_cursor.nil? || @after_cursor.empty?
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# The headers were built when the cursor was, and prepare_token may have
|
|
128
|
+
# refreshed the token since: a cursor enumerated later, or one whose pages
|
|
129
|
+
# outlive the token. Take the current token from the client.
|
|
130
|
+
def request_headers
|
|
131
|
+
@headers.merge(@client.authorized_headers)
|
|
132
|
+
end
|
|
133
|
+
|
|
94
134
|
def after_cursor(json)
|
|
95
135
|
value = nil
|
|
96
136
|
if json.has_key?('pagination')
|
|
@@ -6,15 +6,22 @@ module OneLogin
|
|
|
6
6
|
|
|
7
7
|
attr_accessor :id, :name, :icon, :provisioned
|
|
8
8
|
attr_accessor :extension, :login_id, :personal
|
|
9
|
+
attr_accessor :provisioning_enabled, :provisioning_state, :provisioning_status
|
|
9
10
|
|
|
11
|
+
# v2 renames icon to icon_url and replaces provisioned and personal with
|
|
12
|
+
# the provisioning_* fields. Its login_id is the numeric id of the
|
|
13
|
+
# user's login, where v1 gives the username used to sign in.
|
|
10
14
|
def initialize(data)
|
|
11
15
|
@id = data['id']
|
|
12
16
|
@name = data['name']
|
|
13
|
-
@icon = data['icon']
|
|
17
|
+
@icon = data['icon'] || data['icon_url']
|
|
14
18
|
@provisioned = data['provisioned']
|
|
15
19
|
@extension = data['extension']
|
|
16
20
|
@login_id = data['login_id']
|
|
17
21
|
@personal = data['personal']
|
|
22
|
+
@provisioning_enabled = data['provisioning_enabled']
|
|
23
|
+
@provisioning_state = data['provisioning_state']
|
|
24
|
+
@provisioning_status = data['provisioning_status']
|
|
18
25
|
end
|
|
19
26
|
end
|
|
20
27
|
end
|
|
@@ -28,7 +28,8 @@ module OneLogin
|
|
|
28
28
|
@samaccountname = data['samaccountname'].to_s
|
|
29
29
|
@userprincipalname = data['userprincipalname'].to_s
|
|
30
30
|
@group_id = data['group_id']? data['group_id'].to_i : nil
|
|
31
|
-
|
|
31
|
+
# v1 calls it role_id, v2 role_ids.
|
|
32
|
+
@role_ids = data['role_id'] || data['role_ids'] || []
|
|
32
33
|
@custom_attributes = data['custom_attributes'] ? data['custom_attributes'] : []
|
|
33
34
|
@openid_name = data['openid_name'].to_s
|
|
34
35
|
@locale_code = data['locale_code'].to_s
|
|
@@ -98,6 +98,24 @@ module OneLogin
|
|
|
98
98
|
GET_USERS_ASSIGNED_TO_PRIVILEGE_URL = "https://api.%s.onelogin.com/api/1/privileges/%s/users"
|
|
99
99
|
ASSIGN_USERS_TO_PRIVILEGE_URL = "https://api.%s.onelogin.com/api/1/privileges/%s/users"
|
|
100
100
|
REMOVE_USER_FROM_PRIVILEGE_URL = "https://api.%s.onelogin.com/api/1/privileges/%s/users/%s"
|
|
101
|
+
|
|
102
|
+
# API versions each client method can call, keyed by method name.
|
|
103
|
+
#
|
|
104
|
+
# The first version is the default and matches the version in the
|
|
105
|
+
# method's URL constant. A method that isn't listed only calls the
|
|
106
|
+
# version in its URL constant. List a version here only once the method
|
|
107
|
+
# can parse that version's response: v1 and v2 use different envelopes.
|
|
108
|
+
API_VERSIONS = {
|
|
109
|
+
get_users: [1, 2],
|
|
110
|
+
get_user: [1, 2],
|
|
111
|
+
get_user_apps: [1, 2],
|
|
112
|
+
create_user: [1, 2],
|
|
113
|
+
update_user: [1, 2],
|
|
114
|
+
delete_user: [1, 2],
|
|
115
|
+
get_roles: [1, 2],
|
|
116
|
+
get_role: [1, 2]
|
|
117
|
+
}.transform_values(&:freeze).freeze
|
|
118
|
+
|
|
101
119
|
VALID_ACTIONS = [
|
|
102
120
|
"apps:List",
|
|
103
121
|
"apps:Get",
|
|
@@ -6,7 +6,9 @@ module OneLogin
|
|
|
6
6
|
message = ''
|
|
7
7
|
content = JSON.parse(response.body)
|
|
8
8
|
if content
|
|
9
|
-
|
|
9
|
+
# v1 nests the error under a status object. Some v2 endpoints send
|
|
10
|
+
# status as the bare HTTP code, with the text in description.
|
|
11
|
+
if content['status'].is_a?(Hash)
|
|
10
12
|
status = content['status']
|
|
11
13
|
if status.has_key?('message')
|
|
12
14
|
if status['message'].instance_of?(Hash)
|
|
@@ -21,6 +23,8 @@ module OneLogin
|
|
|
21
23
|
end
|
|
22
24
|
elsif content.has_key?('message')
|
|
23
25
|
message = content['message']
|
|
26
|
+
elsif content.has_key?('description')
|
|
27
|
+
message = content['description']
|
|
24
28
|
elsif content.has_key?('name')
|
|
25
29
|
message = content['name']
|
|
26
30
|
end
|
|
@@ -31,7 +35,7 @@ module OneLogin
|
|
|
31
35
|
def extract_error_attribute_from_response(response)
|
|
32
36
|
attribute = nil
|
|
33
37
|
content = JSON.parse(response.body)
|
|
34
|
-
if content && content.
|
|
38
|
+
if content && content['status'].is_a?(Hash)
|
|
35
39
|
status = content['status']
|
|
36
40
|
if status.has_key?('message') && status['message'].instance_of?(Hash)
|
|
37
41
|
if status['message'].has_key?('attribute')
|
|
@@ -3,13 +3,20 @@ module OneLogin
|
|
|
3
3
|
module Util
|
|
4
4
|
module UrlBuilder
|
|
5
5
|
|
|
6
|
+
# The version segment of a versioned endpoint, e.g. "/api/1/"
|
|
7
|
+
API_VERSION_SEGMENT = %r{/api/\d+/}
|
|
8
|
+
|
|
6
9
|
# Build the URL of the API endpoint
|
|
7
10
|
#
|
|
8
11
|
# @param base [String] Base of the endpoint
|
|
9
12
|
# @param obj_id [String, nil] Id of the referenced object
|
|
10
13
|
# @param extra_id [String, nil] Id of the secundary referenced object
|
|
14
|
+
# @param version [Integer, nil] API version to call. Defaults to the
|
|
15
|
+
# version already in the base.
|
|
11
16
|
#
|
|
12
|
-
def url_for(base, obj_id=nil, extra_id=nil)
|
|
17
|
+
def url_for(base, obj_id=nil, extra_id=nil, version: nil)
|
|
18
|
+
base = with_api_version(base, version) unless version.nil?
|
|
19
|
+
|
|
13
20
|
if obj_id.nil? || obj_id.to_s.empty?
|
|
14
21
|
base % [@region]
|
|
15
22
|
elsif extra_id.nil? || extra_id.to_s.empty?
|
|
@@ -18,6 +25,23 @@ module OneLogin
|
|
|
18
25
|
base % [@region, obj_id, extra_id]
|
|
19
26
|
end
|
|
20
27
|
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
# Swap the version segment of an endpoint, so the URL constants keep
|
|
32
|
+
# their current values and stay the default.
|
|
33
|
+
#
|
|
34
|
+
# Raises rather than calling a version nobody asked for. The client
|
|
35
|
+
# still rescues this into error '500', but error_description then names
|
|
36
|
+
# the endpoint.
|
|
37
|
+
#
|
|
38
|
+
def with_api_version(base, version)
|
|
39
|
+
unless base.scan(API_VERSION_SEGMENT).size == 1
|
|
40
|
+
raise ArgumentError, "#{base} has no single API version segment to replace"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
base.sub(API_VERSION_SEGMENT, "/api/#{version}/")
|
|
44
|
+
end
|
|
21
45
|
end
|
|
22
46
|
end
|
|
23
47
|
end
|
data/lib/onelogin/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: onelogin
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.9.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- OneLogin
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
10
|
+
date: 2026-10-23 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: httparty
|
|
@@ -167,7 +166,6 @@ licenses:
|
|
|
167
166
|
- MIT
|
|
168
167
|
metadata:
|
|
169
168
|
allowed_push_host: https://rubygems.org
|
|
170
|
-
post_install_message:
|
|
171
169
|
rdoc_options: []
|
|
172
170
|
require_paths:
|
|
173
171
|
- lib
|
|
@@ -182,8 +180,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
182
180
|
- !ruby/object:Gem::Version
|
|
183
181
|
version: '0'
|
|
184
182
|
requirements: []
|
|
185
|
-
rubygems_version: 3.2
|
|
186
|
-
signing_key:
|
|
183
|
+
rubygems_version: 3.6.2
|
|
187
184
|
specification_version: 4
|
|
188
185
|
summary: OneLogin's Ruby SDK.
|
|
189
186
|
test_files: []
|