oauth-instructure 0.4.8

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.
Files changed (89) hide show
  1. data/.gemtest +0 -0
  2. data/Gemfile +16 -0
  3. data/Gemfile.lock +47 -0
  4. data/HISTORY +174 -0
  5. data/LICENSE +20 -0
  6. data/README.rdoc +75 -0
  7. data/Rakefile +37 -0
  8. data/TODO +32 -0
  9. data/bin/oauth +5 -0
  10. data/examples/yql.rb +44 -0
  11. data/lib/digest/hmac.rb +104 -0
  12. data/lib/oauth.rb +13 -0
  13. data/lib/oauth/cli.rb +378 -0
  14. data/lib/oauth/client.rb +4 -0
  15. data/lib/oauth/client/action_pack.rb +9 -0
  16. data/lib/oauth/client/em_http.rb +120 -0
  17. data/lib/oauth/client/helper.rb +91 -0
  18. data/lib/oauth/client/net_http.rb +120 -0
  19. data/lib/oauth/consumer.rb +389 -0
  20. data/lib/oauth/core_ext.rb +31 -0
  21. data/lib/oauth/errors.rb +3 -0
  22. data/lib/oauth/errors/error.rb +4 -0
  23. data/lib/oauth/errors/problem.rb +14 -0
  24. data/lib/oauth/errors/unauthorized.rb +12 -0
  25. data/lib/oauth/helper.rb +109 -0
  26. data/lib/oauth/oauth.rb +13 -0
  27. data/lib/oauth/oauth_test_helper.rb +25 -0
  28. data/lib/oauth/request_proxy.rb +24 -0
  29. data/lib/oauth/request_proxy/action_controller_request.rb +116 -0
  30. data/lib/oauth/request_proxy/action_dispatch_request.rb +113 -0
  31. data/lib/oauth/request_proxy/base.rb +174 -0
  32. data/lib/oauth/request_proxy/curb_request.rb +55 -0
  33. data/lib/oauth/request_proxy/em_http_request.rb +66 -0
  34. data/lib/oauth/request_proxy/jabber_request.rb +41 -0
  35. data/lib/oauth/request_proxy/mock_request.rb +44 -0
  36. data/lib/oauth/request_proxy/net_http.rb +73 -0
  37. data/lib/oauth/request_proxy/rack_request.rb +44 -0
  38. data/lib/oauth/request_proxy/typhoeus_request.rb +53 -0
  39. data/lib/oauth/server.rb +66 -0
  40. data/lib/oauth/signature.rb +45 -0
  41. data/lib/oauth/signature/base.rb +110 -0
  42. data/lib/oauth/signature/hmac/base.rb +15 -0
  43. data/lib/oauth/signature/hmac/md5.rb +8 -0
  44. data/lib/oauth/signature/hmac/rmd160.rb +8 -0
  45. data/lib/oauth/signature/hmac/sha1.rb +9 -0
  46. data/lib/oauth/signature/hmac/sha2.rb +8 -0
  47. data/lib/oauth/signature/md5.rb +13 -0
  48. data/lib/oauth/signature/plaintext.rb +23 -0
  49. data/lib/oauth/signature/rsa/sha1.rb +46 -0
  50. data/lib/oauth/signature/sha1.rb +13 -0
  51. data/lib/oauth/token.rb +7 -0
  52. data/lib/oauth/tokens/access_token.rb +71 -0
  53. data/lib/oauth/tokens/consumer_token.rb +33 -0
  54. data/lib/oauth/tokens/request_token.rb +32 -0
  55. data/lib/oauth/tokens/server_token.rb +9 -0
  56. data/lib/oauth/tokens/token.rb +17 -0
  57. data/oauth.gemspec +148 -0
  58. data/tasks/deployment.rake +34 -0
  59. data/tasks/environment.rake +7 -0
  60. data/tasks/website.rake +17 -0
  61. data/test/cases/oauth_case.rb +19 -0
  62. data/test/cases/spec/1_0-final/test_construct_request_url.rb +62 -0
  63. data/test/cases/spec/1_0-final/test_normalize_request_parameters.rb +88 -0
  64. data/test/cases/spec/1_0-final/test_parameter_encodings.rb +86 -0
  65. data/test/cases/spec/1_0-final/test_signature_base_strings.rb +77 -0
  66. data/test/integration/consumer_test.rb +307 -0
  67. data/test/keys/rsa.cert +11 -0
  68. data/test/keys/rsa.pem +16 -0
  69. data/test/test_access_token.rb +26 -0
  70. data/test/test_action_controller_request_proxy.rb +133 -0
  71. data/test/test_consumer.rb +220 -0
  72. data/test/test_curb_request_proxy.rb +77 -0
  73. data/test/test_em_http_client.rb +80 -0
  74. data/test/test_em_http_request_proxy.rb +115 -0
  75. data/test/test_helper.rb +28 -0
  76. data/test/test_hmac_sha1.rb +20 -0
  77. data/test/test_net_http_client.rb +292 -0
  78. data/test/test_net_http_request_proxy.rb +72 -0
  79. data/test/test_oauth_helper.rb +94 -0
  80. data/test/test_rack_request_proxy.rb +40 -0
  81. data/test/test_request_token.rb +51 -0
  82. data/test/test_rsa_sha1.rb +59 -0
  83. data/test/test_server.rb +40 -0
  84. data/test/test_signature.rb +22 -0
  85. data/test/test_signature_base.rb +32 -0
  86. data/test/test_signature_plain_text.rb +31 -0
  87. data/test/test_token.rb +14 -0
  88. data/test/test_typhoeus_request_proxy.rb +80 -0
  89. metadata +274 -0
