TeleAuth 0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/README +106 -0
  2. data/lib/teleauth.rb +251 -0
  3. data/tests/ts_teleauth.rb +54 -0
  4. metadata +41 -0
data/README ADDED
@@ -0,0 +1,106 @@
1
+ == Synopsis
2
+
3
+ Ruby TeleAuth Module.
4
+
5
+ Allows for two-factor authentication within Ruby. Uses the
6
+ TeleAuth[http://www.teleauth.com] service.
7
+
8
+ == Author
9
+
10
+ Mohit Muthanna Cheppudira <mohit AT muthanna DOTcom>
11
+
12
+ == Copyright
13
+
14
+ Copyright (c) 2005 Mohit Muthanna Cheppudira.
15
+ Licensed under the GPL.
16
+
17
+ == Prerequisites
18
+
19
+ To use this module, you will need a TeleAuth API Key. Get yours
20
+ at [http://www.teleauth.com].
21
+
22
+ == Basic Usage
23
+
24
+ The following example calls a user on a specific phone
25
+ number and requests a PIN code.
26
+
27
+ require 'teleauth'
28
+
29
+ conn = TeleAuth::Client.new (
30
+ 'urls' = ['http://teleauth.com/api/auth'],
31
+ 'domain_id' = 'mydomain',
32
+ 'login' = 'dialer',
33
+ 'password' = 'bu4ger'
34
+ )
35
+
36
+ Register a user's phone number.
37
+
38
+ conn.register_phone(
39
+ 'ext_uid' => 'foobar',
40
+ 'phone' => '12332445443'
41
+ )
42
+
43
+ Call user and request PIN code.
44
+
45
+ conn.get_secret( 'ext_uid' => 'foobar' ) { |response|
46
+ puts "PIN code: #{ response['secret'] }"
47
+ }
48
+
49
+
50
+ == TeleAuth API
51
+
52
+ In brief, you can use any API command as a TeleAuth::Client
53
+ method. Arguments are provided as hash parameters. Responses
54
+ are returned as Ruby hashes.
55
+
56
+ Examples:
57
+
58
+ response = conn.validate_user
59
+
60
+ conn.validate_user { |response|
61
+ # do something
62
+ }
63
+
64
+ Register a user's phone number and PIN code.
65
+
66
+ conn.register_phone(
67
+ 'ext_uid' => 'foobar',
68
+ 'phone' => '12332445443',
69
+ 'pin' => '45334',
70
+ )
71
+
72
+ Call the user and validate PIN
73
+
74
+ conn.validate_phone( 'ext_uid' => 'foobar' ) { |response|
75
+ if response['login'] == 'PASS'
76
+ puts "Valid PIN code."
77
+ else
78
+ puts "Authorization failed"
79
+ end
80
+ end
81
+
82
+
83
+ For the TeleAuth API reference, visit http://teleauth.com
84
+
85
+ == Logging, Exceptions and Errors
86
+
87
+ The class raises the TeleAuth::APIError exception if the API command
88
+ failed.
89
+
90
+ If you have multiple URLs, eg. for failover, the module can
91
+ inform you if a failover took place.
92
+
93
+ conn.on_command_fail { |url|
94
+ puts "Failed to connect to #{ url }. Trying next one."
95
+ }
96
+
97
+
98
+ If you need nice debug output, use on_log:
99
+
100
+ con.on_log { |msg|
101
+ $stderr.puts( "LOG: #{ msg }" )
102
+ end
103
+
104
+ == Support
105
+
106
+ Get on the {TeleAuth Mailing List}[http://lists.sourceforge.net/lists/listinfo/teleauth-users]
@@ -0,0 +1,251 @@
1
+ require 'uri'
2
+ require 'yaml'
3
+ require 'net/http'
4
+
5
+ =begin rdoc
6
+
7
+ == Synopsis
8
+
9
+ Ruby TeleAuth Module.
10
+ $Id$
11
+
12
+ Allows for two-factor authentication within Ruby. Uses the
13
+ TeleAuth[http://www.teleauth.com] service.
14
+
15
+ == Author
16
+
17
+ Mohit Muthanna Cheppudira mohit AT muthanna DOT com
18
+
19
+ == Copyright
20
+
21
+ Copyright (c) 2005 Mohit Muthanna Cheppudira.
22
+ Licensed under the GPL.
23
+
24
+ =end
25
+
26
+ module TeleAuth
27
+
28
+ =begin rdoc
29
+ This exception is raised if an API command could
30
+ not be successfully sent to any of the TeleAuth
31
+ URLs.
32
+ =end
33
+
34
+ class APIError < Exception; end
35
+
36
+ =begin rdoc
37
+
38
+ This is the TeleAuth Client Class. Basic usage:
39
+
40
+ The following example calls a user on a specific phone
41
+ number and requests a PIN code.
42
+
43
+ require 'teleauth'
44
+
45
+ conn = TeleAuth::Client.new (
46
+ 'urls' = ['http://teleauth.com/api/auth'],
47
+ 'domain_id' = 'mydomain',
48
+ 'login' = 'dialer',
49
+ 'password' = 'bu4ger'
50
+ )
51
+
52
+ # Register a user's phone number.
53
+ conn.register_phone(
54
+ 'ext_uid' => 'foobar',
55
+ 'phone' => '12332445443'
56
+ )
57
+
58
+ conn.get_secret( 'ext_uid' => 'foobar' ) { |response|
59
+ puts "PIN code: #{ response['secret'] }"
60
+ }
61
+
62
+ =end
63
+
64
+ class Client
65
+
66
+ =begin rdoc
67
+ [auth] A hash that consists of API authentication parameters.
68
+ [urls] An array of API URLs.
69
+ =end
70
+
71
+ attr_accessor :auth, :urls
72
+
73
+ =begin rdoc
74
+ At a minimum, this method requires a list of URLs, and
75
+ the API Key, like so:
76
+
77
+
78
+ conn = TeleAuth::Client.new(
79
+ "urls" => ["http://teleauth.com/apu/auth", "http://backup.teleauth.com/api/auth"],
80
+ "domain_id" => "public.sample",
81
+ "login" => "admin",
82
+ "password" => "p4ss"
83
+ )
84
+
85
+ The URLs are a list of primary and failover API servers. When
86
+ an API command is sent, each of these servers are cycled through
87
+ until one of them works.
88
+ =end
89
+
90
+ def initialize( params = {} )
91
+ if params.has_key?( 'urls' )
92
+ self.urls = params['urls']
93
+
94
+ # Delete this key, as it shouldn't be passed in
95
+ # the API request.
96
+ params.delete( 'urls' )
97
+ else
98
+ self.urls = []
99
+ end
100
+
101
+ @auth = params
102
+ @on_command_fail = proc {}
103
+ @on_log = proc {}
104
+ end
105
+
106
+ =begin rdoc
107
+ Setup a code-block to execute if one of the URLs fail. This could
108
+ be useful for logging, for example. It passes the URL of the API
109
+ server that failed.
110
+
111
+ conn.on_command_fail { |url|
112
+ $stderr.puts "Failed to send command to #{ url }"
113
+ }
114
+ =end
115
+
116
+ def on_command_fail( &block )
117
+ @on_command_fail = block
118
+ end
119
+
120
+ =begin rdoc
121
+ Our logger. Call this and specify a logging routing to receive more
122
+ debug information.
123
+
124
+ conn.on_log { |msg|
125
+ $stderr.puts "LOG: #{ msg }"
126
+ end
127
+ =end
128
+
129
+ def on_log( &block )
130
+ @on_log = block
131
+ end
132
+
133
+ def log( *args )
134
+ @on_log.call( *args )
135
+ end
136
+
137
+ =begin rdoc
138
+ The main communications routine. Establish a connection to the API
139
+ server, and send the command. Private.
140
+ =end
141
+
142
+ def api_send( command_hash )
143
+
144
+ # For each URL...
145
+ @urls.each do |url|
146
+ log( "Trying #{ url }" )
147
+ uri = URI.parse( url )
148
+
149
+ # Make sure it's HTTP/(S) ...
150
+ if uri.scheme == "http"
151
+ response = ""
152
+
153
+ # Build the POST parameters..
154
+ post_params = command_hash.keys.collect { |key|
155
+ key + "=" + command_hash[key]
156
+ }.join( "&" )
157
+
158
+ log( "Sending: #{ post_params }" )
159
+
160
+ begin
161
+ Net::HTTP.start( uri.host ) do |query|
162
+ response = query.post( uri.path, post_params )
163
+ end
164
+
165
+ log( "Response: #{ response.message }" )
166
+
167
+ if response.message == "OK"
168
+ log( "Body: #{ response.body }" )
169
+ return response.body
170
+ else
171
+ # HTTP level failure...
172
+ @on_command_fail.call( url )
173
+ next
174
+ end
175
+ rescue Exception => e
176
+ # Socket level failure...
177
+ @on_command_fail.call( url )
178
+ next
179
+ end
180
+ else
181
+ # Unsupported URI scheme...
182
+ @on_command_fail.call( url )
183
+ end
184
+ end
185
+
186
+ # All failed. Return Nil.
187
+ return nil
188
+ end
189
+
190
+ =begin rdoc
191
+ This method creates a hash with parameters for api_send
192
+ =end
193
+ def send_command( *args )
194
+ # Extract the instance method name
195
+ command = args.shift
196
+
197
+ # No Arguments?
198
+ if (params = args.shift).nil?
199
+ params = Hash.new
200
+ end
201
+
202
+ # Pass the extracted method name as the API command
203
+ command_hash = auth.merge( params ).merge( 'cmd' => command.to_s )
204
+ response = api_send( command_hash )
205
+
206
+ raise APIError if response.nil?
207
+ response
208
+ end
209
+
210
+ =begin rdoc
211
+ Check to see if we have connectivity by sending a "version" API command.
212
+ =end
213
+
214
+ def ping?
215
+ begin
216
+ version
217
+ rescue Exception => e
218
+ return false
219
+ end
220
+
221
+ true
222
+ end
223
+
224
+ =begin rdoc
225
+ This is where the magic happens. Any instance method that is not defined
226
+ reaches here. We just propogate the request to send_command, which
227
+ extracts the method name, and substitutes it for the API command. This
228
+ get's fed to api_send.
229
+
230
+ This function also yields to a code block, so commands can be sent in
231
+ multiple forms:
232
+
233
+ conn.get_user_list { |user_list|
234
+ # ... do something with user_list
235
+ }
236
+
237
+ or
238
+
239
+ user_list = conn.get_user_list
240
+ =end
241
+
242
+ def method_missing( *args )
243
+ response = YAML::load( send_command( *args ) )
244
+ yield response if block_given?
245
+ response
246
+ end
247
+
248
+ protected :api_send, :log
249
+ end
250
+
251
+ end
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # PickAxe magic. Helps run tests from any directory.
4
+ $:.unshift File.join( File.dirname( __FILE__ ), "..", "lib" )
5
+
6
+ require 'teleauth'
7
+ require 'test/unit'
8
+
9
+ include TeleAuth
10
+
11
+ =begin rdoc
12
+ Test class for TeleAuth::Client.
13
+ =end
14
+
15
+ class TestClient < Test::Unit::TestCase
16
+ def setup
17
+
18
+ # Setup API Test parameters here. Make sure
19
+ # you use an invalid URL before a valid one
20
+ # to test failures.
21
+
22
+ @conn = Client.new(
23
+ "urls" => ["http://abc.d/f", "http://teleauth.com/api/auth"],
24
+ "domain_id" => "public.test",
25
+ "login" => "reader",
26
+ "password" => "reader"
27
+ )
28
+ end
29
+
30
+ def teardown
31
+ # Nothing to do...
32
+ end
33
+
34
+ def test_ping
35
+ assert_equal( @conn.ping?, true )
36
+ end
37
+
38
+ def test_commands
39
+ failed = false
40
+ @conn.on_command_fail {
41
+ failed = true
42
+ }
43
+
44
+ # Test both formats of commands...
45
+ assert_equal( @conn.validate_user['result'], 'OK' )
46
+
47
+ @conn.validate_user { |response|
48
+ assert_equal response['result'], 'OK'
49
+ }
50
+
51
+ # The first URL should have failed.
52
+ assert_equal failed, true
53
+ end
54
+ end
metadata ADDED
@@ -0,0 +1,41 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.8.10
3
+ specification_version: 1
4
+ name: TeleAuth
5
+ version: !ruby/object:Gem::Version
6
+ version: "0.5"
7
+ date: 2005-08-26
8
+ summary: Ruby library for the TeleAuth authentication system. Requires a TeleAuth API key.
9
+ require_paths:
10
+ - lib
11
+ email: mohit@muthanna.com
12
+ homepage: http://teleauth.com
13
+ rubyforge_project:
14
+ description:
15
+ autorequire: teleauth
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ -
22
+ - ">"
23
+ - !ruby/object:Gem::Version
24
+ version: 0.0.0
25
+ version:
26
+ platform: ruby
27
+ authors:
28
+ - Mohit Muthanna Cheppudira
29
+ files:
30
+ - lib/teleauth.rb
31
+ - tests/ts_teleauth.rb
32
+ - README
33
+ test_files:
34
+ - tests/ts_teleauth.rb
35
+ rdoc_options: []
36
+ extra_rdoc_files:
37
+ - README
38
+ executables: []
39
+ extensions: []
40
+ requirements: []
41
+ dependencies: []