prevoty 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/Gemfile +2 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +38 -0
  6. data/Rakefile +8 -0
  7. data/lib/prevoty.rb +31 -0
  8. data/lib/prevoty/client.rb +341 -0
  9. data/lib/prevoty/crypto.rb +33 -0
  10. data/lib/prevoty/exceptions/account_quota_exceeded.rb +4 -0
  11. data/lib/prevoty/exceptions/bad_api_key.rb +4 -0
  12. data/lib/prevoty/exceptions/bad_input_parameter.rb +4 -0
  13. data/lib/prevoty/exceptions/internal_error.rb +4 -0
  14. data/lib/prevoty/hash.rb +12 -0
  15. data/lib/prevoty/pattern.rb +18 -0
  16. data/lib/prevoty/responses/api_key_info.rb +12 -0
  17. data/lib/prevoty/responses/decrypt_result.rb +9 -0
  18. data/lib/prevoty/responses/delete_token.rb +10 -0
  19. data/lib/prevoty/responses/ecdsa_private_key.rb +19 -0
  20. data/lib/prevoty/responses/ecdsa_public_key.rb +19 -0
  21. data/lib/prevoty/responses/ecdsa_signature.rb +17 -0
  22. data/lib/prevoty/responses/encrypt_result.rb +25 -0
  23. data/lib/prevoty/responses/filter_content.rb +11 -0
  24. data/lib/prevoty/responses/filter_statistics.rb +28 -0
  25. data/lib/prevoty/responses/generate_token.rb +10 -0
  26. data/lib/prevoty/responses/hash_result.rb +9 -0
  27. data/lib/prevoty/responses/input_validation.rb +10 -0
  28. data/lib/prevoty/responses/query_analysis.rb +87 -0
  29. data/lib/prevoty/responses/rsa_private_key.rb +22 -0
  30. data/lib/prevoty/responses/rsa_public_key.rb +17 -0
  31. data/lib/prevoty/responses/rsa_signature.rb +15 -0
  32. data/lib/prevoty/responses/signature_verify.rb +13 -0
  33. data/lib/prevoty/responses/validate_token.rb +10 -0
  34. data/lib/prevoty/version.rb +3 -0
  35. data/prevoty.gemspec +25 -0
  36. data/test/specs/client_spec.rb +563 -0
  37. data/test/test_helper.rb +10 -0
  38. metadata +124 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 63fa617b429dc2087bbf0917932fc28f49e12b7c
