authy 2.1.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Authy [![Build Status](https://travis-ci.org/authy/authy-ruby.png?branch=api-updates)](https://travis-ci.org/authy/authy-ruby) [![Code Climate](https://codeclimate.com/github/authy/authy-ruby.png)](https://codeclimate.com/github/authy/authy-ruby)
1
+ # Authy [![Build Status](https://travis-ci.org/authy/authy-ruby.png?branch=master)](https://travis-ci.org/authy/authy-ruby) [![Code Climate](https://codeclimate.com/github/authy/authy-ruby.png)](https://codeclimate.com/github/authy/authy-ruby)
2
2
 
3
3
  Ruby library to access the Authy API
4
4
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.1.0
1
+ 2.2.0
data/authy.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "authy"
8
- s.version = "2.1.0"
8
+ s.version = "2.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Authy", "David A. Cuadrado"]
12
- s.date = "2013-06-03"
12
+ s.date = "2013-06-17"
13
13
  s.description = "Ruby library to access Authy services"
14
14
  s.email = "krawek@gmail.com"
15
15
  s.executables = ["authy-api-console"]
@@ -35,8 +35,10 @@ Gem::Specification.new do |s|
35
35
  "lib/authy/core_ext.rb",
36
36
  "lib/authy/models/user.rb",
37
37
  "lib/authy/response.rb",
38
+ "lib/authy/url_helpers.rb",
38
39
  "spec/authy/api_spec.rb",
39
40
  "spec/authy/response_spec.rb",
41
+ "spec/authy/url_helpers_spec.rb",
40
42
  "spec/spec_helper.rb"
41
43
  ]
42
44
  s.homepage = "http://github.com/authy/authy"
data/lib/authy.rb CHANGED
@@ -4,6 +4,7 @@ require 'httpclient'
4
4
  require 'httpclient/include_client'
5
5
  require 'json'
6
6
 
7
+ require 'authy/url_helpers'
7
8
  require 'authy/core_ext'
8
9
  require 'authy/response'
9
10
  require 'authy/models/user'
data/lib/authy/api.rb CHANGED
@@ -6,9 +6,12 @@ module Authy
6
6
  class API
7
7
  USER_AGENT = "authy-ruby"
8
8
 
9
+ include Authy::URL
10
+
9
11
  extend HTTPClient::IncludeClient
10
12
  include_http_client
11
13
 
14
+
12
15
  def self.register_user(attributes)
13
16
  api_key = attributes.delete(:api_key)
