fusebox 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +19 -0
- data/README.md +45 -0
- data/lib/fusebox/core_ext/net_http.rb +21 -0
- data/lib/fusebox/request.rb +378 -0
- data/lib/fusebox/response.rb +79 -0
- data/lib/fusebox/version.rb +4 -0
- data/lib/fusebox.rb +12 -0
- data/spec/fusebox_request_spec.rb +58 -0
- data/spec/fusebox_response_spec.rb +22 -0
- data/spec/net_http_spec.rb +18 -0
- data/spec/spec.opts +3 -0
- data/spec/spec_helper.rb +1 -0
- metadata +109 -0
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2010 Mudbug Media, Gabe Martin-Dempesy
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
[FuseMail](http://fusemail.com) is a business email hosting provider offering outsourced email hosting to businesses and resellers.
|
2
|
+
|
3
|
+
**fusebox** is a ruby gem that provides a 1:1 native ruby interface for every command of [FuseMail Platform Programming Interface v2.6](http://www.fusemail.com/support/administration-api), which allows you to manage your accounts, domains, forwards, and aliases via an underlying HTTP interface.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
gem install fusebox
|
7
|
+
|
8
|
+
## Configuration
|
9
|
+
Although the library supports passing a username and password to {Fusebox::Request#initialize}, we recommend storing authentication information in a yaml file within {Fusebox::Request.auth_yaml_paths} as:
|
10
|
+
|
11
|
+
# cat ~/.fusemail.yaml
|
12
|
+
username: my_username
|
13
|
+
password: my_password
|
14
|
+
|
15
|
+
## Examples
|
16
|
+
### Fetch a list of users
|
17
|
+
response = Fusebox::Request.new.report
|
18
|
+
if response.success?
|
19
|
+
response.records.each { |user| puts user.inspect }
|
20
|
+
end
|
21
|
+
|
22
|
+
### Create a new account
|
23
|
+
response = Fusebox::Request.new.order(:account_type => 'group_subaccount', :group_parent => "postmaster@example.com", :user => "user@example.com", :password => 'WooEmail!', :first_name => 'Test', :last_name => 'User')
|
24
|
+
if response.success?
|
25
|
+
puts "Success!"
|
26
|
+
else
|
27
|
+
puts "Failure: " + response.detail
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
## Documentation
|
32
|
+
http://rubydoc.info/github/mudbugmedia/fusebox/master/frames
|
33
|
+
|
34
|
+
## TODO
|
35
|
+
* Ruby 1.8's OpenSSL does not verify certificates and displays "warning: peer certificate won't be verified in this SSL session"
|
36
|
+
* CLI tools with Thor
|
37
|
+
* Logging hook
|
38
|
+
* Leverage ActiveModel to create Account, Domain, Alias, etc, classes.
|
39
|
+
|
40
|
+
## Authors
|
41
|
+
The fusebox gem is independently developed and maintained by [Mudbug Media](http://mudbugmedia.com/) and [Gabe Martin-Dempesy](http://mudbugmedia.com/team/gabe).
|
42
|
+
|
43
|
+
FuseMail LLC, and its parent company j2 Global Communications, do not provide support or maintenance for this software.
|
44
|
+
|
45
|
+
Copyright © 2010
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Net
|
2
|
+
class HTTP
|
3
|
+
# Posts HTML form data to the URL, but allow for SSL.
|
4
|
+
#
|
5
|
+
# The existing 1.8.x implementaiton via post_form does not allow for SSL connections
|
6
|
+
#
|
7
|
+
# @param [URI] url
|
8
|
+
# @param [Hash] POST data
|
9
|
+
def HTTP.post_form_with_ssl(url, params)
|
10
|
+
req = Post.new(url.path)
|
11
|
+
req.form_data = params
|
12
|
+
req.basic_auth url.user, url.password if url.user
|
13
|
+
http = new(url.host, url.port)
|
14
|
+
http.use_ssl = (url.scheme == 'https')
|
15
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
16
|
+
http.start {|http|
|
17
|
+
http.request(req)
|
18
|
+
}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,378 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Fusebox
|
4
|
+
# @see http://www.fusemail.com/support/administration-api
|
5
|
+
class Request
|
6
|
+
|
7
|
+
class << self
|
8
|
+
# @return [Array<String>] Paths to search for API platform authentication information
|
9
|
+
attr_accessor :auth_yaml_paths
|
10
|
+
|
11
|
+
# @return [String] API URL to POST requests to
|
12
|
+
attr_accessor :url
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return [String] Platform API username
|
16
|
+
attr_accessor :username
|
17
|
+
|
18
|
+
# @return [String] Platform API password
|
19
|
+
attr_accessor :password
|
20
|
+
|
21
|
+
self.auth_yaml_paths = %w(~/.fusemail.yaml)
|
22
|
+
self.url = 'https://www.fusemail.com/api/request.html'
|
23
|
+
|
24
|
+
# @return [Array<String>] List of available API commands
|
25
|
+
COMMANDS = %w(adddomain addforward changeusername checkalias checkdomain suspend enable getforward modify order terminate removealias removedomain removeforward report reportmail suspend)
|
26
|
+
|
27
|
+
# @param [String] username API username. If not provided, auth_yaml_paths will be searched for authentication information instead.
|
28
|
+
# @param [String] password API password
|
29
|
+
def initialize (username = nil, password = nil)
|
30
|
+
if username && password
|
31
|
+
@username = username
|
32
|
+
@password = password
|
33
|
+
else
|
34
|
+
load_auth_from_yaml
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# This request will add a domain to the specified account. The must be under your platform
|
39
|
+
# @see http://www.fusemail.com/support/administration-api/requests/adddomain adddomain API documentation
|
40
|
+
# @param [Array] opts
|
41
|
+
# @option opts [String] :domain The domain to add
|
42
|
+
# @option opts [String] :user The account to add the domain to
|
43
|
+
# @return [Response]
|
44
|
+
def adddomain (opts)
|
45
|
+
default_options = {
|
46
|
+
:domain => '',
|
47
|
+
:user => ''
|
48
|
+
}
|
49
|
+
|
50
|
+
opts.reverse_merge! default_options
|
51
|
+
post 'adddomain', opts
|
52
|
+
end
|
53
|
+
|
54
|
+
# This request will add an email forwarder.
|
55
|
+
# @see http://www.fusemail.com/support/administration-api/requests/addforward addforward API documentation
|
56
|
+
# @param [Array] opts
|
57
|
+
# @option opts [String] :user Username of FuseMail account to add forwarder to
|
58
|
+
# @option opts [String] :forward_what Email address of forwarder
|
59
|
+
# @option opts [String] :forward_to External email address that forwarder will send to
|
60
|
+
# @return [Response]
|
61
|
+
def addforward (opts)
|
62
|
+
default_options = {
|
63
|
+
:user => '',
|
64
|
+
:forward_what => '',
|
65
|
+
:forward_to => ''
|
66
|
+
}
|
67
|
+
|
68
|
+
opts.reverse_merge! default_options
|
69
|
+
post 'addforward', opts
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
# This request will check the availability of an alias against the whole system. Remember to add an alias, the domain must belong to the platform or to that account.
|
74
|
+
# @see http://www.fusemail.com/support/administration-api/requests/checkalias checkalias API documentation
|
75
|
+
# @param [Array] opts
|
76
|
+
# @option opts [String] :alias The alias to check the availability of (e.g. user@example.com)
|
77
|
+
# @return [Response]
|
78
|
+
def checkalias (opts)
|
79
|
+
default_options = {
|
80
|
+
:alias => ''
|
81
|
+
}
|
82
|
+
|
83
|
+
opts.reverse_merge! default_options
|
84
|
+
post 'checkalias', opts
|
85
|
+
end
|
86
|
+
|
87
|
+
# This request is used to change the an account's username
|
88
|
+
# @see http://www.fusemail.com/support/administration-api/requests/changeusername checkalias API documentation
|
89
|
+
# @param [Array] opts
|
90
|
+
# @param opts [String] :user Username of FuseMail account to modify
|
91
|
+
# @param opts [String] :newuser New username of the account
|
92
|
+
# @return [Response]
|
93
|
+
def changeusername (opts)
|
94
|
+
default_options = {
|
95
|
+
:user => '',
|
96
|
+
:newuser => ''
|
97
|
+
}
|
98
|
+
|
99
|
+
opts.reverse_merge! default_options
|
100
|
+
post 'changeusername', opts
|
101
|
+
end
|
102
|
+
|
103
|
+
# This request will check the availability of a domain name. This only checks if the domain name is available on our system, it does not reflect registrar status.
|
104
|
+
# @see http://www.fusemail.com/support/administration-api/requests/checkdomain checkdomain API documentation
|
105
|
+
# @param [Array] opts
|
106
|
+
# @option opts [String] :domain The domain to check the availability of
|
107
|
+
# @return [Response]
|
108
|
+
def checkdomain (opts)
|
109
|
+
default_options = {
|
110
|
+
:domain => ''
|
111
|
+
}
|
112
|
+
|
113
|
+
opts.reverse_merge! default_options
|
114
|
+
post 'checkdomain', opts
|
115
|
+
end
|
116
|
+
|
117
|
+
# This request is used to change the an account's username
|
118
|
+
# @see http://www.fusemail.com/support/administration-api/requests/changeusername changeusername API documentation
|
119
|
+
# @param [Array] opts
|
120
|
+
# @option opts [String] :user Username of FuseMail account to modify
|
121
|
+
# @return [Response]
|
122
|
+
def suspend (opts)
|
123
|
+
default_options = {
|
124
|
+
:user => '',
|
125
|
+
}
|
126
|
+
|
127
|
+
opts.reverse_merge! default_options
|
128
|
+
post 'suspend', opts
|
129
|
+
end
|
130
|
+
|
131
|
+
# The enable request allow you to activate an account under your platform or temporarily start access to the account. Below are the variables that are specific to this request.
|
132
|
+
# @see http://www.fusemail.com/support/administration-api/requests/enable enable API documentation
|
133
|
+
# @param [Array] opts
|
134
|
+
# @option opts [String] :user Username of FuseMail account to enable
|
135
|
+
# @return [Response]
|
136
|
+
def enable (opts)
|
137
|
+
default_options = {
|
138
|
+
:user => ''
|
139
|
+
}
|
140
|
+
|
141
|
+
opts.reverse_merge! default_options
|
142
|
+
post 'enable', opts
|
143
|
+
end
|
144
|
+
|
145
|
+
# This request will return the forward currently set on an alias in the {Response#detail} attribute
|
146
|
+
# @see http://www.fusemail.com/support/administration-api/requests/getforward getforward API documentation
|
147
|
+
# @param [Array] opts
|
148
|
+
# @option opts [String] :user Username of FuseMail account where the forwarding alias resides
|
149
|
+
# @option opts [String] :forward_what Alias for the forwarder
|
150
|
+
# @return [Response]
|
151
|
+
def getforward (opts)
|
152
|
+
default_options = {
|
153
|
+
:user => '',
|
154
|
+
:forward_what => ''
|
155
|
+
}
|
156
|
+
|
157
|
+
opts.reverse_merge! default_options
|
158
|
+
post 'getforward', opts
|
159
|
+
end
|
160
|
+
|
161
|
+
# This request is used to modify personal information, password, and the account plan of the account. Only send the variables you wish to modify. If a NULL variable is detected, no change will be made to the account.
|
162
|
+
# @see http://www.fusemail.com/support/administration-api/requests/modify modify API documentation
|
163
|
+
# @param opts (see Fusemail::Request#order)
|
164
|
+
# @return [Response]
|
165
|
+
def modify (opts)
|
166
|
+
default_options = {
|
167
|
+
}
|
168
|
+
|
169
|
+
opts.reverse_merge! default_options
|
170
|
+
post 'modify', opts
|
171
|
+
end
|
172
|
+
|
173
|
+
# This is a request to submit a new order and create a new account under your Fused Platform account. Orders are processed within 5 minutes of request submission. Below are the variables that are specific to this type of request.
|
174
|
+
# @see http://www.fusemail.com/support/administration-api/requests/order order API documentation
|
175
|
+
# @param [Array] opts
|
176
|
+
# @option opts [String] :user Username of FuseMail account to create
|
177
|
+
# @option opts [String] :password Password of FuseMail account to create
|
178
|
+
# @option opts [String] :first_name First name of person
|
179
|
+
# @option opts [String] :last_name Last name of person
|
180
|
+
# @option opts [String] :email Other contact email address
|
181
|
+
# @option opts [String] :street Street Address of person
|
182
|
+
# @option opts [String] :city City of Address of person
|
183
|
+
# @option opts [String] :state State of Address of person
|
184
|
+
# @option opts [String] :postal Postal Code of Address of person
|
185
|
+
# @option opts [String] :country Country of Address of person
|
186
|
+
# @option opts [String] :account_type ('group_subaccount') Type of account to create, possible options: personal_basic, personal_power, personal_ultimate, group_basic, group_power, group_ultimate, group_subaccount. See 'Account Plans' under your platform account for the API name you use.
|
187
|
+
# @option opts [String] :group_parent The username of the main group account that this sub-account belongs to. This field is only required when using a group_subaccount account_type.
|
188
|
+
# @option opts [String] :maxdisk ('1000') The maximum amount of disk space an account can consume in Megabytes (MB) (mainly used for group_subaccount's), integer only.
|
189
|
+
# @option opts [Array<String>] :alias This field contains additional aliases to add to this account upon order creation.
|
190
|
+
# @return [Response]
|
191
|
+
def order (opts)
|
192
|
+
default_options = {
|
193
|
+
:account_type => 'group_subaccount',
|
194
|
+
:first_name => '',
|
195
|
+
:last_name => '',
|
196
|
+
:maxdisk => 1000
|
197
|
+
}
|
198
|
+
|
199
|
+
opts.reverse_merge! default_options
|
200
|
+
post 'order', opts
|
201
|
+
end
|
202
|
+
|
203
|
+
# The terminate request is used to permanently remove an account and all of the account data associated with it. This operation cannot be reversed and therefore should be used with caution.
|
204
|
+
# @see http://www.fusemail.com/support/administration-api/requests/terminate terminate API documentation
|
205
|
+
# @param [Array] opts
|
206
|
+
# @option opts [String] 'user' Username of FuseMail account to terminate
|
207
|
+
# @option opts [Boolean] 'purge' (false) Will purge all data (such as removing the username) from our system. This process might take a few hours to complete.
|
208
|
+
# @return [Response]
|
209
|
+
def terminate (opts)
|
210
|
+
default_options = {
|
211
|
+
:user => '',
|
212
|
+
:purge => false
|
213
|
+
}
|
214
|
+
|
215
|
+
opts.reverse_merge! default_options
|
216
|
+
post 'terminate', opts
|
217
|
+
end
|
218
|
+
|
219
|
+
# This request will remove a single alias from a fusemail account
|
220
|
+
# @see http://www.fusemail.com/support/administration-api/requests/removealias removealias API documentation
|
221
|
+
# @param [Array] opts
|
222
|
+
# @option opts [String] 'user' FuseMail user to delete alias from
|
223
|
+
# @option opts [String] 'alias' alias to delete (e.g. user@example.com )
|
224
|
+
# @return [Response]
|
225
|
+
def removealias (opts)
|
226
|
+
default_options = {
|
227
|
+
:user => '',
|
228
|
+
:alias => ''
|
229
|
+
}
|
230
|
+
|
231
|
+
opts.reverse_merge! default_options
|
232
|
+
post 'removealias', opts
|
233
|
+
end
|
234
|
+
|
235
|
+
# This request will remove a domain name and all its mail aliases, auto-responders, mailing lists & forwarders associated with it. Please see below for the specific requirements for this request.
|
236
|
+
# @see http://www.fusemail.com/support/administration-api/requests/removedomain removedomain API documentation
|
237
|
+
# @param [Array] opts
|
238
|
+
# @option opts [String] 'domain' The domain to delete
|
239
|
+
# @option opts [Boolean] 'confirm' (true) This must be set to true to confirm that you understand all aliases, auto-responders, mailing lists & forwarders with this domain will be permanently deleted.
|
240
|
+
# @return [Response]
|
241
|
+
def removedomain (opts)
|
242
|
+
default_options = {
|
243
|
+
:domain => '',
|
244
|
+
:confirm => true
|
245
|
+
}
|
246
|
+
|
247
|
+
opts.reverse_merge! default_options
|
248
|
+
post 'removedomain', opts
|
249
|
+
end
|
250
|
+
|
251
|
+
|
252
|
+
# This request will remove an existing email forwarder
|
253
|
+
# @see http://www.fusemail.com/support/administration-api/requests/removeforward removeforward API documentation
|
254
|
+
# @param [Array] opts
|
255
|
+
# @option opts [String] 'user' Username of FuseMail account to remove forwarder to
|
256
|
+
# @option opts [String] 'forward_what' Email address of forwarder
|
257
|
+
# @option opts [String] 'forward_to' External email address that forwarder will send to
|
258
|
+
# @return [Response]
|
259
|
+
def removeforward (opts)
|
260
|
+
default_options = {
|
261
|
+
:user => '',
|
262
|
+
:forward_what => '',
|
263
|
+
:forward_to => ''
|
264
|
+
}
|
265
|
+
|
266
|
+
opts.reverse_merge! default_options
|
267
|
+
post 'removeforward', opts
|
268
|
+
end
|
269
|
+
|
270
|
+
# This request will provide information about one or more accounts under your platform in CSV format
|
271
|
+
# @see http://www.fusemail.com/support/administration-api/requests/report report API documentation
|
272
|
+
# @param [Array] opts
|
273
|
+
# @option opts [String] 'user' ('all') The username you wish to query for information; you may also enter the username "all" to get information about all users under your platform
|
274
|
+
# @option opts [Boolean] 'group_subaccount' (true) Provide information not only for the Group Administration account but also for the group sub-accounts under the Group Administration account
|
275
|
+
# @option opts ['basic', 'extended'] report_type ('basic') Level of detailed in returned results
|
276
|
+
# @return [Response]
|
277
|
+
def report (opts = {})
|
278
|
+
default_options = {
|
279
|
+
:user => 'all',
|
280
|
+
:group_subaccount => true,
|
281
|
+
:report_type => 'basic'
|
282
|
+
}
|
283
|
+
|
284
|
+
opts.reverse_merge! default_options
|
285
|
+
post 'report', opts, "report_#{opts[:report_type]}".to_sym
|
286
|
+
end
|
287
|
+
|
288
|
+
# This request will provide information about mail aliases, forwarders, autoresponders, or mailing lists on one or more accounts under your platform in CSV format.
|
289
|
+
# @see http://www.fusemail.com/support/administration-api/requests/reportmail reportmail API documentation
|
290
|
+
# @param [Array] opts
|
291
|
+
# @option opts [String] 'user' ('all') The username you wish to query for information; you may also enter the username "all" to get information about all users under your platform
|
292
|
+
# @option opts [Boolean] 'group_subaccount' (true) Provide information not only for the Group Administration account but also for the group sub-accounts under the Group Administration account
|
293
|
+
# @option opts ['all', 'alias', 'forwarder', 'autorespond', 'mailinglist'] report_type ('all')
|
294
|
+
# * 'all' = Provide aliases, forwarders, autoresponders, and mailing list info
|
295
|
+
# * 'alias' = Provide only alias information
|
296
|
+
# * 'forwarder' = Provide only fowarder information
|
297
|
+
# * 'autorespond' = Provide only autoresponder information
|
298
|
+
# * 'mailinglist' = Provide only mailing list information
|
299
|
+
# @return [Response]
|
300
|
+
def reportmail (opts = {})
|
301
|
+
default_options = {
|
302
|
+
:user => 'all',
|
303
|
+
:group_subaccount => true,
|
304
|
+
:report_type => 'extended'
|
305
|
+
}
|
306
|
+
|
307
|
+
opts.reverse_merge! default_options
|
308
|
+
post 'reportmail', opts, :reportmail
|
309
|
+
end
|
310
|
+
|
311
|
+
# The suspend request allow you to suspend an account under your platform or temporarily stop access to the account without deleting any of the accounts data. Below are the variables that are specific to this request.
|
312
|
+
# @see http://www.fusemail.com/support/administration-api/requests/suspend suspend API documentation
|
313
|
+
# @param [Array] opts
|
314
|
+
# @option opts [String] 'user' Username of FuseMail account to suspend
|
315
|
+
# @return [Response]
|
316
|
+
def suspend (opts)
|
317
|
+
default_options = {
|
318
|
+
:user => ''
|
319
|
+
}
|
320
|
+
|
321
|
+
opts.reverse_merge! default_options
|
322
|
+
post 'suspend', opts
|
323
|
+
end
|
324
|
+
|
325
|
+
protected
|
326
|
+
|
327
|
+
# Load the platform authentication informaiton from a YAML file
|
328
|
+
# @see Request.auth_yaml_paths
|
329
|
+
def load_auth_from_yaml
|
330
|
+
self.class.auth_yaml_paths.map { |path| File.expand_path(path) }.select { |path| File.exist?(path) }.each do |path|
|
331
|
+
auth = YAML.load(File.read(path))
|
332
|
+
@username = auth['username']
|
333
|
+
@password = auth['password']
|
334
|
+
return if @username && @password
|
335
|
+
end
|
336
|
+
|
337
|
+
raise "Could not locate a fusemail authentication file in locations: #{self.class.auth_yaml_paths.inspect}"
|
338
|
+
end
|
339
|
+
|
340
|
+
# @param [String] command
|
341
|
+
# @param [Hash] post_vars
|
342
|
+
# @param [Fusebox::Request::CSV_MAPS.keys, nil] result_map_type (nil) For commands that return CSV data, which column map to use
|
343
|
+
# @return [Fusebox::Response]
|
344
|
+
def post (command, post_vars, result_map_type = nil)
|
345
|
+
post_vars.reverse_merge!(:PlatformUser => @username, :PlatformPassword => @password, :request => command)
|
346
|
+
post_vars = self.class.convert_post_vars(post_vars)
|
347
|
+
|
348
|
+
result = Net::HTTP.post_form_with_ssl(URI.parse(self.class.url), post_vars)
|
349
|
+
Response.new(result, result_map_type)
|
350
|
+
end
|
351
|
+
|
352
|
+
# Convert non-string values in post vars to Fusemail's expected formatting
|
353
|
+
# * Boolean => 'yes' or 'no'
|
354
|
+
# * Array => Remove 'foo' and create 'foo[0]', 'foo[1]'
|
355
|
+
# @param [Hash] post_vars
|
356
|
+
# @return [Hash] post_vars
|
357
|
+
def self.convert_post_vars (post_vars)
|
358
|
+
ret = {}
|
359
|
+
post_vars.each_pair do |key, value|
|
360
|
+
# Convert booleans to 'yes', 'no' strings
|
361
|
+
if [TrueClass, FalseClass].include?(value.class)
|
362
|
+
ret[key] = (value ? 'yes' : 'no')
|
363
|
+
|
364
|
+
# Convert arrays into 'key[0]', 'key[1]', ...
|
365
|
+
elsif value.class == Array
|
366
|
+
value.each_with_index do |value, index|
|
367
|
+
ret["#{key}[#{index}]"] = value
|
368
|
+
end
|
369
|
+
else
|
370
|
+
ret[key] = value
|
371
|
+
end
|
372
|
+
end
|
373
|
+
|
374
|
+
ret
|
375
|
+
end
|
376
|
+
|
377
|
+
end
|
378
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'csv' # We're favoring the stdlib csv in favor of not adding dependencies
|
2
|
+
|
3
|
+
module Fusebox
|
4
|
+
# @see http://www.fusemail.com/support/administration-api/httphttps-response Fusemail Response documentation
|
5
|
+
class Response
|
6
|
+
|
7
|
+
# @return [Net::HTTPOK]
|
8
|
+
attr_reader :http_response
|
9
|
+
|
10
|
+
# @return [Fixnum] Numeric code # of
|
11
|
+
attr_reader :code
|
12
|
+
|
13
|
+
# @return [String] Human-readable description of response, corresponding to {#code}
|
14
|
+
attr_reader :detail
|
15
|
+
|
16
|
+
# @return [Array<Hash>] Array of records returned by query-type commands, e.g. 'report'
|
17
|
+
attr_reader :records
|
18
|
+
|
19
|
+
# Column name mapping for CSV data returned by report and reportmail request types
|
20
|
+
CSV_MAPS = {
|
21
|
+
:report_basic => [
|
22
|
+
:username,
|
23
|
+
:internal_account_id,
|
24
|
+
:status,
|
25
|
+
:password,
|
26
|
+
:account_plan
|
27
|
+
],
|
28
|
+
|
29
|
+
:report_extended => [
|
30
|
+
:username,
|
31
|
+
:internal_account_id,
|
32
|
+
:status,
|
33
|
+
:password,
|
34
|
+
:account_plan,
|
35
|
+
:creation_date,
|
36
|
+
:first_name,
|
37
|
+
:last_name,
|
38
|
+
:company_name,
|
39
|
+
:street_1,
|
40
|
+
:street_2,
|
41
|
+
:city,
|
42
|
+
:state,
|
43
|
+
:phone,
|
44
|
+
:disk_usage
|
45
|
+
],
|
46
|
+
|
47
|
+
:reportmail => [
|
48
|
+
:username,
|
49
|
+
:internal_account_id,
|
50
|
+
:email_type,
|
51
|
+
:email_name,
|
52
|
+
:email_destination
|
53
|
+
]
|
54
|
+
}
|
55
|
+
|
56
|
+
# @param [Net::HTTPOK] http_response Response from {Net::HTTP.post_form_with_ssl}
|
57
|
+
# @param [Fusebox::Request::CSV_MAPS.keys] result_map_type Which CSV_MAPS to use to map map column names of CSV results (for report and reportmail types)
|
58
|
+
def initialize (http_response, result_map_type = nil)
|
59
|
+
@http_response = http_response
|
60
|
+
records = http_response.body.split(/[\r\n]/)
|
61
|
+
code, @detail = records.shift.split('||')
|
62
|
+
@code = code.to_i
|
63
|
+
|
64
|
+
if result_map_type
|
65
|
+
raise ArgumentError, "result_map_type: #{result_map_type} does not exist in CSV_MAPS" unless CSV_MAPS[result_map_type]
|
66
|
+
@records = records.map do |line|
|
67
|
+
Hash[CSV_MAPS[result_map_type].zip(CSV.parse_line(line))]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
# @return [Boolean]
|
74
|
+
def success?
|
75
|
+
@code == 1
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
data/lib/fusebox.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__)
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
gem 'activesupport'
|
5
|
+
require 'active_support'
|
6
|
+
require 'active_support/core_ext/hash/reverse_merge' # @todo: 1.9 requires this to be explicitly included - why?
|
7
|
+
require 'net/https'
|
8
|
+
|
9
|
+
require 'fusebox/version'
|
10
|
+
require 'fusebox/request'
|
11
|
+
require 'fusebox/response'
|
12
|
+
require 'fusebox/core_ext/net_http'
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Fusebox::Request do
|
4
|
+
it "should instantiate" do
|
5
|
+
@request = Fusebox::Request.new
|
6
|
+
end
|
7
|
+
|
8
|
+
Fusebox::Request::COMMANDS.each do |command|
|
9
|
+
describe command do
|
10
|
+
it "should call post" do
|
11
|
+
request = Fusebox::Request.new('user', 'pass')
|
12
|
+
request.should_receive(:post).and_return(nil)
|
13
|
+
request.send(command, {})
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'convert_post_vars' do
|
19
|
+
it "should convert booleans to 'yes' 'no' strings" do
|
20
|
+
post_vars = Fusebox::Request.convert_post_vars({ 'positive' => true, 'negative' => false })
|
21
|
+
post_vars['positive'].should == 'yes'
|
22
|
+
post_vars['negative'].should == 'no'
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should convert arrays" do
|
26
|
+
post_vars = Fusebox::Request.convert_post_vars({ 'my_array' => %w(ichi ni san) })
|
27
|
+
post_vars.values.length.should == 3
|
28
|
+
post_vars.keys.should_not include('my_array')
|
29
|
+
post_vars['my_array[0]'].should == 'ichi'
|
30
|
+
post_vars['my_array[1]'].should == 'ni'
|
31
|
+
post_vars['my_array[2]'].should == 'san'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe 'post' do
|
36
|
+
it "should" do
|
37
|
+
mocked_httpok = mock('Net::HTTPOK')
|
38
|
+
mocked_httpok.stub!(:body).and_return('1||Success')
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "authentication" do
|
44
|
+
it "should load authentication from yaml" do
|
45
|
+
Fusebox::Request.auth_yaml_paths = [File.join(File.dirname(__FILE__), 'fixtures', 'fusemail.yaml')]
|
46
|
+
req = Fusebox::Request.new
|
47
|
+
req.username.should == 'my_yaml_username'
|
48
|
+
req.password.should == 'my_yaml_password'
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should not load yaml when a username and password are provided" do
|
52
|
+
req = Fusebox::Request.new('my_inst_username', 'my_inst_password')
|
53
|
+
req.username.should == 'my_inst_username'
|
54
|
+
req.password.should == 'my_inst_password'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Fusebox::Response do
|
4
|
+
it "should instantiate" do
|
5
|
+
mocked_httpok = mock('Net::HTTPOK')
|
6
|
+
mocked_httpok.stub!(:body).and_return('1||Success')
|
7
|
+
resp = Fusebox::Response.new(mocked_httpok)
|
8
|
+
resp.success?.should == true
|
9
|
+
resp.detail.should == 'Success'
|
10
|
+
resp.code.should == 1
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should populate records" do
|
14
|
+
mocked_httpok = mock('Net::HTTPOK')
|
15
|
+
mocked_httpok.stub!(:body).and_return("1||Success \n\"test@example.com\",\"302953\",\"Alias\",\"test-*@example.com\",\"\"\n\"test@example.com\",\"302953\",\"Alias\",\"admin@example.com\",\"\"\n\"test@example.com\",\"302953\",\"Alias\",\"test@example.com\",\"\"\n")
|
16
|
+
resp = Fusebox::Response.new(mocked_httpok, :reportmail)
|
17
|
+
resp.records.should be_a(Array)
|
18
|
+
resp.records.length.should == 3
|
19
|
+
resp.records.first.should be_a(Hash)
|
20
|
+
resp.records.first[:username].should == 'test@example.com'
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Net::HTTP do
|
4
|
+
describe :post_form_with_ssl do
|
5
|
+
it "should SSL verify" do
|
6
|
+
lambda {
|
7
|
+
result = Net::HTTP.post_form_with_ssl URI.parse('https://www.fusemail.com/api/request.html'), {}
|
8
|
+
result.class.should == Net::HTTPOK
|
9
|
+
}.should_not raise_exception
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should reject SSL mismatches" do
|
13
|
+
lambda {
|
14
|
+
Net::HTTP.post_form_with_ssl URI.parse('https://72.32.178.162/'), {}
|
15
|
+
}.should raise_exception(OpenSSL::SSL::SSLError, /hostname/)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../lib/fusebox")
|
metadata
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fusebox
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 25
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 1
|
10
|
+
version: 0.1.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Gabe Martin-Dempesy
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-10-06 00:00:00 -05:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: activesupport
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 2
|
32
|
+
- 0
|
33
|
+
version: "2.0"
|
34
|
+
type: :runtime
|
35
|
+
version_requirements: *id001
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rspec
|
38
|
+
prerelease: false
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
hash: 3
|
45
|
+
segments:
|
46
|
+
- 0
|
47
|
+
version: "0"
|
48
|
+
type: :development
|
49
|
+
version_requirements: *id002
|
50
|
+
description: FuseMail API client library
|
51
|
+
email:
|
52
|
+
- gabe@mudbugmedia.com.com
|
53
|
+
executables: []
|
54
|
+
|
55
|
+
extensions: []
|
56
|
+
|
57
|
+
extra_rdoc_files: []
|
58
|
+
|
59
|
+
files:
|
60
|
+
- lib/fusebox/core_ext/net_http.rb
|
61
|
+
- lib/fusebox/request.rb
|
62
|
+
- lib/fusebox/response.rb
|
63
|
+
- lib/fusebox/version.rb
|
64
|
+
- lib/fusebox.rb
|
65
|
+
- spec/fusebox_request_spec.rb
|
66
|
+
- spec/fusebox_response_spec.rb
|
67
|
+
- spec/net_http_spec.rb
|
68
|
+
- spec/spec.opts
|
69
|
+
- spec/spec_helper.rb
|
70
|
+
- LICENSE
|
71
|
+
- README.md
|
72
|
+
has_rdoc: true
|
73
|
+
homepage: http://github.com/mudbugmedia/fusebox
|
74
|
+
licenses: []
|
75
|
+
|
76
|
+
post_install_message:
|
77
|
+
rdoc_options: []
|
78
|
+
|
79
|
+
require_paths:
|
80
|
+
- lib
|
81
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
hash: 3
|
87
|
+
segments:
|
88
|
+
- 0
|
89
|
+
version: "0"
|
90
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
91
|
+
none: false
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
hash: 23
|
96
|
+
segments:
|
97
|
+
- 1
|
98
|
+
- 3
|
99
|
+
- 6
|
100
|
+
version: 1.3.6
|
101
|
+
requirements: []
|
102
|
+
|
103
|
+
rubyforge_project:
|
104
|
+
rubygems_version: 1.3.7
|
105
|
+
signing_key:
|
106
|
+
specification_version: 3
|
107
|
+
summary: FuseMail API client library
|
108
|
+
test_files: []
|
109
|
+
|