4
+ data.tar.gz: e1050721f2a1332245c474607adfc086901887fc
5
+ SHA512:
6
+ metadata.gz: e6f7ac8b2a3b01e3ecfff195e68a553b49f7462a69413a27c13236b39002dcdfa3cf4d3a50d950662f5a8a1b2ba2da42d12811b0a79e3b275c6220f120e42abd
7
+ data.tar.gz: c05eb8efdf398245f98fcc90daec454f0eb5f3dfdf0b5ce0a75dd70e0b6df76454c4f46f53ad0eb208ad5fcec171fb65769e0bad096b90e936dea8482fad7d1d
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .*swp
19
+ .DS_Store
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Prevoty
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,38 @@
1
+ # Prevoty
2
+
3
+ The Prevoty REST API is the easiest way for individuals and organizations to
4
+ prevent cross-site scripting (XSS) attacks in their web applications. The API
5
+ has been designed to provide simple access to the powerful content analysis
6
+ systems and intelligence tools that Prevoty has developed.
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ gem 'prevoty'
13
+
14
+ And then execute:
15
+
16
+ $ bundle
17
+
18
+ Or install it yourself as:
19
+
20
+ $ gem install prevoty
21
+
22
+ ## Usage
23
+
24
+ 1) Pull a copy or .zip/.tar of this repository
25
+
26
+ 2) Make sure you have an API key (located in your Prevoty Console http://prevoty.com)
27
+
28
+ 3) Edit `example.rb` - you will want to put in your API and configuration keys
29
+
30
+ 4) Run `ruby example.rb`
31
+
32
+ ## Contributing
33
+
34
+ 1. Fork it ( http://github.com/prevoty/prevoty-ruby/fork )
35
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
36
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
37
+ 4. Push to the branch (`git push origin my-new-feature`)
38
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ task :default => :test
5
+
6
+ Rake::TestTask.new do |t|
7
+ t.pattern = './test/**/*_spec.rb'
8
+ end
data/lib/prevoty.rb ADDED
@@ -0,0 +1,31 @@
1
+ require 'prevoty/version'
2
+ require 'prevoty/client'
3
+ require 'prevoty/pattern'
4
+ require 'prevoty/hash'
5
+ require 'prevoty/crypto'
6
+
7
+ # exceptions
8
+ require 'prevoty/exceptions/bad_input_parameter'
9
+ require 'prevoty/exceptions/bad_api_key'
10
+ require 'prevoty/exceptions/internal_error'
11
+ require 'prevoty/exceptions/account_quota_exceeded'
12
+
13
+ # server responses
14
+ require 'prevoty/responses/api_key_info'
15
+ require 'prevoty/responses/filter_content'
16
+ require 'prevoty/responses/filter_statistics'
17
+ require 'prevoty/responses/generate_token'
18
+ require 'prevoty/responses/validate_token'
19
+ require 'prevoty/responses/delete_token'
20
+ require 'prevoty/responses/query_analysis'
21
+ require 'prevoty/responses/input_validation'
22
+ require 'prevoty/responses/hash_result'
23
+ require 'prevoty/responses/encrypt_result'
24
+ require 'prevoty/responses/decrypt_result'
25
+ require 'prevoty/responses/rsa_public_key'
26
+ require 'prevoty/responses/rsa_private_key'
27
+ require 'prevoty/responses/ecdsa_public_key'
28
+ require 'prevoty/responses/ecdsa_private_key'
29
+ require 'prevoty/responses/rsa_signature'
30
+ require 'prevoty/responses/ecdsa_signature'
31
+ require 'prevoty/responses/signature_verify'
@@ -0,0 +1,341 @@
1
+ require 'httparty'
2
+ require 'json'
3
+
4
+ module Prevoty
5
+ class Client
6
+ attr_accessor :api_key, :base
7
+
8
+ def initialize(api_key=nil, base=nil)
9
+ @api_key = api_key
10
+ @base = base ||= 'https://api.prevoty.com'
11
+ end
12
+
13
+ def verify_api_key
14
+ params = {api_key: @api_key}
15
+
16
+ response = HTTParty.get("#{@base}/1/key/verify", query: params)
17
+ case response.code
18
+ when 200 then return true
19
+ when 400 then raise BadInputParameter
20
+ when 403 then raise BadAPIKey
21
+ when 500 then raise InternalError
22
+ else false
23
+ end
24
+ end
25
+
26
+ def api_key_info
27
+ params = {api_key: @api_key}
28
+
29
+ response = HTTParty.get("#{@base}/1/key/info", query: params)
30
+ case response.code
31
+ when 200 then APIKeyInfo.new(JSON.parse(response.body))
32
+ when 400 then raise BadInputParameter
33
+ when 403 then raise BadAPIKey
34
+ when 500 then raise InternalError
35
+ else raise Exception
36
+ end
37
+ end
38
+
39
+ def verify_content_configuration(configuration_key)
40
+ params = {api_key: @api_key, rule_key: configuration_key}
41
+
42
+ response = HTTParty.get("#{@base}/1/rule/verify", query: params)
43
+ case response.code
44
+ when 200 then return true
45
+ when 400 then raise BadInputParameter
46
+ when 403 then raise BadAPIKey
47
+ when 500 then raise InternalError
48
+ else raise Exception
49
+ end
50
+ end
51
+
52
+ def filter_content(input, configuration_key)
53
+ params = {api_key: @api_key, rule_key: configuration_key, input: input}
54
+
55
+ response = HTTParty.post("#{@base}/1/xss/filter", query: params)
56
+ case response.code
57
+ when 200 then return FilterContent.new(JSON.parse(response.body))
58
+ when 400 then raise BadInputParameter
59
+ when 403 then raise BadAPIKey
60
+ when 413 then raise RequestTooLarge
61
+ when 500 then raise InternalError
62
+ when 507 then raise AccountQuotaExceeded
63
+ else raise Exception
64
+ end
65
+ end
66
+
67
+ def bulk_filter(input, configuration_key)
68
+ params = {api_key: @api_key, rule_key: configuration_key, input: input}
69
+
70
+ response = HTTParty.post("#{@base}/1/xss/bulkfilter", query: params)
71
+ case response.code
72
+ when 200 then return FilterContent.new(JSON.parse(response.body))
73
+ when 400 then raise BadInputParameter
74
+ when 403 then raise BadAPIKey
75
+ when 413 then raise RequestTooLarge
76
+ when 500 then raise InternalError
77
+ when 507 then raise AccountQuotaExceeded
78
+ else raise Exception
79
+ end
80
+ end
81
+
82
+ def generate_timed_token(user_identifier, action, ttl)
83
+ params = {api_key: @api_key, user_identifier: user_identifier, action: action, ttl: ttl}
84
+
85
+ response = HTTParty.get("#{@base}/1/token/timed/generate", query: params)
86
+ case response.code
87
+ when 200 then return GenerateToken.new(JSON.parse(response.body))
88
+ when 400 then raise BadInputParameter
89
+ when 403 then raise BadAPIKey
90
+ when 500 then raise InternalError
91
+ when 507 then raise AccountQuotaExceeded
92
+ else raise Exception
93
+ end
94
+ end
95
+
96
+ def validate_timed_token(user_identifier, action, token)
97
+ params = {api_key: @api_key, user_identifier: user_identifier, action: action, token: token}
98
+
99
+ response = HTTParty.get("#{@base}/1/token/timed/validate", query: params)
100
+ case response.code
101
+ when 200 then return ValidateToken.new(JSON.parse(response.body))
102
+ when 400 then raise BadInputParameter
103
+ when 403 then raise BadAPIKey
104
+ when 500 then raise InternalError
105
+ when 507 then raise AccountQuotaExceeded
106
+ else raise Exception
107
+ end
108
+ end
109
+
110
+ def delete_timed_token(user_identifier, action, token)
111
+ params = {api_key: @api_key, user_identifier: user_identifier, action: action, token: token}
112
+
113
+ response = HTTParty.get("#{@base}/1/token/timed/delete", query: params)
114
+ case response.code
115
+ when 200 then return DeleteToken.new(JSON.parse(response.body))
116
+ when 400 then raise BadInputParameter
117
+ when 403 then raise BadAPIKey
118
+ when 500 then raise InternalError
119
+ when 507 then raise AccountQuotaExceeded
120
+ else raise Exception
121
+ end
122
+ end
123
+
124
+ def generate_persisted_token(user_identifier, action)
125
+ params = {api_key: @api_key, user_identifier: user_identifier, action: action}
126
+
127
+ response = HTTParty.get("#{@base}/1/token/persisted/generate", query: params)
128
+ case response.code
129
+ when 200 then return GenerateToken.new(JSON.parse(response.body))
130
+ when 400 then raise BadInputParameter
131
+ when 403 then raise BadAPIKey
132
+ when 500 then raise InternalError
133
+ when 507 then raise AccountQuotaExceeded
134
+ else raise Exception
135
+ end
136
+ end
137
+
138
+ def validate_persisted_token(user_identifier, action, token)
139
+ params = {api_key: @api_key, user_identifier: user_identifier, action: action, token: token}
140
+
141
+ response = HTTParty.get("#{@base}/1/token/persisted/validate", query: params)
142
+ case response.code
143
+ when 200 then return ValidateToken.new(JSON.parse(response.body))
144
+ when 400 then raise BadInputParameter
145
+ when 403 then raise BadAPIKey
146
+ when 500 then raise InternalError
147
+ when 507 then raise AccountQuotaExceeded
148
+ else raise Exception
149
+ end
150
+ end
151
+
152
+ def delete_persisted_token(user_identifier, action, token)
153
+ params = {api_key: @api_key, user_identifier: user_identifier, action: action, token: token}
154
+
155
+ response = HTTParty.get("#{@base}/1/token/persisted/delete", query: params)
156
+ case response.code
157
+ when 200 then return DeleteToken.new(JSON.parse(response.body))
158
+ when 400 then raise BadInputParameter
159
+ when 403 then raise BadAPIKey
160
+ when 500 then raise InternalError
161
+ when 507 then raise AccountQuotaExceeded
162
+ else raise Exception
163
+ end
164
+ end
165
+
166
+ def analyze_query(query, config_key)
167
+ params = {api_key: @api_key, query: query, config_key: config_key}
168
+
169
+ response = HTTParty.post("#{@base}/1/query/parse", query: params)
170
+ case response.code
171
+ when 200 then return QueryAnalysis.new(JSON.parse(response.body))
172
+ when 400 then raise BadInputParameter
173
+ when 403 then raise BadAPIKey
174
+ when 500 then raise InternalError
175
+ when 507 then raise AccountQuotaExceeded
176
+ else raise Exception
177
+ end
178
+ end
179
+
180
+ def validate_pattern(pattern, input)
181
+ params = {api_key: @api_key, input: input}
182
+
183
+ return call_pattern("#{@base}/1/pattern/#{pattern}", params)
184
+ end
185
+
186
+ def validate_string(input, min, max, length)
187
+ params = {api_key: @api_key, input: input, min: min, max: max, length: length}
188
+
189
+ return call_pattern("#{@base}/1/pattern/string", params)
190
+ end
191
+
192
+ def hash(input, function)
193
+ params = {api_key: @api_key, payload: input, function: function}
194
+
195
+ response = HTTParty.post("#{@base}/1/crypto/hash", query: params)
196
+ case response.code
197
+ when 200 then return HashResult.new(JSON.parse(response.body))
198
+ when 400 then raise BadInputParameter
199
+ when 403 then raise BadAPIKey
200
+ when 500 then raise InternalError
201
+ when 507 then raise AccountQuotaExceeded
202
+ else raise Exception
203
+ end
204
+ end
205
+
206
+ def encrypt(input, algorithm, mode)
207
+ params = {api_key: @api_key, payload: input, algorithm: algorithm, mode: mode}
208
+
209
+ response = HTTParty.post("#{@base}/1/crypto/encrypt", query: params)
210
+ case response.code
211
+ when 200 then return EncryptResult.new(JSON.parse(response.body))
212
+ when 400 then raise BadInputParameter
213
+ when 403 then raise BadAPIKey
214
+ when 500 then raise InternalError
215
+ when 507 then raise AccountQuotaExceeded
216
+ else raise Exception
217
+ end
218
+ end
219
+
220
+ def decrypt(result)
221
+ params = {api_key: @api_key, obj: result.to_json}
222
+
223
+ response = HTTParty.post("#{@base}/1/crypto/decrypt", query: params)
224
+ case response.code
225
+ when 200 then return DecryptResult.new(JSON.parse(response.body))
226
+ when 400 then raise BadInputParameter
227
+ when 403 then raise BadAPIKey
228
+ when 500 then raise InternalError
229
+ when 507 then raise AccountQuotaExceeded
230
+ else raise Exception
231
+ end
232
+ end
233
+
234
+ def generate_rsa_keypair(keysize)
235
+ params = {api_key: @api_key, algorithm: Prevoty::Crypto::KeyAlgorithms::RSA_PKCS, meta: keysize}
236
+
237
+ response = HTTParty.post("#{@base}/1/crypto/genkeypair", query: params)
238
+ case response.code
239
+ when 200 then return RSAPrivateKey.new(JSON.parse(response.body))
240
+ when 400 then raise BadInputParameter
241
+ when 403 then raise BadAPIKey
242
+ when 500 then raise InternalError
243
+ when 507 then raise AccountQuotaExceeded
244
+ else raise Exception
245
+ end
246
+ end
247
+
248
+ def generate_ecdsa_keypair(curve)
249
+ params = {api_key: @api_key, algorithm: Prevoty::Crypto::KeyAlgorithms::ECDSA, meta: curve}
250
+
251
+ response = HTTParty.post("#{@base}/1/crypto/genkeypair", query: params)
252
+ case response.code
253
+ when 200 then return ECDSAPrivateKey.new(JSON.parse(response.body))
254
+ when 400 then raise BadInputParameter
255
+ when 403 then raise BadAPIKey
256
+ when 500 then raise InternalError
257
+ when 507 then raise AccountQuotaExceeded
258
+ else raise Exception
259
+ end
260
+ end
261
+
262
+ def rsa_pss_signature(payload, func, private_key, options)
263
+ params = {api_key: @api_key, algorithm: Prevoty::Crypto::KeyAlgorithms::RSA_PSS, hash: func, key: private_key.to_json, payload: payload, opt: options}
264
+ return call_rsa_signature(params)
265
+ end
266
+
267
+ def rsa_pkcs_signature(payload, func, private_key)
268
+ params = {api_key: @api_key, algorithm: Prevoty::Crypto::KeyAlgorithms::RSA_PKCS, hash: func, key: private_key.to_json, payload: payload}
269
+ return call_rsa_signature(params)
270
+ end
271
+
272
+ def ecdsa_signature(payload, func, private_key)
273
+ params = {api_key: @api_key, algorithm: Prevoty::Crypto::KeyAlgorithms::ECDSA, hash: func, key: private_key.to_json, payload: payload}
274
+ return call_ecdsa_signature(params)
275
+ end
276
+
277
+ def verify_rsa_pss_signature(payload, func, public_key, signature, options)
278
+ params = {api_key: @api_key, algorithm: Prevoty::Crypto::KeyAlgorithms::RSA_PSS, hash: func, key: public_key.to_json, sig: signature.to_json, payload: payload, opt: options}
279
+ return call_verify_signature(params)
280
+ end
281
+
282
+ def verify_rsa_pkcs_signature(payload, func, public_key, signature)
283
+ params = {api_key: @api_key, algorithm: Prevoty::Crypto::KeyAlgorithms::RSA_PKCS, hash: func, key: public_key.to_json, sig: signature.to_json, payload: payload}
284
+ return call_verify_signature(params)
285
+ end
286
+
287
+ def verify_ecdsa_signature(payload, func, public_key, signature)
288
+ params = {api_key: @api_key, algorithm: Prevoty::Crypto::KeyAlgorithms::ECDSA, hash: func, key: public_key.to_json, sig: signature.to_json, payload: payload}
289
+ return call_verify_signature(params)
290
+ end
291
+
292
+ private
293
+ def call_pattern(url, params)
294
+ response = HTTParty.get(url, query: params)
295
+ case response.code
296
+ when 200 then return InputValidation.new(JSON.parse(response.body))
297
+ when 400 then raise BadInputParameter
298
+ when 403 then raise BadAPIKey
299
+ when 500 then raise InternalError
300
+ when 507 then raise AccountQuotaExceeded
301
+ else raise Exception
302
+ end
303
+ end
304
+
305
+ def call_rsa_signature(params)
306
+ response = HTTParty.post("#{@base}/1/crypto/sign", query: params)
307
+ case response.code
308
+ when 200 then return RSASignature.new(JSON.parse(response.body))
309
+ when 400 then raise BadInputParameter
310
+ when 403 then raise BadAPIKey
311
+ when 500 then raise InternalError
312
+ when 507 then raise AccountQuotaExceeded
313
+ else raise Exception
314
+ end
315
+ end
316
+
317
+ def call_ecdsa_signature(params)
318
+ response = HTTParty.post("#{@base}/1/crypto/sign", query: params)
319
+ case response.code
320
+ when 200 then return ECDSASignature.new(JSON.parse(response.body))
321
+ when 400 then raise BadInputParameter
322
+ when 403 then raise BadAPIKey
323
+ when 500 then raise InternalError
324
+ when 507 then raise AccountQuotaExceeded
325
+ else raise Exception
326
+ end
327
+ end
328
+
329
+ def call_verify_signature(params)
330
+ response = HTTParty.post("#{@base}/1/crypto/verify", query: params)
331
+ case response.code
332
+ when 200 then return SignatureVerify.new(JSON.parse(response.body))
333
+ when 400 then raise BadInputParameter
334
+ when 403 then raise BadAPIKey
335
+ when 500 then raise InternalError
336
+ when 507 then raise AccountQuotaExceeded
337
+ else raise Exception
338
+ end
339
+ end
340
+ end
341
+ end