maestrano 0.3.0 → 0.4.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 +333 -3
- data/lib/maestrano.rb +4 -2
- data/lib/maestrano/account/bill.rb +2 -2
- data/lib/maestrano/account/recurring_bill.rb +2 -2
- data/lib/maestrano/api/list_object.rb +12 -12
- data/lib/maestrano/api/object.rb +13 -13
- data/lib/maestrano/api/operation/base.rb +7 -7
- data/lib/maestrano/api/operation/create.rb +3 -3
- data/lib/maestrano/api/operation/delete.rb +2 -2
- data/lib/maestrano/api/operation/list.rb +3 -3
- data/lib/maestrano/api/operation/update.rb +2 -2
- data/lib/maestrano/api/resource.rb +4 -4
- data/lib/maestrano/api/util.rb +5 -5
- data/lib/maestrano/sso.rb +1 -1
- data/lib/maestrano/version.rb +1 -1
- data/test/helpers/api_helpers.rb +1 -1
- data/test/maestrano/account/bill_test.rb +2 -2
- data/test/maestrano/account/recurring_bill_test.rb +2 -2
- data/test/maestrano/api/object_test.rb +1 -1
- data/test/maestrano/api/resource_test.rb +12 -12
- data/test/maestrano/maestrano_test.rb +5 -0
- data/test/maestrano/sso_test.rb +1 -1
- data/test/test_helper.rb +1 -0
- metadata +2 -2
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -3,6 +3,24 @@
|
|
3
3
|
</p>
|
4
4
|
|
5
5
|
Maestrano Cloud Integration is currently in closed beta. Want to know more? Send us an email to <contact@maestrano.com>.
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
- - -
|
10
|
+
|
11
|
+
1. [Getting Setup](#getting-setup)
|
12
|
+
2. [Getting Started with Rails](#getting-started-with-rails)
|
13
|
+
3. [Getting Started](#getting-started)
|
14
|
+
4. [Single Sign-On Setup](#single-sign-on-setup)
|
15
|
+
* [User Setup](#user-setup)
|
16
|
+
* [Group Setup](#group-setup)
|
17
|
+
* [Controller Setup](#controller-setup)
|
18
|
+
* [Other Controllers](#other-controllers)
|
19
|
+
5. [API](#api)
|
20
|
+
* [Bill](#bill)
|
21
|
+
* [Recurring Bill](#recurring-bill)
|
22
|
+
|
23
|
+
- - -
|
6
24
|
|
7
25
|
## Getting Setup
|
8
26
|
Before integrating with us you will need an API Key. Maestrano Cloud Integration being still in closed beta you will need to contact us beforehand to gain production access.
|
@@ -18,7 +36,18 @@ If you're looking at integrating Maestrano in your Rails application then you sh
|
|
18
36
|
More details on the [maestrano-rails project page](https://github.com/maestrano/maestrano-rails).
|
19
37
|
|
20
38
|
## Getting Started
|
21
|
-
|
39
|
+
|
40
|
+
To install the gem run
|
41
|
+
```console
|
42
|
+
gem install maestrano
|
43
|
+
```
|
44
|
+
|
45
|
+
Or add it to your Gemfile
|
46
|
+
```ruby
|
47
|
+
gem 'maestrano'
|
48
|
+
```
|
49
|
+
|
50
|
+
Once installed the first step is to create an initializer to configure the behaviour of the Maestrano gem - including setting your API key.
|
22
51
|
|
23
52
|
The initializer should look like this:
|
24
53
|
```ruby
|
@@ -35,11 +64,12 @@ Maestrano.configure do |config|
|
|
35
64
|
# More details on http://api-sandbox.maestrano.io
|
36
65
|
config.environment = 'test' # or 'production'
|
37
66
|
|
38
|
-
# ==> API key
|
39
|
-
# Your application API key which you can retrieve on http://maestrano.com
|
67
|
+
# ==> App ID & API key
|
68
|
+
# Your application App ID and API key which you can retrieve on http://maestrano.com
|
40
69
|
# via your cloud partner dashboard.
|
41
70
|
# For testing you can retrieve/generate an api_key from the API Sandbox directly
|
42
71
|
# on http://api-sandbox.maestrano.io
|
72
|
+
config.app_id = (config.environment == 'production' ? 'prod_app_id' : 'sandbox_app_id')
|
43
73
|
config.api_key = (config.environment == 'production' ? 'prod_api_key' : 'sandbox_api_key')
|
44
74
|
|
45
75
|
# ==> Single Sign-On activation
|
@@ -244,3 +274,303 @@ def verify_maestrano_session
|
|
244
274
|
true
|
245
275
|
end
|
246
276
|
```
|
277
|
+
|
278
|
+
## 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).
|
280
|
+
|
281
|
+
### Payment API
|
282
|
+
|
283
|
+
#### Bill
|
284
|
+
A bill represents a single charge on a given group.
|
285
|
+
|
286
|
+
```ruby
|
287
|
+
Maestrano::Account::Bill
|
288
|
+
```
|
289
|
+
|
290
|
+
##### Attributes
|
291
|
+
|
292
|
+
<table>
|
293
|
+
<tr>
|
294
|
+
<th>Field</th>
|
295
|
+
<th>Mode</th>
|
296
|
+
<th>Type</th>
|
297
|
+
<th>Required</th>
|
298
|
+
<th>Default</th>
|
299
|
+
<th>Description</th>
|
300
|
+
<tr>
|
301
|
+
|
302
|
+
<tr>
|
303
|
+
<td><b>id</b></td>
|
304
|
+
<td>readonly</td>
|
305
|
+
<td>string</td>
|
306
|
+
<td>-</td>
|
307
|
+
<td>-</td>
|
308
|
+
<td>The id of the bill</td>
|
309
|
+
<tr>
|
310
|
+
|
311
|
+
<tr>
|
312
|
+
<td><b>group_id</b></td>
|
313
|
+
<td>read/write</td>
|
314
|
+
<td>string</td>
|
315
|
+
<td><b>Yes</b></td>
|
316
|
+
<td>-</td>
|
317
|
+
<td>The id of the group you are charging</td>
|
318
|
+
<tr>
|
319
|
+
|
320
|
+
<tr>
|
321
|
+
<td><b>price_cents</b></td>
|
322
|
+
<td>read/write</td>
|
323
|
+
<td>Integer</td>
|
324
|
+
<td><b>Yes</b></td>
|
325
|
+
<td>-</td>
|
326
|
+
<td>The amount in cents to charge to the customer</td>
|
327
|
+
<tr>
|
328
|
+
|
329
|
+
<tr>
|
330
|
+
<td><b>description</b></td>
|
331
|
+
<td>read/write</td>
|
332
|
+
<td>String</td>
|
333
|
+
<td><b>Yes</b></td>
|
334
|
+
<td>-</td>
|
335
|
+
<td>A description of the product billed as it should appear on customer invoice</td>
|
336
|
+
<tr>
|
337
|
+
|
338
|
+
<tr>
|
339
|
+
<td><b>created_at</b></td>
|
340
|
+
<td>readonly</td>
|
341
|
+
<td>Time</td>
|
342
|
+
<td>-</td>
|
343
|
+
<td>-</td>
|
344
|
+
<td>When the the bill was created</td>
|
345
|
+
<tr>
|
346
|
+
|
347
|
+
<tr>
|
348
|
+
<td><b>status</b></td>
|
349
|
+
<td>readonly</td>
|
350
|
+
<td>String</td>
|
351
|
+
<td>-</td>
|
352
|
+
<td>-</td>
|
353
|
+
<td>Status of the bill. Either 'submitted', 'invoiced' or 'cancelled'.</td>
|
354
|
+
<tr>
|
355
|
+
|
356
|
+
<tr>
|
357
|
+
<td><b>currency</b></td>
|
358
|
+
<td>read/write</td>
|
359
|
+
<td>String</td>
|
360
|
+
<td>-</td>
|
361
|
+
<td>AUD</td>
|
362
|
+
<td>The currency of the amount charged in <a href="http://en.wikipedia.org/wiki/ISO_4217#Active_codes">ISO 4217 format</a> (3 letter code)</td>
|
363
|
+
<tr>
|
364
|
+
|
365
|
+
<tr>
|
366
|
+
<td><b>units</b></td>
|
367
|
+
<td>read/write</td>
|
368
|
+
<td>Decimal(10,2)</td>
|
369
|
+
<td>-</td>
|
370
|
+
<td>1.0</td>
|
371
|
+
<td>How many units are billed for the amount charged</td>
|
372
|
+
<tr>
|
373
|
+
|
374
|
+
<tr>
|
375
|
+
<td><b>period_started_at</b></td>
|
376
|
+
<td>read/write</td>
|
377
|
+
<td>Time</td>
|
378
|
+
<td>-</td>
|
379
|
+
<td>-</td>
|
380
|
+
<td>If the bill relates to a specific period then specifies when the period started. Both period_started_at and period_ended_at need to be filled in order to appear on customer invoice.</td>
|
381
|
+
<tr>
|
382
|
+
|
383
|
+
<tr>
|
384
|
+
<td><b>period_ended_at</b></td>
|
385
|
+
<td>read/write</td>
|
386
|
+
<td>Time</td>
|
387
|
+
<td>-</td>
|
388
|
+
<td>-</td>
|
389
|
+
<td>If the bill relates to a specific period then specifies when the period ended. Both period_started_at and period_ended_at need to be filled in order to appear on customer invoice.</td>
|
390
|
+
<tr>
|
391
|
+
|
392
|
+
</table>
|
393
|
+
|
394
|
+
##### Actions
|
395
|
+
|
396
|
+
List all bills you have created and iterate through the list
|
397
|
+
```ruby
|
398
|
+
bills = Maestrano::Account::Bill.all
|
399
|
+
bills.each { |b| puts b.id }
|
400
|
+
```
|
401
|
+
|
402
|
+
Access a single bill by id
|
403
|
+
```ruby
|
404
|
+
bill = Maestrano::Account::Bill.retrieve("bill-f1d2s54")
|
405
|
+
puts bill.group_id
|
406
|
+
```
|
407
|
+
|
408
|
+
Create a new bill
|
409
|
+
```ruby
|
410
|
+
bill = Maestrano::Account::Bill.create(group_id: "cld-3", price_cents: 2000, description: "Product purchase")
|
411
|
+
puts bill.id
|
412
|
+
```
|
413
|
+
|
414
|
+
Cancel a bill
|
415
|
+
```ruby
|
416
|
+
bill = Maestrano::Account::Bill.retrieve("bill-f1d2s54")
|
417
|
+
bill.cancel
|
418
|
+
```
|
419
|
+
|
420
|
+
#### Recurring Bill
|
421
|
+
A recurring bill charges a given customer at a regular interval without you having to do anything.
|
422
|
+
|
423
|
+
```ruby
|
424
|
+
Maestrano::Account::RecurringBill
|
425
|
+
```
|
426
|
+
|
427
|
+
##### Attributes
|
428
|
+
|
429
|
+
<table>
|
430
|
+
<tr>
|
431
|
+
<th>Field</th>
|
432
|
+
<th>Mode</th>
|
433
|
+
<th>Type</th>
|
434
|
+
<th>Required</th>
|
435
|
+
<th>Default</th>
|
436
|
+
<th>Description</th>
|
437
|
+
<tr>
|
438
|
+
|
439
|
+
<tr>
|
440
|
+
<td><b>id</b></td>
|
441
|
+
<td>readonly</td>
|
442
|
+
<td>string</td>
|
443
|
+
<td>-</td>
|
444
|
+
<td>-</td>
|
445
|
+
<td>The id of the recurring bill</td>
|
446
|
+
<tr>
|
447
|
+
|
448
|
+
<tr>
|
449
|
+
<td><b>group_id</b></td>
|
450
|
+
<td>read/write</td>
|
451
|
+
<td>string</td>
|
452
|
+
<td><b>Yes</b></td>
|
453
|
+
<td>-</td>
|
454
|
+
<td>The id of the group you are charging</td>
|
455
|
+
<tr>
|
456
|
+
|
457
|
+
<tr>
|
458
|
+
<td><b>price_cents</b></td>
|
459
|
+
<td>read/write</td>
|
460
|
+
<td>Integer</td>
|
461
|
+
<td><b>Yes</b></td>
|
462
|
+
<td>-</td>
|
463
|
+
<td>The amount in cents to charge to the customer</td>
|
464
|
+
<tr>
|
465
|
+
|
466
|
+
<tr>
|
467
|
+
<td><b>description</b></td>
|
468
|
+
<td>read/write</td>
|
469
|
+
<td>String</td>
|
470
|
+
<td><b>Yes</b></td>
|
471
|
+
<td>-</td>
|
472
|
+
<td>A description of the product billed as it should appear on customer invoice</td>
|
473
|
+
<tr>
|
474
|
+
|
475
|
+
<tr>
|
476
|
+
<td><b>period</b></td>
|
477
|
+
<td>read/write</td>
|
478
|
+
<td>String</td>
|
479
|
+
<td>-</td>
|
480
|
+
<td>Month</td>
|
481
|
+
<td>The unit of measure for the billing cycle. Must be one of the following: 'Day', 'Week', 'SemiMonth', 'Month', 'Year'</td>
|
482
|
+
<tr>
|
483
|
+
|
484
|
+
<tr>
|
485
|
+
<td><b>frequency</b></td>
|
486
|
+
<td>read/write</td>
|
487
|
+
<td>Integer</td>
|
488
|
+
<td>-</td>
|
489
|
+
<td>1</td>
|
490
|
+
<td>The number of billing periods that make up one billing cycle. The combination of billing frequency and billing period must be less than or equal to one year. If the billing period is SemiMonth, the billing frequency must be 1.</td>
|
491
|
+
<tr>
|
492
|
+
|
493
|
+
<tr>
|
494
|
+
<td><b>cycles</b></td>
|
495
|
+
<td>read/write</td>
|
496
|
+
<td>Integer</td>
|
497
|
+
<td>-</td>
|
498
|
+
<td>nil</td>
|
499
|
+
<td>The number of cycles this bill should be active for. In other words it's the number of times this recurring bill should charge the customer.</td>
|
500
|
+
<tr>
|
501
|
+
|
502
|
+
<tr>
|
503
|
+
<td><b>start_date</b></td>
|
504
|
+
<td>read/write</td>
|
505
|
+
<td>Time</td>
|
506
|
+
<td>-</td>
|
507
|
+
<td>Now</td>
|
508
|
+
<td>The date when this recurring bill should start billing the customer</td>
|
509
|
+
<tr>
|
510
|
+
|
511
|
+
<tr>
|
512
|
+
<td><b>created_at</b></td>
|
513
|
+
<td>readonly</td>
|
514
|
+
<td>Time</td>
|
515
|
+
<td>-</td>
|
516
|
+
<td>-</td>
|
517
|
+
<td>When the the bill was created</td>
|
518
|
+
<tr>
|
519
|
+
|
520
|
+
<tr>
|
521
|
+
<td><b>currency</b></td>
|
522
|
+
<td>read/write</td>
|
523
|
+
<td>String</td>
|
524
|
+
<td>-</td>
|
525
|
+
<td>AUD</td>
|
526
|
+
<td>The currency of the amount charged in <a href="http://en.wikipedia.org/wiki/ISO_4217#Active_codes">ISO 4217 format</a> (3 letter code)</td>
|
527
|
+
<tr>
|
528
|
+
|
529
|
+
<tr>
|
530
|
+
<td><b>status</b></td>
|
531
|
+
<td>readonly</td>
|
532
|
+
<td>String</td>
|
533
|
+
<td>-</td>
|
534
|
+
<td>-</td>
|
535
|
+
<td>Status of the recurring bill. Either 'pending', 'active', 'expired' or 'cancelled'.</td>
|
536
|
+
<tr>
|
537
|
+
|
538
|
+
</table>
|
539
|
+
|
540
|
+
##### Actions
|
541
|
+
|
542
|
+
List all recurring bills you have created and iterate through the list
|
543
|
+
```ruby
|
544
|
+
rec_bills = Maestrano::Account::RecurringBill.all
|
545
|
+
rec_bills.each { |b| puts b.id }
|
546
|
+
```
|
547
|
+
|
548
|
+
Access a single recurring bill by id
|
549
|
+
```ruby
|
550
|
+
rec_bill = Maestrano::Account::RecurringBill.retrieve("rbill-f1d2s54")
|
551
|
+
puts rec_bill.group_id
|
552
|
+
```
|
553
|
+
|
554
|
+
Create a new recurring bill
|
555
|
+
```ruby
|
556
|
+
rec_bill = Maestrano::Account::RecurringBill.create(group_id: "cld-3", price_cents: 2000, description: "Product purchase", period: 'Month', start_date: Time.now)
|
557
|
+
puts rec_bill.id
|
558
|
+
```
|
559
|
+
|
560
|
+
Cancel a recurring bill
|
561
|
+
```ruby
|
562
|
+
rec_bill = Maestrano::Account::RecurringBill.retrieve("rbill-f1d2s54")
|
563
|
+
rec_bill.cancel
|
564
|
+
```
|
565
|
+
|
566
|
+
|
567
|
+
## Support
|
568
|
+
This README is still in the process of being written and improved. As such it might not cover some of the questions you might have.
|
569
|
+
|
570
|
+
So if you have any question or need help integrating with us just let us know at support@maestrano.com
|
571
|
+
|
572
|
+
## License
|
573
|
+
|
574
|
+
MIT License. Copyright 2014 Maestrano Pty Ltd. https://maestrano.com
|
575
|
+
|
576
|
+
You are not granted rights or licenses to the trademarks of Maestrano.
|
data/lib/maestrano.rb
CHANGED
@@ -58,6 +58,7 @@ module Maestrano
|
|
58
58
|
def self.configure
|
59
59
|
self.config ||= Configuration.new
|
60
60
|
yield(config)
|
61
|
+
self.config.api_token = "#{self.config.app_id}:#{self.config.api_key}"
|
61
62
|
end
|
62
63
|
|
63
64
|
# Get configuration parameter value
|
@@ -69,12 +70,13 @@ module Maestrano
|
|
69
70
|
end
|
70
71
|
|
71
72
|
class Configuration
|
72
|
-
attr_accessor :environment, :api_key, :sso_enabled,
|
73
|
+
attr_accessor :environment, :app_id, :api_key, :sso_enabled,
|
73
74
|
:app_host, :sso_app_init_path, :sso_app_consume_path, :user_creation_mode,
|
74
|
-
:verify_ssl_certs, :api_version
|
75
|
+
:verify_ssl_certs, :api_version, :api_token
|
75
76
|
|
76
77
|
def initialize
|
77
78
|
@environment = 'test'
|
79
|
+
@app_id = nil
|
78
80
|
@api_key = nil
|
79
81
|
@sso_enabled = true
|
80
82
|
@app_host = 'http://localhost:3000'
|
@@ -5,8 +5,8 @@ module Maestrano
|
|
5
5
|
include Maestrano::API::Operation::Create
|
6
6
|
|
7
7
|
def cancel
|
8
|
-
response,
|
9
|
-
refresh_from(response,
|
8
|
+
response, api_token = Maestrano::API::Operation::Base.request(:delete, url, @api_token)
|
9
|
+
refresh_from(response, api_token)
|
10
10
|
self
|
11
11
|
end
|
12
12
|
end
|
@@ -5,8 +5,8 @@ module Maestrano
|
|
5
5
|
include Maestrano::API::Operation::Create
|
6
6
|
|
7
7
|
def cancel
|
8
|
-
response,
|
9
|
-
refresh_from(response,
|
8
|
+
response, api_token = Maestrano::API::Operation::Base.request(:delete, url, @api_token)
|
9
|
+
refresh_from(response, api_token)
|
10
10
|
self
|
11
11
|
end
|
12
12
|
end
|
@@ -15,22 +15,22 @@ module Maestrano
|
|
15
15
|
self.data.each(&blk)
|
16
16
|
end
|
17
17
|
|
18
|
-
def retrieve(id,
|
19
|
-
|
20
|
-
response,
|
21
|
-
Util.convert_to_maestrano_object(response,
|
18
|
+
def retrieve(id, api_token=nil)
|
19
|
+
api_token ||= @api_token
|
20
|
+
response, api_token = Maestrano::API::Operation::Base.request(:get,"#{url}/#{CGI.escape(id)}", api_token)
|
21
|
+
Util.convert_to_maestrano_object(response, api_token)
|
22
22
|
end
|
23
23
|
|
24
|
-
def create(params={},
|
25
|
-
|
26
|
-
response,
|
27
|
-
Util.convert_to_maestrano_object(response,
|
24
|
+
def create(params={}, api_token=nil)
|
25
|
+
api_token ||= @api_token
|
26
|
+
response, api_token = Maestrano::API::Operation::Base.request(:post, url, api_token, params)
|
27
|
+
Util.convert_to_maestrano_object(response, api_token)
|
28
28
|
end
|
29
29
|
|
30
|
-
def all(params={},
|
31
|
-
|
32
|
-
response,
|
33
|
-
Util.convert_to_maestrano_object(response,
|
30
|
+
def all(params={}, api_token=nil)
|
31
|
+
api_token ||= @api_token
|
32
|
+
response, api_token = Maestrano::API::Operation::Base.request(:get, url, api_token, params)
|
33
|
+
Util.convert_to_maestrano_object(response, api_token)
|
34
34
|
end
|
35
35
|
end
|
36
36
|
end
|
data/lib/maestrano/api/object.rb
CHANGED
@@ -3,15 +3,15 @@ module Maestrano
|
|
3
3
|
class Object
|
4
4
|
include Enumerable
|
5
5
|
|
6
|
-
attr_accessor :
|
7
|
-
@@permanent_attributes = Set.new([:
|
6
|
+
attr_accessor :api_token
|
7
|
+
@@permanent_attributes = Set.new([:api_token, :id])
|
8
8
|
|
9
9
|
# The default :id method is deprecated and isn't useful to us
|
10
10
|
if method_defined?(:id)
|
11
11
|
undef :id
|
12
12
|
end
|
13
13
|
|
14
|
-
def initialize(id=nil,
|
14
|
+
def initialize(id=nil, api_token=nil)
|
15
15
|
# parameter overloading!
|
16
16
|
if id.kind_of?(Hash)
|
17
17
|
@retrieve_options = id.dup
|
@@ -21,7 +21,7 @@ module Maestrano
|
|
21
21
|
@retrieve_options = {}
|
22
22
|
end
|
23
23
|
|
24
|
-
@
|
24
|
+
@api_token = api_token
|
25
25
|
@values = {}
|
26
26
|
# This really belongs in API::Resource, but not putting it there allows us
|
27
27
|
# to have a unified inspect method
|
@@ -30,9 +30,9 @@ module Maestrano
|
|
30
30
|
@values[:id] = id if id
|
31
31
|
end
|
32
32
|
|
33
|
-
def self.construct_from(values,
|
34
|
-
obj = self.new(values[:id],
|
35
|
-
obj.refresh_from(values,
|
33
|
+
def self.construct_from(values, api_token=nil)
|
34
|
+
obj = self.new(values[:id], api_token)
|
35
|
+
obj.refresh_from(values, api_token)
|
36
36
|
obj
|
37
37
|
end
|
38
38
|
|
@@ -45,8 +45,8 @@ module Maestrano
|
|
45
45
|
"#<#{self.class}:0x#{self.object_id.to_s(16)}#{id_string}> JSON: " + JSON.pretty_generate(@values)
|
46
46
|
end
|
47
47
|
|
48
|
-
def refresh_from(values,
|
49
|
-
@
|
48
|
+
def refresh_from(values, api_token, partial=false)
|
49
|
+
@api_token = api_token
|
50
50
|
|
51
51
|
@previous_metadata = values[:metadata]
|
52
52
|
removed = partial ? Set.new : Set.new(@values.keys - values.keys)
|
@@ -63,7 +63,7 @@ module Maestrano
|
|
63
63
|
@unsaved_values.delete(k)
|
64
64
|
end
|
65
65
|
values.each do |k, v|
|
66
|
-
@values[k] = Util.convert_to_maestrano_object(v,
|
66
|
+
@values[k] = Util.convert_to_maestrano_object(v, api_token)
|
67
67
|
@transient_values.delete(k)
|
68
68
|
@unsaved_values.delete(k)
|
69
69
|
end
|
@@ -102,12 +102,12 @@ module Maestrano
|
|
102
102
|
end
|
103
103
|
|
104
104
|
def _dump(level)
|
105
|
-
Marshal.dump([@values, @
|
105
|
+
Marshal.dump([@values, @api_token])
|
106
106
|
end
|
107
107
|
|
108
108
|
def self._load(args)
|
109
|
-
values,
|
110
|
-
construct_from(values,
|
109
|
+
values, api_token = Marshal.load(args)
|
110
|
+
construct_from(values, api_token)
|
111
111
|
end
|
112
112
|
|
113
113
|
if RUBY_VERSION < '1.9.2'
|
@@ -3,7 +3,7 @@ module Maestrano
|
|
3
3
|
module Operation
|
4
4
|
module Base
|
5
5
|
# class << self
|
6
|
-
# attr_accessor :
|
6
|
+
# attr_accessor :api_token, :api_base, :verify_ssl_certs, :api_version
|
7
7
|
# end
|
8
8
|
|
9
9
|
def self.api_url(url='')
|
@@ -11,8 +11,8 @@ module Maestrano
|
|
11
11
|
end
|
12
12
|
|
13
13
|
# Perform remote request
|
14
|
-
def self.request(method, url,
|
15
|
-
unless
|
14
|
+
def self.request(method, url, api_token, params={}, headers={})
|
15
|
+
unless api_token ||= Maestrano.param('api_token')
|
16
16
|
raise Maestrano::API::Error::AuthenticationError.new('No API key provided.')
|
17
17
|
end
|
18
18
|
|
@@ -37,7 +37,7 @@ module Maestrano
|
|
37
37
|
payload = uri_encode(params)
|
38
38
|
end
|
39
39
|
|
40
|
-
request_opts.update(:headers => request_headers(
|
40
|
+
request_opts.update(:headers => request_headers(api_token).update(headers),
|
41
41
|
:method => method, :open_timeout => 30,
|
42
42
|
:payload => payload, :url => url, :timeout => 80)
|
43
43
|
|
@@ -63,7 +63,7 @@ module Maestrano
|
|
63
63
|
handle_restclient_error(e)
|
64
64
|
end
|
65
65
|
|
66
|
-
[parse(response),
|
66
|
+
[parse(response), api_token]
|
67
67
|
end
|
68
68
|
|
69
69
|
private
|
@@ -109,10 +109,10 @@ module Maestrano
|
|
109
109
|
map { |k,v| "#{k}=#{Util.url_encode(v)}" }.join('&')
|
110
110
|
end
|
111
111
|
|
112
|
-
def self.request_headers(
|
112
|
+
def self.request_headers(api_token)
|
113
113
|
headers = {
|
114
114
|
:user_agent => "Maestrano/v1 RubyBindings/#{Maestrano::VERSION}",
|
115
|
-
:authorization => "Basic #{Base64.encode64(
|
115
|
+
:authorization => "Basic #{Base64.encode64(api_token)}",
|
116
116
|
:content_type => 'application/x-www-form-urlencoded'
|
117
117
|
}
|
118
118
|
|
@@ -3,9 +3,9 @@ module Maestrano
|
|
3
3
|
module Operation
|
4
4
|
module Create
|
5
5
|
module ClassMethods
|
6
|
-
def create(params={},
|
7
|
-
response,
|
8
|
-
Util.convert_to_maestrano_object(response,
|
6
|
+
def create(params={}, api_token=nil)
|
7
|
+
response, api_token = Maestrano::API::Operation::Base.request(:post, self.url, api_token, params)
|
8
|
+
Util.convert_to_maestrano_object(response, api_token)
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
@@ -3,8 +3,8 @@ module Maestrano
|
|
3
3
|
module Operation
|
4
4
|
module Delete
|
5
5
|
def delete(params = {})
|
6
|
-
response,
|
7
|
-
refresh_from(response,
|
6
|
+
response, api_token = Maestrano::API::Operation::Base.request(:delete, url, @api_token, params)
|
7
|
+
refresh_from(response, api_token)
|
8
8
|
self
|
9
9
|
end
|
10
10
|
end
|
@@ -3,9 +3,9 @@ module Maestrano
|
|
3
3
|
module Operation
|
4
4
|
module List
|
5
5
|
module ClassMethods
|
6
|
-
def all(filters={},
|
7
|
-
response,
|
8
|
-
Util.convert_to_maestrano_object(response,
|
6
|
+
def all(filters={}, api_token=nil)
|
7
|
+
response, api_token = Maestrano::API::Operation::Base.request(:get, url, api_token, filters)
|
8
|
+
Util.convert_to_maestrano_object(response, api_token)
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
@@ -12,8 +12,8 @@ module Maestrano
|
|
12
12
|
if values.length > 0
|
13
13
|
values.delete(:id)
|
14
14
|
|
15
|
-
response,
|
16
|
-
refresh_from(response,
|
15
|
+
response, api_token = Maestrano::API::Operation::Base.request(:put, url, @api_token, values)
|
16
|
+
refresh_from(response, api_token)
|
17
17
|
end
|
18
18
|
self
|
19
19
|
end
|
@@ -24,13 +24,13 @@ module Maestrano
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def refresh
|
27
|
-
response,
|
28
|
-
refresh_from(response,
|
27
|
+
response, api_token = Maestrano::API::Operation::Base.request(:get, url, @api_token, @retrieve_options)
|
28
|
+
refresh_from(response, api_token)
|
29
29
|
self
|
30
30
|
end
|
31
31
|
|
32
|
-
def self.retrieve(id,
|
33
|
-
instance = self.new(id,
|
32
|
+
def self.retrieve(id, api_token=nil)
|
33
|
+
instance = self.new(id, api_token)
|
34
34
|
instance.refresh
|
35
35
|
instance
|
36
36
|
end
|
data/lib/maestrano/api/util.rb
CHANGED
@@ -26,7 +26,7 @@ module Maestrano
|
|
26
26
|
}
|
27
27
|
end
|
28
28
|
|
29
|
-
def self.convert_to_maestrano_object(resp,
|
29
|
+
def self.convert_to_maestrano_object(resp, api_token)
|
30
30
|
case resp
|
31
31
|
when Array
|
32
32
|
if resp.empty? || !resp.first[:object]
|
@@ -35,17 +35,17 @@ module Maestrano
|
|
35
35
|
list = convert_to_maestrano_object({
|
36
36
|
object: 'internal_list_object',
|
37
37
|
data:[],
|
38
|
-
url: convert_to_maestrano_object(resp.first,
|
39
|
-
},
|
38
|
+
url: convert_to_maestrano_object(resp.first, api_token).class.url
|
39
|
+
},api_token)
|
40
40
|
|
41
41
|
resp.each do |i|
|
42
|
-
list.data.push(convert_to_maestrano_object(i,
|
42
|
+
list.data.push(convert_to_maestrano_object(i, api_token))
|
43
43
|
end
|
44
44
|
list
|
45
45
|
end
|
46
46
|
when Hash
|
47
47
|
# Try converting to a known object class. If none available, fall back to generic Maestrano::API::Object
|
48
|
-
object_classes.fetch(resp[:object], Maestrano::API::Object).construct_from(resp,
|
48
|
+
object_classes.fetch(resp[:object], Maestrano::API::Object).construct_from(resp, api_token)
|
49
49
|
else
|
50
50
|
# Automatically parse iso8601 dates
|
51
51
|
if resp =~ /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/
|
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('app_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')
|
data/lib/maestrano/version.rb
CHANGED
data/test/helpers/api_helpers.rb
CHANGED
@@ -30,8 +30,8 @@ module Maestrano
|
|
30
30
|
|
31
31
|
|
32
32
|
should "should successfully create a remote bill when passed correct parameters" do
|
33
|
-
@api_mock.expects(:post).with do |url,
|
34
|
-
url == "#{Maestrano.param('api_host')}#{Maestrano.param('api_base')}account/bills" &&
|
33
|
+
@api_mock.expects(:post).with do |url, api_token, params|
|
34
|
+
url == "#{Maestrano.param('api_host')}#{Maestrano.param('api_base')}account/bills" && api_token.nil? &&
|
35
35
|
CGI.parse(params) == {"group_id"=>["cld-1"], "price_cents"=>["23000"], "currency"=>["AUD"], "description"=>["Some bill"]}
|
36
36
|
end.once.returns(test_response(test_account_bill))
|
37
37
|
|
@@ -30,8 +30,8 @@ module Maestrano
|
|
30
30
|
|
31
31
|
|
32
32
|
should "successfully create a remote bill when passed correct parameters" do
|
33
|
-
@api_mock.expects(:post).with do |url,
|
34
|
-
url == "#{Maestrano.param('api_host')}#{Maestrano.param('api_base')}account/recurring_bills" &&
|
33
|
+
@api_mock.expects(:post).with do |url, api_token, params|
|
34
|
+
url == "#{Maestrano.param('api_host')}#{Maestrano.param('api_base')}account/recurring_bills" && api_token.nil? &&
|
35
35
|
CGI.parse(params) == {"group_id"=>["cld-1"], "price_cents"=>["23000"], "currency"=>["AUD"], "description"=>["Some recurring bill"], "period"=>["Month"]}
|
36
36
|
end.once.returns(test_response(test_account_recurring_bill))
|
37
37
|
|
@@ -35,7 +35,7 @@ module Maestrano
|
|
35
35
|
end
|
36
36
|
|
37
37
|
should "specifying invalid api credentials should raise an exception" do
|
38
|
-
response = test_response(
|
38
|
+
response = test_response(test_invalid_api_token_error, 401)
|
39
39
|
assert_raises Maestrano::API::Error::AuthenticationError do
|
40
40
|
@api_mock.expects(:get).once.raises(RestClient::ExceptionWithResponse.new(response, 401))
|
41
41
|
Maestrano::Account::Bill.retrieve("failing_bill")
|
@@ -43,7 +43,7 @@ module Maestrano
|
|
43
43
|
end
|
44
44
|
|
45
45
|
should "AuthenticationErrors should have an http status, http body, and JSON body" do
|
46
|
-
response = test_response(
|
46
|
+
response = test_response(test_invalid_api_token_error, 401)
|
47
47
|
begin
|
48
48
|
@api_mock.expects(:get).once.raises(RestClient::ExceptionWithResponse.new(response, 401))
|
49
49
|
Maestrano::Account::Bill.retrieve("failing_bill")
|
@@ -51,7 +51,7 @@ module Maestrano
|
|
51
51
|
assert_equal(401, e.http_status)
|
52
52
|
assert_equal(true, !!e.http_body)
|
53
53
|
assert_equal(true, !!e.json_body[:errors])
|
54
|
-
assert_equal(
|
54
|
+
assert_equal(test_invalid_api_token_error['errors'].first.join(" "), e.json_body[:errors].first.join(" "))
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
@@ -68,7 +68,7 @@ module Maestrano
|
|
68
68
|
|
69
69
|
should "use the per-object credential when creating" do
|
70
70
|
Maestrano::API::Operation::Base.expects(:execute_request).with do |opts|
|
71
|
-
opts[:headers][:authorization] == "Basic #{Base64.encode64('
|
71
|
+
opts[:headers][:authorization] == "Basic #{Base64.encode64('someid:somekey')}"
|
72
72
|
end.returns(test_response(test_account_bill))
|
73
73
|
|
74
74
|
Maestrano::Account::Bill.create({
|
@@ -77,7 +77,7 @@ module Maestrano
|
|
77
77
|
currency: 'AUD',
|
78
78
|
description: 'Some bill'
|
79
79
|
},
|
80
|
-
'
|
80
|
+
'someid:somekey'
|
81
81
|
)
|
82
82
|
end
|
83
83
|
end
|
@@ -85,7 +85,7 @@ module Maestrano
|
|
85
85
|
context "with a global API key set" do
|
86
86
|
should "use the per-object credential when creating" do
|
87
87
|
Maestrano::API::Operation::Base.expects(:execute_request).with do |opts|
|
88
|
-
opts[:headers][:authorization] == "Basic #{Base64.encode64('
|
88
|
+
opts[:headers][:authorization] == "Basic #{Base64.encode64('someid:somekey')}"
|
89
89
|
end.returns(test_response(test_account_bill))
|
90
90
|
|
91
91
|
Maestrano::Account::Bill.create({
|
@@ -94,7 +94,7 @@ module Maestrano
|
|
94
94
|
currency: 'AUD',
|
95
95
|
description: 'Some bill'
|
96
96
|
},
|
97
|
-
'
|
97
|
+
'someid:somekey'
|
98
98
|
)
|
99
99
|
end
|
100
100
|
end
|
@@ -159,7 +159,7 @@ module Maestrano
|
|
159
159
|
end
|
160
160
|
|
161
161
|
should "setting a nil value for a param should exclude that param from the GET request" do
|
162
|
-
@api_mock.expects(:get).with do |url,
|
162
|
+
@api_mock.expects(:get).with do |url, api_token, params|
|
163
163
|
uri = URI(url)
|
164
164
|
query = CGI.parse(uri.query)
|
165
165
|
(url =~ %r{^#{Maestrano.param('api_host')}#{Maestrano.param('api_base')}account/bills?} &&
|
@@ -169,9 +169,9 @@ module Maestrano
|
|
169
169
|
end
|
170
170
|
|
171
171
|
should "setting a nil value for a param should exclude that param from the POST request" do
|
172
|
-
@api_mock.expects(:post).with do |url,
|
172
|
+
@api_mock.expects(:post).with do |url, api_token, params|
|
173
173
|
url == "#{Maestrano.param('api_host')}#{Maestrano.param('api_base')}account/bills" &&
|
174
|
-
|
174
|
+
api_token.nil? &&
|
175
175
|
CGI.parse(params) == { 'group_id' => ['cld-1'], 'price_cents' => ['23000'], 'currency' => ['AUD'] }
|
176
176
|
end.returns(test_response(test_account_bill))
|
177
177
|
Maestrano::Account::Bill.create({
|
@@ -241,9 +241,9 @@ module Maestrano
|
|
241
241
|
# end
|
242
242
|
|
243
243
|
should "updating an object should issue a PUT request with only the changed properties" do
|
244
|
-
@api_mock.expects(:put).with do |url,
|
244
|
+
@api_mock.expects(:put).with do |url, api_token, params|
|
245
245
|
url == "#{Maestrano.param('api_host')}#{Maestrano.param('api_base')}account/bills/bill-1" &&
|
246
|
-
|
246
|
+
api_token.nil? && CGI.parse(params) == {'description' => ['another_mn']}
|
247
247
|
end.once.returns(test_response(test_account_bill))
|
248
248
|
|
249
249
|
c = Maestrano::Account::Bill.construct_from(test_account_bill[:data])
|
@@ -45,5 +45,10 @@ class MaestranoTest < Test::Unit::TestCase
|
|
45
45
|
assert Maestrano.param(parameter) == Maestrano::Configuration::EVT_CONFIG[:production][parameter.to_sym]
|
46
46
|
end
|
47
47
|
end
|
48
|
+
|
49
|
+
should "build the api_token based on the app_id and api_key" do
|
50
|
+
Maestrano.configure { |config| config.app_id = "bla"; config.api_key = "blo" }
|
51
|
+
assert_equal "bla:blo", Maestrano.param(:api_token)
|
52
|
+
end
|
48
53
|
end
|
49
54
|
end
|
data/test/maestrano/sso_test.rb
CHANGED
@@ -40,7 +40,7 @@ module Maestrano
|
|
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('app_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')
|
data/test/test_helper.rb
CHANGED
@@ -38,6 +38,7 @@ class Test::Unit::TestCase
|
|
38
38
|
@api_mock = mock('api_mock')
|
39
39
|
Maestrano::API::Operation::Base.mock_rest_client = @api_mock
|
40
40
|
Maestrano.configure do |config|
|
41
|
+
config.app_id = "app-1"
|
41
42
|
config.api_key = "g15354F34f3x5z"
|
42
43
|
config.environment = 'production'
|
43
44
|
end
|
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.4.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-05-31 00:00:00 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rest-client
|