14
17
  params = {
@@ -32,10 +35,9 @@ module Authy
32
35
  user_id = params.delete(:id) || params.delete('id')
33
36
  params[:force] = true if params[:force].nil? && params['force'].nil?
34
37
 
35
- url = "#{Authy.api_uri}/protected/json/verify/#{escape_for_url(token)}/#{escape_for_url(user_id)}"
36
- response = http_client.get(url, {:api_key => Authy.api_key}.merge(params))
37
-
38
- Authy::Response.new(response)
38
+ get_request("protected/json/verify/:token/:user_id", params.merge({
39
+ "token" => token,
40
+ "user_id" => user_id}))
39
41
  end
40
42
 
41
43
  # options:
@@ -44,10 +46,7 @@ module Authy
44
46
  def self.request_sms(params)
45
47
  user_id = params.delete(:id) || params.delete('id')
46
48
 
47
- url = "#{Authy.api_uri}/protected/json/sms/#{escape_for_url(user_id)}"
48
- response = http_client.get(url, {:api_key => Authy.api_key}.merge(params))
49
-
50
- Authy::Response.new(response)
49
+ get_request("protected/json/sms/:user_id", params.merge({"user_id" => user_id}))
51
50
  end
52
51
 
53
52
  # options:
@@ -56,10 +55,7 @@ module Authy
56
55
  def self.request_phone_call(params)
57
56
  user_id = params.delete(:id) || params.delete('id')
58
57
 
59
- url = "#{Authy.api_uri}/protected/json/call/#{escape_for_url(user_id)}"
60
- response = http_client.get(url, {:api_key => Authy.api_key}.merge(params))
61
-
62
- Authy::Response.new(response)
58
+ get_request("protected/json/call/:user_id", params.merge({"user_id" => user_id}))
63
59
  end
64
60
 
65
61
  # options:
@@ -67,44 +63,51 @@ module Authy
67
63
  def self.delete_user(params)
68
64
  user_id = params.delete(:id) || params.delete('id')
69
65
 
70
- url = "#{Authy.api_uri}/protected/json/users/delete/#{escape_for_url(user_id)}"
71
- response = http_client.post(url, {:api_key => Authy.api_key}.merge(params))
66
+ post_request("protected/json/users/delete/:user_id", params.merge({"user_id" =>user_id}))
67
+ end
68
+
69
+ private
72
70
 
71
+ def self.post_request(uri, params = {})
72
+ uri_params = keys_to_verify(uri, params)
73
+ state, error = validate_for_url(uri_params, params)
74
+
75
+ response = if state
76
+ url = "#{Authy.api_uri}/#{eval_uri(uri, params)}"
77
+ params = clean_uri_params(uri_params, params)
78
+ http_client.post(url, :body => escape_query({:api_key => Authy.api_key}.merge(params)))
79
+ else
80
+ build_error_response(error)
81
+ end
73
82
  Authy::Response.new(response)
74
83
  end
75
84
 
76
- private
77
- def self.escape_for_url(field)
78
- URI.escape(field.to_s.strip, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
85
+ def self.get_request(uri, params = {})
86
+ uri_params = keys_to_verify(uri, params)
87
+ state, error = validate_for_url(uri_params, params)
88
+ response = if state
89
+ url = "#{Authy.api_uri}/#{eval_uri(uri, params)}"
90
+ params = clean_uri_params(uri_params, params)
91
+ http_client.get(url, {:api_key => Authy.api_key}.merge(params))
92
+ else
93
+ build_error_response(error)
94
+ end
95
+ Authy::Response.new(response)
79
96
  end
80
97
 
81
- # Copied and extended from httpclient's HTTP::Message#escape_query()
82
- def self.escape_query(query, namespace = nil) # :nodoc:
83
- pairs = []
84
- query.each { |attr, value|
85
- left = namespace ? "#{namespace}[#{attr.to_s}]" : attr.to_s
86
- if values = Array.try_convert(value)
87
- values.each { |value|
88
- if value.respond_to?(:read)
89
- value = value.read
90
- end
91
-
92
- if value.kind_of?(Hash)
93
- pairs.push(escape_query(value, left+"[]"))
94
- else
95
- pairs.push(HTTP::Message.escape(left+ '[]') << '=' << HTTP::Message.escape(value.to_s))
96
- end
97
- }
98
- elsif values = Hash.try_convert(value)
99
- pairs.push(escape_query(values, left.dup))
100
- else
101
- if value.respond_to?(:read)
102
- value = value.read
103
- end
104
- pairs.push(HTTP::Message.escape(left) << '=' << HTTP::Message.escape(value.to_s))
105
- end
106
- }
107
- pairs.join('&')
98
+ def self.build_error_response(error = "blank uri param found")
99
+ OpenStruct.new(
100
+ {
101
+ 'status' => 400,
102
+ 'body' =>
103
+ {
104
+ 'success' => false,
105
+ 'message' => error,
106
+ 'errors' => {
107
+ 'message' => error
108
+ }
109
+ }.to_json
110
+ })
108
111
  end
109
112
  end
110
113
  end
@@ -0,0 +1,74 @@
1
+ module Authy
2
+ module URL
3
+ def self.included receiver
4
+ receiver.extend ClassMethods
5
+ end
6
+
7
+ module ClassMethods
8
+ def keys_to_verify(uri, params)
9
+ uri.scan(/:(\w+)/).flatten
10
+ end
11
+
12
+ def clean_uri_params(uri_params, params)
13
+ params.reject { |k, v| uri_params.include? k}
14
+ end
15
+
16
+ def eval_uri(uri, params = {})
17
+ uri.gsub(/:\w+/) {|s| params[s.gsub(":", "")]}
18
+ end
19
+
20
+ def validate_for_url(names, to_validate = {})
21
+ names.each do |name|
22
+ value = to_validate[name]
23
+ if value.nil? or value.to_s.empty? or value.to_s.split(" ").size == 0
24
+ puts "#{name} param is blank."
25
+ return [ false, "#{name} is blank." ]
26
+ end
27
+ end
28
+ [ true, ""]
29
+ end
30
+
31
+ def escape_for_url(field)
32
+ URI.escape(field.to_s.strip, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
33
+ end
34
+
35
+ def to_param(left, right)
36
+ HTTP::Message.escape(left) + '=' + HTTP::Message.escape(right.to_s)
37
+ end
38
+
39
+ def params_from_array(left, values)
40
+ values.map do |value|
41
+ if value.respond_to?(:read)
42
+ value = value.read
43
+ end
44
+
45
+ if value.kind_of?(Hash)
46
+ escape_query(value, left+"[]")
47
+ else
48
+ to_param(left + '[]', value)
49
+ end
50
+ end
51
+ end
52
+
53
+ # Copied and extended from httpclient's HTTP::Message#escape_query()
54
+ def escape_query(query, namespace = nil) # :nodoc:
55
+ pairs = []
56
+
57
+ query.each do |attr, value|
58
+ left = namespace ? "#{namespace}[#{attr.to_s}]" : attr.to_s
59
+ if values = Array.try_convert(value)
60
+ pairs += params_from_array(left, values)
61
+ elsif values = Hash.try_convert(value)
62
+ pairs.push(escape_query(values, left.dup))
63
+ else
64
+ if value.respond_to?(:read)
65
+ value = value.read
66
+ end
67
+ pairs.push(to_param(left, value))
68
+ end
69
+ end
70
+ pairs.join('&')
71
+ end
72
+ end
73
+ end
74
+ end
@@ -33,6 +33,7 @@ describe "Authy::API" do
33
33
  user.should_not be_ok
34
34
  user.errors['message'].should =~ /invalid api key/i
35
35
  end
36
+
36
37
  end
37
38
 
38
39
  describe "verificating tokens" do
@@ -114,4 +115,25 @@ describe "Authy::API" do
114
115
  end
115
116
  end
116
117
  end
118
+
119
+ describe "blank params" do
120
+ before do
121
+ @user = Authy::API.register_user(:email => generate_email, :cellphone => generate_cellphone, :country_code => 1)
122
+ @user.should be_ok
123
+ end
124
+
125
+ [:request_sms, :request_phone_call, :delete_user].each do |method|
126
+ it "should return a proper response with the errors for #{method}" do
127
+ response = Authy::API.send(method, :id => nil)
128
+ response.should_not be_ok
129
+ response.message.should == "user_id is blank."
130
+ end
131
+ end
132
+
133
+ it "should return a prope response with the errors for verify" do
134
+ response = Authy::API.verify({})
135
+ response.should_not be_ok
136
+ response.message.should == "token is blank."
137
+ end
138
+ end
117
139
  end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Authy::URL" do
4
+ class Dummy
5
+ include Authy::URL
6
+ end
7
+
8
+ describe "escape_for_url" do
9
+ it "should user URI escape" do
10
+ URI.should_receive :escape
11
+ Dummy.escape_for_url("that")
12
+ end
13
+
14
+ it "should use Regexp" do
15
+ Regexp.should_receive(:new).with("[^#{URI::PATTERN::UNRESERVED}]").and_return(/a/)
16
+ Dummy.escape_for_url("that")
17
+ end
18
+ end
19
+
20
+ describe "to_param" do
21
+ it "should user HTTP::Message.escape" do
22
+ HTTP::Message.should_receive(:escape).exactly(2).times.and_return "basic string"
23
+ Dummy.to_param('key', 'value')
24
+ end
25
+
26
+ it "should paramify the left to right" do
27
+ Dummy.to_param('key', 'value').should == 'key=value'
28
+ end
29
+ end
30
+
31
+ describe "params_from_array" do
32
+ it "should return an array of params" do
33
+ Dummy.params_from_array("da key", ["one", "two"]).should == [HTTP::Message.escape("da key[]") + "=one", HTTP::Message.escape("da key[]") + "=two"]
34
+ end
35
+ end
36
+ end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: authy
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 2.1.0
5
+ version: 2.2.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Authy
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-06-03 00:00:00.000000000 Z
13
+ date: 2013-06-17 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  version_requirements: !ruby/object:Gem::Requirement
@@ -166,8 +166,10 @@ files:
166
166
  - lib/authy/core_ext.rb
167
167
  - lib/authy/models/user.rb
168
168
  - lib/authy/response.rb
169
+ - lib/authy/url_helpers.rb
169
170
  - spec/authy/api_spec.rb
170
171
  - spec/authy/response_spec.rb
172
+ - spec/authy/url_helpers_spec.rb
171
173
  - spec/spec_helper.rb
172
174
  homepage: http://github.com/authy/authy
173
175
  licenses:
@@ -183,7 +185,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
183
185
  - !ruby/object:Gem::Version
184
186
  segments:
185
187
  - 0
186
- hash: 1227098339926430603
188
+ hash: -1090702034643817061
187
189
  version: '0'
188
190
  required_rubygems_version: !ruby/object:Gem::Requirement
189
191
  none: false