gmail_xoauth 0.3.2 → 0.4.1

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.
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Author: Nicolas Fouché <nicolas@silentale.com>
1
+ Author: Nicolas Fouché <nicolas.fouche@gmail.com>
2
2
  Copyright: (C) 2011 Silentale SAS
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
data/README.markdown CHANGED
@@ -1,18 +1,48 @@
1
1
  # gmail_xoauth [![Dependency Status](https://gemnasium.com/nfo/gmail_xoauth.png)](https://gemnasium.com/nfo/gmail_xoauth)
2
2
 
3
- Get access to [Gmail IMAP and STMP via OAuth](http://code.google.com/apis/gmail/oauth), using the standard Ruby Net libraries.
3
+ Get access to [Gmail IMAP and STMP via OAuth2](https://developers.google.com/google-apps/gmail/xoauth2_protocol) and [OAuth 1.0a](https://developers.google.com/google-apps/gmail/oauth_protocol), using the standard Ruby Net libraries.
4
4
 
5
5
  The gem supports 3-legged OAuth, and 2-legged OAuth for Google Apps Business or Education account owners.
6
6
 
7
- Note: 2-legged OAuth support was added by [Wojciech Kruszewski](https://github.com/wojciech).
8
-
9
7
  ## Install
10
8
 
11
9
  $ gem install gmail_xoauth
12
10
 
13
- ## Usage
11
+ ## Usage for OAuth 2.0
12
+
13
+ ### Get your OAuth 2.0 tokens
14
+
15
+ You can generate and validate your OAuth 2.0 tokens thanks to the [oauth2.py tool](http://code.google.com/p/google-mail-oauth2-tools/wiki/OAuth2DotPyRunThrough).
16
+
17
+ Create your API project in the [Google APIs console](https://code.google.com/apis/console/), from the "API Access" tab.
18
+
19
+ $ python oauth2.py --generate_oauth2_token --client_id=364545978226.apps.googleusercontent.com --client_secret=zNrNsBzOOnQy8_O-8LkofeTR
20
+
21
+ ### IMAP OAuth 2.0
14
22
 
15
- ### Get your OAuth tokens
23
+ ```ruby
24
+ require 'gmail_xoauth'
25
+ imap = Net::IMAP.new('imap.gmail.com', 993, usessl = true, certs = nil, verify = false)
26
+ imap.authenticate('XOAUTH2', 'myemail@gmail.com', my_oauth2_token)
27
+ messages_count = imap.status('INBOX', ['MESSAGES'])['MESSAGES']
28
+ puts "Seeing #{messages_count} messages in INBOX"
29
+ ```
30
+
31
+ ### SMTP OAuth 2.0
32
+
33
+ ```ruby
34
+ require 'gmail_xoauth'
35
+ smtp = Net::SMTP.new('smtp.gmail.com', 587)
36
+ smtp.enable_starttls_auto
37
+ smtp.start('gmail.com', 'myemail@gmail.com', my_oauth2_token, :xoauth2)
38
+ smtp.finish
39
+ ```
40
+
41
+ ## Usage for OAuth 1.0a
42
+
43
+ == *[OAuth 1.0 has been officially deprecated as of April 20, 2012](https://developers.google.com/google-apps/gmail/oauth_protocol)*. ==
44
+
45
+ ### Get your OAuth 1.0a tokens
16
46
 
17
47
  For testing, you can generate and validate your OAuth tokens thanks to the awesome [xoauth.py tool](http://code.google.com/p/google-mail-xoauth-tools/wiki/XoauthDotPyRunThrough).
18
48
 
@@ -20,76 +50,85 @@ For testing, you can generate and validate your OAuth tokens thanks to the aweso
20
50
 
21
51
  Or if you want some webapp code, check the [gmail-oauth-sinatra](https://github.com/nfo/gmail-oauth-sinatra) project.
22
52
 
23
- ### IMAP
53
+ ### IMAP 3-legged OAuth 1.0a
24
54
 
25
55
  For your tests, Gmail allows to set 'anonymous' as the consumer key and secret.
26
56
 
27
- require 'gmail_xoauth'
28
- imap = Net::IMAP.new('imap.gmail.com', 993, usessl = true, certs = nil, verify = false)
29
- imap.authenticate('XOAUTH', 'myemail@gmail.com',
30
- :consumer_key => 'anonymous',
31
- :consumer_secret => 'anonymous',
32
- :token => '4/nM2QAaunKUINb4RrXPC55F-mix_k',
33
- :token_secret => '41r18IyXjIvuyabS/NDyW6+m'
34
- )
35
- messages_count = imap.status('INBOX', ['MESSAGES'])['MESSAGES']
36
- puts "Seeing #{messages_count} messages in INBOX"
57
+ ```ruby
58
+ require 'gmail_xoauth'
59
+ imap = Net::IMAP.new('imap.gmail.com', 993, usessl = true, certs = nil, verify = false)
60
+ imap.authenticate('XOAUTH', 'myemail@gmail.com',
61
+ :consumer_key => 'anonymous',
62
+ :consumer_secret => 'anonymous',
63
+ :token => '4/nM2QAaunKUINb4RrXPC55F-mix_k',
64
+ :token_secret => '41r18IyXjIvuyabS/NDyW6+m'
65
+ )
66
+ messages_count = imap.status('INBOX', ['MESSAGES'])['MESSAGES']
67
+ puts "Seeing #{messages_count} messages in INBOX"
68
+ ```
37
69
 
38
70
  Note that the [Net::IMAP#login](http://www.ruby-doc.org/core/classes/Net/IMAP.html#M004191) method does not use support custom authenticators, so you have to use the [Net::IMAP#authenticate](http://www.ruby-doc.org/core/classes/Net/IMAP.html#M004190) method.
39
71
 
40
- If you use 2-legged OAuth:
72
+ ### IMAP 2-legged OAuth 1.0a
41
73
 
42
- require 'gmail_xoauth'
43
- imap = Net::IMAP.new('imap.gmail.com', 993, usessl = true, certs = nil, verify = false)
44
- imap.authenticate('XOAUTH', 'myemail@mydomain.com',
45
- :two_legged => true,
46
- :consumer_key => 'a',
47
- :consumer_secret => 'b'
48
- )
74
+ ```ruby
75
+ require 'gmail_xoauth'
76
+ imap = Net::IMAP.new('imap.gmail.com', 993, usessl = true, certs = nil, verify = false)
77
+ imap.authenticate('XOAUTH', 'myemail@mydomain.com',
78
+ :two_legged => true,
79
+ :consumer_key => 'a',
80
+ :consumer_secret => 'b'
81
+ )
82
+ ```
49
83
 
50
- ### SMTP
84
+ ### SMTP 3-legged OAuth 1.0a
51
85
 
52
86
  For your tests, Gmail allows to set 'anonymous' as the consumer key and secret.
53
87
 
54
- require 'gmail_xoauth'
55
- smtp = Net::SMTP.new('smtp.gmail.com', 587)
56
- smtp.enable_starttls_auto
57
- secret = {
58
- :consumer_key => 'anonymous',
59
- :consumer_secret => 'anonymous',
60
- :token => '4/nM2QAaunKUINb4RrXPC55F-mix_k',
61
- :token_secret => '41r18IyXjIvuyabS/NDyW6+m'
62
- }
63
- smtp.start('gmail.com', 'myemail@gmail.com', secret, :xoauth)
64
- smtp.finish
65
-
66
- Note that +Net::SMTP#enable_starttls_auto+ is not defined in Ruby 1.8.6.
67
-
68
- If you use 2-legged OAuth:
69
-
70
- require 'gmail_xoauth'
71
- smtp = Net::SMTP.new('smtp.gmail.com', 587)
72
- smtp.enable_starttls_auto
73
- secret = {
74
- :two_legged => true,
75
- :consumer_key => 'a',
76
- :consumer_secret => 'b'
77
- }
78
- smtp.start('gmail.com', 'myemail@mydomain.com', secret, :xoauth)
79
- smtp.finish
80
-
88
+ ```ruby
89
+ require 'gmail_xoauth'
90
+ smtp = Net::SMTP.new('smtp.gmail.com', 587)
91
+ smtp.enable_starttls_auto
92
+ secret = {
93
+ :consumer_key => 'anonymous',
94
+ :consumer_secret => 'anonymous',
95
+ :token => '4/nM2QAaunKUINb4RrXPC55F-mix_k',
96
+ :token_secret => '41r18IyXjIvuyabS/NDyW6+m'
97
+ }
98
+ smtp.start('gmail.com', 'myemail@gmail.com', secret, :xoauth)
99
+ smtp.finish
100
+ ```
101
+
102
+ Note that `Net::SMTP#enable_starttls_auto` is not defined in Ruby 1.8.6.
103
+
104
+ ### SMTP 2-legged OAuth 1.0a
105
+
106
+ ```ruby
107
+ require 'gmail_xoauth'
108
+ smtp = Net::SMTP.new('smtp.gmail.com', 587)
109
+ smtp.enable_starttls_auto
110
+ secret = {
111
+ :two_legged => true,
112
+ :consumer_key => 'a',
113
+ :consumer_secret => 'b'
114
+ }
115
+ smtp.start('gmail.com', 'myemail@mydomain.com', secret, :xoauth)
116
+ smtp.finish
117
+ ```
81
118
 
82
119
  ## Compatibility
83
120
 
84
- 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.
121
+ Tested on Ruby MRI 1.8.6, 1.8.7, 1.9.1, 1.9.2 and 1.9.3. Feel free to send me a message if you tested this code with other implementations of Ruby.
85
122
 
86
123
  The only external dependency is the [oauth gem](http://rubygems.org/gems/oauth).
87
124
 
88
125
  ## History
89
126
 
127
+ * 0.4.1 Changed to way to give the OAuth 2.0 token, see https://github.com/nfo/gmail_xoauth/commit/b7b936cfb094c2fc9b8e9e48526906191423cb88
128
+ * 0.4.0 [XOAUTH2](https://developers.google.com/google-apps/gmail/xoauth2_protocol) support, thanks to [glongman](https://github.com/glongman)
90
129
  * 0.3.2 New email for the maintainer
91
130
  * 0.3.1 2-legged OAuth support confirmed by [BobDohnal](https://github.com/BobDohnal)
92
- * 0.3.0 Experimental 2-legged OAuth support
131
+ * 0.3.0 Experimental 2-legged OAuth support, thanks to [wojciech](https://github.com/wojciech)
93
132
  * 0.2.0 SMTP support
94
133
  * 0.1.0 Initial release with IMAP support and 3-legged OAuth
95
134
 
@@ -107,6 +146,6 @@ The only external dependency is the [oauth gem](http://rubygems.org/gems/oauth).
107
146
 
108
147
  http://about.me/nfo
109
148
 
110
- ## Copyright
149
+ ## License
111
150
 
112
- Copyright (c) 2011 Silentale SAS. See LICENSE for details.
151
+ See LICENSE for details.
data/lib/gmail_xoauth.rb CHANGED
@@ -1,3 +1,5 @@
1
1
  require 'gmail_xoauth/oauth_string'
2
2
  require 'gmail_xoauth/imap_xoauth_authenticator'
3
+ require 'gmail_xoauth/imap_xoauth2_authenticator'
3
4
  require 'gmail_xoauth/smtp_xoauth_authenticator'
5
+ require 'gmail_xoauth/smtp_xoauth2_authenticator'
@@ -0,0 +1,24 @@
1
+ require 'net/imap'
2
+
3
+ module GmailXoauth
4
+ class ImapXoauth2Authenticator
5
+
6
+ def process(data)
7
+ build_oauth2_string(@user, @oauth2_token)
8
+ end
9
+
10
+ private
11
+
12
+ # +user+ is an email address: roger@gmail.com
13
+ # +oauth2_token+ is the OAuth2 token
14
+ def initialize(user, oauth2_token)
15
+ @user = user
16
+ @oauth2_token = oauth2_token
17
+ end
18
+
19
+ include OauthString
20
+
21
+ end
22
+ end
23
+
24
+ Net::IMAP.add_authenticator('XOAUTH2', GmailXoauth::ImapXoauth2Authenticator)
@@ -4,7 +4,7 @@ module GmailXoauth
4
4
  private
5
5
 
6
6
  #
7
- # Builds the "oauth protocol parameter string". See http://code.google.com/apis/gmail/oauth/protocol.html#sasl
7
+ # Builds the "oauth protocol parameter string". See https://developers.google.com/google-apps/gmail/oauth_protocol#sasl_initial_client_request
8
8
  #
9
9
  # +request_url+ https://mail.google.com/mail/b/user_name@gmail.com/{imap|smtp}/
10
10
  # +oauth_params+ contains the following keys:
@@ -45,10 +45,19 @@ module GmailXoauth
45
45
  oauth_request_params.map { |k,v| "#{k}=\"#{OAuth::Helper.escape(v)}\"" }.sort.join(',')
46
46
  end
47
47
 
48
- # See http://code.google.com/apis/gmail/oauth/protocol.html#sasl
48
+ # See https://developers.google.com/google-apps/gmail/oauth_protocol#sasl_initial_client_request
49
49
  def build_sasl_client_request(request_url, oauth_string)
50
50
  'GET ' + request_url + ' ' + oauth_string
51
51
  end
52
+
53
+ #
54
+ # Builds the "oauth2 protocol authentication string". See https://developers.google.com/google-apps/gmail/xoauth2_protocol
55
+ #
56
+ # +user+ is an email address: roger@gmail.com
57
+ # +oauth2_token+ is the oauth2 token
58
+ def build_oauth2_string(user, oauth2_token)
59
+ "user=%s\1auth=Bearer %s\1\1".encode("us-ascii") % [user, oauth2_token]
60
+ end
52
61
 
53
62
  end
54
63
  end
@@ -0,0 +1,25 @@
1
+ require 'net/smtp'
2
+ require 'base64'
3
+
4
+ module GmailXoauth
5
+ module SmtpXoauth2Authenticator
6
+
7
+ def auth_xoauth2(user, oauth2_token)
8
+ check_auth_args user, oauth2_token
9
+
10
+ auth_string = build_oauth2_string(user, oauth2_token)
11
+ res = critical {
12
+ get_response("AUTH XOAUTH2 #{base64_encode(auth_string)}")
13
+ }
14
+
15
+ check_auth_response res
16
+ res
17
+ end
18
+
19
+ include OauthString
20
+
21
+ end
22
+ end
23
+
24
+ # Not pretty, right ?
25
+ Net::SMTP.__send__('include', GmailXoauth::SmtpXoauth2Authenticator)
@@ -1,3 +1,3 @@
1
1
  module GmailXoauth
2
- VERSION = "0.3.2"
2
+ VERSION = "0.4.1"
3
3
  end
data/test/helper.rb CHANGED
@@ -26,7 +26,8 @@ VALID_CREDENTIALS = begin
26
26
  rescue Errno::ENOENT
27
27
  STDERR.puts %(
28
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/.
29
+ It should contain valid OAuth tokens. Valid tokens oauth tokens can be generated thanks to \"xoauth.py\":http://code.google.com/p/google-mail-xoauth-tools/.
30
+ It should also ontain a valid OAuth2 access token. Valid tokens oauth2 tokens can be generated thanks to \"oauth2.py\":http://code.google.com/p/google-mail-oauth2-tools//. Note that oauth2 access tokens are time limited (an hour in my experience).
30
31
  Of course, this file is .gitignored. Template:
31
32
 
32
33
  ---
@@ -35,6 +36,7 @@ Of course, this file is .gitignored. Template:
35
36
  :consumer_secret: anonymous # "anonymous" is a valid value for testing
36
37
  :token: 1/nE2xBCDOU0429bTeJySE11kRE95qzKQNlfTaaBcDeFg
37
38
  :token_secret: 123Z/bMsi9fFhN6qHFWOabcd
39
+ :oauth2_token: ya29.AHES6ZTIpsLuSyMwnh-3C40WWcuiOe4N7he0a8xnkvDk_6Q_6yUg7E
38
40
 
39
41
  )
40
42
  false
@@ -0,0 +1,32 @@
1
+ require 'helper'
2
+
3
+ class TestImapXoauth2Authenticator < Test::Unit::TestCase
4
+
5
+ def setup
6
+ end
7
+
8
+ def test_xoauth2_authenticator_is_enabled
9
+ authenticators = Net::IMAP.__send__('class_variable_get', '@@authenticators')
10
+ assert_not_nil authenticators['XOAUTH2']
11
+ assert_equal authenticators['XOAUTH2'], GmailXoauth::ImapXoauth2Authenticator
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('XOAUTH2', 'roger@moore.com', 'a')
18
+ end
19
+ end
20
+
21
+ def test_authenticate_with_valid_credentials
22
+ return unless VALID_CREDENTIALS
23
+
24
+ imap = Net::IMAP.new('imap.gmail.com', 993, usessl = true, certs = nil, verify = false)
25
+ imap.authenticate('XOAUTH2', VALID_CREDENTIALS[:email], VALID_CREDENTIALS[:oauth2_token])
26
+ mailboxes = imap.list('', '*')
27
+ assert_instance_of Array, mailboxes
28
+ assert_instance_of Net::IMAP::MailboxList, mailboxes.first
29
+ ensure
30
+ imap.disconnect if imap
31
+ end
32
+ end
@@ -0,0 +1,32 @@
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_xoauth2), 'The Net::SMTP class should define the method :auth_xoauth2'
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', 'a', :xoauth2)
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
+ assert_nothing_raised do
27
+ smtp.start('gmail.com', VALID_CREDENTIALS[:email], VALID_CREDENTIALS[:oauth2_token], :xoauth2)
28
+ end
29
+ ensure
30
+ smtp.finish if smtp && smtp.started?
31
+ end
32
+ end
@@ -34,7 +34,7 @@ class TestSmtpXoauthAuthenticator < Test::Unit::TestCase
34
34
  smtp.start('gmail.com', VALID_CREDENTIALS[:email], secret, :xoauth)
35
35
  end
36
36
  ensure
37
- smtp.finish if smtp.started?
37
+ smtp.finish if smtp && smtp.started?
38
38
  end
39
39
 
40
40
  def test_2_legged_authenticate_with_invalid_credentials
@@ -61,6 +61,6 @@ class TestSmtpXoauthAuthenticator < Test::Unit::TestCase
61
61
  smtp.start('gmail.com', VALID_CREDENTIALS[:email], secret, :xoauth)
62
62
  end
63
63
  ensure
64
- smtp.finish if smtp.started?
64
+ smtp.finish if smtp && smtp.started?
65
65
  end
66
66
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gmail_xoauth
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.4.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-16 00:00:00.000000000 Z
12
+ date: 2012-09-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: oauth
@@ -51,14 +51,18 @@ executables: []
51
51
  extensions: []
52
52
  extra_rdoc_files: []
53
53
  files:
54
+ - lib/gmail_xoauth/imap_xoauth2_authenticator.rb
54
55
  - lib/gmail_xoauth/imap_xoauth_authenticator.rb
55
56
  - lib/gmail_xoauth/oauth_string.rb
57
+ - lib/gmail_xoauth/smtp_xoauth2_authenticator.rb
56
58
  - lib/gmail_xoauth/smtp_xoauth_authenticator.rb
57
59
  - lib/gmail_xoauth/version.rb
58
60
  - lib/gmail_xoauth.rb
59
61
  - test/helper.rb
62
+ - test/test_imap_xoauth2_authenticator.rb
60
63
  - test/test_imap_xoauth_authenticator.rb
61
64
  - test/test_oauth_string.rb
65
+ - test/test_smtp_xoauth2_authenticator.rb
62
66
  - test/test_smtp_xoauth_authenticator.rb
63
67
  - LICENSE
64
68
  - README.markdown
@@ -83,7 +87,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
83
87
  version: 1.3.6
84
88
  requirements: []
85
89
  rubyforge_project:
86
- rubygems_version: 1.8.21
90
+ rubygems_version: 1.8.23
87
91
  signing_key:
88
92
  specification_version: 3
89
93
  summary: Get access to Gmail IMAP and STMP via OAuth, using the standard Ruby Net