google_auth_bridge 0.1.0

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