gmail_xoauth 0.2.0 → 0.3.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.
@@ -2,7 +2,9 @@
2
2
 
3
3
  Get access to [Gmail IMAP and STMP via OAuth](http://code.google.com/apis/gmail/oauth), using the standard Ruby Net libraries.
4
4
 
5
- The gem only supports 3-legged OAuth. If you need [2-legged OAuth feel](http://code.google.com/apis/accounts/docs/OAuth.html) free to fork!
5
+ The gem supports 3-legged and 2-legged OAuth.
6
+
7
+ Note: 2-legged OAuth support was coded by [Wojciech Kruszewski](https://github.com/wojciech). I could not test it as I don't have a Google Apps Business or Education account. Please [send me a message](https://github.com/inbox/new/nfo) if it works for you.
6
8
 
7
9
  ## Install
8
10
 
@@ -16,6 +18,8 @@ For testing, you can generate and validate your OAuth tokens thanks to the aweso
16
18
 
17
19
  $ python xoauth.py --generate_oauth_token --user=myemail@gmail.com
18
20
 
21
+ Or if you want some webapp code, check the [gmail-oauth-sinatra](https://github.com/nfo/gmail-oauth-sinatra) project.
22
+
19
23
  ### IMAP
20
24
 
21
25
  For your tests, Gmail allows to set 'anonymous' as the consumer key and secret.
@@ -53,10 +57,16 @@ Note that +Net::SMTP#enable_starttls_auto+ is not defined in Ruby 1.8.6.
53
57
 
54
58
  ## Compatibility
55
59
 
56
- Tested on Ruby MRI 1.8.6, 1.8.7 and 1.9.1. Feel free to send me a message if you tested this code with other implementations of Ruby.
60
+ Tested on Ruby MRI 1.8.6, 1.8.7, 1.9.1 and 1.9.2. Feel free to send me a message if you tested this code with other implementations of Ruby.
57
61
 
58
62
  The only external dependency is the [oauth gem](http://rubygems.org/gems/oauth).
59
63
 
64
+ ## History
65
+
66
+ * 0.3.0 Experimental 2-legged OAuth support. [Give some feedback](https://github.com/inbox/new/nfo) !
67
+ * 0.2.0 SMTP support
68
+ * 0.1.0 Initial release with IMAP support and 3-legged OAuth
69
+
60
70
  ## Note on Patches/Pull Requests
61
71
 
62
72
  * Fork the project.
@@ -67,6 +77,10 @@ The only external dependency is the [oauth gem](http://rubygems.org/gems/oauth).
67
77
  (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
68
78
  * Send me a pull request. Bonus points for topic branches.
69
79
 
80
+ ## Contact me
81
+
82
+ http://about.me/nfo
83
+
70
84
  ## Copyright
71
85
 
72
86
  Copyright (c) 2010 Silentale SAS. See LICENSE for details.
@@ -13,7 +13,13 @@ module GmailXoauth
13
13
  # +user+ is an email address: roger@gmail.com
14
14
  # +password+ is a hash of oauth parameters, see +build_oauth_string+
15
15
  def initialize(user, password)
16
- @request_url = "https://mail.google.com/mail/b/#{user}/imap/"
16
+ @request_url = "https://mail.google.com/mail/b/#{user}/imap/";
17
+
18
+ if password[:two_legged]
19
+ password = password.merge({:xoauth_requestor_id => user})
20
+ @request_url += "?xoauth_requestor_id=#{CGI.escape(user)}";
21
+ end
22
+
17
23
  @oauth_string = build_oauth_string(@request_url, password)
18
24
  end
19
25
 
@@ -22,4 +28,4 @@ module GmailXoauth
22
28
  end
23
29
  end
24
30
 
25
- Net::IMAP.add_authenticator('XOAUTH', GmailXoauth::ImapXoauthAuthenticator)
31
+ Net::IMAP.add_authenticator('XOAUTH', GmailXoauth::ImapXoauthAuthenticator)
@@ -21,14 +21,17 @@ module GmailXoauth
21
21
  'oauth_nonce' => OAuth::Helper.generate_key,
22
22
  "oauth_signature_method" => 'HMAC-SHA1',
23
23
  'oauth_timestamp' => OAuth::Helper.generate_timestamp,
24
- "oauth_token" => oauth_params[:token],
25
24
  'oauth_version' => '1.0'
26
25
  }
26
+ oauth_request_params["oauth_token"] = oauth_params[:token] unless oauth_params[:two_legged]
27
27
 
28
+ oauth_request_params_for_signing = oauth_request_params.dup
29
+ oauth_request_params_for_signing["xoauth_requestor_id"] = oauth_params[:xoauth_requestor_id] if oauth_params[:two_legged]
30
+
28
31
  request = OAuth::RequestProxy.proxy(
29
32
  'method' => 'GET',
30
33
  'uri' => request_url,
31
- 'parameters' => oauth_request_params
34
+ 'parameters' => oauth_request_params_for_signing
32
35
  )
33
36
 
34
37
  oauth_request_params['oauth_signature'] =
@@ -41,11 +44,11 @@ module GmailXoauth
41
44
  # Inspired from OAuth::RequestProxy::Base#oauth_header
42
45
  oauth_request_params.map { |k,v| "#{k}=\"#{OAuth::Helper.escape(v)}\"" }.sort.join(',')
43
46
  end
44
-
47
+
45
48
  # See http://code.google.com/apis/gmail/oauth/protocol.html#sasl
46
49
  def build_sasl_client_request(request_url, oauth_string)
47
50
  'GET ' + request_url + ' ' + oauth_string
48
51
  end
49
52
 
50
53
  end
51
- end
54
+ end
@@ -8,7 +8,14 @@ module GmailXoauth
8
8
  check_auth_args user, secret
9
9
 
10
10
  request_url = "https://mail.google.com/mail/b/#{user}/smtp/"
11
+
12
+ if secret[:two_legged]
13
+ request_url += "?xoauth_requestor_id=#{CGI.escape(user)}";
14
+ secret = secret.merge({:xoauth_requestor_id => user})
15
+ end
16
+
11
17
  oauth_string = build_oauth_string(request_url, secret)
18
+
12
19
  sasl_client_request = build_sasl_client_request(request_url, oauth_string)
13
20
 
14
21
  res = critical {
@@ -25,4 +32,4 @@ module GmailXoauth
25
32
  end
26
33
 
27
34
  # Not pretty, right ?
28
- Net::SMTP.__send__('include', GmailXoauth::SmtpXoauthAuthenticator)
35
+ Net::SMTP.__send__('include', GmailXoauth::SmtpXoauthAuthenticator)
@@ -0,0 +1,3 @@
1
+ module GmailXoauth
2
+ VERSION = "0.3.0"
3
+ end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 2
7
+ - 3
8
8
  - 0
9
- version: 0.2.0
9
+ version: 0.3.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - "Nicolas Fouch\xC3\xA9"
@@ -14,13 +14,14 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-05-18 00:00:00 +02:00
17
+ date: 2010-12-13 00:00:00 +01:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: oauth
22
22
  prerelease: false
23
23
  requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
24
25
  requirements:
25
26
  - - ">="
26
27
  - !ruby/object:Gem::Version
@@ -35,6 +36,7 @@ dependencies:
35
36
  name: shoulda
36
37
  prerelease: false
37
38
  requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
38
40
  requirements:
39
41
  - - ">="
40
42
  - !ruby/object:Gem::Version
@@ -44,30 +46,24 @@ dependencies:
44
46
  type: :development
45
47
  version_requirements: *id002
46
48
  description: Get access to Gmail IMAP and STMP via OAuth, using the standard Ruby Net libraries
47
- email: nicolas@silentale.com
49
+ email:
50
+ - nicolas@silentale.com
48
51
  executables: []
49
52
 
50
53
  extensions: []
51
54
 
52
- extra_rdoc_files:
53
- - LICENSE
54
- - README.markdown
55
+ extra_rdoc_files: []
56
+
55
57
  files:
56
- - .gitignore
57
- - LICENSE
58
- - README.markdown
59
- - Rakefile
60
- - VERSION
61
- - lib/gmail_xoauth.rb
62
58
  - lib/gmail_xoauth/imap_xoauth_authenticator.rb
63
59
  - lib/gmail_xoauth/oauth_string.rb
64
60
  - lib/gmail_xoauth/smtp_xoauth_authenticator.rb
65
- - test/helper.rb
66
- - test/test_imap_xoauth_authenticator.rb
67
- - test/test_oauth_string.rb
68
- - test/test_smtp_xoauth_authenticator.rb
61
+ - lib/gmail_xoauth/version.rb
62
+ - lib/gmail_xoauth.rb
63
+ - LICENSE
64
+ - README.markdown
69
65
  has_rdoc: true
70
- homepage: http://github.com/nfo/gmail_xoauth
66
+ homepage: http://geeks.silentale.com/2010/05/26/gmail-and-oauth-ruby-gem
71
67
  licenses: []
72
68
 
73
69
  post_install_message:
@@ -76,6 +72,7 @@ rdoc_options:
76
72
  require_paths:
77
73
  - lib
78
74
  required_ruby_version: !ruby/object:Gem::Requirement
75
+ none: false
79
76
  requirements:
80
77
  - - ">="
81
78
  - !ruby/object:Gem::Version
@@ -83,21 +80,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
83
80
  - 0
84
81
  version: "0"
85
82
  required_rubygems_version: !ruby/object:Gem::Requirement
83
+ none: false
86
84
  requirements:
87
85
  - - ">="
88
86
  - !ruby/object:Gem::Version
89
87
  segments:
90
- - 0
91
- version: "0"
88
+ - 1
89
+ - 3
90
+ - 6
91
+ version: 1.3.6
92
92
  requirements: []
93
93
 
94
94
  rubyforge_project:
95
- rubygems_version: 1.3.6
95
+ rubygems_version: 1.3.7
96
96
  signing_key:
97
97
  specification_version: 3
98
98
  summary: Get access to Gmail IMAP and STMP via OAuth, using the standard Ruby Net libraries
99
- test_files:
100
- - test/helper.rb
101
- - test/test_imap_xoauth_authenticator.rb
102
- - test/test_oauth_string.rb
103
- - test/test_smtp_xoauth_authenticator.rb
99
+ test_files: []
100
+
data/.gitignore DELETED
@@ -1,24 +0,0 @@
1
- ## MAC OS
2
- .DS_Store
3
-
4
- ## TEXTMATE
5
- *.tmproj
6
- tmtags
7
-
8
- ## EMACS
9
- *~
10
- \#*
11
- .\#*
12
-
13
- ## VIM
14
- *.swp
15
-
16
- ## PROJECT::GENERAL
17
- coverage
18
- rdoc
19
- pkg
20
- *.gemspec
21
- *.gem
22
-
23
- ## PROJECT::SPECIFIC
24
- test/valid_credentials.yml
data/Rakefile DELETED
@@ -1,53 +0,0 @@
1
- require 'rubygems'
2
- require 'rake'
3
-
4
- begin
5
- require 'jeweler'
6
- Jeweler::Tasks.new do |gem|
7
- gem.name = "gmail_xoauth"
8
- gem.summary = %Q{Get access to Gmail IMAP and STMP via OAuth, using the standard Ruby Net libraries}
9
- gem.description = %Q{Get access to Gmail IMAP and STMP via OAuth, using the standard Ruby Net libraries}
10
- gem.email = "nicolas@silentale.com"
11
- gem.homepage = "http://github.com/nfo/gmail_xoauth"
12
- gem.authors = ["Nicolas Fouch\303\251"]
13
- gem.add_dependency "oauth", ">= 0.3.6"
14
- gem.add_development_dependency "shoulda", ">= 0"
15
- end
16
- Jeweler::GemcutterTasks.new
17
- rescue LoadError
18
- puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
19
- end
20
-
21
- require 'rake/testtask'
22
- Rake::TestTask.new(:test) do |test|
23
- test.libs << 'lib' << 'test'
24
- test.pattern = 'test/**/test_*.rb'
25
- test.verbose = true
26
- end
27
-
28
- begin
29
- require 'rcov/rcovtask'
30
- Rcov::RcovTask.new do |test|
31
- test.libs << 'test'
32
- test.pattern = 'test/**/test_*.rb'
33
- test.verbose = true
34
- end
35
- rescue LoadError
36
- task :rcov do
37
- abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
38
- end
39
- end
40
-
41
- task :test => :check_dependencies
42
-
43
- task :default => :test
44
-
45
- require 'rake/rdoctask'
46
- Rake::RDocTask.new do |rdoc|
47
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
48
-
49
- rdoc.rdoc_dir = 'rdoc'
50
- rdoc.title = "gmail_xoauth #{version}"
51
- rdoc.rdoc_files.include('README*')
52
- rdoc.rdoc_files.include('lib/**/*.rb')
53
- end
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 0.2.0
@@ -1,44 +0,0 @@
1
- require 'yaml'
2
-
3
- require 'rubygems'
4
- require 'test/unit'
5
- require 'mocha'
6
-
7
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
8
- $LOAD_PATH.unshift(File.dirname(__FILE__))
9
- require 'gmail_xoauth'
10
-
11
- # Wanna debug ? Activate the IMAP debug mode, it will show the client/server conversation
12
- # Net::IMAP.debug = true
13
-
14
- # SMTP debugging can only be enabled on Net::SMTP instances
15
- # Net::SMTP.class_eval do
16
- # def initialize_with_debug(*args)
17
- # initialize_without_debug(*args)
18
- # @debug_output = STDERR
19
- # end
20
- # alias_method :initialize_without_debug, :initialize
21
- # alias_method :initialize, :initialize_with_debug
22
- # end
23
-
24
- VALID_CREDENTIALS = begin
25
- YAML.load_file(File.join(File.dirname(__FILE__), 'valid_credentials.yml'))
26
- rescue Errno::ENOENT
27
- STDERR.puts %(
28
- Warning: some tests are disabled because they require valid credentials. To enable them, create a file \"test/valid_credentials.yml\".
29
- It should contain valid OAuth tokens. Valid tokens can be generated thanks to \"xoauth.py\":http://code.google.com/p/google-mail-xoauth-tools/.
30
- Of course, this file is .gitignored. Template:
31
-
32
- ---
33
- :email: someuser@gmail.com
34
- :consumer_key: anonymous # "anonymous" is a valid value for testing
35
- :consumer_secret: anonymous # "anonymous" is a valid value for testing
36
- :token: 1/nE2xBCDOU0429bTeJySE11kRE95qzKQNlfTaaBcDeFg
37
- :token_secret: 123Z/bMsi9fFhN6qHFWOabcd
38
-
39
- )
40
- false
41
- end
42
-
43
- class Test::Unit::TestCase
44
- end
@@ -1,40 +0,0 @@
1
- require 'helper'
2
-
3
- class TestImapXoauthAuthenticator < Test::Unit::TestCase
4
-
5
- def setup
6
- end
7
-
8
- def test_xoauth_authenticator_is_enabled
9
- authenticators = Net::IMAP.__send__('class_variable_get', '@@authenticators')
10
- assert_not_nil authenticators['XOAUTH']
11
- assert_equal authenticators['XOAUTH'], GmailXoauth::ImapXoauthAuthenticator
12
- end
13
-
14
- def test_authenticate_with_invalid_credentials
15
- imap = Net::IMAP.new('imap.gmail.com', 993, usessl = true, certs = nil, verify = false)
16
- assert_raise(Net::IMAP::NoResponseError) do
17
- imap.authenticate('XOAUTH', 'roger@moore.com',
18
- :token => 'a',
19
- :token_secret => 'b'
20
- )
21
- end
22
- end
23
-
24
- def test_authenticate_with_valid_credentials
25
- return unless VALID_CREDENTIALS
26
-
27
- imap = Net::IMAP.new('imap.gmail.com', 993, usessl = true, certs = nil, verify = false)
28
- imap.authenticate('XOAUTH', VALID_CREDENTIALS[:email],
29
- :consumer_key => VALID_CREDENTIALS[:consumer_key],
30
- :consumer_secret => VALID_CREDENTIALS[:consumer_secret],
31
- :token => VALID_CREDENTIALS[:token],
32
- :token_secret => VALID_CREDENTIALS[:token_secret]
33
- )
34
- mailboxes = imap.list('', '*')
35
- assert_instance_of Array, mailboxes
36
- assert_instance_of Net::IMAP::MailboxList, mailboxes.first
37
- ensure
38
- imap.disconnect if imap
39
- end
40
- end
@@ -1,54 +0,0 @@
1
- require 'helper'
2
-
3
- class TestOauthString < Test::Unit::TestCase
4
-
5
- def setup
6
- end
7
-
8
- def test_build_oauth_string_should_accept_custom_consumer
9
- OAuth::Helper.stubs(:generate_key).returns('abc')
10
- OAuth::Helper.stubs(:generate_timestamp).returns(1274215474)
11
-
12
- request_url = "https://mail.google.com/mail/b/user_name@gmail.com/imap/"
13
- oauth_params = {
14
- :consumer_key => 'c',
15
- :consumer_secret => 'd',
16
- :token => 'a',
17
- :token_secret => 'b',
18
- }
19
-
20
- oauth_string = C.new.__send__('build_oauth_string', request_url, oauth_params)
21
-
22
- assert_equal(
23
- 'oauth_consumer_key="c",oauth_nonce="abc",oauth_signature="eseW9YybDf3fPToiwyLdUwSlfUw%3D",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1274215474",oauth_token="a",oauth_version="1.0"',
24
- oauth_string
25
- )
26
- end
27
-
28
- def test_build_oauth_string_should_set_consumer_anonymous_by_default
29
- OAuth::Helper.stubs(:generate_key).returns('abc')
30
- OAuth::Helper.stubs(:generate_timestamp).returns(1274215474)
31
-
32
- request_url = "https://mail.google.com/mail/b/user_name@gmail.com/imap/"
33
- oauth_params = {
34
- :token => 'a',
35
- :token_secret => 'b',
36
- }
37
-
38
- oauth_string = C.new.__send__('build_oauth_string', request_url, oauth_params)
39
-
40
- assert_equal(
41
- 'oauth_consumer_key="anonymous",oauth_nonce="abc",oauth_signature="weu3Z%2Baqn6YUNnSLJmIvUwnCEmo%3D",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1274215474",oauth_token="a",oauth_version="1.0"',
42
- oauth_string
43
- )
44
- end
45
-
46
- def test_build_sasl_client_request
47
- assert_equal 'GET 1 2', C.new.__send__('build_sasl_client_request', '1', '2')
48
- end
49
-
50
- end
51
-
52
- class C
53
- include GmailXoauth::OauthString
54
- end
@@ -1,39 +0,0 @@
1
- require 'helper'
2
-
3
- class TestSmtpXoauthAuthenticator < Test::Unit::TestCase
4
-
5
- def setup
6
- end
7
-
8
- def test_smtp_authenticator_is_enabled
9
- assert Net::SMTP.new(nil).respond_to?(:auth_xoauth), 'The Net::SMTP class should define the method :auth_xoauth'
10
- end
11
-
12
- def test_authenticate_with_invalid_credentials
13
- smtp = Net::SMTP.new('smtp.gmail.com', 587)
14
- smtp.enable_starttls_auto
15
- assert_raise(Net::SMTPAuthenticationError) do
16
- smtp.start('gmail.com', 'roger@moore.com', {:token => 'a', :token_secret => 'b'}, :xoauth)
17
- end
18
- end
19
-
20
- def test_authenticate_with_valid_credentials
21
- return unless VALID_CREDENTIALS
22
-
23
- smtp = Net::SMTP.new('smtp.gmail.com', 587)
24
- smtp.enable_starttls_auto
25
-
26
- secret = {
27
- :consumer_key => VALID_CREDENTIALS[:consumer_key],
28
- :consumer_secret => VALID_CREDENTIALS[:consumer_secret],
29
- :token => VALID_CREDENTIALS[:token],
30
- :token_secret => VALID_CREDENTIALS[:token_secret],
31
- }
32
-
33
- assert_nothing_raised do
34
- smtp.start('gmail.com', VALID_CREDENTIALS[:email], secret, :xoauth)
35
- end
36
- ensure
37
- smtp.finish if smtp
38
- end
39
- end