gmail_xoauth 0.3.2 → 0.4.1

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