gmail-oauth 0.0.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.
@@ -0,0 +1,5 @@
1
+ README.markdown
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,21 @@
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
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Bob Potter
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,40 @@
1
+ gmail-oauth
2
+ ===========
3
+
4
+ Implements Gmail OAuth access methods for Net::IMAP and Net::SMTP
5
+
6
+ Fully working examples (including fetching the access_token) for smtp and imap are in examples/
7
+
8
+ IMAP Usage
9
+ ----------
10
+
11
+ require 'gmail-oauth'
12
+ imap = Net::IMAP.new('imap.gmail.com',993,true)
13
+
14
+ # For 3legged oauth provide an OAuth::AcessToken
15
+ imap.authenticate('XOAUTH', "example@gmail.com", :access_token => access_token)
16
+
17
+ # For 2legged oauth just provide the OAuth::Consumer
18
+ #imap.authenticate('XOAUTH', "example@gmail.com", :consumer => consumer)
19
+
20
+ imap.list("*","*").each do |folder|
21
+ puts folder.name
22
+ end
23
+
24
+ SMTP Usage
25
+ ----------
26
+
27
+ require 'gmail-oauth'
28
+
29
+ raw_email = generate_email()
30
+
31
+ smtp = Net::SMTP.new('smtp.gmail.com')
32
+ smtp.enable_starttls
33
+ smtp.start('gmail.com', "example@gmail.com", {:access_token => access_token}, :xoauth)
34
+ smtp.send_message raw_email, "example@gmail.com", "destination@gmail.com"
35
+ smtp.finish
36
+
37
+ Copyright
38
+ ---------
39
+
40
+ Copyright (c) 2010 Bob Potter. See LICENSE for details.
@@ -0,0 +1,39 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "gmail-oauth"
8
+ gem.summary = %Q{Implements Gmail OAuth access methods for Net::IMAP and Net::SMTP}
9
+ gem.description = %Q{Implements Gmail OAuth access methods for Net::IMAP and Net::SMTP}
10
+ gem.email = "bobby.potter@gmail.com"
11
+ gem.homepage = "http://github.com/bpot/gmail-oauth"
12
+ gem.authors = ["Bob Potter"]
13
+ gem.add_development_dependency "rspec", ">= 2.0.0.beta.16"
14
+ gem.add_dependency "oauth"
15
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
+ end
17
+ Jeweler::GemcutterTasks.new
18
+ rescue LoadError
19
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
20
+ end
21
+
22
+ require 'rspec/core/rake_task'
23
+ RSpec::Core::RakeTask.new(:spec) do |c|
24
+ c.ruby_opts = "-rubygems"
25
+ end
26
+
27
+ task :spec => :check_dependencies
28
+
29
+ task :default => :spec
30
+
31
+ require 'rake/rdoctask'
32
+ Rake::RDocTask.new do |rdoc|
33
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
34
+
35
+ rdoc.rdoc_dir = 'rdoc'
36
+ rdoc.title = "gmail-oauth #{version}"
37
+ rdoc.rdoc_files.include('README*')
38
+ rdoc.rdoc_files.include('lib/**/*.rb')
39
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,26 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
2
+ require 'rubygems'
3
+ require 'gmail-oauth'
4
+
5
+ raise ArgumentError, "please provide email address (ruby examples/three_legged_imap.rb [email_address])" unless ARGV[0]
6
+
7
+ gmail_address = ARGV[0]
8
+
9
+ consumer = OAuth::Consumer.new("anonymous", "anonymous",
10
+ :site => "https://www.google.com",
11
+ :request_token_path => "/accounts/OAuthGetRequestToken",
12
+ :authorize_path => "/accounts/OAuthAuthorizeToken",
13
+ :access_token_path => "/accounts/OAuthGetAccessToken")
14
+
15
+ rt = consumer.get_request_token({:oauth_callback => "oob"}, {:scope => "https://mail.google.com/"})
16
+ print rt.authorize_url + "\n"
17
+ print "Enter verification code: "
18
+ code = $stdin.gets.chomp
19
+ access_token = rt.get_access_token(:oauth_verifier => code)
20
+
21
+ #Net::IMAP.debug = true
22
+ imap = Net::IMAP.new('imap.gmail.com',993,true)
23
+ imap.authenticate('XOAUTH', gmail_address, :access_token => access_token)
24
+ imap.list("*","*").each do |folder|
25
+ puts folder.name
26
+ end
@@ -0,0 +1,38 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
2
+ require 'rubygems'
3
+ require 'gmail-oauth'
4
+
5
+ raise ArgumentError, "please provide email address (ruby examples/three_legged_smtp.rb [email_address])" unless ARGV[0]
6
+
7
+ gmail_address = ARGV[0]
8
+
9
+ consumer = OAuth::Consumer.new("anonymous", "anonymous",
10
+ :site => "https://www.google.com",
11
+ :request_token_path => "/accounts/OAuthGetRequestToken",
12
+ :authorize_path => "/accounts/OAuthAuthorizeToken",
13
+ :access_token_path => "/accounts/OAuthGetAccessToken")
14
+
15
+ rt = consumer.get_request_token({:oauth_callback => "oob"}, {:scope => "https://mail.google.com/"})
16
+ print rt.authorize_url + "\n"
17
+ print "Enter verification code: "
18
+ code = $stdin.gets.chomp
19
+ access_token = rt.get_access_token(:oauth_verifier => code)
20
+
21
+
22
+ msgstr = <<END_OF_MESSAGE
23
+ From: Blah <#{gmail_address}>
24
+ To: Destination Address <#{gmail_address}>
25
+ Subject: test message
26
+ Date: Sat, 23 Jun 2001 16:26:43 +0900
27
+ Message-Id: <unique.message.id.string@example.com>
28
+
29
+ This is a test message.
30
+ END_OF_MESSAGE
31
+
32
+ smtp = Net::SMTP.new('smtp.gmail.com')
33
+ smtp.enable_starttls
34
+ smtp.debug_output = $stdout
35
+ #smtp.enable_tls
36
+ smtp.start('gmail.com', gmail_address, {:access_token => access_token}, :xoauth)
37
+ smtp.send_message msgstr, gmail_address, gmail_address
38
+ smtp.finish
@@ -0,0 +1,32 @@
1
+ require 'gmail-oauth/request'
2
+ require 'gmail-oauth/client'
3
+ require 'net/imap'
4
+ require 'net/smtp'
5
+ require 'oauth'
6
+ require 'cgi'
7
+
8
+ class Net::IMAP
9
+ class XOAuthAuthenticator
10
+ def initialize(email_address, opts = {})
11
+ @email_address = email_address
12
+ @opts = opts
13
+ end
14
+
15
+ def process(s)
16
+ GmailOAuth::Client.new(@email_address, @opts).xoauth_string
17
+ end
18
+ end
19
+ add_authenticator 'XOAUTH', XOAuthAuthenticator
20
+ end
21
+
22
+ class Net::SMTP
23
+ def auth_xoauth(email_address, options)
24
+ auth_string = GmailOAuth::Client.new(email_address, options.merge(:service => :smtp)).xoauth_string
25
+ res = critical {
26
+ get_response('AUTH XOAUTH ' + base64_encode(auth_string))
27
+ }
28
+ check_auth_response res
29
+ res
30
+ end
31
+ end
32
+
@@ -0,0 +1,38 @@
1
+ module GmailOAuth
2
+ # Client.new("user@gmail.com", :access_token => @access_token)
3
+ # Client.new("user@mywork.com", :consumer => @consumer)
4
+ class Client
5
+ def initialize(email_address, options = {})
6
+ raise ArgumentError, "Must provide either an access token (3legged oauth) or a consumer (2legged oauth)" if options[:access_token].nil? && options[:consumer].nil?
7
+
8
+ @email_address = email_address
9
+ @access_token = options[:access_token]
10
+ if @access_token
11
+ @consumer = @access_token.consumer
12
+ else
13
+ @consumer = options[:consumer]
14
+ end
15
+ @service = options[:service] || :imap
16
+ end
17
+
18
+ def xoauth_string
19
+ params = request["parameters"].merge("oauth_signature" => signature)
20
+
21
+ prefix = "GET #{request["uri"]} "
22
+ prefix + params.keys.sort.select { |k| k != "xoauth_requestor_id" }.collect { |k| "#{k}=\"#{CGI.escape(params[k])}\"" }.join(",")
23
+ end
24
+
25
+ private
26
+ def signature
27
+ OAuth::Signature.sign(request, :scheme => 'header') { [access_token_secret, @consumer.secret] }
28
+ end
29
+
30
+ def access_token_secret
31
+ @access_token ? @access_token.secret : nil
32
+ end
33
+
34
+ def request
35
+ @request ||= Request.new(@email_address, @access_token, @consumer, @service).request
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,48 @@
1
+ module GmailOAuth
2
+ class Request
3
+ def initialize(email_address, access_token, consumer, service = :imap)
4
+ @email_address = email_address
5
+ @consumer = consumer
6
+ @access_token = access_token
7
+ @service = service
8
+ end
9
+
10
+ def request
11
+ {
12
+ "uri" => request_uri,
13
+ "parameters" => parameters,
14
+ "method" => "GET"
15
+ }
16
+ end
17
+
18
+ private
19
+ def two_legged?
20
+ !@access_token
21
+ end
22
+
23
+ def request_uri
24
+ uri = "https://mail.google.com/mail/b/#{@email_address}/#{@service}/"
25
+ if two_legged?
26
+ uri += "?xoauth_requestor_id=#{CGI.escape(@email_address)}"
27
+ end
28
+ uri
29
+ end
30
+
31
+ def parameters
32
+ params = {
33
+ "oauth_signature_method" => "HMAC-SHA1",
34
+ "oauth_version" => "1.0",
35
+ "oauth_nonce" => OAuth::Helper.generate_nonce,
36
+ "oauth_timestamp" => OAuth::Helper.generate_timestamp,
37
+ "oauth_consumer_key" => @consumer.key
38
+ }
39
+
40
+ if two_legged?
41
+ params["xoauth_requestor_id"] = @email_address
42
+ else
43
+ params["oauth_token"] = @access_token.token
44
+ end
45
+ params
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,66 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe GmailOAuth::Request do
4
+
5
+ def consumer
6
+ OAuth::Consumer.new('consumer_key','secret')
7
+ end
8
+
9
+ def access_token
10
+ OAuth::AccessToken.new(consumer, 'access_token','secret')
11
+ end
12
+
13
+ context "2legged imap" do
14
+ before(:each) do
15
+ @request = GmailOAuth::Request.new("user@mywork.com", nil, consumer)
16
+ end
17
+
18
+ it "should have the correct request uri" do
19
+ @request.request["uri"].should == "https://mail.google.com/mail/b/user@mywork.com/imap/?xoauth_requestor_id=user%40mywork.com"
20
+ end
21
+
22
+ it "should have oauth_version of 1.0" do
23
+ @request.request["parameters"]["oauth_version"].should == "1.0"
24
+ end
25
+
26
+ it "should have oauth_signature_method of HMAC_SHA1" do
27
+ @request.request["parameters"]["oauth_signature_method"].should == "HMAC-SHA1"
28
+ end
29
+
30
+ it "should use access token's consumer's key" do
31
+ @request.request["parameters"]["oauth_consumer_key"].should == "consumer_key"
32
+ end
33
+
34
+ it "should have the email as the xoauth_requestor_id parameter" do
35
+ @request.request["parameters"]["xoauth_requestor_id"].should == "user@mywork.com"
36
+ end
37
+ end
38
+
39
+ context "3legged imap" do
40
+ before(:each) do
41
+ @request = GmailOAuth::Request.new("user@gmail.com", access_token, consumer)
42
+ end
43
+
44
+ it "should have the correct request uri" do
45
+ @request.request["uri"].should == "https://mail.google.com/mail/b/user@gmail.com/imap/"
46
+ end
47
+
48
+ it "should use access token's consumer's key" do
49
+ @request.request["parameters"]["oauth_consumer_key"].should == "consumer_key"
50
+ end
51
+
52
+ it "should have the access token as the oauth_token parameter" do
53
+ @request.request["parameters"]["oauth_token"].should == "access_token"
54
+ end
55
+ end
56
+
57
+ context "3legged smtp" do
58
+ before(:each) do
59
+ @request = GmailOAuth::Request.new("user@gmail.com", access_token, consumer, :smtp)
60
+ end
61
+
62
+ it "should have the correct request uri" do
63
+ @request.request["uri"].should == "https://mail.google.com/mail/b/user@gmail.com/smtp/"
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,9 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'gmail-oauth'
4
+ require 'rubygems'
5
+ require 'rspec/core'
6
+
7
+ RSpec.configure do |c|
8
+
9
+ end
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gmail-oauth
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Bob Potter
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-07-08 00:00:00 -05:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rspec
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 62196419
30
+ segments:
31
+ - 2
32
+ - 0
33
+ - 0
34
+ - beta
35
+ - 16
36
+ version: 2.0.0.beta.16
37
+ type: :development
38
+ version_requirements: *id001
39
+ - !ruby/object:Gem::Dependency
40
+ name: oauth
41
+ prerelease: false
42
+ requirement: &id002 !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ hash: 3
48
+ segments:
49
+ - 0
50
+ version: "0"
51
+ type: :runtime
52
+ version_requirements: *id002
53
+ description: Implements Gmail OAuth access methods for Net::IMAP and Net::SMTP
54
+ email: bobby.potter@gmail.com
55
+ executables: []
56
+
57
+ extensions: []
58
+
59
+ extra_rdoc_files:
60
+ - LICENSE
61
+ - README.markdown
62
+ files:
63
+ - .document
64
+ - .gitignore
65
+ - LICENSE
66
+ - README.markdown
67
+ - Rakefile
68
+ - VERSION
69
+ - examples/three_legged_imap.rb
70
+ - examples/three_legged_smtp.rb
71
+ - lib/gmail-oauth.rb
72
+ - lib/gmail-oauth/client.rb
73
+ - lib/gmail-oauth/request.rb
74
+ - spec/gmail-oauth_request_spec.rb
75
+ - spec/spec_helper.rb
76
+ has_rdoc: true
77
+ homepage: http://github.com/bpot/gmail-oauth
78
+ licenses: []
79
+
80
+ post_install_message:
81
+ rdoc_options:
82
+ - --charset=UTF-8
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ none: false
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ hash: 3
91
+ segments:
92
+ - 0
93
+ version: "0"
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ hash: 3
100
+ segments:
101
+ - 0
102
+ version: "0"
103
+ requirements: []
104
+
105
+ rubyforge_project:
106
+ rubygems_version: 1.3.7
107
+ signing_key:
108
+ specification_version: 3
109
+ summary: Implements Gmail OAuth access methods for Net::IMAP and Net::SMTP
110
+ test_files:
111
+ - spec/gmail-oauth_request_spec.rb
112
+ - spec/spec_helper.rb
113
+ - examples/three_legged_smtp.rb
114
+ - examples/three_legged_imap.rb