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.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +72 -0
- data/Rakefile +2 -0
- data/google_oauth_calendar.gemspec +17 -0
- data/lib/google_oauth_calendar.rb +4 -0
- data/lib/google_oauth_calendar/version.rb +3 -0
- data/lib/rails/generators/google_oauth_calendar/install/install_generator.rb +83 -0
- data/lib/rails/generators/google_oauth_calendar/install/templates/client_builder.rb +29 -0
- data/lib/rails/generators/google_oauth_calendar/install/templates/home_controller.rb +14 -0
- data/lib/rails/generators/google_oauth_calendar/install/templates/index.html.erb +15 -0
- data/lib/rails/generators/google_oauth_calendar/install/templates/omniauth.rb +11 -0
- data/lib/rails/generators/google_oauth_calendar/install/templates/sessions_controller.rb +31 -0
- data/lib/rails/generators/google_oauth_calendar/install/templates/user.rb +17 -0
- metadata +61 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
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.
|
data/README.md
ADDED
@@ -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
|
data/Rakefile
ADDED
@@ -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,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: []
|