maestrano 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +1 -1
- data/README.md +207 -24
- data/lib/maestrano.rb +150 -31
- data/lib/maestrano/api/operation/base.rb +6 -7
- data/lib/maestrano/sso.rb +6 -6
- data/lib/maestrano/sso/base_user.rb +2 -2
- data/lib/maestrano/version.rb +1 -1
- data/test/maestrano/api/resource_test.rb +1 -1
- data/test/maestrano/maestrano_test.rb +180 -36
- data/test/maestrano/sso_test.rb +2 -2
- metadata +2 -2
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -10,13 +10,19 @@ Maestrano Cloud Integration is currently in closed beta. Want to know more? Send
|
|
10
10
|
|
11
11
|
1. [Getting Setup](#getting-setup)
|
12
12
|
2. [Getting Started with Rails](#getting-started-with-rails)
|
13
|
-
3.
|
13
|
+
3. [Getting Started](#getting-started)
|
14
|
+
* [Installation](#installation)
|
15
|
+
* [Configuration](#configuration)
|
16
|
+
* [Metadata Endpoint](#metadata-endpoint)
|
14
17
|
4. [Single Sign-On Setup](#single-sign-on-setup)
|
15
18
|
* [User Setup](#user-setup)
|
16
19
|
* [Group Setup](#group-setup)
|
17
20
|
* [Controller Setup](#controller-setup)
|
18
21
|
* [Other Controllers](#other-controllers)
|
19
|
-
5. [
|
22
|
+
5. [Account Webhooks](#account-webhooks)
|
23
|
+
* [Groups Controller](#groups-controller-service-cancellation)
|
24
|
+
* [Group Users Controller](#group-users-controller-business-member-removal)
|
25
|
+
6. [API](#api)
|
20
26
|
* [Bill](#bill)
|
21
27
|
* [Recurring Bill](#recurring-bill)
|
22
28
|
|
@@ -37,6 +43,8 @@ More details on the [maestrano-rails project page](https://github.com/maestrano/
|
|
37
43
|
|
38
44
|
## Getting Started
|
39
45
|
|
46
|
+
### Installation
|
47
|
+
|
40
48
|
To install the gem run
|
41
49
|
```console
|
42
50
|
gem install maestrano
|
@@ -47,6 +55,8 @@ Or add it to your Gemfile
|
|
47
55
|
gem 'maestrano'
|
48
56
|
```
|
49
57
|
|
58
|
+
|
59
|
+
### Configuration
|
50
60
|
Once installed the first step is to create an initializer to configure the behaviour of the Maestrano gem - including setting your API key.
|
51
61
|
|
52
62
|
The initializer should look like this:
|
@@ -62,25 +72,38 @@ Maestrano.configure do |config|
|
|
62
72
|
# If set to 'test' then requests will be made to api-sandbox.maestrano.io
|
63
73
|
# The api-sandbox allows you to easily test integration scenarios.
|
64
74
|
# More details on http://api-sandbox.maestrano.io
|
75
|
+
#
|
65
76
|
config.environment = 'test' # or 'production'
|
66
77
|
|
78
|
+
# ==> Application host
|
79
|
+
# This is your application host (e.g: my-app.com) which is ultimately
|
80
|
+
# used to redirect users to the right SAML url during SSO handshake.
|
81
|
+
#
|
82
|
+
config.app.host = (config.environment == 'production' ? 'https://my-app.com' : 'http://localhost:3000')
|
83
|
+
|
67
84
|
# ==> App ID & API key
|
68
85
|
# Your application App ID and API key which you can retrieve on http://maestrano.com
|
69
86
|
# via your cloud partner dashboard.
|
70
|
-
# For testing you can retrieve/generate an
|
87
|
+
# For testing you can retrieve/generate an api.id and api.key from the API Sandbox directly
|
71
88
|
# on http://api-sandbox.maestrano.io
|
72
|
-
|
73
|
-
config.
|
89
|
+
#
|
90
|
+
config.api.id = (config.environment == 'production' ? 'prod_app_id' : 'sandbox_app_id')
|
91
|
+
config.api.key = (config.environment == 'production' ? 'prod_api_key' : 'sandbox_api_key')
|
74
92
|
|
75
93
|
# ==> Single Sign-On activation
|
76
94
|
# Enable/Disable single sign-on. When troubleshooting authentication issues
|
77
95
|
# you might want to disable SSO temporarily
|
78
|
-
|
96
|
+
#
|
97
|
+
# config.sso.enabled = true
|
79
98
|
|
80
|
-
# ==>
|
81
|
-
#
|
82
|
-
#
|
83
|
-
|
99
|
+
# ==> Single Sign-On Identity Manager
|
100
|
+
# By default we consider that the domain managing user identification
|
101
|
+
# is the same as your application host (see above config.app.host parameter)
|
102
|
+
# If you have a dedicated domain managing user identification and therefore
|
103
|
+
# responsible for the single sign-on handshake (e.g: https://idp.my-app.com)
|
104
|
+
# then you can specify it below
|
105
|
+
#
|
106
|
+
# config.sso.idm = (config.environment == 'production' ? 'https://idp.my-app.com' : 'http://localhost:3000')
|
84
107
|
|
85
108
|
# ==> SSO Initialization endpoint
|
86
109
|
# This is your application path to the SAML endpoint that allows users to
|
@@ -89,19 +112,15 @@ Maestrano.configure do |config|
|
|
89
112
|
# to Maestrano. Maestrano will then authenticate and authorize the user. Upon
|
90
113
|
# authorization the user gets redirected to your application consumer endpoint
|
91
114
|
# (see below) for initial setup and/or login.
|
92
|
-
#
|
93
|
-
#
|
94
|
-
# <rails_root>/app/controllers/maestrano/auth/saml.rb
|
95
|
-
config.sso_app_init_path = '/maestrano/auth/saml/init'
|
115
|
+
#
|
116
|
+
# config.sso.init_path = '/maestrano/auth/saml/init'
|
96
117
|
|
97
118
|
# ==> SSO Consumer endpoint
|
98
119
|
# This is your application path to the SAML endpoint that allows users to
|
99
120
|
# finalize SSO authentication. During the 'consume' action your application
|
100
121
|
# sets users (and associated group) up and/or log them in.
|
101
|
-
#
|
102
|
-
#
|
103
|
-
# <rails_root>/app/controllers/maestrano/auth/saml.rb
|
104
|
-
config.sso_app_consume_path = '/maestrano/auth/saml/consume'
|
122
|
+
#
|
123
|
+
# config.sso.consume_path = '/maestrano/auth/saml/consume'
|
105
124
|
|
106
125
|
# ==> SSO User creation mode
|
107
126
|
# !IMPORTANT
|
@@ -121,20 +140,69 @@ Maestrano.configure do |config|
|
|
121
140
|
#
|
122
141
|
# == mode: 'real'
|
123
142
|
# In an ideal world a user should be able to belong to several groups in your application.
|
124
|
-
# In this case you would set the '
|
143
|
+
# In this case you would set the 'sso.creation_mode' to 'real' which means that the uid
|
125
144
|
# and email we pass to you are the actual user email and maestrano universal id.
|
126
145
|
#
|
127
146
|
# == mode: 'virtual'
|
128
|
-
# Now let's say that due to technical
|
147
|
+
# Now let's say that due to technical constraints your application cannot authorize a user
|
129
148
|
# to belong to several groups. Well next time John logs in via a different group there will
|
130
149
|
# be a problem: the user already exists (based on uid or email) and cannot be assigned
|
131
|
-
# to a second group. To fix this you can set the '
|
150
|
+
# to a second group. To fix this you can set the 'sso.creation_mode' to 'virtual'. In this
|
132
151
|
# mode users get assigned a truly unique uid and email across groups. So next time John logs
|
133
152
|
# in a whole new user account can be created for him without any validation problem. In this
|
134
153
|
# mode the email we assign to him looks like "usr-sdf54.cld-45aa2@mail.maestrano.com". But don't
|
135
154
|
# worry we take care of forwarding any email you would send to this address
|
136
155
|
#
|
137
|
-
config.
|
156
|
+
# config.sso.creation_mode = 'real' # or 'virtual'
|
157
|
+
|
158
|
+
# ==> Account Webhooks
|
159
|
+
# Single sign on has been setup into your app and Maestrano users are now able
|
160
|
+
# to use your service. Great! Wait what happens when a business (group) decides to
|
161
|
+
# stop using your service? Also what happens when a user gets removed from a business?
|
162
|
+
# Well the endpoints below are for Maestrano to be able to notify you of such
|
163
|
+
# events.
|
164
|
+
#
|
165
|
+
# Even if the routes look restful we issue only issue DELETE requests for the moment
|
166
|
+
# to notify you of any service cancellation (group deletion) or any user being
|
167
|
+
# removed from a group.
|
168
|
+
#
|
169
|
+
# config.webhook.account.groups_path = '/maestrano/account/groups/:id',
|
170
|
+
# config.webhook.account.group_users_path = '/maestrano/account/groups/:group_id/users/:id',
|
171
|
+
end
|
172
|
+
```
|
173
|
+
|
174
|
+
### Metadata Endpoint
|
175
|
+
Your configuration initializer is now all setup and shiny. Great! But need to know about it. Of course
|
176
|
+
we could propose a long and boring form on maestrano.com for you to fill all these details (especially the webhooks) but we thought it would be more convenient to fetch that automatically.
|
177
|
+
|
178
|
+
For that we expect you to create a metadata endpoint that we can fetch regularly (or when you press 'refresh metadata' in your maestrano cloud partner dashboard). By default we assume that it will be located at
|
179
|
+
YOUR_WEBSITE/maestrano/metadata(.json)
|
180
|
+
|
181
|
+
Of course if you prefer a different url you can always change that endpoint in your maestrano cloud partner dashboard.
|
182
|
+
|
183
|
+
What would the controller action look like? First let's talk about authentication. You don't want that endpoint to be visible to anyone. Maestrano always uses http basic authentication to contact your service remotely. The login/password used for this authentication are your actual api.id and api.key.
|
184
|
+
|
185
|
+
So here is an example of controller action for Rails to adapt depending on the framework you're using:
|
186
|
+
|
187
|
+
```ruby
|
188
|
+
class MaestranoMetaDataController < ApplicationController
|
189
|
+
before_filter :authenticate_maestrano!
|
190
|
+
|
191
|
+
def metadata
|
192
|
+
render json: Maestrano.to_metadata
|
193
|
+
end
|
194
|
+
|
195
|
+
private
|
196
|
+
def authenticate_maestrano!
|
197
|
+
authorized = false
|
198
|
+
authenticate_with_http_basic do |app_id, api_token|
|
199
|
+
authorized = Maestrano.authenticate(app_id,api_token)
|
200
|
+
end
|
201
|
+
unless authorized
|
202
|
+
render json: {error: 'Invalid credentials' }, status: :unauthorized
|
203
|
+
end
|
204
|
+
return true
|
205
|
+
end
|
138
206
|
end
|
139
207
|
```
|
140
208
|
|
@@ -275,8 +343,123 @@ def verify_maestrano_session
|
|
275
343
|
end
|
276
344
|
```
|
277
345
|
|
346
|
+
## Account Webhooks
|
347
|
+
Single sign on has been setup into your app and Maestrano users are now able to use your service. Great! Wait what happens when a business (group) decides to stop using your service? Also what happens when a user gets removed from a business? Well the controllers describes in this section are for Maestrano to be able to notify you of such events.
|
348
|
+
|
349
|
+
### Groups Controller (service cancellation)
|
350
|
+
Sad as it is a business might decide to stop using your service at some point. On Maestrano billing entities are represented by groups (used for collaboration & billing). So when a business decides to stop using your service we will issue a DELETE request to the webhook.account.groups_path endpoint (typically /maestrano/account/groups/:id).
|
351
|
+
|
352
|
+
Maestrano only uses this controller for service cancellation so there is no need to implement any other type of action - ie: GET, PUT/PATCH or POST. The use of other http verbs might come in the future to improve the communication between Maestrano and your service but as of now it is not required.
|
353
|
+
|
354
|
+
The controller example below reimplements the authenticate_maestrano! method seen in the [metadata section](#metadata) for completeness. Utimately you should move this method to a helper if you can.
|
355
|
+
|
356
|
+
The example below is for Rails and need to be adapted depending on the framework you're using:
|
357
|
+
```ruby
|
358
|
+
class MaestranoAccountGroupsController < ApplicationController
|
359
|
+
before_filter :authenticate_maestrano!
|
360
|
+
|
361
|
+
# DELETE /maestrano/account/groups/cld-1
|
362
|
+
# Delete an entire group
|
363
|
+
def destroy
|
364
|
+
group_uid = params[:id]
|
365
|
+
|
366
|
+
# Perform deletion steps here
|
367
|
+
# --
|
368
|
+
# If you need to perform a final checkout
|
369
|
+
# then you can call Maestrano::Account::Bill.create({.. final checkout details ..})
|
370
|
+
# --
|
371
|
+
# If Maestrano.param('sso.creation_mode') is set to virtual
|
372
|
+
# then you might want to delete/cancel/block all users under
|
373
|
+
# that group
|
374
|
+
# --
|
375
|
+
# E.g:
|
376
|
+
# organization = Organization.find_by_provider_and_uid('maestrano',group_uid)
|
377
|
+
#
|
378
|
+
# amount_cents = organization.calculate_total_due_remaining
|
379
|
+
# Maestrano::Account::Bill.create({
|
380
|
+
# group_id: group_uid,
|
381
|
+
# price_cents: amount_cents,
|
382
|
+
# description: "Final Payout"
|
383
|
+
# })
|
384
|
+
#
|
385
|
+
# if Maestrano.param('sso.creation_mode') == 'virtual'
|
386
|
+
# organization.members.where(provider:'maestrano').each do |user|
|
387
|
+
# user.destroy
|
388
|
+
# end
|
389
|
+
#
|
390
|
+
# organization.destroy
|
391
|
+
# render json: {success: true}, status: :success
|
392
|
+
#
|
393
|
+
end
|
394
|
+
|
395
|
+
private
|
396
|
+
def authenticate_maestrano!
|
397
|
+
authorized = false
|
398
|
+
authenticate_with_http_basic do |app_id, api_token|
|
399
|
+
authorized = Maestrano.authenticate(app_id,api_token)
|
400
|
+
end
|
401
|
+
unless authorized
|
402
|
+
render json: {error: 'Invalid credentials' }, status: :unauthorized
|
403
|
+
end
|
404
|
+
return true
|
405
|
+
end
|
406
|
+
end
|
407
|
+
```
|
408
|
+
|
409
|
+
### Group Users Controller (business member removal)
|
410
|
+
A business might decide at some point to revoke access to your services for one of its member. In such case we will issue a DELETE request to the webhook.account.group_users_path endpoint (typically /maestrano/account/groups/:group_id/users/:id).
|
411
|
+
|
412
|
+
Maestrano only uses this controller for user membership cancellation so there is no need to implement any other type of action - ie: GET, PUT/PATCH or POST. The use of other http verbs might come in the future to improve the communication between Maestrano and your service but as of now it is not required.
|
413
|
+
|
414
|
+
The controller example below reimplements the authenticate_maestrano! method seen in the [metadata section](#metadata) for completeness. Utimately you should move this method to a helper if you can.
|
415
|
+
|
416
|
+
The example below is for Rails and need to be adapted depending on the framework you're using:
|
417
|
+
```ruby
|
418
|
+
class MaestranoAccountGroupUsersController < ApplicationController
|
419
|
+
before_filter :authenticate_maestrano!
|
420
|
+
|
421
|
+
# DELETE /maestrano/account/groups/cld-1
|
422
|
+
# Delete an entire group
|
423
|
+
def destroy
|
424
|
+
# Set the right uid based on Maestrano.param('sso.creation_mode')
|
425
|
+
user_uid = Maestrano.mask_user(params[:id],params[:group_id])
|
426
|
+
group_uid = params[:group_id]
|
427
|
+
|
428
|
+
# Perform association deletion steps here
|
429
|
+
# --
|
430
|
+
# If Maestrano.param('sso.creation_mode') is set to virtual
|
431
|
+
# then you might want to just delete/cancel/block the user
|
432
|
+
#
|
433
|
+
# E.g
|
434
|
+
# user = User.find_by_provider_and_uid('maestrano',user_uid)
|
435
|
+
# organization = Organization.find_by_provider_and_uid('maestrano',group_uid)
|
436
|
+
#
|
437
|
+
# if Maestrano.param('sso.creation_mode') == 'virtual'
|
438
|
+
# user.destroy
|
439
|
+
# else
|
440
|
+
# organization.remove_user(user)
|
441
|
+
# user.block_access! if user.reload.organizations.empty?
|
442
|
+
# end
|
443
|
+
#
|
444
|
+
# render json: {success: true}, status: :success
|
445
|
+
end
|
446
|
+
|
447
|
+
private
|
448
|
+
def authenticate_maestrano!
|
449
|
+
authorized = false
|
450
|
+
authenticate_with_http_basic do |app_id, api_token|
|
451
|
+
authorized = Maestrano.authenticate(app_id,api_token)
|
452
|
+
end
|
453
|
+
unless authorized
|
454
|
+
render json: {error: 'Invalid credentials' }, status: :unauthorized
|
455
|
+
end
|
456
|
+
return true
|
457
|
+
end
|
458
|
+
end
|
459
|
+
```
|
460
|
+
|
278
461
|
## API
|
279
|
-
The maestrano gem also provides bindings to its REST API allowing to access, create, update or delete various entities under your account (e.g: billing).
|
462
|
+
The maestrano gem also provides bindings to its REST API allowing you to access, create, update or delete various entities under your account (e.g: billing).
|
280
463
|
|
281
464
|
### Payment API
|
282
465
|
|
@@ -532,7 +715,7 @@ Maestrano::Account::RecurringBill
|
|
532
715
|
<td>String</td>
|
533
716
|
<td>-</td>
|
534
717
|
<td>-</td>
|
535
|
-
<td>Status of the recurring bill. Either '
|
718
|
+
<td>Status of the recurring bill. Either 'submitted', 'active', 'expired' or 'cancelled'.</td>
|
536
719
|
<tr>
|
537
720
|
|
538
721
|
</table>
|
data/lib/maestrano.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# libs
|
2
2
|
require 'rest_client'
|
3
3
|
require 'json'
|
4
|
+
require 'ostruct'
|
4
5
|
|
5
6
|
# Version
|
6
7
|
require 'maestrano/version'
|
@@ -58,7 +59,8 @@ module Maestrano
|
|
58
59
|
def self.configure
|
59
60
|
self.config ||= Configuration.new
|
60
61
|
yield(config)
|
61
|
-
self.config.
|
62
|
+
self.config.post_initialize
|
63
|
+
return self
|
62
64
|
end
|
63
65
|
|
64
66
|
# Check that app_id and api_key passed
|
@@ -67,70 +69,187 @@ module Maestrano
|
|
67
69
|
self.param(:app_id) == app_id && self.param(:api_key) == api_key
|
68
70
|
end
|
69
71
|
|
72
|
+
# Take a user uid (either real or virtual)
|
73
|
+
# and a group id and return the user uid that should
|
74
|
+
# be used within the app based on the user_creation_mode
|
75
|
+
# parameter:
|
76
|
+
# 'real': then the real user uid is returned (usr-4d5sfd)
|
77
|
+
# 'virtual': then the virtual user uid is returned (usr-4d5sfd.cld-g4f5d)
|
70
78
|
def self.mask_user(user_uid,group_uid)
|
71
79
|
sanitized_user_uid = self.unmask_user(user_uid)
|
72
|
-
if Maestrano.param('
|
80
|
+
if Maestrano.param('sso.creation_mode') == 'virtual'
|
73
81
|
return "#{sanitized_user_uid}.#{group_uid}"
|
74
82
|
else
|
75
83
|
return sanitized_user_uid
|
76
84
|
end
|
77
85
|
end
|
78
86
|
|
87
|
+
# Take a user uid (either real or virtual)
|
88
|
+
# and return the real uid part
|
79
89
|
def self.unmask_user(user_uid)
|
80
90
|
user_uid.split(".").first
|
81
91
|
end
|
82
92
|
|
83
93
|
# Get configuration parameter value
|
84
94
|
# E.g:
|
85
|
-
# Maestrano.param('
|
95
|
+
# Maestrano.param('api.key')
|
86
96
|
# Maestrano.param(:api_key)
|
87
97
|
def self.param(parameter)
|
88
98
|
self.config.param(parameter)
|
89
99
|
end
|
100
|
+
|
101
|
+
# Return a hash describing the current
|
102
|
+
# Maestrano configuration. The metadata
|
103
|
+
# will be remotely fetched by Maestrano
|
104
|
+
# Exclude any info containing an api key
|
105
|
+
def self.to_metadata
|
106
|
+
{
|
107
|
+
'environment' => self.param('environment'),
|
108
|
+
'app' => {
|
109
|
+
'host' => self.param('app.host')
|
110
|
+
},
|
111
|
+
'api' => {
|
112
|
+
'id' => self.param('api.id'),
|
113
|
+
'version' => self.param('api.version'),
|
114
|
+
'verify_ssl_certs' => self.param('api.verify_ssl_certs'),
|
115
|
+
'lang' => self.param('api.lang'),
|
116
|
+
'lang_version' => self.param('api.lang_version'),
|
117
|
+
'host' => self.param('api.host'),
|
118
|
+
'base' => self.param('api.base'),
|
119
|
+
|
120
|
+
},
|
121
|
+
'sso' => {
|
122
|
+
'enabled' => self.param('sso.enabled'),
|
123
|
+
'init_path' => self.param('sso.init_path'),
|
124
|
+
'consume_path' => self.param('sso.consume_path'),
|
125
|
+
'creation_mode' => self.param('sso.creation_mode'),
|
126
|
+
'idm' => self.param('sso.idm'),
|
127
|
+
'idp' => self.param('sso.idp'),
|
128
|
+
'name_id_format' => self.param('sso.name_id_format'),
|
129
|
+
'x509_fingerprint' => self.param('sso.x509_fingerprint'),
|
130
|
+
'x509_certificate' => self.param('sso.x509_certificate'),
|
131
|
+
}
|
132
|
+
}
|
133
|
+
end
|
90
134
|
|
91
135
|
class Configuration
|
92
|
-
attr_accessor :environment, :
|
93
|
-
:app_host, :sso_app_init_path, :sso_app_consume_path, :user_creation_mode,
|
94
|
-
:verify_ssl_certs, :api_version, :api_token
|
136
|
+
attr_accessor :environment, :app, :sso, :api, :webhook
|
95
137
|
|
96
138
|
def initialize
|
97
139
|
@environment = 'test'
|
98
|
-
|
99
|
-
|
100
|
-
@
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
@
|
106
|
-
|
140
|
+
|
141
|
+
# App config
|
142
|
+
@app = OpenStruct.new({
|
143
|
+
host: 'http://localhost:3000'
|
144
|
+
})
|
145
|
+
|
146
|
+
# API Config
|
147
|
+
@api = OpenStruct.new({
|
148
|
+
id: nil,
|
149
|
+
key: nil,
|
150
|
+
token: nil,
|
151
|
+
version: nil,
|
152
|
+
verify_ssl_certs: false,
|
153
|
+
lang: nil, #set in post_initialize
|
154
|
+
lang_version: nil #set in post_initialize
|
155
|
+
})
|
156
|
+
|
157
|
+
# SSO Config
|
158
|
+
@sso = OpenStruct.new({
|
159
|
+
enabled: true,
|
160
|
+
creation_mode: 'virtual',
|
161
|
+
init_path: '/maestrano/auth/saml/init',
|
162
|
+
consume_path: '/maestrano/auth/saml/consume',
|
163
|
+
idm: @app.host
|
164
|
+
})
|
165
|
+
|
166
|
+
# WebHooks Config
|
167
|
+
@webhook = OpenStruct.new({
|
168
|
+
account: OpenStruct.new({
|
169
|
+
groups_path: '/maestrano/account/groups/:id',
|
170
|
+
group_users_path: '/maestrano/account/groups/:group_id/users/:id',
|
171
|
+
})
|
172
|
+
})
|
173
|
+
end
|
174
|
+
|
175
|
+
# Force or default certain parameters
|
176
|
+
# Used after configure block
|
177
|
+
def post_initialize
|
178
|
+
self.api.token = "#{self.api.id}:#{self.api.key}"
|
179
|
+
self.api.version = Maestrano::VERSION
|
180
|
+
self.api.lang = 'ruby'
|
181
|
+
self.api.lang_version = "#{RUBY_VERSION} p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE})"
|
182
|
+
self.sso.idm ||= self.app.host
|
183
|
+
end
|
184
|
+
|
185
|
+
# Transform legacy parameters into new parameter
|
186
|
+
# style
|
187
|
+
# Dummy mapping
|
188
|
+
def legacy_param_to_new(parameter)
|
189
|
+
case parameter.to_s
|
190
|
+
when 'user_creation_mode'
|
191
|
+
return 'sso.creation_mode'
|
192
|
+
when 'verify_ssl_certs'
|
193
|
+
return 'api.verify_ssl_certs'
|
194
|
+
when 'app_id'
|
195
|
+
return 'api.id'
|
196
|
+
when /^app_(.*)/i
|
197
|
+
return "app.#{$1}"
|
198
|
+
when /^api_(.*)/i
|
199
|
+
return "api.#{$1}"
|
200
|
+
when /^sso_app_(.*)/i
|
201
|
+
return "sso.#{$1}"
|
202
|
+
when /^sso_(.*)/i
|
203
|
+
return "sso.#{$1}"
|
204
|
+
else
|
205
|
+
return parameter.to_s
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
# Handle legacy parameter assignment
|
210
|
+
def method_missing(meth, *args, &block)
|
211
|
+
if meth.to_s =~ /^((?:sso|app|api|user)_.*)=$/
|
212
|
+
new_meth = self.legacy_param_to_new($1) + '='
|
213
|
+
props = new_meth.split('.')
|
214
|
+
last_prop = props.pop
|
215
|
+
obj = props.inject(self,:send)
|
216
|
+
obj.send(last_prop, *args, &block)
|
217
|
+
else
|
218
|
+
super
|
219
|
+
end
|
107
220
|
end
|
108
221
|
|
109
222
|
# Get configuration parameter value
|
110
223
|
def param(parameter)
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
224
|
+
real_param = self.legacy_param_to_new(parameter)
|
225
|
+
props = real_param.split('.')
|
226
|
+
if self.respond_to?(real_param) || props.inject(self) { |result,elem| result && result.respond_to?(elem) ? result.send(elem) || elem : false }
|
227
|
+
last_prop = props.pop
|
228
|
+
obj = props.inject(self,:send)
|
229
|
+
obj.send(last_prop)
|
230
|
+
elsif EVT_CONFIG[@environment.to_s].has_key?(real_param.to_s)
|
231
|
+
EVT_CONFIG[@environment.to_s][real_param.to_s]
|
115
232
|
else
|
116
233
|
raise ArgumentError, "No such configuration parameter: '#{parameter}'"
|
117
234
|
end
|
118
235
|
end
|
119
236
|
|
120
237
|
EVT_CONFIG = {
|
121
|
-
test
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
238
|
+
'test' => {
|
239
|
+
'api.host' => 'http://api-sandbox.maestrano.io',
|
240
|
+
'api.base' => '/api/v1/',
|
241
|
+
'sso.idp' => 'https://maestrano.com',
|
242
|
+
'sso.name_id_format' => Maestrano::Saml::Settings::NAMEID_PERSISTENT,
|
243
|
+
'sso.x509_fingerprint' => '01:06:15:89:25:7d:78:12:28:a6:69:c7:de:63:ed:74:21:f9:f5:36',
|
244
|
+
'sso.x509_certificate' => "-----BEGIN CERTIFICATE-----\nMIIDezCCAuSgAwIBAgIJAOehBr+YIrhjMA0GCSqGSIb3DQEBBQUAMIGGMQswCQYD\nVQQGEwJBVTEMMAoGA1UECBMDTlNXMQ8wDQYDVQQHEwZTeWRuZXkxGjAYBgNVBAoT\nEU1hZXN0cmFubyBQdHkgTHRkMRYwFAYDVQQDEw1tYWVzdHJhbm8uY29tMSQwIgYJ\nKoZIhvcNAQkBFhVzdXBwb3J0QG1hZXN0cmFuby5jb20wHhcNMTQwMTA0MDUyMjM5\nWhcNMzMxMjMwMDUyMjM5WjCBhjELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA05TVzEP\nMA0GA1UEBxMGU3lkbmV5MRowGAYDVQQKExFNYWVzdHJhbm8gUHR5IEx0ZDEWMBQG\nA1UEAxMNbWFlc3RyYW5vLmNvbTEkMCIGCSqGSIb3DQEJARYVc3VwcG9ydEBtYWVz\ndHJhbm8uY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDVkIqo5t5Paflu\nP2zbSbzxn29n6HxKnTcsubycLBEs0jkTkdG7seF1LPqnXl8jFM9NGPiBFkiaR15I\n5w482IW6mC7s8T2CbZEL3qqQEAzztEPnxQg0twswyIZWNyuHYzf9fw0AnohBhGu2\n28EZWaezzT2F333FOVGSsTn1+u6tFwIDAQABo4HuMIHrMB0GA1UdDgQWBBSvrNxo\neHDm9nhKnkdpe0lZjYD1GzCBuwYDVR0jBIGzMIGwgBSvrNxoeHDm9nhKnkdpe0lZ\njYD1G6GBjKSBiTCBhjELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA05TVzEPMA0GA1UE\nBxMGU3lkbmV5MRowGAYDVQQKExFNYWVzdHJhbm8gUHR5IEx0ZDEWMBQGA1UEAxMN\nbWFlc3RyYW5vLmNvbTEkMCIGCSqGSIb3DQEJARYVc3VwcG9ydEBtYWVzdHJhbm8u\nY29tggkA56EGv5giuGMwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQCc\nMPgV0CpumKRMulOeZwdpnyLQI/NTr3VVHhDDxxCzcB0zlZ2xyDACGnIG2cQJJxfc\n2GcsFnb0BMw48K6TEhAaV92Q7bt1/TYRvprvhxUNMX2N8PHaYELFG2nWfQ4vqxES\nRkjkjqy+H7vir/MOF3rlFjiv5twAbDKYHXDT7v1YCg==\n-----END CERTIFICATE-----"
|
127
245
|
},
|
128
|
-
production
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
246
|
+
'production' => {
|
247
|
+
'api.host' => 'https://maestrano.com',
|
248
|
+
'api.base' => '/api/v1/',
|
249
|
+
'sso.idp' => 'https://maestrano.com',
|
250
|
+
'sso.name_id_format' => Maestrano::Saml::Settings::NAMEID_PERSISTENT,
|
251
|
+
'sso.x509_fingerprint' => '2f:57:71:e4:40:19:57:37:a6:2c:f0:c5:82:52:2f:2e:41:b7:9d:7e',
|
252
|
+
'sso.x509_certificate' => "-----BEGIN CERTIFICATE-----\nMIIDezCCAuSgAwIBAgIJAPFpcH2rW0pyMA0GCSqGSIb3DQEBBQUAMIGGMQswCQYD\nVQQGEwJBVTEMMAoGA1UECBMDTlNXMQ8wDQYDVQQHEwZTeWRuZXkxGjAYBgNVBAoT\nEU1hZXN0cmFubyBQdHkgTHRkMRYwFAYDVQQDEw1tYWVzdHJhbm8uY29tMSQwIgYJ\nKoZIhvcNAQkBFhVzdXBwb3J0QG1hZXN0cmFuby5jb20wHhcNMTQwMTA0MDUyNDEw\nWhcNMzMxMjMwMDUyNDEwWjCBhjELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA05TVzEP\nMA0GA1UEBxMGU3lkbmV5MRowGAYDVQQKExFNYWVzdHJhbm8gUHR5IEx0ZDEWMBQG\nA1UEAxMNbWFlc3RyYW5vLmNvbTEkMCIGCSqGSIb3DQEJARYVc3VwcG9ydEBtYWVz\ndHJhbm8uY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD3feNNn2xfEz5/\nQvkBIu2keh9NNhobpre8U4r1qC7h7OeInTldmxGL4cLHw4ZAqKbJVrlFWqNevM5V\nZBkDe4mjuVkK6rYK1ZK7eVk59BicRksVKRmdhXbANk/C5sESUsQv1wLZyrF5Iq8m\na9Oy4oYrIsEF2uHzCouTKM5n+O4DkwIDAQABo4HuMIHrMB0GA1UdDgQWBBSd/X0L\n/Pq+ZkHvItMtLnxMCAMdhjCBuwYDVR0jBIGzMIGwgBSd/X0L/Pq+ZkHvItMtLnxM\nCAMdhqGBjKSBiTCBhjELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA05TVzEPMA0GA1UE\nBxMGU3lkbmV5MRowGAYDVQQKExFNYWVzdHJhbm8gUHR5IEx0ZDEWMBQGA1UEAxMN\nbWFlc3RyYW5vLmNvbTEkMCIGCSqGSIb3DQEJARYVc3VwcG9ydEBtYWVzdHJhbm8u\nY29tggkA8WlwfatbSnIwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQDE\nhe/18oRh8EqIhOl0bPk6BG49AkjhZZezrRJkCFp4dZxaBjwZTddwo8O5KHwkFGdy\nyLiPV326dtvXoKa9RFJvoJiSTQLEn5mO1NzWYnBMLtrDWojOe6Ltvn3x0HVo/iHh\nJShjAn6ZYX43Tjl1YXDd1H9O+7/VgEWAQQ32v8p5lA==\n-----END CERTIFICATE-----"
|
134
253
|
}
|
135
254
|
}
|
136
255
|
end
|
@@ -7,7 +7,7 @@ module Maestrano
|
|
7
7
|
# end
|
8
8
|
|
9
9
|
def self.api_url(url='')
|
10
|
-
Maestrano.param('
|
10
|
+
Maestrano.param('api.host') + Maestrano.param('api.base') + url
|
11
11
|
end
|
12
12
|
|
13
13
|
# Perform remote request
|
@@ -69,7 +69,7 @@ module Maestrano
|
|
69
69
|
private
|
70
70
|
|
71
71
|
def self.ssl_preflight_passed?
|
72
|
-
if !Maestrano.param('verify_ssl_certs')
|
72
|
+
if !Maestrano.param('api.verify_ssl_certs')
|
73
73
|
#$stderr.puts "WARNING: Running without SSL cert verification. " +
|
74
74
|
# "Execute 'Maestrano.configure { |config| config.verify_ssl_certs = true' } to enable verification."
|
75
75
|
return false
|
@@ -85,12 +85,11 @@ module Maestrano
|
|
85
85
|
|
86
86
|
def self.user_agent
|
87
87
|
@uname ||= get_uname
|
88
|
-
lang_version = "#{RUBY_VERSION} p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE})"
|
89
88
|
|
90
89
|
{
|
91
|
-
:bindings_version => Maestrano
|
92
|
-
:lang => '
|
93
|
-
:lang_version => lang_version,
|
90
|
+
:bindings_version => Maestrano.param('api.version'),
|
91
|
+
:lang => Maestrano.param('api.lang'),
|
92
|
+
:lang_version => Maestrano.param('api.lang_version'),
|
94
93
|
:platform => RUBY_PLATFORM,
|
95
94
|
:publisher => 'maestrano',
|
96
95
|
:uname => @uname
|
@@ -111,7 +110,7 @@ module Maestrano
|
|
111
110
|
|
112
111
|
def self.request_headers(api_token)
|
113
112
|
headers = {
|
114
|
-
:user_agent => "Maestrano/v1 RubyBindings/#{Maestrano
|
113
|
+
:user_agent => "Maestrano/v1 RubyBindings/#{Maestrano.param('api.version')}",
|
115
114
|
:authorization => "Basic #{Base64.encode64(api_token)}",
|
116
115
|
:content_type => 'application/x-www-form-urlencoded'
|
117
116
|
}
|
data/lib/maestrano/sso.rb
CHANGED
@@ -5,7 +5,7 @@ module Maestrano
|
|
5
5
|
def self.saml_settings
|
6
6
|
settings = Maestrano::Saml::Settings.new
|
7
7
|
settings.assertion_consumer_service_url = self.consume_url
|
8
|
-
settings.issuer = Maestrano.param('
|
8
|
+
settings.issuer = Maestrano.param('api.id')
|
9
9
|
settings.idp_sso_target_url = self.idp_url
|
10
10
|
settings.idp_cert_fingerprint = Maestrano.param('sso_x509_fingerprint')
|
11
11
|
settings.name_identifier_format = Maestrano.param('sso_name_id_format')
|
@@ -23,18 +23,18 @@ module Maestrano
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def self.enabled?
|
26
|
-
!!Maestrano.param('
|
26
|
+
!!Maestrano.param('sso.enabled')
|
27
27
|
end
|
28
28
|
|
29
29
|
def self.init_url
|
30
|
-
host = Maestrano.param('
|
31
|
-
path = Maestrano.param('
|
30
|
+
host = Maestrano.param('sso.idm')
|
31
|
+
path = Maestrano.param('sso.init_path')
|
32
32
|
return "#{host}#{path}"
|
33
33
|
end
|
34
34
|
|
35
35
|
def self.consume_url
|
36
|
-
host = Maestrano.param('
|
37
|
-
path = Maestrano.param('
|
36
|
+
host = Maestrano.param('sso.idm')
|
37
|
+
path = Maestrano.param('sso.consume_path')
|
38
38
|
return "#{host}#{path}"
|
39
39
|
end
|
40
40
|
|
@@ -25,7 +25,7 @@ module Maestrano
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def to_uid
|
28
|
-
if Maestrano.param('
|
28
|
+
if Maestrano.param('sso.creation_mode') == 'real'
|
29
29
|
return self.uid
|
30
30
|
else
|
31
31
|
return self.virtual_uid
|
@@ -33,7 +33,7 @@ module Maestrano
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def to_email
|
36
|
-
if Maestrano.param('
|
36
|
+
if Maestrano.param('sso.creation_mode') == 'real'
|
37
37
|
return self.email
|
38
38
|
else
|
39
39
|
return self.virtual_email
|
data/lib/maestrano/version.rb
CHANGED
@@ -58,7 +58,7 @@ module Maestrano
|
|
58
58
|
context "when specifying per-object credentials" do
|
59
59
|
context "with no global API key set" do
|
60
60
|
setup do
|
61
|
-
@original_api_key = Maestrano.param('
|
61
|
+
@original_api_key = Maestrano.param('api.key')
|
62
62
|
Maestrano.configure { |c| c.api_key = nil }
|
63
63
|
end
|
64
64
|
|
@@ -3,32 +3,165 @@ require File.expand_path('../../test_helper', __FILE__)
|
|
3
3
|
class MaestranoTest < Test::Unit::TestCase
|
4
4
|
setup do
|
5
5
|
@config = {
|
6
|
-
environment
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
6
|
+
'environment' => 'production',
|
7
|
+
'app.host' => 'http://mysuperapp.com',
|
8
|
+
|
9
|
+
'api.id' => 'app-f54ds4f8',
|
10
|
+
'api.key' => 'someapikey',
|
11
|
+
|
12
|
+
'sso.enabled' => false,
|
13
|
+
'sso.init_path' => '/mno/sso/init',
|
14
|
+
'sso.consume_path' => '/mno/sso/consume',
|
15
|
+
'sso.creation_mode' => 'real',
|
16
|
+
'sso.idm' => 'http://idp.mysuperapp.com',
|
17
|
+
|
18
|
+
'webhook.account.groups_path' => '/mno/groups/:id',
|
19
|
+
'webhook.account.group_users_path' => '/mno/groups/:group_id/users/:id',
|
13
20
|
}
|
14
|
-
|
21
|
+
|
15
22
|
Maestrano.configure do |config|
|
16
|
-
config.environment = @config[
|
17
|
-
config.
|
18
|
-
|
19
|
-
config.
|
20
|
-
config.
|
21
|
-
|
22
|
-
config.
|
23
|
+
config.environment = @config['environment']
|
24
|
+
config.app.host = @config['app.host']
|
25
|
+
|
26
|
+
config.api.id = @config['api.id']
|
27
|
+
config.api.key = @config['api.key']
|
28
|
+
|
29
|
+
config.sso.enabled = @config['sso.enabled']
|
30
|
+
config.sso.idm = @config['sso.idm']
|
31
|
+
config.sso.init_path = @config['sso.init_path']
|
32
|
+
config.sso.consume_path = @config['sso.consume_path']
|
33
|
+
config.sso.creation_mode = @config['sso.creation_mode']
|
34
|
+
|
35
|
+
config.webhook.account.groups_path = @config['webhook.account.groups_path' ]
|
36
|
+
config.webhook.account.group_users_path = @config['webhook.account.group_users_path' ]
|
23
37
|
end
|
24
38
|
end
|
25
39
|
|
26
|
-
context "
|
40
|
+
context "new style configuration" do
|
41
|
+
should "return the specified parameters" do
|
42
|
+
@config.keys.each do |key|
|
43
|
+
assert_equal @config[key], Maestrano.param(key)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
should "build the api_token based on the app_id and api_key" do
|
48
|
+
Maestrano.configure { |config| config.app_id = "bla"; config.api_key = "blo" }
|
49
|
+
assert_equal "bla:blo", Maestrano.param('api.token')
|
50
|
+
end
|
51
|
+
|
52
|
+
should "assign the sso.idm if explicitly set to nil" do
|
53
|
+
Maestrano.configure { |config| config.sso.idm = nil }
|
54
|
+
assert_equal Maestrano.param('app.host'), Maestrano.param('sso.idm')
|
55
|
+
end
|
56
|
+
|
57
|
+
should "force assign the api.lang" do
|
58
|
+
Maestrano.configure { |config| config.api.lang = "bla" }
|
59
|
+
assert_equal 'ruby', Maestrano.param('api.lang')
|
60
|
+
end
|
61
|
+
|
62
|
+
should "force assign the api.lang_version" do
|
63
|
+
Maestrano.configure { |config| config.api.lang_version = "123456" }
|
64
|
+
assert_equal "#{RUBY_VERSION} p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE})", Maestrano.param('api.lang_version')
|
65
|
+
end
|
66
|
+
|
67
|
+
should "force assign the api.version" do
|
68
|
+
Maestrano.configure { |config| config.api.version = "1245" }
|
69
|
+
assert_equal Maestrano::VERSION, Maestrano.param('api.version')
|
70
|
+
end
|
71
|
+
|
72
|
+
context "with environment params" do
|
73
|
+
should "return the right test parameters" do
|
74
|
+
Maestrano.configure { |config| config.environment = 'test' }
|
75
|
+
|
76
|
+
['api.host','api.base','sso.idp', 'sso.name_id_format', 'sso.x509_certificate'].each do |parameter|
|
77
|
+
assert_equal Maestrano::Configuration::EVT_CONFIG['test'][parameter], Maestrano.param(parameter)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
should "return the right production parameters" do
|
82
|
+
Maestrano.configure { |config| config.environment = 'production' }
|
83
|
+
|
84
|
+
['api.host','api.base','sso.idp', 'sso.name_id_format', 'sso.x509_certificate'].each do |parameter|
|
85
|
+
assert_equal Maestrano::Configuration::EVT_CONFIG['production'][parameter], Maestrano.param(parameter)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
context "old style configuration" do
|
93
|
+
setup do
|
94
|
+
@config = {
|
95
|
+
environment: 'production',
|
96
|
+
api_key: 'someapikey',
|
97
|
+
sso_enabled: false,
|
98
|
+
app_host: 'http://mysuperapp.com',
|
99
|
+
sso_app_init_path: '/mno/sso/init',
|
100
|
+
sso_app_consume_path: '/mno/sso/consume',
|
101
|
+
user_creation_mode: 'real',
|
102
|
+
}
|
103
|
+
|
104
|
+
Maestrano.configure do |config|
|
105
|
+
config.environment = @config[:environment]
|
106
|
+
config.api_key = @config[:api_key]
|
107
|
+
config.sso_enabled = @config[:sso_enabled]
|
108
|
+
config.app_host = @config[:app_host]
|
109
|
+
config.sso_app_init_path = @config[:sso_app_init_path]
|
110
|
+
config.sso_app_consume_path = @config[:sso_app_consume_path]
|
111
|
+
config.user_creation_mode = @config[:user_creation_mode]
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
should "build the api_token based on the app_id and api_key" do
|
116
|
+
Maestrano.configure { |config| config.app_id = "bla"; config.api_key = "blo" }
|
117
|
+
assert_equal "bla:blo", Maestrano.param(:api_token)
|
118
|
+
end
|
119
|
+
|
120
|
+
should "assign the sso.idm if explicitly set to nil" do
|
121
|
+
Maestrano.configure { |config| config.sso.idm = nil }
|
122
|
+
assert_equal Maestrano.param('app.host'), Maestrano.param('sso.idm')
|
123
|
+
end
|
124
|
+
|
125
|
+
should "force assign the api.lang" do
|
126
|
+
Maestrano.configure { |config| config.api.lang = "bla" }
|
127
|
+
assert_equal 'ruby', Maestrano.param('api.lang')
|
128
|
+
end
|
129
|
+
|
130
|
+
should "force assign the api.lang_version" do
|
131
|
+
Maestrano.configure { |config| config.api.lang_version = "123456" }
|
132
|
+
assert_equal "#{RUBY_VERSION} p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE})", Maestrano.param('api.lang_version')
|
133
|
+
end
|
134
|
+
|
135
|
+
should "force assign the api.version" do
|
136
|
+
Maestrano.configure { |config| config.api.version = "1245" }
|
137
|
+
assert_equal Maestrano::VERSION, Maestrano.param('api.version')
|
138
|
+
end
|
139
|
+
|
27
140
|
should "return the specified parameters" do
|
28
141
|
@config.keys.each do |key|
|
29
142
|
assert Maestrano.param(key) == @config[key]
|
30
143
|
end
|
31
144
|
end
|
145
|
+
|
146
|
+
context "with environment params" do
|
147
|
+
should "return the right test parameters" do
|
148
|
+
Maestrano.configure { |config| config.environment = 'test' }
|
149
|
+
|
150
|
+
['api_host','api_base','sso_name_id_format', 'sso_x509_certificate'].each do |parameter|
|
151
|
+
key = Maestrano::Configuration.new.legacy_param_to_new(parameter)
|
152
|
+
assert_equal Maestrano::Configuration::EVT_CONFIG['test'][key], Maestrano.param(parameter)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
should "return the right production parameters" do
|
157
|
+
Maestrano.configure { |config| config.environment = 'production' }
|
158
|
+
|
159
|
+
['api_host','api_base','sso_name_id_format', 'sso_x509_certificate'].each do |parameter|
|
160
|
+
key = Maestrano::Configuration.new.legacy_param_to_new(parameter)
|
161
|
+
assert_equal Maestrano::Configuration::EVT_CONFIG['production'][key], Maestrano.param(parameter)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
32
165
|
end
|
33
166
|
|
34
167
|
context "authenticate" do
|
@@ -69,27 +202,38 @@ class MaestranoTest < Test::Unit::TestCase
|
|
69
202
|
end
|
70
203
|
end
|
71
204
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
205
|
+
context "to_metadata" do
|
206
|
+
should "should return the right hash" do
|
207
|
+
expected = {
|
208
|
+
'environment' => @config['environment'],
|
209
|
+
'app' => {
|
210
|
+
'host' => @config['app.host']
|
211
|
+
},
|
212
|
+
'api' => {
|
213
|
+
'id' => @config['api.id'],
|
214
|
+
'version' => Maestrano::VERSION,
|
215
|
+
'verify_ssl_certs' => false,
|
216
|
+
'lang' => 'ruby',
|
217
|
+
'lang_version' => "#{RUBY_VERSION} p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE})",
|
218
|
+
'host' => Maestrano::Configuration::EVT_CONFIG[@config['environment']]['api.host'],
|
219
|
+
'base' => Maestrano::Configuration::EVT_CONFIG[@config['environment']]['api.base'],
|
220
|
+
|
221
|
+
},
|
222
|
+
'sso' => {
|
223
|
+
'enabled' => @config['sso.enabled'],
|
224
|
+
'init_path' => @config['sso.init_path'],
|
225
|
+
'consume_path' => @config['sso.consume_path'],
|
226
|
+
'creation_mode' => @config['sso.creation_mode'],
|
227
|
+
'idm' => @config['sso.idm'],
|
228
|
+
'idp' => Maestrano::Configuration::EVT_CONFIG[@config['environment']]['sso.idp'],
|
229
|
+
'name_id_format' => Maestrano::Configuration::EVT_CONFIG[@config['environment']]['sso.name_id_format'],
|
230
|
+
'x509_fingerprint' => Maestrano::Configuration::EVT_CONFIG[@config['environment']]['sso.x509_fingerprint'],
|
231
|
+
'x509_certificate' => Maestrano::Configuration::EVT_CONFIG[@config['environment']]['sso.x509_certificate'],
|
232
|
+
}
|
233
|
+
}
|
76
234
|
|
77
|
-
|
78
|
-
assert Maestrano.param(parameter) == Maestrano::Configuration::EVT_CONFIG[:test][parameter.to_sym]
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
should "return the right production parameters" do
|
83
|
-
Maestrano.configure { |config| config.environment = 'production' }
|
84
|
-
|
85
|
-
['api_host','api_base','sso_name_id_format', 'sso_x509_certificate'].each do |parameter|
|
86
|
-
assert Maestrano.param(parameter) == Maestrano::Configuration::EVT_CONFIG[:production][parameter.to_sym]
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
should "build the api_token based on the app_id and api_key" do
|
91
|
-
Maestrano.configure { |config| config.app_id = "bla"; config.api_key = "blo" }
|
92
|
-
assert_equal "bla:blo", Maestrano.param(:api_token)
|
235
|
+
assert_equal expected, Maestrano.to_metadata
|
93
236
|
end
|
94
237
|
end
|
238
|
+
|
95
239
|
end
|
data/test/maestrano/sso_test.rb
CHANGED
@@ -34,13 +34,13 @@ module Maestrano
|
|
34
34
|
end
|
35
35
|
|
36
36
|
should "return the right enabled parameter" do
|
37
|
-
assert Maestrano::SSO.enabled? == !!Maestrano.param('
|
37
|
+
assert Maestrano::SSO.enabled? == !!Maestrano.param('sso.enabled')
|
38
38
|
end
|
39
39
|
|
40
40
|
should "return the right saml_settings" do
|
41
41
|
settings = Maestrano::SSO.saml_settings
|
42
42
|
assert settings.assertion_consumer_service_url == Maestrano::SSO.consume_url
|
43
|
-
assert settings.issuer == Maestrano.param('
|
43
|
+
assert settings.issuer == Maestrano.param('api.id')
|
44
44
|
assert settings.idp_sso_target_url == Maestrano::SSO.idp_url
|
45
45
|
assert settings.idp_cert_fingerprint == Maestrano.param('sso_x509_fingerprint')
|
46
46
|
assert settings.name_identifier_format == Maestrano.param('sso_name_id_format')
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: maestrano
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.
|
5
|
+
version: 0.6.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Arnaud Lachaume
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2014-05
|
13
|
+
date: 2014-06-05 00:00:00 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rest-client
|