google_auth_bridge 0.1.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.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ pkg
2
+ Gemfile.lock
3
+ spec/reports
4
+ .bundle
5
+ *.gem
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in google_auth_bridge.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 ssatish
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,54 @@
1
+ Google Authentication Bridge
2
+ ============================
3
+
4
+ Google allow you to authenticate with their APIs with OAuth. That process can be a little tedious if you have to
5
+ do it over and over. Google Authentication Bridge allows you to authenticate with Google and will store the refresh
6
+ token in a file for subsequent use.
7
+
8
+ Usage
9
+ =====
10
+
11
+ With Google Drive https://github.com/gimite/google-drive-ruby
12
+
13
+ auth = GoogleAuthenticationBridge::GoogleAuthentication.new(
14
+ "https://docs.google.com/feeds/ https://docs.googleusercontent.com/ https://spreadsheets.google.com/feeds/",
15
+ "client-id",
16
+ "client-secret",
17
+ "/path/to/token-file.yml"
18
+ )
19
+ # first time to create the refresh token
20
+ token = auth.get_oauth2_access_token("auth-code")
21
+ # subsequent times using the refresh token
22
+ token = auth.get_oauth2_access_token
23
+ session = GoogleDrive.login_with_oauth(token)
24
+
25
+ With Google API Client http://code.google.com/p/google-api-ruby-client/
26
+
27
+ auth = GoogleAuthenticationBridge::GoogleAuthentication.new(
28
+ "https://www.googleapis.com/auth/analytics.readonly",
29
+ "client-id",
30
+ "client-secret",
31
+ "/path/to/token-file.yml"
32
+ )
33
+ # first time to create the refresh token
34
+ token = auth.get_tokens("auth-code")
35
+ # subsequent times using the refresh token
36
+ token = auth.get_tokens
37
+
38
+ client = Google::APIClient.new
39
+ client.update_token!(token)
40
+
41
+ Rather than providing the credentials directly you can build the authentication object from a YAML configuration
42
+ file.
43
+
44
+ auth = GoogleAuthenticationBridge::GoogleAuthentication.create_from_config_file(
45
+ "scope",
46
+ "/path/to/credentials.yml",
47
+ "/path/to/token-file.yml"
48
+ )
49
+
50
+ The credentials file should contain the client id and the client secret.
51
+
52
+ ---
53
+ google_client_id: "client id"
54
+ google_client_secret: "client secret"
data/Rakefile ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require "gem_publisher"
4
+ require "ci/reporter/rake/rspec"
5
+ require "rspec/core/rake_task"
6
+
7
+ RSpec::Core::RakeTask.new do |task|
8
+ task.pattern = 'spec/**/*_spec.rb'
9
+ end
10
+
11
+ desc "Publish gem to RubyGems.org"
12
+ task :publish_gem do |t|
13
+ gem = GemPublisher.publish_if_updated("google_auth_bridge.gemspec", :rubygems)
14
+ puts "Published #{gem}" if gem
15
+ end
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/google_auth_bridge/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = %w(ssatish)
6
+ gem.email = %w(seema.satish@digital.cabinet-office.gov.uk)
7
+ gem.description = "bridge for supporting multiple google authentication libraries"
8
+ gem.summary = "bridge for supporting multiple google authentication libraries"
9
+ gem.homepage = "https://github.com/alphagov/google-auth-bridge"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "google_auth_bridge"
15
+ gem.require_paths = %w(lib)
16
+ gem.version = GoogleAuthenticationBridge::VERSION
17
+
18
+ gem.add_dependency('oauth2')
19
+ gem.add_dependency('google-api-client')
20
+
21
+ gem.add_development_dependency("rake")
22
+ gem.add_development_dependency("rspec")
23
+ gem.add_development_dependency("ci_reporter")
24
+ gem.add_development_dependency("gem_publisher", "~> 1.1.1")
25
+
26
+ end
data/jenkins.sh ADDED
@@ -0,0 +1,6 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ bundle install --path "${HOME}/bundles/${JOB_NAME}"
5
+ bundle exec rake ci:setup:rspec spec --trace
6
+ bundle exec rake publish_gem
@@ -0,0 +1,110 @@
1
+ require "oauth2"
2
+ require "google/api_client"
3
+
4
+ module GoogleAuthenticationBridge
5
+ class GoogleAuthentication
6
+ GOOGLE_REDIRECT_URI = 'urn:ietf:wg:oauth:2.0:oob'
7
+
8
+ def self.create_from_config_file(scope, file_name, token_file)
9
+ config = YAML.load_file(file_name)
10
+ GoogleAuthentication.new(
11
+ scope,
12
+ config["google_client_id"],
13
+ config["google_client_secret"],
14
+ token_file)
15
+ end
16
+
17
+ def initialize(scope, client_id, client_secret, token_file)
18
+ @scope = scope
19
+ @client_id = client_id
20
+ @client_secret = client_secret
21
+ @token_file = token_file
22
+ end
23
+
24
+ def get_tokens(authorization_code=nil)
25
+ client = Google::APIClient.new
26
+ setup_credentials(client, authorization_code)
27
+ refresh_tokens(client)
28
+ end
29
+
30
+ def get_oauth2_access_token(authorization_code=nil)
31
+ OAuth2::AccessToken.from_hash(get_oauth2_client, get_tokens(authorization_code))
32
+ end
33
+
34
+ def get_auth_url
35
+ "https://accounts.google.com/o/oauth2/auth?response_type=code&scope=#{URI::encode(@scope)}&redirect_uri=#{GOOGLE_REDIRECT_URI}&client_id=#{URI::encode(@client_id)}"
36
+ end
37
+
38
+ def load_token_from_file
39
+ raise FileNotFoundError.new(@token_file) unless File.exists? @token_file
40
+
41
+ begin
42
+ token_data = YAML.load_file(@token_file)
43
+ token = token_data[:refresh_token]
44
+
45
+ raise InvalidFileFormatError.new(@token_file) unless token
46
+ token
47
+ rescue
48
+ raise InvalidFileFormatError.new(@token_file)
49
+ end
50
+ end
51
+
52
+ def save_token_to_file(refresh_token)
53
+ raise InvalidTokenError.new(refresh_token) if refresh_token.nil?
54
+ File.open(@token_file, 'w') { |f|
55
+ f.write(YAML.dump({:refresh_token => refresh_token}))
56
+ }
57
+ end
58
+
59
+ private
60
+ def get_oauth2_client
61
+ OAuth2::Client.new(@client_id, @client_secret,
62
+ site: "https://accounts.google.com",
63
+ token_url: "/o/oauth2/token",
64
+ authorize_url: "/o/oauth2/auth"
65
+ )
66
+ end
67
+
68
+ def setup_credentials(client, code)
69
+ authorization = client.authorization
70
+ authorization.client_id = @client_id
71
+ authorization.client_secret = @client_secret
72
+ authorization.scope = @scope
73
+ authorization.redirect_uri = GOOGLE_REDIRECT_URI
74
+ authorization.code = code
75
+ end
76
+
77
+ def refresh_tokens(client)
78
+ if File.exist? @token_file
79
+ client.authorization.update_token!(refresh_token: load_token_from_file)
80
+ tokens = client.authorization.fetch_access_token
81
+ else
82
+ tokens = client.authorization.fetch_access_token
83
+ save_token_to_file(tokens["refresh_token"])
84
+ end
85
+ tokens
86
+ end
87
+
88
+ end
89
+
90
+ class Error < Exception
91
+ end
92
+
93
+ class FileNotFoundError < Error
94
+ def initialize filename
95
+ super "File not found #{filename}"
96
+ end
97
+ end
98
+
99
+ class InvalidFileFormatError < Error
100
+ def initialize filename
101
+ super "Invalid token file format in '#{filename}'."
102
+ end
103
+ end
104
+
105
+ class InvalidTokenError < Error
106
+ def initialize token
107
+ super "Invalid token '#{token.inspect}'."
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,3 @@
1
+ module GoogleAuthenticationBridge
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,54 @@
1
+ require_relative "../lib/google_auth_bridge"
2
+ require "tempfile"
3
+
4
+ describe "Google Authentication Client" do
5
+ before(:each) do
6
+ @filename = "/tmp/test.token"
7
+ @auth = GoogleAuthenticationBridge::GoogleAuthentication.new(nil, nil, nil, @filename)
8
+ @yaml_content = "---\n:refresh_token: foo bar\n"
9
+ @yaml_pattern = /---\s?\n:refresh_token: foo bar\n/
10
+ end
11
+
12
+ after(:each) do
13
+ File.delete(@filename) if File.exists? @filename
14
+ end
15
+
16
+ it "should save refresh token to file as yaml" do
17
+ File.exists?(@filename).should be_false
18
+ @auth.save_token_to_file("foo bar")
19
+ File.exists?(@filename).should be_true
20
+ File.read(@filename).should match(@yaml_pattern)
21
+ end
22
+
23
+ it "should raise an InvalidTokenError exception if the refresh token is nil" do
24
+ lambda {
25
+ @auth.save_token_to_file(nil)
26
+ }.should raise_error(GoogleAuthenticationBridge::InvalidTokenError)
27
+ end
28
+
29
+ it "should load refresh token from yaml file" do
30
+ File.open(@filename, 'w') {|f| f.write(@yaml_content) }
31
+ @auth.load_token_from_file.should == "foo bar"
32
+ end
33
+
34
+ it "should raise a FileNotFoundError exception if the file is not there" do
35
+ lambda {
36
+ @auth.load_token_from_file
37
+ }.should raise_error(GoogleAuthenticationBridge::FileNotFoundError)
38
+ end
39
+
40
+ it "should raise an InvalidFileFormatError exception if the file is badly formatted" do
41
+ File.open(@filename, 'w') {|f| f.write("bad content") }
42
+ lambda {
43
+ @auth.load_token_from_file
44
+ }.should raise_error(GoogleAuthenticationBridge::InvalidFileFormatError)
45
+ end
46
+
47
+
48
+ it "should raise an InvalidFileFormatError exception if the file does not contain refresh token" do
49
+ File.open(@filename, 'w') {|f| f.write("---\n:refresh_token: \n") }
50
+ lambda {
51
+ @auth.load_token_from_file
52
+ }.should raise_error(GoogleAuthenticationBridge::InvalidFileFormatError)
53
+ end
54
+ end
metadata ADDED
@@ -0,0 +1,135 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: google_auth_bridge
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.0
6
+ platform: ruby
7
+ authors:
8
+ - ssatish
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2012-08-24 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: oauth2
17
+ requirement: &id001 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: "0"
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: google-api-client
28
+ requirement: &id002 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: rake
39
+ requirement: &id003 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: "0"
45
+ type: :development
46
+ prerelease: false
47
+ version_requirements: *id003
48
+ - !ruby/object:Gem::Dependency
49
+ name: rspec
50
+ requirement: &id004 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: *id004
59
+ - !ruby/object:Gem::Dependency
60
+ name: ci_reporter
61
+ requirement: &id005 !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: "0"
67
+ type: :development
68
+ prerelease: false
69
+ version_requirements: *id005
70
+ - !ruby/object:Gem::Dependency
71
+ name: gem_publisher
72
+ requirement: &id006 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 1.1.1
78
+ type: :development
79
+ prerelease: false
80
+ version_requirements: *id006
81
+ description: bridge for supporting multiple google authentication libraries
82
+ email:
83
+ - seema.satish@digital.cabinet-office.gov.uk
84
+ executables: []
85
+
86
+ extensions: []
87
+
88
+ extra_rdoc_files: []
89
+
90
+ files:
91
+ - .gitignore
92
+ - Gemfile
93
+ - LICENSE
94
+ - README.md
95
+ - Rakefile
96
+ - google_auth_bridge.gemspec
97
+ - jenkins.sh
98
+ - lib/google_auth_bridge.rb
99
+ - lib/google_auth_bridge/version.rb
100
+ - spec/google_auth_bridge_spec.rb
101
+ homepage: https://github.com/alphagov/google-auth-bridge
102
+ licenses: []
103
+
104
+ post_install_message:
105
+ rdoc_options: []
106
+
107
+ require_paths:
108
+ - lib
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ none: false
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ hash: -2931254444280982549
115
+ segments:
116
+ - 0
117
+ version: "0"
118
+ required_rubygems_version: !ruby/object:Gem::Requirement
119
+ none: false
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ hash: -2931254444280982549
124
+ segments:
125
+ - 0
126
+ version: "0"
127
+ requirements: []
128
+
129
+ rubyforge_project:
130
+ rubygems_version: 1.8.24
131
+ signing_key:
132
+ specification_version: 3
133
+ summary: bridge for supporting multiple google authentication libraries
134
+ test_files:
135
+ - spec/google_auth_bridge_spec.rb