gmail_xoauth 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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