google_oauth_calendar 0.3.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.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in google_oauth_calendar.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Ben Johnson
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.
@@ -0,0 +1,72 @@
1
+ # GoogleOauthCalendar
2
+
3
+ This provides a generator that installs everything you need to be able to authenticate users against
4
+ their Google identity (via oauth2), and then use the google apis to start interacting with their calendars.
5
+ This isn't limited to Google Calendars, but it's a nice starter example to demonstrate their services.
6
+
7
+ Rather than
8
+ the individual instructions at each in each gem, and stubbing your toe a half dozen times in the process, this is
9
+ a one-stop generator.
10
+
11
+ Specifically, it
12
+
13
+ * creates a User model with name & email pulled from Google, and a place to store their access and refresh token
14
+ * initializes omniauth to use the google-oauth2 strategy for signin
15
+ * creates a SessionsController to react to signin/signout
16
+ * installs a basic root controller that has view showing signin/signout links,
17
+ and queries the list of the user's calendars via the google/api_client
18
+
19
+ This gem allows you to install these features after your app already exists, rather than using an application
20
+ template such as [rails_apps_composer](https://github.com/RailsApps/rails_apps_composer). This way, it makes
21
+ fewer assumptions about your other app preferences.
22
+
23
+ ## Configuring Google API
24
+
25
+ You need to configure an API instance at Google for your app's use. This becomes the trust link
26
+ between the systems. You can use a regular google identity for this, Google Apps for Business or other
27
+ paid services are not required, assuming you can deal with their usage limits.
28
+
29
+ 1. Go to to the [Google API Console](https://code.google.com/apis/console/), and create a new project.
30
+ (The name doesn't matter, but will probably match your rails project name)
31
+ 1. Go to the service tab, and enable **Calendar API**
32
+ 1. Go to the **API Access** tab, and create an OAuth 2.0 client ID
33
+ 1. pick a project name
34
+ 1. choose "web application" as the application type
35
+ 1. for "your site or hostname" choose "more options" and use
36
+
37
+ http://localhost:3000/auth/google_oauth2/callback
38
+ 1. copy the client ID and secret into environment variables, for example
39
+
40
+ export GOOGLE_CLIENT_ID = "YOUR_CLIENT_ID"
41
+ export GOOGLE_CLIENT_SECRET = "YOUR_CLIENT_SECRET"
42
+ ## Installation
43
+
44
+ Add this line to your application's Gemfile:
45
+
46
+ gem 'google_oauth_calendar' , :git => 'git@github.com:deafgreatdane/google_oauth_calendar.git'
47
+
48
+ And then execute:
49
+
50
+ $ bundle
51
+ $ rails generate google_oauth_calendar:install
52
+ $ rake db:migrate
53
+ $ rails server
54
+
55
+ When you click the "signin" link, you'll be redirected to google, asked to confirm your app's use of calendar
56
+ APIs, then it direct back to your home page, signed in, and list your calendars.
57
+
58
+ At this point, you can remove the gem from your gemfile, since it's only the generator
59
+
60
+ ## Where to go from here
61
+
62
+ Now you can get to work at adding the real features using your preferred patterns. Some things you'll
63
+ probably end up doing:
64
+
65
+ * add a UserController for seeing who has connected
66
+ * add "filter authenticate_user!" to your secure controllers
67
+ * learn more about the [calendar or other google apis](http://code.google.com/p/google-api-ruby-client/wiki/SupportedAPIs)
68
+ via the [google-api-client](http://code.google.com/p/google-api-ruby-client/)
69
+ * add more "redirect URLs" to your Google API console, corresponding to your stage & production urls.
70
+ * add error handling for chatting with Google
71
+
72
+ Feedback and contributions are welcome, just file an issue or create pull request
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,17 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/google_oauth_calendar/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Ben Johnson"]
6
+ gem.email = ["deafgreatdane@gmail.com"]
7
+ gem.description = %q{a generator for adding google-based users via omniauth, and querying google calendars}
8
+ gem.summary = %q{just run rails generate google_oauth_calendar:install }
9
+ gem.homepage = ""
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_oauth_calendar"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = GoogleOauthCalendar::VERSION
17
+ end
@@ -0,0 +1,4 @@
1
+ require "google_oauth_calendar/version"
2
+
3
+ module GoogleOauthCalendar
4
+ end
@@ -0,0 +1,3 @@
1
+ module GoogleOauthCalendar
2
+ VERSION = "0.3.0"
3
+ end
@@ -0,0 +1,83 @@
1
+ module GoogleOauthCalendar
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+ desc "This generator installs all the snippets for users via google oauth"
5
+ def self.source_root
6
+ @source_root ||= File.join(File.dirname(__FILE__), 'templates')
7
+ end
8
+
9
+ def add_files
10
+ # the gems we're using
11
+ gem "omniauth", ">= 1.0.3"
12
+ gem "omniauth-google-oauth2"
13
+ gem 'google-api-client'
14
+
15
+ # wire up the omniauth strategy. This assumes you have environment
16
+ # variables GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET
17
+ # such as
18
+ # export GOOGLE_CLIENT_ID = "YOUR_CLIENT_ID"
19
+ # export GOOGLE_CLIENT_SECRET = "YOUR_CLIENT_SECRET"
20
+ template 'omniauth.rb', 'config/initializers/omniauth.rb'
21
+
22
+ # this is the controller that connects oauth to user user model
23
+ template 'sessions_controller.rb', 'app/controllers/sessions_controller.rb'
24
+ route("match '/auth/:provider/callback' => 'sessions#create'")
25
+ route("match '/signin' => 'sessions#new', :as => :signin")
26
+ route("match '/signout' => 'sessions#destroy', :as => :signout")
27
+ route("match '/auth/failure' => 'sessions#failure'")
28
+
29
+ # setup the user info
30
+ generate("model User provider:string uid:string name:string email:string token:string refresh_token:string token_expires_at:datetime")
31
+
32
+ inject_into_class "app/models/user.rb", User, <<-USER_METHODS
33
+ def self.create_with_omniauth(auth)
34
+ create! do |user|
35
+ user.provider = auth['provider']
36
+ user.uid = auth['uid']
37
+ if auth['info']
38
+ user.name = auth['info']['name'] || ""
39
+ user.email = auth['info']['email'] || ""
40
+ end
41
+ end
42
+ end
43
+ USER_METHODS
44
+
45
+
46
+ inject_into_class "app/controllers/application_controller.rb", ApplicationController ,<<APP_HELPERS
47
+ helper_method :current_user
48
+ helper_method :user_signed_in?
49
+ helper_method :correct_user?
50
+
51
+ private
52
+ def current_user
53
+ @current_user ||= User.find(session[:user_id]) if session[:user_id]
54
+ end
55
+
56
+ def user_signed_in?
57
+ return true if current_user
58
+ end
59
+
60
+ def correct_user?
61
+ @user = User.find(params[:id])
62
+ unless current_user == @user
63
+ redirect_to root_url, :alert => "Access denied."
64
+ end
65
+ end
66
+
67
+ def authenticate_user!
68
+ if !current_user
69
+ redirect_to root_url, :alert => 'You need to sign in for access to this page.'
70
+ end
71
+ end
72
+ APP_HELPERS
73
+
74
+ # setup the home controller
75
+ template 'home_controller.rb', 'app/controllers/home_controller.rb'
76
+ copy_file 'index.html.erb', 'app/views/home/index.html.erb'
77
+ copy_file 'client_builder.rb', 'lib/client_builder.rb'
78
+ remove_file 'public/index.html'
79
+ route("root :to => 'home#index'")
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,29 @@
1
+ require 'google/api_client'
2
+
3
+ class ClientBuilder
4
+
5
+ def self.get_client(user)
6
+ client = Google::APIClient.new
7
+ client.authorization.scope = 'https://www.googleapis.com/auth/calendar'
8
+ client.authorization.access_token = get_current_token(user)
9
+ client
10
+ end
11
+
12
+ def self.get_current_token(user)
13
+ if (user.token.nil? || (user.token_expires_at.nil? || user.token_expires_at <Time.now))
14
+ # fetch new value here.
15
+ client = OAuth2::Client.new(
16
+ ENV['GOOGLE_CLIENT_ID'], ENV['GOOGLE_CLIENT_SECRET'],
17
+ :site => "https://accounts.google.com",
18
+ :token_url => "/o/oauth2/token",
19
+ :authorize_url => "/o/oauth2/auth")
20
+ access_token = OAuth2::AccessToken.from_hash(client,
21
+ {:refresh_token => user.refresh_token})
22
+ access_token = access_token.refresh!
23
+ user.token = access_token.token
24
+ user.token_expires_at = Time.now + access_token.expires_in
25
+ user.save
26
+ end
27
+ user.token
28
+ end
29
+ end
@@ -0,0 +1,14 @@
1
+ class HomeController < ApplicationController
2
+ require 'google/api_client'
3
+ require 'client_builder'
4
+ def index
5
+ if (user_signed_in? )
6
+ client = ClientBuilder.get_client(current_user)
7
+ service = client.discovered_api('calendar', 'v3')
8
+ result = client.execute(:api_method => service.calendar_list.list)
9
+
10
+ @calendars = result.data
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,15 @@
1
+ <h1>Home</h1>
2
+
3
+ <p>
4
+ <%- if user_signed_in? %>
5
+ Greetings <%= current_user.name %>
6
+ [<%= link_to "sign out", signout_path %>]
7
+ <ul>
8
+ <% @calendars.items.each do |calendar| %>
9
+ <li><%= calendar["summary"] %></li>
10
+ <% end %>
11
+ </ul>
12
+ <% else %>
13
+ [<%= link_to "sign in", signin_path %>]
14
+ <% end %>
15
+ </p>
@@ -0,0 +1,11 @@
1
+ Rails.application.config.middleware.use OmniAuth::Builder do
2
+ scopes = [
3
+ # we need the profile scope in order to login
4
+ "https://www.googleapis.com/auth/userinfo.profile",
5
+ # this and other scopes could be added, but match them up with the
6
+ # features you requested in your API Console
7
+ "https://www.googleapis.com/auth/calendar"
8
+ ]
9
+ provider :google_oauth2, ENV['GOOGLE_CLIENT_ID'], ENV['GOOGLE_CLIENT_SECRET'],
10
+ {:scope =>scopes.join(" ")}
11
+ end
@@ -0,0 +1,31 @@
1
+ class SessionsController < ApplicationController
2
+
3
+ def new
4
+ redirect_to '/auth/google_oauth2'
5
+ end
6
+
7
+ def create
8
+ auth = request.env["omniauth.auth"]
9
+ user = User.where(:provider => auth['provider'],
10
+ :uid => auth['uid']).first || User.create_with_omniauth(auth)
11
+ user.token = auth[:credentials][:token];
12
+ user.token_expires_at = Time.at(auth[:credentials][:expires_at])
13
+ user.refresh_token = auth[:credentials][:refresh_token]
14
+ user.save
15
+
16
+ session[:user_id] = user.id
17
+ redirect_to root_url, :notice => 'Signed in!'
18
+ end
19
+
20
+ def destroy
21
+ reset_session
22
+ redirect_to root_url, :notice => 'Signed out!'
23
+ end
24
+
25
+ def failure
26
+ # if you want to debug something better, this is the object you want
27
+ #auth = request.env["omniauth.error"]
28
+ redirect_to root_url, :alert => "Authentication error: #{params[:message].humanize}"
29
+ end
30
+
31
+ end
@@ -0,0 +1,17 @@
1
+ class User < ActiveRecord::Base
2
+ attr_accessible :email, :name, :provider, :uid
3
+ attr_accessible :provider, :uid, :name, :email
4
+
5
+ def self.create_with_omniauth(auth)
6
+ create! do |user|
7
+ user.provider = auth['provider']
8
+ user.uid = auth['uid']
9
+ if auth['info']
10
+ user.name = auth['info']['name'] || ""
11
+ user.email = auth['info']['email'] || ""
12
+ end
13
+ end
14
+ end
15
+
16
+ end
17
+
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: google_oauth_calendar
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ben Johnson
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-10-26 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: a generator for adding google-based users via omniauth, and querying
15
+ google calendars
16
+ email:
17
+ - deafgreatdane@gmail.com
18
+ executables: []
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - .gitignore
23
+ - Gemfile
24
+ - LICENSE
25
+ - README.md
26
+ - Rakefile
27
+ - google_oauth_calendar.gemspec
28
+ - lib/google_oauth_calendar.rb
29
+ - lib/google_oauth_calendar/version.rb
30
+ - lib/rails/generators/google_oauth_calendar/install/install_generator.rb
31
+ - lib/rails/generators/google_oauth_calendar/install/templates/client_builder.rb
32
+ - lib/rails/generators/google_oauth_calendar/install/templates/home_controller.rb
33
+ - lib/rails/generators/google_oauth_calendar/install/templates/index.html.erb
34
+ - lib/rails/generators/google_oauth_calendar/install/templates/omniauth.rb
35
+ - lib/rails/generators/google_oauth_calendar/install/templates/sessions_controller.rb
36
+ - lib/rails/generators/google_oauth_calendar/install/templates/user.rb
37
+ homepage: ''
38
+ licenses: []
39
+ post_install_message:
40
+ rdoc_options: []
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ! '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ requirements: []
56
+ rubyforge_project:
57
+ rubygems_version: 1.8.24
58
+ signing_key:
59
+ specification_version: 3
60
+ summary: just run rails generate google_oauth_calendar:install
61
+ test_files: []