roauth 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/LICENSE +19 -0
  2. data/README.markdown +38 -0
  3. data/lib/roauth.rb +102 -0
  4. metadata +58 -0
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2010 Alex MacCaw
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.markdown ADDED
@@ -0,0 +1,38 @@
1
+ Based on SOAuth: http://github.com/tofumatt/SOAuth
2
+
3
+ A *simple* OAuth library that supports OAuth header signing, and header verifying.
4
+
5
+ gem install roauth
6
+
7
+ Example Client:
8
+
9
+ uri = 'https://twitter.com/direct_messages.json'
10
+ oauth = {
11
+ :consumer_key => "consumer_key",
12
+ :consumer_secret => "consumer_secret",
13
+ :access_key => "access_key",
14
+ :access_secret => "access_secret"
15
+ }
16
+ params = {
17
+ 'count' => "11",
18
+ 'since_id' => "5000"
19
+ }
20
+ oauth_header = ROAuth.header(oauth, uri, params)
21
+
22
+ http_uri = URI.parse(uri)
23
+ request = Net::HTTP.new(http_uri.host, http_uri.port)
24
+ request.get(uri.request_uri, {'Authorization', oauth_header})
25
+
26
+ Example Server:
27
+
28
+ oauth_header = ROAuth.parse(request.header['Authorization'])
29
+
30
+ # Implementation specific
31
+ consumer = Consumer.find_by_key(oauth_header[:consumer_key])
32
+ access_token = AccessToken.find_by_token(oauth_header[:access_key])
33
+ oauth = {
34
+ :consumer_secret => consumer.secret,
35
+ :access_secret => access_token.secret
36
+ }
37
+
38
+ ROAuth.verify(oauth, oauth_header, request.request_uri, params) #=> true/false
data/lib/roauth.rb ADDED
@@ -0,0 +1,102 @@
1
+ require "base64"
2
+ require "openssl"
3
+ require "uri"
4
+
5
+ module ROAuth
6
+ class UnsupportedSignatureMethod < Exception; end
7
+ class MissingOAuthParams < Exception; end
8
+
9
+ # Supported {signature methods}[http://oauth.net/core/1.0/#signing_process];
10
+ SIGNATURE_METHODS = {"HMAC-SHA1" => OpenSSL::Digest::Digest.new("sha1")}
11
+ OAUTH_PARAMS = [:consumer_key, :token, :signature_method, :version, :nonce, :timestamp]
12
+
13
+ # Return an {OAuth "Authorization" HTTP header}[http://oauth.net/core/1.0/#auth_header] from request data
14
+ def header(oauth, uri, params = {}, http_method = :get)
15
+ oauth[:signature_method] ||= "HMAC-SHA1"
16
+ oauth[:version] ||= "1.0" # Assumed version, according to the spec
17
+ oauth[:nonce] ||= Base64.encode64(OpenSSL::Random.random_bytes(32)).gsub(/\W/, '')
18
+ oauth[:timestamp] ||= Time.now.to_i
19
+ oauth[:token] ||= oauth.delete(:access_key)
20
+ oauth[:token_secret] ||= oauth.delete(:access_secret)
21
+
22
+ sig_params = params.dup
23
+ sig_params.merge!(oauth_params(oauth))
24
+ sig_params.merge!(:oauth_signature => escape(signature(oauth, uri, sig_params, http_method)))
25
+
26
+ %{OAuth } + sig_params.map {|key, value| [key, value].join("=") }.join(", ")
27
+ end
28
+
29
+ def parse(header)
30
+ header = header.dup
31
+ header = header.gsub!(/^OAuth\s/, "")
32
+ header = header.split(", ")
33
+ header = header.inject({}) {|hash, item|
34
+ key, value = item.split("=")
35
+ key.gsub!(/^oauth_/, "")
36
+ hash[key.to_sym] = unescape(value)
37
+ hash
38
+ }
39
+ header[:access_key] = header[:token]
40
+ header
41
+ end
42
+
43
+ def verify(oauth, header, uri, params = {}, http_method = :get)
44
+ header = header.is_a?(String) ? parse(header) : header.dup
45
+
46
+ client_signature = header.delete(:signature)
47
+ oauth[:consumer_key] ||= header[:consumer_key]
48
+ oauth[:token] ||= header[:token]
49
+
50
+ sig_params = params.dup
51
+ sig_params.merge!(oauth_params(header))
52
+
53
+ client_signature == signature(oauth, uri, sig_params, http_method)
54
+ end
55
+
56
+ protected
57
+ def oauth_params(oauth)
58
+ oauth = oauth.to_a.select {|key, value|
59
+ OAUTH_PARAMS.include?(key)
60
+ }
61
+ oauth.inject({}) {|hash, (key, value)|
62
+ hash["oauth_#{key}"] = escape(value)
63
+ hash
64
+ }
65
+ end
66
+
67
+ def signature(oauth, uri, params, http_method = :get)
68
+ sig_base = http_method.to_s.upcase + "&" + escape(uri) + "&" + normalize(params)
69
+ digest = SIGNATURE_METHODS[oauth[:signature_method]]
70
+ secret = "#{escape(oauth[:consumer_secret])}&#{escape(oauth[:token_secret])}"
71
+
72
+ puts "Secret: #{secret}"
73
+ puts "Sigbase: #{sig_base}"
74
+
75
+ Base64.encode64(OpenSSL::HMAC.digest(digest, secret, sig_base)).chomp.gsub(/\n/, "")
76
+ end
77
+
78
+ # Escape characters in a string according to the {OAuth spec}[http://oauth.net/core/1.0/]
79
+ def escape(value)
80
+ URI::escape(value.to_s, /[^a-zA-Z0-9\-\.\_\~]/) # Unreserved characters -- must not be encoded
81
+ end
82
+
83
+ def unescape(value)
84
+ URI::unescape(value)
85
+ end
86
+
87
+ # Normalize a string of parameters based on the {OAuth spec}[http://oauth.net/core/1.0/#rfc.section.9.1.1]
88
+ def normalize(params)
89
+ params.sort.map do |key, values|
90
+ if values.is_a?(Array)
91
+ # Multiple values were provided for a single key
92
+ # in a hash
93
+ values.sort.collect do |v|
94
+ [escape(key), escape(v)] * "%3D"
95
+ end
96
+ else
97
+ [escape(key), escape(values)] * "%3D"
98
+ end
99
+ end * "%26"
100
+ end
101
+ extend self
102
+ end
metadata ADDED
@@ -0,0 +1,58 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: roauth
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Alex MacCaw
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-02-20 00:00:00 +00:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Simple Ruby OAuth library
17
+ email: info@eribium.org
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - LICENSE
24
+ - README.markdown
25
+ files:
26
+ - LICENSE
27
+ - README.markdown
28
+ - lib/roauth.rb
29
+ has_rdoc: true
30
+ homepage: http://github.com/maccman/roauth
31
+ licenses: []
32
+
33
+ post_install_message:
34
+ rdoc_options:
35
+ - --charset=UTF-8
36
+ require_paths:
37
+ - lib
38
+ required_ruby_version: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: "0"
43
+ version:
44
+ required_rubygems_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: "0"
49
+ version:
50
+ requirements: []
51
+
52
+ rubyforge_project:
53
+ rubygems_version: 1.3.5
54
+ signing_key:
55
+ specification_version: 3
56
+ summary: Simple Ruby OAuth library
57
+ test_files: []
58
+