@@ -0,0 +1,44 @@
1
+ require 'oauth/request_proxy/base'
2
+ require 'uri'
3
+ require 'rack'
4
+
5
+ module OAuth::RequestProxy
6
+ class RackRequest < OAuth::RequestProxy::Base
7
+ proxies Rack::Request
8
+
9
+ def method
10
+ request.env["rack.methodoverride.original_method"] || request.request_method
11
+ end
12
+
13
+ def uri
14
+ request.url
15
+ end
16
+
17
+ def parameters
18
+ if options[:clobber_request]
19
+ options[:parameters] || {}
20
+ else
21
+ params = request_params.merge(query_params).merge(header_params)
22
+ params.merge(options[:parameters] || {})
23
+ end
24
+ end
25
+
26
+ def signature
27
+ parameters['oauth_signature']
28
+ end
29
+
30
+ protected
31
+
32
+ def query_params
33
+ request.GET
34
+ end
35
+
36
+ def request_params
37
+ if request.content_type and request.content_type.to_s.downcase.start_with?("application/x-www-form-urlencoded")
38
+ request.POST
39
+ else
40
+ {}
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,53 @@
1
+ require 'oauth/request_proxy/base'
2
+ require 'typhoeus'
3
+ require 'typhoeus/request'
4
+ require 'uri'
5
+ require 'cgi'
6
+
7
+ module OAuth::RequestProxy::Typhoeus
8
+ class Request < OAuth::RequestProxy::Base
9
+ # Proxy for signing Typhoeus::Request requests
10
+ # Usage example:
11
+ # oauth_params = {:consumer => oauth_consumer, :token => access_token}
12
+ # req = Typhoeus::Request.new(uri, options)
13
+ # oauth_helper = OAuth::Client::Helper.new(req, oauth_params.merge(:request_uri => uri))
14
+ # req.headers.merge!({"Authorization" => oauth_helper.header})
15
+ # hydra = Typhoeus::Hydra.new()
16
+ # hydra.queue(req)
17
+ # hydra.run
18
+ # response = req.response
19
+ proxies Typhoeus::Request
20
+
21
+ def method
22
+ request.method.to_s.upcase
23
+ end
24
+
25
+ def uri
26
+ options[:uri].to_s
27
+ end
28
+
29
+ def parameters
30
+ if options[:clobber_request]
31
+ options[:parameters]
32
+ else
33
+ post_parameters.merge(query_parameters).merge(options[:parameters] || {})
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def query_parameters
40
+ query = URI.parse(request.url).query
41
+ query ? CGI.parse(query) : {}
42
+ end
43
+
44
+ def post_parameters
45
+ # Post params are only used if posting form data
46
+ if method == 'POST'
47
+ OAuth::Helper.stringify_keys(request.params || {})
48
+ else
49
+ {}
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,66 @@
1
+ require 'oauth/helper'
2
+ require 'oauth/consumer'
3
+
4
+ module OAuth
5
+ # This is mainly used to create consumer credentials and can pretty much be ignored if you want to create your own
6
+ class Server
7
+ include OAuth::Helper
8
+ attr_accessor :base_url
9
+
10
+ @@server_paths = {
11
+ :request_token_path => "/oauth/request_token",
12
+ :authorize_path => "/oauth/authorize",
13
+ :access_token_path => "/oauth/access_token"
14
+ }
15
+
16
+ # Create a new server instance
17
+ def initialize(base_url, paths = {})
18
+ @base_url = base_url
19
+ @paths = @@server_paths.merge(paths)
20
+ end
21
+
22
+ def generate_credentials
23
+ [generate_key(16), generate_key]
24
+ end
25
+
26
+ def generate_consumer_credentials(params = {})
27
+ Consumer.new(*generate_credentials)
28
+ end
29
+
30
+ # mainly for testing purposes
31
+ def create_consumer
32
+ creds = generate_credentials
33
+ Consumer.new(creds[0], creds[1],
34
+ {
35
+ :site => base_url,
36
+ :request_token_path => request_token_path,
37
+ :authorize_path => authorize_path,
38
+ :access_token_path => access_token_path
39
+ })
40
+ end
41
+
42
+ def request_token_path
43
+ @paths[:request_token_path]
44
+ end
45
+
46
+ def request_token_url
47
+ base_url + request_token_path
48
+ end
49
+
50
+ def authorize_path
51
+ @paths[:authorize_path]
52
+ end
53
+
54
+ def authorize_url
55
+ base_url + authorize_path
56
+ end
57
+
58
+ def access_token_path
59
+ @paths[:access_token_path]
60
+ end
61
+
62
+ def access_token_url
63
+ base_url + access_token_path
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,45 @@
1
+ module OAuth
2
+ module Signature
3
+ # Returns a list of available signature methods
4
+ def self.available_methods
5
+ @available_methods ||= {}
6
+ end
7
+
8
+ # Build a signature from a +request+.
9
+ #
10
+ # Raises UnknownSignatureMethod exception if the signature method is unknown.
11
+ def self.build(request, options = {}, &block)
12
+ request = OAuth::RequestProxy.proxy(request, options)
13
+ klass = available_methods[
14
+ (request.signature_method ||
15
+ ((c = request.options[:consumer]) && c.options[:signature_method]) ||
16
+ "").downcase]
17
+ raise UnknownSignatureMethod, request.signature_method unless klass
18
+ klass.new(request, options, &block)
19
+ end
20
+
21
+ # Sign a +request+
22
+ def self.sign(request, options = {}, &block)
23
+ self.build(request, options, &block).signature
24
+ end
25
+
26
+ # Verify the signature of +request+
27
+ def self.verify(request, options = {}, &block)
28
+ self.build(request, options, &block).verify
29
+ end
30
+
31
+ # Create the signature base string for +request+. This string is the normalized parameter information.
32
+ #
33
+ # See Also: {OAuth core spec version 1.0, section 9.1.1}[http://oauth.net/core/1.0#rfc.section.9.1.1]
34
+ def self.signature_base_string(request, options = {}, &block)
35
+ self.build(request, options, &block).signature_base_string
36
+ end
37
+
38
+ # Create the body hash for a request
39
+ def self.body_hash(request, options = {}, &block)
40
+ self.build(request, options, &block).body_hash
41
+ end
42
+
43
+ class UnknownSignatureMethod < Exception; end
44
+ end
45
+ end
@@ -0,0 +1,110 @@
1
+ require 'oauth/signature'
2
+ require 'oauth/helper'
3
+ require 'oauth/request_proxy/base'
4
+ require 'base64'
5
+
6
+ module OAuth::Signature
7
+ class Base
8
+ include OAuth::Helper
9
+
10
+ attr_accessor :options
11
+ attr_reader :token_secret, :consumer_secret, :request
12
+
13
+ def self.implements(signature_method = nil)
14
+ return @implements if signature_method.nil?
15
+ @implements = signature_method
16
+ OAuth::Signature.available_methods[@implements] = self
17
+ end
18
+
19
+ def self.digest_class(digest_class = nil)
20
+ return @digest_class if digest_class.nil?
21
+ @digest_class = digest_class
22
+ end
23
+
24
+ def self.digest_klass(digest_klass = nil)
25
+ return @digest_klass if digest_klass.nil?
26
+ @digest_klass = digest_klass
27
+ end
28
+
29
+ def self.hash_class(hash_class = nil)
30
+ return @hash_class if hash_class.nil?
31
+ @hash_class = hash_class
32
+ end
33
+
34
+ def initialize(request, options = {}, &block)
35
+ raise TypeError unless request.kind_of?(OAuth::RequestProxy::Base)
36
+ @request = request
37
+ @options = options
38
+
39
+ ## consumer secret was determined beforehand
40
+
41
+ @consumer_secret = options[:consumer].secret if options[:consumer]
42
+
43
+ # presence of :consumer_secret option will override any Consumer that's provided
44
+ @consumer_secret = options[:consumer_secret] if options[:consumer_secret]
45
+
46
+ ## token secret was determined beforehand
47
+
48
+ @token_secret = options[:token].secret if options[:token]
49
+
50
+ # presence of :token_secret option will override any Token that's provided
51
+ @token_secret = options[:token_secret] if options[:token_secret]
52
+
53
+ # override secrets based on the values returned from the block (if any)
54
+ if block_given?
55
+ # consumer secret and token secret need to be looked up based on pieces of the request
56
+ secrets = yield block.arity == 1 ? request : [token, consumer_key, nonce, request.timestamp]
57
+ if secrets.is_a?(Array) && secrets.size == 2
58
+ @token_secret = secrets[0]
59
+ @consumer_secret = secrets[1]
60
+ end
61
+ end
62
+ end
63
+
64
+ def signature
65
+ Base64.encode64(digest).chomp.gsub(/\n/,'')
66
+ end
67
+
68
+ def ==(cmp_signature)
69
+ Base64.decode64(signature) == Base64.decode64(cmp_signature)
70
+ end
71
+
72
+ def verify
73
+ self == self.request.signature
74
+ end
75
+
76
+ def signature_base_string
77
+ request.signature_base_string
78
+ end
79
+
80
+ def body_hash
81
+ if self.class.hash_class
82
+ Base64.encode64(self.class.hash_class.digest(request.body || '')).chomp.gsub(/\n/,'')
83
+ else
84
+ nil # no body hash algorithm defined, so don't generate one
85
+ end
86
+ end
87
+
88
+ private
89
+
90
+ def token
91
+ request.token
92
+ end
93
+
94
+ def consumer_key
95
+ request.consumer_key
96
+ end
97
+
98
+ def nonce
99
+ request.nonce
100
+ end
101
+
102
+ def secret
103
+ "#{escape(consumer_secret)}&#{escape(token_secret)}"
104
+ end
105
+
106
+ def digest
107
+ self.class.digest_class.digest(signature_base_string)
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,15 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'oauth/signature/base'
4
+ require 'digest/hmac'
5
+
6
+ module OAuth::Signature::HMAC
7
+ class Base < OAuth::Signature::Base
8
+
9
+ private
10
+ def digest
11
+ self.class.digest_class Object.module_eval("::Digest::#{self.class.digest_klass}")
12
+ Digest::HMAC.digest(signature_base_string, secret, self.class.digest_class)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,8 @@
1
+ require 'oauth/signature/hmac/base'
2
+
3
+ module OAuth::Signature::HMAC
4
+ class MD5 < Base
5
+ implements 'hmac-md5'
6
+ digest_class 'MD5'
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ require 'oauth/signature/hmac/base'
2
+
3
+ module OAuth::Signature::HMAC
4
+ class RMD160 < Base
5
+ implements 'hmac-rmd160'
6
+ digest_klass 'RMD160'
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ require 'oauth/signature/hmac/base'
2
+
3
+ module OAuth::Signature::HMAC
4
+ class SHA1 < Base
5
+ implements 'hmac-sha1'
6
+ digest_klass 'SHA1'
7
+ hash_class ::Digest::SHA1
8
+ end
9
+ end
@@ -0,0 +1,8 @@
1
+ require 'oauth/signature/hmac/base'
2
+
3
+ module OAuth::Signature::HMAC
4
+ class SHA2 < Base
5
+ implements 'hmac-sha2'
6
+ digest_klass 'SHA2'
7
+ end
8
+ end
@@ -0,0 +1,13 @@
1
+ require 'oauth/signature/base'
2
+ require 'digest/md5'
3
+
4
+ module OAuth::Signature
5
+ class MD5 < Base
6
+ implements 'md5'
7
+ digest_class Digest::MD5
8
+
9
+ def signature_base_string
10
+ secret + super
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,23 @@
1
+ require 'oauth/signature/base'
2
+
3
+ module OAuth::Signature
4
+ class PLAINTEXT < Base
5
+ implements 'plaintext'
6
+
7
+ def signature
8
+ signature_base_string
9
+ end
10
+
11
+ def ==(cmp_signature)
12
+ signature.to_s == cmp_signature.to_s
13
+ end
14
+
15
+ def signature_base_string
16
+ secret
17
+ end
18
+
19
+ def secret
20
+ super
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,46 @@
1
+ require 'oauth/signature/base'
2
+ require 'openssl'
3
+
4
+ module OAuth::Signature::RSA
5
+ class SHA1 < OAuth::Signature::Base
6
+ implements 'rsa-sha1'
7
+ hash_class ::Digest::SHA1
8
+
9
+ def ==(cmp_signature)
10
+ public_key.verify(OpenSSL::Digest::SHA1.new, Base64.decode64(cmp_signature.is_a?(Array) ? cmp_signature.first : cmp_signature), signature_base_string)
11
+ end
12
+
13
+ def public_key
14
+ if consumer_secret.is_a?(String)
15
+ decode_public_key
16
+ elsif consumer_secret.is_a?(OpenSSL::X509::Certificate)
17
+ consumer_secret.public_key
18
+ else
19
+ consumer_secret
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def decode_public_key
26
+ case consumer_secret
27
+ when /-----BEGIN CERTIFICATE-----/
28
+ OpenSSL::X509::Certificate.new( consumer_secret).public_key
29
+ else
30
+ OpenSSL::PKey::RSA.new( consumer_secret)
31
+ end
32
+ end
33
+
34
+ def digest
35
+ private_key = OpenSSL::PKey::RSA.new(
36
+ if options[:private_key_file]
37
+ IO.read(options[:private_key_file])
38
+ else
39
+ consumer_secret
40
+ end
41
+ )
42
+
43
+ private_key.sign(OpenSSL::Digest::SHA1.new, signature_base_string)
44
+ end
45
+ end
46
+ end