mxhero-api 1.1.3 → 1.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +14 -0
- data/VERSION +1 -1
- data/lib/communication.rb +1 -0
- data/lib/email-sync.rb +78 -0
- data/lib/mxhero-api.rb +621 -617
- data/lib/response.rb +1 -0
- data/mxhero-api.gemspec +5 -5
- data/test/fixtures/api/emailsync_delete.yml +32 -0
- data/test/fixtures/api/emailsync_fetch_all.yml +34 -0
- data/test/fixtures/api/emailsync_task_by_id.yml +34 -0
- data/test/helper.rb +1 -1
- data/test/test_emailsync.rb +169 -0
- metadata +11 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 535eca4642e82189a54e53e6c6cf5fd33d9f5a95
|
4
|
+
data.tar.gz: 98e5d823eac1440b0770e14f098dc4837de59c7d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 969b79fbd3b9f95d86646be9b97f7d85d248cb9b1ee97237a6480458e3a98e1b6c3783a92d45d9da9d0344924b5dfdc2c12a0d31accbb08386acd60a819ab3b7
|
7
|
+
data.tar.gz: c3042de5c0ba0e3ccb34ae2edf360198dc86e47d86842a4dfda182c67aaea9ae0b16c703ac956373f244e0787a337a5226fa0169aa5ee5c421e1483f009ce54c
|
data/README.md
CHANGED
@@ -82,6 +82,20 @@ Some examples, **complete documentation in the [API client documentation](http:/
|
|
82
82
|
|
83
83
|
Complete documentation in the [API client documentation](http://www.rubydoc.info/gems/mxhero-api/MxHero/API/Client.html)
|
84
84
|
|
85
|
+
## Run test
|
86
|
+
|
87
|
+
Run all test
|
88
|
+
|
89
|
+
rake test
|
90
|
+
|
91
|
+
Run specific method
|
92
|
+
|
93
|
+
ruby test/test_emailsync.rb --name=test_delete -v
|
94
|
+
|
95
|
+
Or:
|
96
|
+
|
97
|
+
rake test TEST=test/test_foobar.rb TESTOPTS="--name=test_foobar1 -v"
|
98
|
+
|
85
99
|
## Build a new version
|
86
100
|
|
87
101
|
rake version:bump
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.1.
|
1
|
+
1.1.4
|
data/lib/communication.rb
CHANGED
@@ -12,6 +12,7 @@ module MxHero
|
|
12
12
|
# @param body [String] (default: nil)
|
13
13
|
# @param [Hash] more_options
|
14
14
|
# @option more_options [Boolean] :throw_exception (default: true) throw exception if the response status are between 500 and 600
|
15
|
+
# @return [HTTP::Message](http://www.rubydoc.info/gems/httpclient/HTTP/Message)
|
15
16
|
def call(method, url, body = nil, more_options = {})
|
16
17
|
unless @client
|
17
18
|
@client ||= HTTPClient.new
|
data/lib/email-sync.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require_relative 'communication'
|
3
|
+
require_relative 'urls'
|
4
|
+
#require_relative 'response'
|
5
|
+
|
6
|
+
module MxHero::API
|
7
|
+
|
8
|
+
class EmailSync
|
9
|
+
|
10
|
+
include Communication
|
11
|
+
include Urls
|
12
|
+
|
13
|
+
#attr_reader :domain
|
14
|
+
|
15
|
+
def initialize(config = {})
|
16
|
+
@service_url = config[:api_url]
|
17
|
+
@username = config[:username]
|
18
|
+
@password = config[:password]
|
19
|
+
@verbose = config[:verbose] || false
|
20
|
+
end
|
21
|
+
|
22
|
+
def all(domain, params = {})
|
23
|
+
wrap_response_from call(:get, url(domain, params))
|
24
|
+
end
|
25
|
+
|
26
|
+
def task_by_id(domain, id)
|
27
|
+
return if id.nil? || id.empty?
|
28
|
+
wrap_response_from call(:get, "#{url(domain)}#{id}")
|
29
|
+
end
|
30
|
+
|
31
|
+
def delete(domain, id)
|
32
|
+
return if id.nil? || id.empty?
|
33
|
+
wrap_response_from call(:delete, "#{url(domain)}#{id}")
|
34
|
+
end
|
35
|
+
|
36
|
+
# Make a request in the endpoin /emailsync/#{domain}
|
37
|
+
# @param method [Symbol] indicate the HTTP verb (:get, :post, :put, etc)
|
38
|
+
# @param path [String] the path after the base URL (base url: #{api_url}/emailsync/#{domain})
|
39
|
+
# @param [Hash] more
|
40
|
+
# @option more [Hash] :params the URL parameters to add in the URL (ex. {limit: 10} => ?limit=10)
|
41
|
+
# @option more [Hash] :body the body content to send in POST or PUT
|
42
|
+
#
|
43
|
+
# @return [HTTP::Message](http://www.rubydoc.info/gems/httpclient/HTTP/Message)
|
44
|
+
# Useful methods: status, content
|
45
|
+
def request(domain, method, path = '/', more = {})
|
46
|
+
url = "#{@service_url}/emailsync/#{domain}#{path}#{parse_params(more[:params])}"
|
47
|
+
call(method, url, more[:body])
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def url(domain, params = {})
|
53
|
+
"#{@service_url}/emailsync/#{domain}/#{parse_params(params)}"
|
54
|
+
end
|
55
|
+
|
56
|
+
def parse_params(params = {})
|
57
|
+
return if blank?(params)
|
58
|
+
'?' << params.map do |key, value|
|
59
|
+
"#{URI::encode(key.to_s)}=#{URI::encode(value.to_s)}"
|
60
|
+
end.join('&')
|
61
|
+
end
|
62
|
+
|
63
|
+
def wrap_response_from(response)
|
64
|
+
Response.new(response.status, json_parse(default_content(response.content)))
|
65
|
+
end
|
66
|
+
|
67
|
+
def blank?(value)
|
68
|
+
value.nil? || value.empty?
|
69
|
+
end
|
70
|
+
|
71
|
+
def default_content(content)
|
72
|
+
blank?(content) ? '{}' : content
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
data/lib/mxhero-api.rb
CHANGED
@@ -4,505 +4,508 @@
|
|
4
4
|
require 'date'
|
5
5
|
require 'cgi'
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
7
|
+
require_relative 'response'
|
8
|
+
require_relative 'communication'
|
9
|
+
require_relative 'urls'
|
10
|
+
require_relative 'groups'
|
11
|
+
require_relative 'dto'
|
12
|
+
require_relative 'directories'
|
13
|
+
require_relative 'pst-converter'
|
14
|
+
require_relative 'resource'
|
15
|
+
require_relative 'resources/account'
|
16
|
+
require_relative 'resources/domain'
|
17
|
+
require_relative 'resources/group'
|
18
|
+
require_relative 'email-sync'
|
19
|
+
|
17
20
|
|
18
21
|
module MxHero::API
|
19
22
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
23
|
+
# A client to interact with mxhero engine API
|
24
|
+
class Client
|
25
|
+
include Communication
|
26
|
+
include Urls
|
27
|
+
|
28
|
+
# @param [Hash] config the options of configuration
|
29
|
+
# @option config [String] :api_url The URL to consume the API
|
30
|
+
# @option config [String] :username The username for access the API
|
31
|
+
# @option config [String] :password The password for the user that access the API
|
32
|
+
# @option config [Boolean] :verbose (false) If true puts information about http operations
|
33
|
+
def initialize(config = {})
|
34
|
+
@service_url = config[:api_url]
|
35
|
+
@username = config[:username]
|
36
|
+
@password = config[:password]
|
37
|
+
@verbose = config[:verbose] || false
|
38
|
+
end
|
39
|
+
|
40
|
+
# Expose directories api
|
41
|
+
#
|
42
|
+
# @return MxHero::API::Directories
|
43
|
+
def directories(domain)
|
44
|
+
@directories ||= Directories.new(domain, api_url: @service_url,
|
45
|
+
username: @username, password: @password, verbose: @verbose)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Find a rule by domain and ID
|
49
|
+
#
|
50
|
+
# @param domain [String]
|
51
|
+
# @param id [Integer] the rule id
|
52
|
+
#
|
53
|
+
# @return [Hash, nil] the Rule information or nil if not exist
|
54
|
+
#
|
55
|
+
# @raise an exception when the status code isn't 200
|
56
|
+
def domain_rule(domain, id)
|
57
|
+
url = domain_rule_url(domain, id)
|
58
|
+
response = call(:get, url)
|
59
|
+
raise 'an error ocurred when try to communicate with the API' if response.status != 200
|
60
|
+
json_parse(response.content)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Update a rule
|
64
|
+
# @return [MxHero::API::Response] When the rule is update correctly then return MxHero::API::Response object without msg (msg nil)
|
65
|
+
# In case of error, the message is completed with the cause of error
|
66
|
+
def update_rule(rule)
|
67
|
+
url = domain_rule_url(rule[:domain], rule[:id])
|
68
|
+
response = call(:put, url, rule.to_json)
|
69
|
+
parse_response(response)
|
70
|
+
end
|
71
|
+
|
72
|
+
# In case of error, the message is completed with the cause of error
|
73
|
+
def rule_status(domain, rule_id, enabled = true)
|
74
|
+
url = domain_rule_url(domain, rule_id)+"/status?enabled=#{enabled}"
|
75
|
+
response = call(:put, url)
|
76
|
+
parse_response(response)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Retrive all the domains
|
80
|
+
#
|
81
|
+
# TODO: Improve the response. We really need manage pagination here?
|
82
|
+
#
|
83
|
+
# @return [Hash] with the list of domains
|
84
|
+
# * :elements [Array<Hash>] the list of domains as a Hash, when any element contains:
|
85
|
+
# * :domain [String]
|
86
|
+
# * :server [String]
|
87
|
+
# * :creationDate [Fixnum]
|
88
|
+
# * :updateDate [Fixnum]
|
89
|
+
# * :aliases
|
90
|
+
# * :ldap
|
91
|
+
# * :totalElements
|
92
|
+
# * :totalPages
|
93
|
+
# * :actualPage
|
94
|
+
#
|
95
|
+
# @raise an exception when the status code isn't 200
|
96
|
+
def domains(params = {})
|
97
|
+
url = domains_url
|
98
|
+
limit, offset = params.values_at(:limit, :offset)
|
99
|
+
url = paginate(domains_url, { limit: limit, offset: offset }) if limit && offset
|
100
|
+
response = call(:get, url)
|
101
|
+
raise 'an error ocurred when try to communicate with the API' if response.status != 200
|
102
|
+
response_as_a_hash = json_parse(response.content)
|
103
|
+
response_as_a_hash
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
# Move COS to trial
|
108
|
+
# @return true | false
|
109
|
+
def move_to_trial(domain)
|
110
|
+
url = domain_by_id_url(domain) + '/cos/trial'
|
111
|
+
response = call(:put, url)
|
112
|
+
response.status == 200
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
# Create a new domain base on domain_obj hash
|
117
|
+
#
|
118
|
+
# @param domain_obj The domain to be created. For example:
|
119
|
+
# [Hash] with detailed domain
|
120
|
+
# * :domain [String]
|
121
|
+
# * :server [String]
|
122
|
+
# * :inbound [Boolean]
|
123
|
+
# * :outbound [Boolean]
|
124
|
+
# * :features [Array<Hash>]
|
125
|
+
# * :cos [Hash]
|
126
|
+
# * :source [String] (gapps|on_premise|ms_agent|office365)
|
127
|
+
# * :aliases [Array<String>]
|
128
|
+
# * :ldap [Hash]
|
129
|
+
#
|
130
|
+
# @return [Boolean] true if was successfully created
|
131
|
+
#
|
132
|
+
def create_domain(domain_obj = {})
|
133
|
+
response = call(:post, domains_url, domain_obj.to_json, throw_exception: false)
|
134
|
+
response.status == 201
|
135
|
+
end
|
136
|
+
|
137
|
+
# Create a new domain base on domain_obj hash
|
138
|
+
#
|
139
|
+
# @param domain_obj The domain to be created. For example:
|
140
|
+
# [Hash] with detailed domain
|
141
|
+
# * :domain [String]
|
142
|
+
# * :server [String]
|
143
|
+
# * :inbound [Boolean]
|
144
|
+
# * :outbound [Boolean]
|
145
|
+
# * :features [Array<Hash>]
|
146
|
+
# * :cos [Hash]
|
147
|
+
# * :source [String] (gapps|on_premise|ms_agent|office365)
|
148
|
+
# * :aliases [Array<String>]
|
149
|
+
# * :ldap [Hash]
|
150
|
+
#
|
151
|
+
# @return [Boolean] true if was successfully created
|
152
|
+
#
|
153
|
+
def add_feature(domain_name, feature_component)
|
154
|
+
feature = {
|
155
|
+
feature: feature_component,
|
156
|
+
maxRulesAmount: 1
|
157
|
+
}
|
158
|
+
response = call(:post, features_url(domain_name), feature.to_json, throw_exception: false)
|
159
|
+
response.status == 200
|
160
|
+
end
|
161
|
+
|
162
|
+
# Retrive the domain information
|
163
|
+
#
|
164
|
+
# @param name The domain name or id. For example: 'mydomain.com'
|
165
|
+
# @return [Domain] or nil if not found
|
166
|
+
#
|
167
|
+
# @raise an exception when the status code is not 200 (ok) or 404 (not found)
|
168
|
+
#
|
169
|
+
def domain(name)
|
170
|
+
domain_info = fetch domain_by_id_url(name), on_error: "An error ocurred when try to fetch the domain #{name}."
|
171
|
+
return nil unless domain_info
|
172
|
+
Domain.new domain_info
|
173
|
+
end
|
174
|
+
|
175
|
+
#def update_cos(domain, cos)
|
176
|
+
# domain_by_id_url(name) + "cos/#{cos}"
|
177
|
+
# response = call(:post, url, msg.to_json, throw_exception: false)
|
178
|
+
#end
|
179
|
+
|
180
|
+
|
181
|
+
# Fetch the LDAP information of the domain
|
182
|
+
#
|
183
|
+
# @return [Hash] with
|
184
|
+
# * :domain
|
185
|
+
# * :directoryType
|
186
|
+
# * :addres
|
187
|
+
# * :port
|
188
|
+
# * :sslFlag [Boolean]
|
189
|
+
# * :user
|
190
|
+
# * :password
|
191
|
+
# * :filter
|
192
|
+
# * :base
|
193
|
+
# * :nextUpdate
|
194
|
+
# * :lastUpdate
|
195
|
+
# * :error
|
196
|
+
# * :overrideFlag
|
197
|
+
# * :dnAuthenticate
|
198
|
+
# * :properties [Array]
|
199
|
+
#
|
200
|
+
def ldap_info(domain)
|
201
|
+
fetch domain_by_id_url(domain) + '/adldap',
|
202
|
+
on_error: "An error was ocurred when try to fecht the ldap information of #{domain}"
|
203
|
+
end
|
204
|
+
|
205
|
+
|
206
|
+
|
207
|
+
#
|
208
|
+
# Retrive all the account from one domain
|
209
|
+
#
|
210
|
+
# @params [String] domain
|
211
|
+
# @params [String] filter_account the account to filter in the list. This can be a part of an account.
|
212
|
+
# @param [Hash] refinement
|
213
|
+
# @option refinement [Fixnum] :limit of elements per page
|
214
|
+
# @option refinement [Fixnum] :offset number of page (start in 1)
|
215
|
+
# @option refinement [String] :account filter accounts that start with this value
|
216
|
+
# @option refinement [Boolean] :without_group filter accounts without group
|
217
|
+
#
|
218
|
+
#
|
219
|
+
# @return [Hash] with the following elements:
|
220
|
+
# * :elements [Array<Hash>] the list of accounts as a Hash, when any element contains:
|
221
|
+
# * :account [String] example: alex
|
222
|
+
# * :domain [String] example: mxhero.com
|
223
|
+
# * :createdDate [Fixnum] example: 1375909565000 (epoch format)
|
224
|
+
# * :updatedDate [Fixnum]
|
225
|
+
# * :group [String]
|
226
|
+
# * :aliases [Array<Hash>] the list of aliases of one account
|
227
|
+
# * :name [String]
|
228
|
+
# * :domain [String]
|
229
|
+
# * :dataSource [String]
|
230
|
+
# * :dataSource [String]
|
231
|
+
# * :totalElements [Fixnum]
|
232
|
+
# * :totalPages [Fixnum]
|
233
|
+
# * :actualPage [Fixnum]
|
234
|
+
#
|
235
|
+
# @raise an exception when the status code isn't 200
|
236
|
+
def accounts_by_domain(domain, refinement = {}) #filter_account = nil, pagination = {})
|
237
|
+
params = refinement.dup
|
238
|
+
filter_account = params.delete(:account)
|
239
|
+
filter_account = CGI::escape(filter_account) if filter_account
|
240
|
+
without_group = params.delete(:without_group) || false
|
241
|
+
limit, offset = params.values_at(:limit, :offset)
|
242
|
+
|
243
|
+
if without_group
|
244
|
+
url = accounts_without_group_url(domain, filter_account)
|
245
|
+
else
|
246
|
+
url = paginate accounts_by_domain_url(domain, filter_account), { limit: limit, offset: offset }
|
247
|
+
end
|
248
|
+
response = call(:get, url)
|
249
|
+
json_parse(response.content)
|
250
|
+
end
|
251
|
+
|
252
|
+
def accounts_without_group_url(domain, filter_account)
|
253
|
+
domain_by_id_url(domain) + "/groups/accounts/available?account=#{filter_account}"
|
254
|
+
end
|
255
|
+
|
256
|
+
def verbose?
|
257
|
+
@verbose
|
258
|
+
end
|
259
|
+
|
260
|
+
def verbose=(verbose)
|
261
|
+
@verbose = verbose
|
262
|
+
end
|
263
|
+
|
264
|
+
# @param domain [String]
|
265
|
+
# @param [Hash] msg
|
266
|
+
# @option msg [String] :domain
|
267
|
+
# @option msg [Boolean] :twoWays
|
268
|
+
# @option msg [Boolean] :enabled
|
269
|
+
# @option msg [String] :name
|
270
|
+
# @option msg [Integer] :created in epoch format
|
271
|
+
# @option msg [Hash] :fromDirection
|
272
|
+
# @option msg [Hash] :toDirection
|
273
|
+
# @option msg [Array<Hash>] :properties
|
274
|
+
# @option msg [String] :component
|
275
|
+
#
|
276
|
+
# @return [MxHero::API::Response]
|
277
|
+
def create_rule_for_domain(domain, msg)
|
278
|
+
url = rules_for_domain_url(domain)
|
279
|
+
response = call(:post, url, msg.to_json, throw_exception: false)
|
280
|
+
parse_response(response)
|
281
|
+
end
|
282
|
+
|
283
|
+
## Create a rule
|
284
|
+
##
|
285
|
+
## @param [Hash] msg
|
286
|
+
## @option msg [String] :domain
|
287
|
+
## @option msg [Boolean] :twoWays
|
288
|
+
## @option msg [Boolean] :enabled
|
289
|
+
## @option msg [String] :name
|
290
|
+
## @option msg [Integer] :created in epoch format
|
291
|
+
## @option msg [Hash] :fromDirection
|
292
|
+
## @option msg [Hash] :toDirection
|
293
|
+
## @option msg [Array<Hash>] :properties
|
294
|
+
## @option msg [String] :component
|
295
|
+
##
|
296
|
+
## [MxHero::API::Response]
|
297
|
+
#def create_rule(msg)
|
298
|
+
# response = call(:post, rules_url, msg.to_json, throw_exception: false)
|
299
|
+
# parse_response(response)
|
300
|
+
#end
|
301
|
+
|
302
|
+
# Retrieve all the rules for one domain
|
303
|
+
#
|
304
|
+
# @param [String] domain
|
305
|
+
# @param [String] component Filter the list of rules by this component [optional]
|
306
|
+
#
|
307
|
+
# @return [MxHero::API::Response] reponse
|
308
|
+
# the key :msg contains an array of rules for the domain.
|
309
|
+
def rules_for_domain(domain, component = nil)
|
310
|
+
url = rules_for_domain_url(domain)
|
311
|
+
url << "?component=#{component}" if component
|
312
|
+
response = call(:get, url)
|
313
|
+
parse_response(response, on_empty: [])
|
314
|
+
end
|
315
|
+
|
316
|
+
# @return [Boolean] true when operation it's ok
|
317
|
+
def delete_rule(domain, id)
|
318
|
+
url = domain_rule_url(domain, id)
|
319
|
+
response = call(:delete, url)
|
320
|
+
return true if response.status == 200
|
321
|
+
return false
|
322
|
+
end
|
323
|
+
|
324
|
+
# @param [String] domain
|
325
|
+
# @param [String] account Ex.: test or mxhero (the user name)
|
326
|
+
# @return [MxHero::API::Response] reponse
|
327
|
+
# the key :msg contains a Hash with the key, value of any property.
|
328
|
+
# Example:
|
329
|
+
#
|
330
|
+
# { 'email': 'test@mxhero.com', 'name': 'John', 'lastname': 'Doe', ... }
|
331
|
+
#
|
332
|
+
def account_properties(domain, account)
|
333
|
+
url = account_properties_url(domain, account)
|
334
|
+
response = call(:get, url)
|
335
|
+
if response.status == 200
|
336
|
+
props = {}
|
337
|
+
json_parse(response.content).each { |property| props[property[:name]] = property[:value] }
|
338
|
+
return Response.new(response.code, props)
|
339
|
+
end
|
340
|
+
parse_response(response)
|
341
|
+
end
|
342
|
+
|
343
|
+
# @param [String] domain
|
344
|
+
# @param [String] account
|
345
|
+
# @param [Hash] properties The properties of the account. Ex.: { 'email': 'test@mxhero.com', 'name': 'John', 'lastname': 'Doe', ... }
|
346
|
+
#
|
347
|
+
# @return [MxHero::API::Response]. On success not return msg.
|
348
|
+
def update_account_properties(domain, account, properties)
|
349
|
+
url = account_properties_url(domain, account)
|
350
|
+
response = call(:put, url, account_properties_to_json(properties))
|
351
|
+
parse_response(response)
|
352
|
+
end
|
353
|
+
|
354
|
+
#
|
355
|
+
# @param [String] domain
|
356
|
+
# @param [Array<Hash>] accounts. An array of hash with :account and :properties. The :properties
|
357
|
+
# contains a Hash with the equivalent of name and value.
|
358
|
+
# @param [String] scope :groups, :properties or :both (default: properties)
|
359
|
+
#
|
360
|
+
def update_accounts(domain, accounts, scope = :properties)
|
361
|
+
scope_param = scope == :both ? 'groups,properties' : scope.to_s
|
362
|
+
#url = "/domains/#{domain}/accounts/upload?scope=#{scope_param}"
|
363
|
+
url = accounts_by_domain_url(domain) + "/upload?scope=#{scope_param}"
|
364
|
+
|
365
|
+
message = []
|
366
|
+
accounts.each do |account|
|
367
|
+
properties = remap_properties(account[:properties])
|
368
|
+
message << { account: account[:account], properties: properties, group: account[:group], domain: domain }
|
369
|
+
#message << { account: account[:account], properties: properties, group: account[:group] }
|
370
|
+
end
|
371
|
+
response = call(:put, url, message.to_json) # accounts to json
|
372
|
+
parse_response(response)
|
373
|
+
end
|
374
|
+
|
375
|
+
# @return [Hash|String|nil] can return a hash with the key and value of any
|
376
|
+
# system property. If use a parameter (key) return the string of this value.
|
377
|
+
# In the two cases return nil when not found values
|
378
|
+
#
|
379
|
+
def system_properties(key = nil)
|
380
|
+
response = call(:get, system_properties_url(key))
|
381
|
+
if response.status == 200
|
382
|
+
parsed = json_parse(response.content)
|
383
|
+
if parsed.is_a? Array
|
384
|
+
props = {}
|
385
|
+
parsed.each { |property| props[property[:key]] = property[:value] }
|
386
|
+
return props
|
387
|
+
else
|
388
|
+
return parsed[:value]
|
389
|
+
end
|
390
|
+
end
|
391
|
+
|
392
|
+
nil
|
393
|
+
end
|
394
|
+
|
395
|
+
# Update or create a system property
|
396
|
+
def save_system_property(key, value)
|
397
|
+
property = { key: key, value: value }.to_json
|
398
|
+
response = if system_properties(key).nil?
|
399
|
+
call(:post, system_properties_url, property)
|
400
|
+
else
|
401
|
+
call(:put, system_properties_url(key), property)
|
402
|
+
end
|
403
|
+
|
404
|
+
parse_response(response).success?
|
405
|
+
end
|
406
|
+
|
407
|
+
# Obtain the list of users admin in a specific domain
|
408
|
+
# @return [Array<UserVO>|nil] when there is no users for that domain.
|
409
|
+
# If the domain doesn't exist then return nil
|
410
|
+
def users_for_domain(domain)
|
411
|
+
users = nil
|
412
|
+
response = call(:get, users_for_domain_url(domain), throw_exception: false)
|
413
|
+
if response.status == 200
|
414
|
+
users = json_parse(response.content)
|
415
|
+
end
|
416
|
+
users
|
417
|
+
end
|
418
|
+
|
419
|
+
# Obtain the list of domains to one user
|
420
|
+
# @return [Array<String>|nil] when the user exist but don't have domains the list is empty.
|
421
|
+
# If the user isn't exist then return nil
|
422
|
+
def user_domains(user)
|
423
|
+
domains = nil
|
424
|
+
response = call(:get, user_domains_url(user))
|
425
|
+
if response.status == 200
|
426
|
+
content = json_parse(response.content)
|
427
|
+
domains = content.map { |info| info[:domain] }
|
428
|
+
end
|
429
|
+
domains
|
430
|
+
end
|
431
|
+
|
432
|
+
# Fetch the user
|
433
|
+
# @return [MxHero::API::Response | nil]
|
434
|
+
def fetch_user(user)
|
435
|
+
response = call(:get, user_url(user))
|
436
|
+
if response.status == 200
|
437
|
+
return parse_response(response)
|
438
|
+
end
|
439
|
+
nil
|
440
|
+
end
|
441
|
+
|
442
|
+
|
443
|
+
# Create a new user
|
444
|
+
# @param [Hash] user_info
|
445
|
+
# @option user_info [String] :name
|
446
|
+
# @option user_info [String] :lastName
|
447
|
+
# @option user_info [String] :notifyEmail
|
448
|
+
# @option user_info [String] :userName
|
449
|
+
# @option user_info [String] :locale
|
450
|
+
# @option user_info [String] :password
|
451
|
+
#
|
452
|
+
# @param [Array<String>] domains
|
453
|
+
#
|
454
|
+
def create_user(user_info, *domains)
|
455
|
+
user = {
|
456
|
+
name: "", lastName: "", notifyEmail: "",
|
457
|
+
userName: "", locale: "en_US", password: "1234",
|
458
|
+
authorities: ["ROLE_DOMAIN_ADMIN"],
|
459
|
+
created: DateTime.now.strftime('%Q'),
|
460
|
+
domains: domains.map { |domain| { domain: domain } }
|
461
|
+
}
|
462
|
+
user.merge!(user_info)
|
463
|
+
response = call(:post, users_url, user.to_json, throw_exception: false)
|
464
|
+
response.status == 201
|
465
|
+
end
|
466
|
+
|
467
|
+
# Associate domains with an existing user
|
468
|
+
# @param [String] user
|
469
|
+
# @param [String] domains
|
470
|
+
#
|
471
|
+
def associate_user_domain(user, domain)
|
472
|
+
domain_obj = { domain: domain }
|
473
|
+
response = call(:post, user_domains_url(user), domain_obj.to_json, throw_exception: false)
|
474
|
+
response.status == 200
|
475
|
+
end
|
476
|
+
|
477
|
+
# Unassociate specific domain from an user admin
|
478
|
+
# @param [String] user
|
479
|
+
# @param [String] domain
|
480
|
+
#
|
481
|
+
def unassociate_user_domain(user, domain)
|
482
|
+
response = call(:delete, user_with_domain_url(user,domain), throw_exception: false)
|
483
|
+
response.status == 200
|
484
|
+
end
|
485
|
+
|
486
|
+
|
487
|
+
# Update user
|
488
|
+
# @param [Hash] user retrieve to update
|
489
|
+
#
|
490
|
+
# @param user_name [String]
|
491
|
+
#
|
492
|
+
def update_user(user, user_name)
|
493
|
+
response = call(:put, user_url(user_name), user.to_json, throw_exception: false)
|
494
|
+
parse_response(response)
|
495
|
+
end
|
496
|
+
|
497
|
+
# Validate if the an user and password match
|
498
|
+
#
|
499
|
+
def valid_user_credentials?(user, password)
|
500
|
+
validate_user_credential_url = user_url(user) + "password/#{password}"
|
501
|
+
response = call(:get, validate_user_credential_url)
|
502
|
+
response.status == 204
|
503
|
+
end
|
504
|
+
|
505
|
+
def set_new_password(user_name, new_password)
|
506
|
+
response = call(:put, user_url_set_password(user_name, new_password), throw_exception: false)
|
507
|
+
response.status == 200
|
508
|
+
end
|
506
509
|
|
507
510
|
# test_msg example:
|
508
511
|
# {
|
@@ -538,126 +541,127 @@ module MxHero::API
|
|
538
541
|
parse_response(response)
|
539
542
|
end
|
540
543
|
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
544
|
+
|
545
|
+
# --------------------------------------------------------------------------------------------------------------------------------
|
546
|
+
private
|
547
|
+
|
548
|
+
def users_url
|
549
|
+
service_url + "/users"
|
550
|
+
end
|
551
|
+
|
552
|
+
def user_url(user)
|
553
|
+
users_url + "/#{user}/"
|
554
|
+
end
|
555
|
+
|
556
|
+
def user_domains_url(user)
|
557
|
+
user_url(user) + "domains"
|
558
|
+
end
|
559
|
+
|
560
|
+
def users_for_domain_url(domain)
|
561
|
+
users_url + "/domain/#{domain}/"
|
562
|
+
end
|
563
|
+
|
564
|
+
def user_with_domain_url(user,domain)
|
565
|
+
user_url(user) + "domains/#{domain}/"
|
566
|
+
end
|
567
|
+
|
568
|
+
def user_url_set_password(user,new_password)
|
569
|
+
pass_esc = CGI::escape(new_password)
|
570
|
+
users_url + "/#{user}/setPassword?newPassword=#{pass_esc}"
|
571
|
+
end
|
572
|
+
|
573
|
+
# Fetch an element from an URL. That element maybe not found
|
574
|
+
# @return a Hash when the element exist. Or return nil when not found.
|
575
|
+
#
|
576
|
+
# @raise RuntimeError when an error ocurrs.
|
577
|
+
def fetch(url, msg)
|
578
|
+
response = call(:get, url)
|
579
|
+
return json_parse(response.content) if response.ok?
|
580
|
+
return nil if response.code == 404
|
581
|
+
|
582
|
+
error = msg[:on_error] + " HTTP code: #{response.code}"
|
583
|
+
if response.content.include?('message')
|
584
|
+
hash = json_parse(response.content)
|
585
|
+
error << " Response message: #{hash[:message]}"
|
586
|
+
end
|
587
|
+
|
588
|
+
raise error
|
589
|
+
end
|
590
|
+
|
591
|
+
def remap_properties(properties)
|
592
|
+
return nil if properties.nil?
|
593
|
+
properties.keys.map { |name| { name: name, value: properties[name] } }
|
594
|
+
end
|
595
|
+
|
596
|
+
# Complete the URL with the pagination info (:limit and :offset)
|
597
|
+
# @param [String] original URL. Ex.: http://www.example.com/api/accounts
|
598
|
+
# @param [Hash] pagination
|
599
|
+
# @option pagination [Fixnum] :limit of elements per page
|
600
|
+
# @option pagination [Fixnum] :offset number of page (start in 1)
|
601
|
+
#
|
602
|
+
# @return [String] the URL with the pagination parameters.
|
603
|
+
# Ex.: url: http://www.example.com/api/accounts
|
604
|
+
# pagination: { limit: 4, offset: 2 }
|
605
|
+
# return > http://www.example.com/api/accounts?limit=4&offset=2
|
606
|
+
def paginate(url, pagination)
|
607
|
+
paginated = url.dup
|
608
|
+
connector = url.include?('?') ? '&' : '?'
|
609
|
+
[ :limit, :offset ].map do |elem|
|
610
|
+
if pagination.key? elem
|
611
|
+
paginated << "#{connector}#{elem.to_s}=#{pagination[elem]}"
|
612
|
+
connector = '&'
|
613
|
+
end
|
614
|
+
end
|
615
|
+
paginated
|
616
|
+
end
|
617
|
+
|
618
|
+
def account_properties_to_json(properties)
|
619
|
+
out = []
|
620
|
+
properties.each do |key, value|
|
621
|
+
out << { name: key, value: value }
|
622
|
+
end
|
623
|
+
out.to_json
|
624
|
+
end
|
625
|
+
|
626
|
+
def rules_for_domain_url(domain)
|
627
|
+
service_url + "/domains/#{domain}/rules"
|
628
|
+
end
|
629
|
+
|
630
|
+
def rules_url
|
631
|
+
service_url + '/rules'
|
632
|
+
end
|
633
|
+
|
634
|
+
def accounts_by_domain_url(domain, filter_account = nil)
|
635
|
+
filter = filter_account ? "?account=#{filter_account}" : ''
|
636
|
+
domain_by_id_url(domain) + 'accounts' + filter
|
637
|
+
end
|
638
|
+
|
639
|
+
def domain_rule_url(domain, id)
|
640
|
+
rules_for_domain_url(domain) + "/#{id}"
|
641
|
+
end
|
642
|
+
|
643
|
+
def features_url(domain)
|
644
|
+
domain_by_id_url(domain) + "/features"
|
645
|
+
end
|
646
|
+
|
647
|
+
def account_properties_url(domain, account)
|
648
|
+
accounts_by_domain_url(domain) + "/#{account}/properties"
|
649
|
+
end
|
650
|
+
|
651
|
+
def system_properties_url(key = nil)
|
652
|
+
fixed_key = key.nil? ? nil : "#{key}/"
|
653
|
+
service_url + "/system/properties/#{fixed_key}"
|
654
|
+
end
|
655
|
+
|
656
|
+
# @return [MxHero::API::Response] a response object
|
657
|
+
def parse_response(response, opts = { on_empty: nil })
|
658
|
+
json = response.content
|
659
|
+
hash = json.nil? || json.empty? ? opts[:on_empty] : json_parse(json)
|
660
|
+
Response.new(response.code, hash)
|
661
|
+
end
|
662
|
+
|
663
|
+
|
664
|
+
|
665
|
+
end
|
662
666
|
|
663
667
|
end
|